From 4a121696d12faa85f1d386cd596c63b0b673ced3 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 31 May 2016 14:48:18 +0200 Subject: [PATCH 1/2] fix: destroy hanging connections after timeout --- src/index.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 383fd6a..a44e1e8 100644 --- a/src/index.js +++ b/src/index.js @@ -56,6 +56,17 @@ function TCP () { } handler(conn) }) + + listener.__connections = {} + listener.on('connection', (conn) => { + const key = `${conn.remoteAddress}:${conn.remotePort}` + listener.__connections[key] = conn + + conn.on('close', () => { + delete listener.__connections[key] + }) + }) + listener.listen(m.toOptions(), () => { // Node.js likes to convert addr to IPv6 (when 0.0.0.0 for e.g) const address = listener.address() @@ -86,13 +97,22 @@ function TCP () { } this.close = (callback) => { + const closeTimeout = 300 + if (listeners.length === 0) { log('Called close with no active listeners') return callback() } - parallel(listeners.map((listener) => { - return (cb) => listener.close(cb) + parallel(listeners.map((listener) => (cb) => { + setTimeout(() => { + Object.keys(listener.__connections).forEach((key) => { + log('destroying %s', key) + listener.__connections[key].destroy() + }) + }, closeTimeout) + + listener.close(cb) }), callback) } From 2ed01e8f5b533bed75bbe546832a6d43d30c1f7a Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 31 May 2016 21:49:12 +0200 Subject: [PATCH 2/2] fix: address cr --- src/index.js | 6 +++--- test/index.spec.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index a44e1e8..037aa10 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ const contains = require('lodash.contains') exports = module.exports = TCP const IPFS_CODE = 421 +const CLOSE_TIMEOUT = 300 function TCP () { if (!(this instanceof TCP)) { @@ -97,8 +98,7 @@ function TCP () { } this.close = (callback) => { - const closeTimeout = 300 - + log('closing') if (listeners.length === 0) { log('Called close with no active listeners') return callback() @@ -110,7 +110,7 @@ function TCP () { log('destroying %s', key) listener.__connections[key].destroy() }) - }, closeTimeout) + }, CLOSE_TIMEOUT) listener.close(cb) }), callback) diff --git a/test/index.spec.js b/test/index.spec.js index 33a638c..df3ed8a 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -148,4 +148,35 @@ describe('libp2p-tcp', function () { expect(valid[0]).to.deep.equal(mh1) done() }) + + it('destroys after timeout', (done) => { + const server = new TCPlibp2p() + const mh = multiaddr('/ip4/127.0.0.1/tcp/9090') + server.createListener(mh, (conn) => { + const i = setInterval(() => { + conn.read() + conn.write('hi\n') + }, 100) + i.unref() + }, () => { + let connected = 0 + const connectHandler = () => { + connected++ + if (connected === 10) { + setTimeout(() => { + server.close(done) + }, 1) + } + } + const errorHandler = () => {} + + for (let i = 0; i < 10; i++) { + const client = net.connect(9090) + client.on('connect', connectHandler) + + // just ignore the resets + client.on('error', errorHandler) + } + }) + }) })