From a799bf88e0e26763f8cb072500b10f3cc3102e87 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 1 Nov 2026 19:51:08 +0100 Subject: libp2p: remember wrong addresses --- src/transport/libp2p/book.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/transport/libp2p/book.rs') diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index c5a73c4..8620895 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -44,6 +44,11 @@ pub(super) struct Book { /// Addresses of directly connected peers dialled for a better path (`explore`): /// not again while connected, unless our own interfaces change. pub(super) explored: HashMap>, + /// Addresses where a dial for a peer reached another (`wrongPeerId`), say a NATed + /// peer's LAN address in a range our LAN uses too: not that peer's, whatever + /// identify or the member list say, so not kept, dialled or explored again. As long + /// as the peer is known (`prune`), `WRONG_PER_PEER` each. + pub(super) wrong: HashMap>, pub(super) listening: Vec, /// Where the router forwards to our listen addresses (UPnP, `Libp2pConfig::upnp`). pub(super) mapped: Vec, @@ -224,6 +229,7 @@ impl Book { self.addresses.remove(peer); self.identified.remove(peer); self.explored.remove(peer); + self.wrong.remove(peer); self.relays.remove(peer); self.public_relays.remove(peer); self.continuum.remove(peer); @@ -467,6 +473,19 @@ impl Book { /// one it doesn't publish (`Libp2pConfig::ignore`). Nor one in a range this node /// leaves out, directly or through a relay there (`left_out`): never dialled, it /// would only take a place, and be passed on. + /// A dial for `peer` at `address` reached another peer: `address` isn't `peer`'s. + /// Forgotten, and not taken again (`wrong`). + pub(super) fn not_theirs(&mut self, peer: PeerId, address: Multiaddr) { + let address = without_peer(address); + if let Some(known) = self.addresses.get_mut(&peer) { + known.retain(|known| *known != address); + } + let wrong = self.wrong.entry(peer).or_default(); + if wrong.len() < WRONG_PER_PEER { + wrong.insert(address); + } + } + pub(super) fn remember(&mut self, peer: PeerId, address: Multiaddr) { let address = without_peer(address); if !self.addresses.contains_key(&peer) && self.addresses.len() >= MAX_PEERS { @@ -475,6 +494,13 @@ impl Book { if self.left_out(&address) { return; } + if self + .wrong + .get(&peer) + .is_some_and(|wrong| wrong.contains(&address)) + { + return; + } if self .identified .get(&peer) -- cgit v1.3.1