From f306cba84f8b6a91e0ad8ec1a1bdff92f6e37003 Mon Sep 17 00:00:00 2001 From: Jacob Heun Date: Wed, 5 Jun 2019 16:43:42 +0200 Subject: [PATCH] fix: clear blacklist for peer when connection is established (#340) --- src/connection/manager.js | 8 +++++++- src/dialer/queue.js | 3 ++- test/dial-fsm.node.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/connection/manager.js b/src/connection/manager.js index 38bb4e5bed..42d9749bee 100644 --- a/src/connection/manager.js +++ b/src/connection/manager.js @@ -36,8 +36,14 @@ class ConnectionManager { this.switch.emit('connection:start', connection.theirPeerInfo) if (connection.getState() === 'MUXED') { this.switch.emit('peer-mux-established', connection.theirPeerInfo) + // Clear the blacklist of the peer + this.switch.dialer.clearBlacklist(connection.theirPeerInfo) } else { - connection.once('muxed', () => this.switch.emit('peer-mux-established', connection.theirPeerInfo)) + connection.once('muxed', () => { + this.switch.emit('peer-mux-established', connection.theirPeerInfo) + // Clear the blacklist of the peer + this.switch.dialer.clearBlacklist(connection.theirPeerInfo) + }) } } } diff --git a/src/dialer/queue.js b/src/dialer/queue.js index c4e0f871d5..8279adc3ec 100644 --- a/src/dialer/queue.js +++ b/src/dialer/queue.js @@ -82,10 +82,11 @@ class Queue { * @param {string} protocol * @param {boolean} useFSM If callback should use a ConnectionFSM instead * @param {function(Error, Connection)} callback + * @returns {void} */ add (protocol, useFSM, callback) { if (!this.isDialAllowed()) { - nextTick(callback, ERR_BLACKLISTED()) + return nextTick(callback, ERR_BLACKLISTED()) } this._queue.push({ protocol, useFSM, callback }) } diff --git a/test/dial-fsm.node.js b/test/dial-fsm.node.js index e7ddd653e7..3bcc5312b2 100644 --- a/test/dial-fsm.node.js +++ b/test/dial-fsm.node.js @@ -10,6 +10,7 @@ chai.use(dirtyChai) const sinon = require('sinon') const PeerBook = require('peer-book') const parallel = require('async/parallel') +const series = require('async/series') const WS = require('libp2p-websockets') const TCP = require('libp2p-tcp') const secio = require('libp2p-secio') @@ -25,16 +26,18 @@ describe('dialFSM', () => { let switchA let switchB let switchC + let switchDialOnly let peerAId let peerBId let protocol - before((done) => createInfos(3, (err, infos) => { + before((done) => createInfos(4, (err, infos) => { expect(err).to.not.exist() const peerA = infos[0] const peerB = infos[1] const peerC = infos[2] + const peerDialOnly = infos[3] peerAId = peerA.id.toB58String() peerBId = peerB.id.toB58String() @@ -48,22 +51,27 @@ describe('dialFSM', () => { switchA = new Switch(peerA, new PeerBook()) switchB = new Switch(peerB, new PeerBook()) switchC = new Switch(peerC, new PeerBook()) + switchDialOnly = new Switch(peerDialOnly, new PeerBook()) switchA.transport.add('tcp', new TCP()) switchB.transport.add('tcp', new TCP()) switchC.transport.add('ws', new WS()) + switchDialOnly.transport.add('ws', new WS()) switchA.connection.crypto(secio.tag, secio.encrypt) switchB.connection.crypto(secio.tag, secio.encrypt) switchC.connection.crypto(secio.tag, secio.encrypt) + switchDialOnly.connection.crypto(secio.tag, secio.encrypt) switchA.connection.addStreamMuxer(multiplex) switchB.connection.addStreamMuxer(multiplex) switchC.connection.addStreamMuxer(multiplex) + switchDialOnly.connection.addStreamMuxer(multiplex) switchA.connection.reuse() switchB.connection.reuse() switchC.connection.reuse() + switchDialOnly.connection.reuse() parallel([ (cb) => switchA.start(cb), @@ -155,6 +163,30 @@ describe('dialFSM', () => { }) }) + it('should clear the blacklist for a peer that connected to us', (done) => { + series([ + // Attempt to dial the peer that's not listening + (cb) => switchC.dial(switchDialOnly._peerInfo, (err) => { + expect(err).to.exist() + cb() + }), + // Dial from the dial only peer + (cb) => switchDialOnly.dial(switchC._peerInfo, (err) => { + expect(err).to.not.exist() + // allow time for muxing to occur + setTimeout(cb, 100) + }), + // "Dial" to the dial only peer, this should reuse the existing connection + (cb) => switchC.dial(switchDialOnly._peerInfo, (err) => { + expect(err).to.not.exist() + cb() + }) + ], (err) => { + expect(err).to.not.exist() + done() + }) + }) + it('should emit a `closed` event when closed', (done) => { protocol = '/closed/1.0.0' switchB.handle(protocol, () => { })