From c9e8dd5714df11a4591efd6245452cf718d43081 Mon Sep 17 00:00:00 2001 From: Jacob Heun Date: Fri, 9 Nov 2018 23:10:52 +0100 Subject: [PATCH] feat: add support for ip6 wildcards License: MIT Signed-off-by: Jacob Heun --- package.json | 11 ++++----- src/index.js | 10 ++++---- src/listener.js | 53 +++++++++++++++++++---------------------- test/compliance.spec.js | 1 + test/listen-dial.js | 19 ++++++++++++++- 5 files changed, 52 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index a07eaf3..2308548 100644 --- a/package.json +++ b/package.json @@ -34,22 +34,19 @@ "npm": ">=3.0.0" }, "devDependencies": { - "aegir": "^15.1.0", - "chai": "^4.1.2", + "aegir": "^17.0.1", + "chai": "^4.2.0", "dirty-chai": "^2.0.1", "interface-transport": "~0.3.6", - "lodash.isfunction": "^3.0.9", "pull-stream": "^3.6.9" }, "dependencies": { "class-is": "^1.1.0", - "debug": "^3.1.0", + "debug": "^4.1.0", "interface-connection": "~0.3.2", "ip-address": "^5.8.9", - "lodash.includes": "^4.3.0", - "lodash.isfunction": "^3.0.9", "mafmt": "^6.0.2", - "multiaddr": "^5.0.0", + "multiaddr": "^5.0.2", "once": "^1.4.0", "stream-to-pull-stream": "^1.7.2" }, diff --git a/src/index.js b/src/index.js index b04c223..0e8215e 100644 --- a/src/index.js +++ b/src/index.js @@ -4,8 +4,6 @@ const net = require('net') const toPull = require('stream-to-pull-stream') const mafmt = require('mafmt') const withIs = require('class-is') -const includes = require('lodash.includes') -const isFunction = require('lodash.isfunction') const Connection = require('interface-connection').Connection const once = require('once') const debug = require('debug') @@ -17,7 +15,7 @@ function noop () {} class TCP { dial (ma, options, callback) { - if (isFunction(options)) { + if (typeof options === 'function') { callback = options options = {} } @@ -53,7 +51,7 @@ class TCP { } createListener (options, handler) { - if (isFunction(options)) { + if (typeof options === 'function') { handler = options options = {} } @@ -69,11 +67,11 @@ class TCP { } return multiaddrs.filter((ma) => { - if (includes(ma.protoNames(), 'p2p-circuit')) { + if (ma.protoNames().includes('p2p-circuit')) { return false } - if (includes(ma.protoNames(), 'ipfs')) { + if (ma.protoNames().includes('ipfs')) { ma = ma.decapsulate('ipfs') } diff --git a/src/listener.js b/src/listener.js index 30b3076..75e27e0 100644 --- a/src/listener.js +++ b/src/listener.js @@ -3,7 +3,6 @@ const multiaddr = require('multiaddr') const Connection = require('interface-connection').Connection const os = require('os') -const includes = require('lodash.includes') const net = require('net') const toPull = require('stream-to-pull-stream') const EventEmitter = require('events').EventEmitter @@ -12,7 +11,6 @@ const log = debug('libp2p:tcp:listen') const getMultiaddr = require('./get-multiaddr') -const IPFS_CODE = 421 const CLOSE_TIMEOUT = 2000 function noop () {} @@ -79,15 +77,10 @@ module.exports = (handler) => { }) } - let ipfsId let listeningAddr listener.listen = (ma, callback) => { listeningAddr = ma - if (includes(ma.protoNames(), 'ipfs')) { - ipfsId = getIpfsId(ma) - listeningAddr = ma.decapsulate('ipfs') - } const lOpts = listeningAddr.toOptions() log('Listening on %s %s', lOpts.port, lOpts.host) @@ -105,33 +98,43 @@ module.exports = (handler) => { // Because TCP will only return the IPv6 version // we need to capture from the passed multiaddr if (listeningAddr.toString().indexOf('ip4') !== -1) { - let m = listeningAddr.decapsulate('tcp') - m = m.encapsulate('/tcp/' + address.port) - if (ipfsId) { - m = m.encapsulate('/ipfs/' + ipfsId) - } - - if (m.toString().indexOf('0.0.0.0') !== -1) { + if (listeningAddr.toString().indexOf('0.0.0.0') !== -1) { const netInterfaces = os.networkInterfaces() Object.keys(netInterfaces).forEach((niKey) => { netInterfaces[niKey].forEach((ni) => { - if (ni.family === 'IPv4') { - multiaddrs.push(multiaddr(m.toString().replace('0.0.0.0', ni.address))) + if (ni.family === 'IPv4' && !ni.internal) { + multiaddrs.push( + multiaddr(listeningAddr.toString().replace('0.0.0.0', ni.address)) + ) } }) }) } else { - multiaddrs.push(m) + multiaddrs.push(listeningAddr) } } if (address.family === 'IPv6') { - let ma = multiaddr('/ip6/' + address.address + '/tcp/' + address.port) - if (ipfsId) { - ma = ma.encapsulate('/ipfs/' + ipfsId) + // Listen on all available addresses when using wildcard + if (listeningAddr.toString().indexOf('/::/') !== -1) { + const netInterfaces = os.networkInterfaces() + Object.keys(netInterfaces).forEach((niKey) => { + netInterfaces[niKey].forEach((ni) => { + if (ni.family === address.family) { + const maOpts = listeningAddr.toOptions() + if (maOpts.host === '::') { + maOpts.family = address.family + maOpts.address = ni.address + multiaddrs.push( + multiaddr.fromNodeAddress(maOpts, maOpts.transport) + ) + } + } + }) + }) + } else { + multiaddrs.push(listeningAddr) } - - multiaddrs.push(ma) } callback(null, multiaddrs) @@ -140,12 +143,6 @@ module.exports = (handler) => { return listener } -function getIpfsId (ma) { - return ma.stringTuples().filter((tuple) => { - return tuple[0] === IPFS_CODE - })[0][1] -} - function trackSocket (server, socket) { const key = `${socket.remoteAddress}:${socket.remotePort}` server.__connections[key] = socket diff --git a/test/compliance.spec.js b/test/compliance.spec.js index 1339086..a58c334 100644 --- a/test/compliance.spec.js +++ b/test/compliance.spec.js @@ -13,6 +13,7 @@ describe('interface-transport compliance', () => { multiaddr('/ip4/127.0.0.1/tcp/9091'), multiaddr('/ip4/127.0.0.1/tcp/9092'), multiaddr('/ip4/127.0.0.1/tcp/9093'), + multiaddr('/ip6/::/tcp/9094'), multiaddr('/dns4/ipfs.io') ] cb(null, tcp, addrs) diff --git a/test/listen-dial.js b/test/listen-dial.js index 7d8f119..092745c 100644 --- a/test/listen-dial.js +++ b/test/listen-dial.js @@ -108,7 +108,24 @@ describe('listen', () => { listener.getAddrs((err, multiaddrs) => { expect(err).to.not.exist() expect(multiaddrs.length > 0).to.equal(true) - expect(multiaddrs[0].toString().indexOf('0.0.0.0')).to.equal(-1) + multiaddrs.forEach((m) => { + expect(m.toOptions().host).to.not.eql('0.0.0.0') + }) + listener.close(done) + }) + }) + }) + + it('getAddrs from listening on ip6 \'::\'', (done) => { + const mh = multiaddr('/ip6/::/tcp/9090') + const listener = tcp.createListener((conn) => {}) + listener.listen(mh, () => { + listener.getAddrs((err, multiaddrs) => { + expect(err).to.not.exist() + expect(multiaddrs.length > 0).to.equal(true) + multiaddrs.forEach((m) => { + expect(m.toOptions().host).to.not.eql('::') + }) listener.close(done) }) })