aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport/libp2p/book.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-01 19:51:08 +0100
committertv <tv@krebsco.de>2026-11-01 19:51:08 +0100
commit5c5efb0440d50a91de942817f0886fcba6d5d3ae (patch)
treea90edcf5136f9130e8c0d113405357da2044c0e4 /src/transport/libp2p/book.rs
parentd5bac903cf181b2f1ace38ae330bb0a286d26da3 (diff)
libp2p: remember wrong addresses
Diffstat (limited to 'src/transport/libp2p/book.rs')
-rw-r--r--src/transport/libp2p/book.rs26
1 files changed, 26 insertions, 0 deletions
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<PeerId, std::collections::HashSet<Multiaddr>>,
+ /// 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<PeerId, std::collections::HashSet<Multiaddr>>,
pub(super) listening: Vec<Multiaddr>,
/// Where the router forwards to our listen addresses (UPnP, `Libp2pConfig::upnp`).
pub(super) mapped: Vec<Multiaddr>,
@@ -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 {
@@ -476,6 +495,13 @@ impl Book {
return;
}
if self
+ .wrong
+ .get(&peer)
+ .is_some_and(|wrong| wrong.contains(&address))
+ {
+ return;
+ }
+ if self
.identified
.get(&peer)
.is_some_and(|said| is_ip(&address) && !said.contains(&address))