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.
This commit is contained in:
teor 2021-05-14 15:48:04 +10:00
parent f541f85792
commit c40cbee42f
2 changed files with 20 additions and 2 deletions

View File

@ -139,7 +139,15 @@ impl AddressBook {
recent_peers = self.recently_live_peers().count(), 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 // Communication with these addresses can be monitored via Zebra's
// metrics. (The address book is for valid peer addresses.) // metrics. (The address book is for valid peer addresses.)

View File

@ -156,7 +156,9 @@ impl MetaAddr {
/// ///
/// # Security /// # 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: /// Otherwise:
/// - malicious peers could interfere with other peers' `AddressBook` state, /// - malicious peers could interfere with other peers' `AddressBook` state,
/// or /// or
@ -226,6 +228,14 @@ impl MetaAddr {
self.last_seen 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? /// Is this address valid for outbound connections?
pub fn is_valid_for_outbound(&self) -> bool { pub fn is_valid_for_outbound(&self) -> bool {
self.services.contains(PeerServices::NODE_NETWORK) self.services.contains(PeerServices::NODE_NETWORK)