net: add more aggressive dos prevention.
This commit is contained in:
parent
4876e80631
commit
05c38853d7
@ -195,3 +195,35 @@ exports.ZERO_SIG = Buffer.alloc(64, 0x00);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
exports.ZERO_NONCE = Buffer.alloc(8, 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;
|
||||||
|
|||||||
@ -811,7 +811,7 @@ class InvPacket extends Packet {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
toWriter(bw) {
|
toWriter(bw) {
|
||||||
assert(this.items.length <= 50000);
|
assert(this.items.length <= common.MAX_INV);
|
||||||
|
|
||||||
bw.writeVarint(this.items.length);
|
bw.writeVarint(this.items.length);
|
||||||
|
|
||||||
@ -840,7 +840,7 @@ class InvPacket extends Packet {
|
|||||||
fromReader(br) {
|
fromReader(br) {
|
||||||
const count = br.readVarint();
|
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++)
|
for (let i = 0; i < count; i++)
|
||||||
this.items.push(InvItem.fromReader(br));
|
this.items.push(InvItem.fromReader(br));
|
||||||
@ -1012,7 +1012,7 @@ class GetBlocksPacket extends Packet {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
toWriter(bw) {
|
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.writeU32(this.version);
|
||||||
bw.writeVarint(this.locator.length);
|
bw.writeVarint(this.locator.length);
|
||||||
@ -1046,7 +1046,7 @@ class GetBlocksPacket extends Packet {
|
|||||||
|
|
||||||
const count = br.readVarint();
|
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++)
|
for (let i = 0; i < count; i++)
|
||||||
this.locator.push(br.readHash('hex'));
|
this.locator.push(br.readHash('hex'));
|
||||||
|
|||||||
@ -1293,7 +1293,13 @@ class Peer extends EventEmitter {
|
|||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
entry = new RequestEntry();
|
entry = new RequestEntry();
|
||||||
|
|
||||||
this.responseMap.set(type, entry);
|
this.responseMap.set(type, entry);
|
||||||
|
|
||||||
|
if (this.responseMap.size >= common.MAX_REQUEST) {
|
||||||
|
this.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.setTimeout(timeout);
|
entry.setTimeout(timeout);
|
||||||
|
|||||||
@ -865,7 +865,7 @@ class Pool extends EventEmitter {
|
|||||||
|
|
||||||
items.push(node.hash);
|
items.push(node.hash);
|
||||||
|
|
||||||
if (items.length === 50000)
|
if (items.length === common.MAX_INV)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1586,7 +1586,7 @@ class Pool extends EventEmitter {
|
|||||||
async _handleInv(peer, packet) {
|
async _handleInv(peer, packet) {
|
||||||
const items = packet.items;
|
const items = packet.items;
|
||||||
|
|
||||||
if (items.length > 50000) {
|
if (items.length > common.MAX_INV) {
|
||||||
peer.increaseBan(100);
|
peer.increaseBan(100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1738,7 +1738,7 @@ class Pool extends EventEmitter {
|
|||||||
async handleGetData(peer, packet) {
|
async handleGetData(peer, packet) {
|
||||||
const items = packet.items;
|
const items = packet.items;
|
||||||
|
|
||||||
if (items.length > 50000) {
|
if (items.length > common.MAX_INV) {
|
||||||
this.logger.warning(
|
this.logger.warning(
|
||||||
'Peer sent inv with >50k items (%s).',
|
'Peer sent inv with >50k items (%s).',
|
||||||
peer.hostname());
|
peer.hostname());
|
||||||
@ -2802,12 +2802,10 @@ class Pool extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.blockMode === 1) {
|
if (peer.compactBlocks.size >= 15) {
|
||||||
if (peer.compactBlocks.size >= 15) {
|
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname());
|
||||||
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname());
|
peer.destroy();
|
||||||
peer.destroy();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block.now = Date.now();
|
block.now = Date.now();
|
||||||
@ -3349,6 +3347,14 @@ class Pool extends EventEmitter {
|
|||||||
if (items.length === 0)
|
if (items.length === 0)
|
||||||
return;
|
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(
|
this.logger.debug(
|
||||||
'Requesting %d/%d blocks from peer with getdata (%s).',
|
'Requesting %d/%d blocks from peer with getdata (%s).',
|
||||||
items.length,
|
items.length,
|
||||||
@ -3393,6 +3399,14 @@ class Pool extends EventEmitter {
|
|||||||
if (items.length === 0)
|
if (items.length === 0)
|
||||||
return;
|
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(
|
this.logger.debug(
|
||||||
'Requesting %d/%d txs from peer with getdata (%s).',
|
'Requesting %d/%d txs from peer with getdata (%s).',
|
||||||
items.length,
|
items.length,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user