Skip to content

Commit

Permalink
feat: add autorenew functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dryajov committed Aug 8, 2018
1 parent 43e9891 commit 41767d1
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
42 changes: 41 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,59 @@ const NatPmp = require('./mappers/pmp')
const UPnP = require('./mappers/upnp')
const EE = require('events')
const tryEach = require('async/tryEach')
const eachSeries = require('async/eachSeries')
const parallel = require('async/parallel')
const waterfall = require('async/waterfall')
const network = require('network')

const log = require('debug')('libp2p-nat-mngr')

class NatManager extends EE {
constructor (mappers) {
constructor (mappers, options) {
super()

options = options || {
autorenew: true,
every: 60 * 10 * 1000
}

this.mappers = mappers || [
new NatPmp(),
new UPnP()
]

this.activeMappings = {}

if (options.autorenew) {
setInterval(() => {
this.renewMappings()
}, options.every)
}
}

renewMappings (callback) {
callback = callback || (() => {})
this.getPublicIp((err, ip) => {
if (err) {
return log(err)
}

eachSeries(Object.keys(this.activeMappings), (key, cb) => {
const mapping = this.activeMappings[key].mappings[key]
if (mapping.externalIp !== ip) {
delete this.activeMappings[key]
this.addMapping(mapping.internalPort,
mapping.externalPort,
mapping.ttl,
(err) => {
if (err) {
return log(err)
}
return cb()
})
}
}, callback)
})
}

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

const mapKey = `${mapping.externalIp}:${mapping.externalPort}`
this.activeMappings[mapKey] = mapper
this.emit('mapping', mapping)
cb(null, mapping)
})
}
Expand Down
31 changes: 29 additions & 2 deletions test/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ chai.use(require('chai-checkmark'))
const Manager = require('../src')
const Mapper = require('../src/mappers')

const network = require('network')

const expect = chai.expect

describe('NAT manager', () => {
Expand All @@ -17,7 +19,7 @@ describe('NAT manager', () => {
super('mapper1')
}

_addPortMapping (intPort, extPort, lifetime, cb) {
_addPortMapping (intPort, extPort, ttl, cb) {
cb(null, this.newMapping(intPort))
}
}
Expand All @@ -38,7 +40,7 @@ describe('NAT manager', () => {
let fail = true

class Mapper1 extends Mapper {
_addPortMapping (intPort, extPort, lifetime, cb) {
_addPortMapping (intPort, extPort, ttl, cb) {
cb(fail ? new Error('fail') : null, this.newMapping(intPort))
fail = false
}
Expand All @@ -57,4 +59,29 @@ describe('NAT manager', () => {
done()
})
})

it('should renew mapping', (done) => {
class Mapper1 extends Mapper {
_addPortMapping (intPort, extPort, ttl, cb) {
const mapping = this.newMapping(intPort)
mapping.externalIp = '127.0.0.1'
mapping.externalPort = intPort
cb(null, mapping)
}
}

const manager = new Manager([
new Mapper1('1')
])

manager.addMapping(55555, 55555, 0, (err, mapping) => {
manager.renewMappings(() => {
expect(err).to.not.exist()
expect(mapping).to.exist()
expect(mapping.protocol).to.eql('1')
expect(mapping.internalPort).to.eql(55555)
done()
})
})
})
})

0 comments on commit 41767d1

Please sign in to comment.