p2p: Don't participate in addr relay with feeler connections
What changed, and why it matters
This change is a small network-efficiency cleanup, not a security fix. Bitcoin Core's 'feeler' connections are brief probes used to check whether another node is online. Previously, the software would ask feeler peers for addresses (sending a GETADDR message) even though it disconnects almost immediately and never reads the reply. The patch stops that unnecessary request, saving a little bandwidth. It does not fix a vulnerability and does not change how attackers could interact with the network.
No security action required. Treat as a normal network-cleanup patch; review for correctness if backporting, but it is not a vulnerability fix.
Security signals we found
No security-relevant signal: change is described by the project as a bandwidth optimization
No memory safety, cryptographic, consensus, or authorization change
No bug class such as DoS, eclipse-attack vector, or information leak is introduced or fixed
Evidence from the diff
The commit modifies PeerManagerImpl::SetupAddressRelay in src/net_processing.cpp to return false for feeler connections (node.IsFeelerConn()), and updates the version-message handling comment to include feelers alongside inbound and block-relay-only peers as cases where GETADDR is not sent. Because GETADDR is what initializes addr relay on both sides, feelers will no longer participate in address relay in either direction. A functional test is updated to assert that no GETADDR is sent to a feeler peer.
Changed components
src/net_processing.cpp: PeerManagerImpl::SetupAddressRelaysrc/net_processing.cpp: version-message GETADDR decision logictest/functional/p2p_addr_relay.pyInspect captured patch +12 / −2
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 28d7d2c1..12fc5066 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -3748,7 +3748,7 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
// Attempt to initialize address relay for outbound peers and use result
// to decide whether to send GETADDR, so that we don't send it to
- // inbound or outbound block-relay-only peers.
+ // inbound, feelers, or outbound block-relay-only peers.
bool send_getaddr{false};
if (!pfrom.IsInboundConn()) {
send_getaddr = SetupAddressRelay(pfrom, peer);
@@ -5612,6 +5612,11 @@ bool PeerManagerImpl::SetupAddressRelay(const CNode& node, Peer& peer)
// information of addr traffic to infer the link.
if (node.IsBlockOnlyConn()) return false;
+ // We don't participate in addr relay with feeler connections because
+ // they are disconnected shortly after the handshake completes,
+ // before the node will receive the addr response.
+ if (node.IsFeelerConn()) return false;
+
if (!peer.m_addr_relay_enabled.exchange(true)) {
// During version message processing (non-block-relay-only outbound peers)
// or on first addr-related message we have received (inbound peers), initialize
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
index 65b21c0d..1464e23c 100755
--- a/test/functional/p2p_addr_relay.py
+++ b/test/functional/p2p_addr_relay.py
@@ -280,12 +280,17 @@ class AddrTest(BitcoinTestFramework):
tip_header = from_hex(CBlockHeader(), self.nodes[0].getblockheader(self.nodes[0].getbestblockhash(), False))
full_outbound_peer.send_and_ping(msg_headers([tip_header]))
- self.log.info('Check that we do not send a getaddr message to a block-relay-only or inbound peer')
+ self.log.info('Check that we do not send a getaddr message to a block-relay-only, feeler or inbound peer')
block_relay_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=1, connection_type="block-relay-only")
block_relay_peer.sync_with_ping()
assert_equal(block_relay_peer.getaddr_received(), False)
block_relay_peer.send_and_ping(msg_headers([tip_header]))
+ feeler_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=2, connection_type="feeler")
+ # bitcoind closes feeler connections as soon as it receives a version message
+ assert_equal(feeler_peer.is_connected, False)
+ assert_equal(feeler_peer.getaddr_received(), False)
+
inbound_peer = self.nodes[0].add_p2p_connection(AddrReceiver(send_getaddr=False))
inbound_peer.sync_with_ping()
assert_equal(inbound_peer.getaddr_received(), False)
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.