diff --git a/src/index.js b/src/index.js index 383fd6a..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)) { @@ -56,6 +57,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 +98,21 @@ function TCP () { } this.close = (callback) => { + log('closing') 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() + }) + }, 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) + } + }) + }) })