pool: add ignore list.

This commit is contained in:
Christopher Jeffrey 2016-07-25 12:35:52 -07:00
parent 6ed877c06c
commit 0dea0888e2
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 80 additions and 14 deletions

View File

@ -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() {

View File

@ -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() {

View File

@ -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

View File

@ -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