net: add more aggressive dos prevention.

This commit is contained in:
Christopher Jeffrey 2018-07-04 12:56:11 -07:00
parent 4876e80631
commit 05c38853d7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 65 additions and 13 deletions

View File

@ -195,3 +195,35 @@ exports.ZERO_SIG = Buffer.alloc(64, 0x00);
*/
exports.ZERO_NONCE = Buffer.alloc(8, 0x00);
/**
* Maximum inv/getdata size.
* @const {Number}
* @default
*/
exports.MAX_INV = 50000;
/**
* Maximum number of requests.
* @const {Number}
* @default
*/
exports.MAX_REQUEST = 5000;
/**
* Maximum number of block requests.
* @const {Number}
* @default
*/
exports.MAX_BLOCK_REQUEST = 50000 + 1000;
/**
* Maximum number of tx requests.
* @const {Number}
* @default
*/
exports.MAX_TX_REQUEST = 10000;

View File

@ -811,7 +811,7 @@ class InvPacket extends Packet {
*/
toWriter(bw) {
assert(this.items.length <= 50000);
assert(this.items.length <= common.MAX_INV);
bw.writeVarint(this.items.length);
@ -840,7 +840,7 @@ class InvPacket extends Packet {
fromReader(br) {
const count = br.readVarint();
assert(count <= 50000, 'Inv item count too high.');
assert(count <= common.MAX_INV, 'Inv item count too high.');
for (let i = 0; i < count; i++)
this.items.push(InvItem.fromReader(br));
@ -1012,7 +1012,7 @@ class GetBlocksPacket extends Packet {
*/
toWriter(bw) {
assert(this.locator.length <= 50000, 'Too many block hashes.');
assert(this.locator.length <= common.MAX_INV, 'Too many block hashes.');
bw.writeU32(this.version);
bw.writeVarint(this.locator.length);
@ -1046,7 +1046,7 @@ class GetBlocksPacket extends Packet {
const count = br.readVarint();
assert(count <= 50000, 'Too many block hashes.');
assert(count <= common.MAX_INV, 'Too many block hashes.');
for (let i = 0; i < count; i++)
this.locator.push(br.readHash('hex'));

View File

@ -1293,7 +1293,13 @@ class Peer extends EventEmitter {
if (!entry) {
entry = new RequestEntry();
this.responseMap.set(type, entry);
if (this.responseMap.size >= common.MAX_REQUEST) {
this.destroy();
return;
}
}
entry.setTimeout(timeout);

View File

@ -865,7 +865,7 @@ class Pool extends EventEmitter {
items.push(node.hash);
if (items.length === 50000)
if (items.length === common.MAX_INV)
break;
}
@ -1586,7 +1586,7 @@ class Pool extends EventEmitter {
async _handleInv(peer, packet) {
const items = packet.items;
if (items.length > 50000) {
if (items.length > common.MAX_INV) {
peer.increaseBan(100);
return;
}
@ -1738,7 +1738,7 @@ class Pool extends EventEmitter {
async handleGetData(peer, packet) {
const items = packet.items;
if (items.length > 50000) {
if (items.length > common.MAX_INV) {
this.logger.warning(
'Peer sent inv with >50k items (%s).',
peer.hostname());
@ -2802,12 +2802,10 @@ class Pool extends EventEmitter {
return;
}
if (this.options.blockMode === 1) {
if (peer.compactBlocks.size >= 15) {
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname());
peer.destroy();
return;
}
if (peer.compactBlocks.size >= 15) {
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname());
peer.destroy();
return;
}
block.now = Date.now();
@ -3349,6 +3347,14 @@ class Pool extends EventEmitter {
if (items.length === 0)
return;
if (peer.blockMap.size >= common.MAX_BLOCK_REQUEST) {
this.logger.warning(
'Peer advertised too many blocks (%s).',
peer.hostname());
peer.destroy();
return;
}
this.logger.debug(
'Requesting %d/%d blocks from peer with getdata (%s).',
items.length,
@ -3393,6 +3399,14 @@ class Pool extends EventEmitter {
if (items.length === 0)
return;
if (peer.txMap.size >= common.MAX_TX_REQUEST) {
this.logger.warning(
'Peer advertised too many txs (%s).',
peer.hostname());
peer.destroy();
return;
}
this.logger.debug(
'Requesting %d/%d txs from peer with getdata (%s).',
items.length,