Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dryajov authored and jacobheun committed Jan 3, 2019
1 parent 9c9f274 commit d4efb4d
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
test/repo-tests*
**/bundle.js
**/.nyc_output
**/.vscode/

# Logs
logs
Expand Down
67 changes: 67 additions & 0 deletions src/mappers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use strict'
const debug = require('debug')

class BaseMapper {
constructor (name) {
this.name = name
this.mappings = {}

this.log = debug(`nat-puncher:${name}`)
this.log.err = debug(`nat-puncher:${name}:error`)
}

newMapping (port) {
return {
routerIp: null,
internalIp: null,
internalPort: port,
externalIp: null, // Only provided by PCP, undefined for other protocols
externalPort: null, // The actual external port of the mapping, -1 on failure
ttl: null, // The actual (response) lifetime of the mapping
protocol: this.name, // The protocol used to make the mapping ('natPmp', 'pcp', 'upnp')
nonce: null, // Only for PCP; the nonce field for deletion
errInfo: null // Error message if failure; currently used only for UPnP
}
}

addMapping (intPort, extPort, ttl, callback) {
// If lifetime is zero, we want to refresh every 24 hours
ttl = !ttl ? 24 * 60 * 60 : ttl

this._addPortMapping(intPort,
extPort,
ttl,
(err, mapping) => {
if (err) {
this.log.err(err)
return callback(err)
}
this.mappings[`${mapping.externalIp}:${mapping.externalPort}`] = mapping
callback(null, mapping)
})
}

_addPortMapping (intPort, extPort, lifetime, cb) {
cb(new Error('Not implemented!'))
}

deleteMapping (mapping, callback) {
this._removePortMapping(mapping.internalPort,
mapping.externalPort,
(err) => {
if (err) {
return callback(err)
}

// delete the mappings
delete this.mappings[`${mapping.externalIp}:${mapping.externalPort}`]
callback()
})
}

_removePortMapping (intPort, extPort, callback) {
callback(new Error('Not implemented!'))
}
}

module.exports = BaseMapper
60 changes: 60 additions & 0 deletions test/manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
chai.use(require('dirty-chai'))
chai.use(require('chai-checkmark'))

const Manager = require('../src')
const Mapper = require('../src/mappers')

const expect = chai.expect

describe('NAT manager', () => {
it('should create mappings', (done) => {
class Mapper1 extends Mapper {
constructor () {
super('mapper1')
}

_addPortMapping (intPort, extPort, lifetime, cb) {
cb(null, this.newMapping(intPort))
}
}

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

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

it('should try mappings in order', (done) => {
let fail = true

class Mapper1 extends Mapper {
_addPortMapping (intPort, extPort, lifetime, cb) {
cb(fail ? new Error('fail') : null, this.newMapping(intPort))
fail = false
}
}

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

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

0 comments on commit d4efb4d

Please sign in to comment.