From 0dea0888e247ee18df21908f0a9765952d9b4036 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 25 Jul 2016 12:35:52 -0700 Subject: [PATCH] pool: add ignore list. --- browser/proxysocket.js | 6 ++++-- browser/wsproxy.js | 5 ++++- lib/bcoin/peer.js | 46 ++++++++++++++++++++++++++++++++---------- lib/bcoin/pool.js | 37 +++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/browser/proxysocket.js b/browser/proxysocket.js index 9e408ce9..c253df76 100644 --- a/browser/proxysocket.js +++ b/browser/proxysocket.js @@ -58,8 +58,10 @@ function ProxySocket(uri) { self.emit('close'); }); - this.socket.on('tcp error', function(err) { - self.emit('error', new Error(err)); + this.socket.on('tcp error', function(e) { + var err = new Error(e.message); + err.code = e.code; + self.emit('error', err); }); this.socket.on('close', function() { diff --git a/browser/wsproxy.js b/browser/wsproxy.js index b112c6e0..41df1c35 100644 --- a/browser/wsproxy.js +++ b/browser/wsproxy.js @@ -120,7 +120,10 @@ module.exports = function wsproxy(options) { }); socket.on('error', function(err) { - ws.emit('tcp error', err.message); + ws.emit('tcp error', { + message: err.message, + code: err.code || null + }); }); socket.on('close', function() { diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index 634a1159..beb2b6ab 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -198,7 +198,14 @@ Peer.prototype._init = function init() { this.socket.once('error', function(err) { self._error(err); - self.setMisbehavior(100); + + switch (err.code) { + case 'ECONNREFUSED': + case 'EHOSTUNREACH': + case 'ENETUNREACH': + self.ignore(); + break; + } }); this.socket.once('close', function() { @@ -215,8 +222,8 @@ Peer.prototype._init = function init() { }); this.parser.on('error', function(err) { - self.reject(null, 'malformed', 'error parsing message', 10); self._error(err, true); + self.reject(null, 'malformed', 'error parsing message', 10); }); if (this.connected) { @@ -270,7 +277,6 @@ Peer.prototype._onAck = function _onAck(err) { if (err) { this._error(err); - this.destroy(); return; } @@ -372,7 +378,8 @@ Peer.prototype.createSocket = function createSocket(port, host) { }); this._connectTimeout = setTimeout(function() { - self.destroy(); + self._error('Connection timed out.'); + self.ignore(); }, 10000); return socket; @@ -1292,21 +1299,21 @@ Peer.prototype._handleVersion = function _handleVersion(version) { if (!this.network.selfConnect) { if (version.nonce.cmp(this.pool.localNonce) === 0) { this._error('We connected to ourself. Oops.'); - this.setMisbehavior(100); + this.ignore(); return; } } if (version.version < constants.MIN_VERSION) { this._error('Peer doesn\'t support required protocol version.'); - this.setMisbehavior(100); + this.ignore(); return; } if (this.type !== Peer.types.LEECH) { if (!version.hasNetwork()) { this._error('Peer does not support network services.'); - this.setMisbehavior(100); + this.ignore(); return; } } @@ -1314,7 +1321,7 @@ Peer.prototype._handleVersion = function _handleVersion(version) { if (this.pool.options.headers) { if (!version.hasHeaders()) { this._error('Peer doesn\'t support getheaders.'); - this.setMisbehavior(100); + this.ignore(); return; } } @@ -1322,7 +1329,7 @@ Peer.prototype._handleVersion = function _handleVersion(version) { if (this.pool.options.spv) { if (!version.hasBloom()) { this._error('Peer does not support bip37.'); - this.setMisbehavior(100); + this.ignore(); return; } } @@ -1331,13 +1338,13 @@ Peer.prototype._handleVersion = function _handleVersion(version) { if (!version.hasWitness()) { if (!this.network.oldWitness) { this._error('Peer does not support segregated witness.'); - this.setMisbehavior(100); + this.ignore(); return; } this.request('havewitness', function(err) { if (err) { self._error('Peer does not support segregated witness.'); - self.setMisbehavior(100); + self.ignore(); } }); } @@ -2118,6 +2125,15 @@ Peer.prototype.isMisbehaving = function isMisbehaving() { return this.pool.isMisbehaving(this.host); }; +/** + * Check whether the peer is ignored. + * @returns {Boolean} + */ + +Peer.prototype.isIgnored = function isIgnored() { + return this.pool.isIgnored(this.host); +}; + /** * Increase banscore on peer. * @param {Number} score @@ -2127,6 +2143,14 @@ Peer.prototype.setMisbehavior = function setMisbehavior(score) { return this.pool.setMisbehavior(this, score); }; +/** + * Ignore peer. + */ + +Peer.prototype.ignore = function setIgnore() { + return this.pool.ignore(this); +}; + /** * Send a `reject` packet to peer. * @see Framer.reject diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 2b1f4c35..64fb8fcd 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -178,6 +178,8 @@ function Pool(options) { all: [], // Misbehaving hosts misbehaving: {}, + // Ignored hosts + ignored: {}, // Map of hosts map: {} }; @@ -446,6 +448,13 @@ Pool.prototype.listen = function listen(callback) { return; } + if (self.isIgnored(host)) { + hostname = IP.hostname(host, socket.remotePort); + self.logger.debug('Ignoring leech (%s).', hostname); + socket.destroy(); + return; + } + self._addLeech(socket); }); @@ -1814,6 +1823,9 @@ Pool.prototype.getRandom = function getRandom(hosts, unique) { if (this.isMisbehaving(host.host)) continue; + if (this.isIgnored(host.host)) + continue; + if (unique && this.getPeer(host.host)) continue; @@ -1923,6 +1935,31 @@ Pool.prototype.isMisbehaving = function isMisbehaving(host) { return false; }; +/** + * Ignore peer. + * @param {Peer} peer + */ + +Pool.prototype.ignore = function ignore(peer) { + this.logger.debug('Ignoring peer (%s).', peer.host); + if (!this.removeHost(peer.host)) + this.peers.ignored[peer.host] = true; + peer.destroy(); +}; + +/** + * Test whether the host/peer is ignored. + * @param {String} host + * @returns {Boolean} + */ + +Pool.prototype.isIgnored = function isIgnored(host) { + if (host.host) + host = host.host; + + return this.peers.ignored[host] === true; +}; + /** * Attempt to retrieve external IP from icanhazip.com. * @param {Function} callback