Skip to content

Commit 2f94f41

Browse files
dryajovjacobheun
authored andcommitted
feat: add autorenew functionality
1 parent 9374578 commit 2f94f41

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

src/index.js

+41-1
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,59 @@ const NatPmp = require('./mappers/pmp')
44
const UPnP = require('./mappers/upnp')
55
const EE = require('events')
66
const tryEach = require('async/tryEach')
7+
const eachSeries = require('async/eachSeries')
78
const parallel = require('async/parallel')
89
const waterfall = require('async/waterfall')
910
const network = require('network')
1011

12+
const log = require('debug')('libp2p-nat-mngr')
13+
1114
class NatManager extends EE {
12-
constructor (mappers) {
15+
constructor (mappers, options) {
1316
super()
1417

18+
options = options || {
19+
autorenew: true,
20+
every: 60 * 10 * 1000
21+
}
22+
1523
this.mappers = mappers || [
1624
new NatPmp(),
1725
new UPnP()
1826
]
1927

2028
this.activeMappings = {}
29+
30+
if (options.autorenew) {
31+
setInterval(() => {
32+
this.renewMappings()
33+
}, options.every)
34+
}
35+
}
36+
37+
renewMappings (callback) {
38+
callback = callback || (() => {})
39+
this.getPublicIp((err, ip) => {
40+
if (err) {
41+
return log(err)
42+
}
43+
44+
eachSeries(Object.keys(this.activeMappings), (key, cb) => {
45+
const mapping = this.activeMappings[key].mappings[key]
46+
if (mapping.externalIp !== ip) {
47+
delete this.activeMappings[key]
48+
this.addMapping(mapping.internalPort,
49+
mapping.externalPort,
50+
mapping.ttl,
51+
(err) => {
52+
if (err) {
53+
return log(err)
54+
}
55+
return cb()
56+
})
57+
}
58+
}, callback)
59+
})
2160
}
2261

2362
addMapping (intPort, extPort, ttl, callback) {
@@ -33,6 +72,7 @@ class NatManager extends EE {
3372

3473
const mapKey = `${mapping.externalIp}:${mapping.externalPort}`
3574
this.activeMappings[mapKey] = mapper
75+
this.emit('mapping', mapping)
3676
cb(null, mapping)
3777
})
3878
}

test/manager.js

+27-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('NAT manager', () => {
1717
super('mapper1')
1818
}
1919

20-
_addPortMapping (intPort, extPort, lifetime, cb) {
20+
_addPortMapping (intPort, extPort, ttl, cb) {
2121
cb(null, this.newMapping(intPort))
2222
}
2323
}
@@ -38,7 +38,7 @@ describe('NAT manager', () => {
3838
let fail = true
3939

4040
class Mapper1 extends Mapper {
41-
_addPortMapping (intPort, extPort, lifetime, cb) {
41+
_addPortMapping (intPort, extPort, ttl, cb) {
4242
cb(fail ? new Error('fail') : null, this.newMapping(intPort))
4343
fail = false
4444
}
@@ -57,4 +57,29 @@ describe('NAT manager', () => {
5757
done()
5858
})
5959
})
60+
61+
it('should renew mapping', (done) => {
62+
class Mapper1 extends Mapper {
63+
_addPortMapping (intPort, extPort, ttl, cb) {
64+
const mapping = this.newMapping(intPort)
65+
mapping.externalIp = '127.0.0.1'
66+
mapping.externalPort = intPort
67+
cb(null, mapping)
68+
}
69+
}
70+
71+
const manager = new Manager([
72+
new Mapper1('1')
73+
])
74+
75+
manager.addMapping(55555, 55555, 0, (err, mapping) => {
76+
manager.renewMappings(() => {
77+
expect(err).to.not.exist()
78+
expect(mapping).to.exist()
79+
expect(mapping.protocol).to.eql('1')
80+
expect(mapping.internalPort).to.eql(55555)
81+
done()
82+
})
83+
})
84+
})
6085
})

0 commit comments

Comments
 (0)