From c40cbee42f0897932b03ba9fbb53bf6219e4c5f8 Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 14 May 2021 15:48:04 +1000 Subject: [PATCH] Remove address book peers that have changed to clients If an address book peer stops advertising the NODE_SERVICES bit, remove it from the address book. --- zebra-network/src/address_book.rs | 10 +++++++++- zebra-network/src/meta_addr.rs | 12 +++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/zebra-network/src/address_book.rs b/zebra-network/src/address_book.rs index fdbad1c2..3061e5f5 100644 --- a/zebra-network/src/address_book.rs +++ b/zebra-network/src/address_book.rs @@ -139,7 +139,15 @@ impl AddressBook { recent_peers = self.recently_live_peers().count(), ); - // Drop any unspecified or client addresses. + // If a node that we are directly connected to has changed to a client, + // remove it from the address book. + if new.is_direct_client() && self.contains_addr(&new.addr) { + std::mem::drop(_guard); + self.take(new.addr); + return; + } + + // Never add unspecified addresses or client services. // // Communication with these addresses can be monitored via Zebra's // metrics. (The address book is for valid peer addresses.) diff --git a/zebra-network/src/meta_addr.rs b/zebra-network/src/meta_addr.rs index 700b608f..5bbbd302 100644 --- a/zebra-network/src/meta_addr.rs +++ b/zebra-network/src/meta_addr.rs @@ -156,7 +156,9 @@ impl MetaAddr { /// /// # Security /// - /// This address must be the remote address from an outbound connection. + /// This address must be the remote address from an outbound connection, + /// and the services must be the services from that peer's handshake. + /// /// Otherwise: /// - malicious peers could interfere with other peers' `AddressBook` state, /// or @@ -226,6 +228,14 @@ impl MetaAddr { self.last_seen } + /// Is this address a directly connected client? + pub fn is_direct_client(&self) -> bool { + match self.last_connection_state { + Responded => !self.services.contains(PeerServices::NODE_NETWORK), + NeverAttemptedGossiped | NeverAttemptedAlternate | Failed | AttemptPending => false, + } + } + /// Is this address valid for outbound connections? pub fn is_valid_for_outbound(&self) -> bool { self.services.contains(PeerServices::NODE_NETWORK)