From f52e924cda59173ef63dd2635034fd954d09ce7e Mon Sep 17 00:00:00 2001 From: kilpatty Date: Sat, 6 Jul 2019 13:43:11 -0500 Subject: [PATCH] net-pool: Check outbound peers for same group before connecting This commit checks the outbound peers to see which group their network addresses lives in before connecting. By doing this, we prevent a node from connecting to all outbound addresses in a very close network group bunch. This helps prevent someone spinning up multiple nodes on a similar network e.g. AWS, GCP and using those to fill other nodes' outbounds. This commit just adds 2 operations in both addOutbound and addLoader. It first checks if the new address pull from hostlist belongs in the same group as an already connected peer. If it does not, it precedes as usual, and if the connection succeeds then it adds that new outbound group to the list of groups currently connected to. Co-authored-by: Nodari Chkuaselidze --- lib/net/pool.js | 12 +++++++++++- test/net-netaddress-test.js | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/net/pool.js b/lib/net/pool.js index 90bb6270..2c4d2f32 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -10,7 +10,6 @@ const assert = require('bsert'); const EventEmitter = require('events'); const {Lock} = require('bmutex'); const IP = require('binet'); -const dns = require('bdns'); const tcp = require('btcp'); const UPNP = require('bupnp'); const socks = require('bsocks'); @@ -85,6 +84,7 @@ class Pool extends EventEmitter { this.pendingFilter = null; this.refillTimer = null; this.discoverTimer = null; + this.connectedGroups = new Set(); this.checkpoints = false; this.headerChain = new List(); @@ -663,6 +663,7 @@ class Pool extends EventEmitter { this.logger.info('Adding loader peer (%s).', peer.hostname()); this.peers.add(peer); + this.connectedGroups.add(addr.getGroup()); this.setLoader(peer); } @@ -3367,6 +3368,7 @@ class Pool extends EventEmitter { if (!entry) break; + const addr = entry.addr; if (this.peers.has(addr.hostname)) @@ -3390,6 +3392,10 @@ class Pool extends EventEmitter { if (this.options.brontideOnly && !addr.hasKey()) continue; + // Don't connect to outbound peers in the same group. + if (this.connectedGroups.has(addr.getGroup())) + continue; + if (i < pc30 && now - entry.lastAttempt < 600) continue; @@ -3428,6 +3434,7 @@ class Pool extends EventEmitter { const peer = this.createOutbound(addr); this.peers.add(peer); + this.connectedGroups.add(addr.getGroup()); this.emit('peer', peer); } @@ -3482,6 +3489,9 @@ class Pool extends EventEmitter { removePeer(peer) { this.peers.remove(peer); + if (peer.outbound) + this.connectedGroups.delete(peer.address.getGroup()); + for (const hash of peer.blockMap.keys()) this.resolveBlock(peer, hash); diff --git a/test/net-netaddress-test.js b/test/net-netaddress-test.js index 222d2087..fa4a275b 100644 --- a/test/net-netaddress-test.js +++ b/test/net-netaddress-test.js @@ -1,5 +1,14 @@ 'use strict'; +/* Parts of this software are based on bitcoin/bitcoin: + * Copyright (c) 2009-2019, The Bitcoin Core Developers (MIT License). + * Copyright (c) 2009-2019, The Bitcoin Developers (MIT License). + * https://github.com/bitcoin/bitcoin + * + * Resources: + * https://github.com/bitcoin/bitcoin/blob/46fc4d1a24c88e797d6080336e3828e45e39c3fd/src/test/netbase_tests.cpp + */ + const assert = require('bsert'); const NetAddress = require('../lib/net/netaddress'); const Network = require('../lib/protocol/network');