diff options
| author | tv <tv@krebsco.de> | 2026-11-01 13:27:28 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-01 13:27:28 +0100 |
| commit | 12fbf8bf78408abbfde0ec1802f39307def4a0ee (patch) | |
| tree | c3251256b854f20d1c31d6024fd937c8b2d5491b /src/transport | |
| parent | c945e63f619bca888f203ab8eafce6b10cb59a3c (diff) | |
libp2p: relays use address ignore/route filter
Diffstat (limited to 'src/transport')
| -rw-r--r-- | src/transport/libp2p/book.rs | 4 | ||||
| -rw-r--r-- | src/transport/libp2p/errors.rs | 2 | ||||
| -rw-r--r-- | src/transport/libp2p/mod.rs | 5 | ||||
| -rw-r--r-- | src/transport/libp2p/relays.rs | 25 |
4 files changed, 23 insertions, 13 deletions
diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index c2296d3..e502bf8 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -427,7 +427,7 @@ impl Book { /// Where `peer` may be reached through the relays we know (named, then members that /// relay): for a peer known by its ID only (a seed `/p2p/<peer ID>`), which may hold /// a slot on one of them. `local`: this node, never its own relay. - pub(super) fn through_relays(&self, peer: PeerId, local: PeerId) -> Vec<Multiaddr> { + pub(super) fn through_relays(&mut self, peer: PeerId, local: PeerId) -> Vec<Multiaddr> { let mut relays: Vec<(PeerId, Multiaddr)> = self .named_relays .iter() @@ -444,7 +444,7 @@ impl Book { relays .into_iter() .chain(members) - .filter(|(relay, _)| *relay != local && *relay != peer) + .filter(|(relay, address)| *relay != local && *relay != peer && !self.left_out(address)) .map(|(_, address)| address.with(Protocol::P2pCircuit).with(Protocol::P2p(peer))) .take(ADDRESSES_PER_PEER) .collect() diff --git a/src/transport/libp2p/errors.rs b/src/transport/libp2p/errors.rs index e024b1c..bb6b090 100644 --- a/src/transport/libp2p/errors.rs +++ b/src/transport/libp2p/errors.rs @@ -76,6 +76,8 @@ pub(super) fn relay_refused(debug: &str, innermost: &str) -> bool { "connection gated", "UnsupportedProtocol", "WrongPeerId", + // `Ignoring`: in a range left out, whoever dialled. + "IgnoredAddress", ]; refusals.iter().any(|pattern| debug.contains(pattern)) || innermost == "Failed" } diff --git a/src/transport/libp2p/mod.rs b/src/transport/libp2p/mod.rs index 2ad07e5..0d26625 100644 --- a/src/transport/libp2p/mod.rs +++ b/src/transport/libp2p/mod.rs @@ -415,7 +415,8 @@ impl Transport for Libp2pTransport { if relay != self.peer_id { let new = { let mut book = lock(&self.book); - let new = book.relays.get(&relay) != Some(&address); + // One in a range left out is no use (`Book::left_out`). + let new = book.relays.get(&relay) != Some(&address) && !book.left_out(&address); if new && (book.relays.len() < MAX_PEERS || book.relays.contains_key(&relay)) { book.relays.insert(relay, address.clone()); } @@ -521,7 +522,7 @@ impl Transport for Libp2pTransport { // A peer ID only (`/p2p/<peer ID>`): reached where it's known, or through the // relays we know. if let [Protocol::P2p(peer)] = address.iter().collect::<Vec<_>>()[..] { - let book = lock(&self.book); + let mut book = lock(&self.book); if book.addresses.contains_key(&peer) || !book.through_relays(peer, self.peer_id).is_empty() { diff --git a/src/transport/libp2p/relays.rs b/src/transport/libp2p/relays.rs index 41d7e1d..81a97fe 100644 --- a/src/transport/libp2p/relays.rs +++ b/src/transport/libp2p/relays.rs @@ -73,23 +73,30 @@ pub(super) fn pick_relays( let now = tokio::time::Instant::now(); book.failed_relays.retain(|_, until| now < *until); let failed = book.failed_relays.clone(); - let usable = |offers: &HashMap<PeerId, Multiaddr>| -> HashMap<PeerId, Multiaddr> { + // Not paused, and not in a range left out (ignored, or without a route): those + // would only be denied or fail, again and again. + let usable = |book: &mut Book, offers: HashMap<PeerId, Multiaddr>| { offers - .iter() - .filter(|(relay, _)| !failed.contains_key(relay)) - .map(|(relay, address)| (*relay, address.clone())) - .collect() + .into_iter() + .filter(|(relay, address)| !failed.contains_key(relay) && !book.left_out(address)) + .collect::<HashMap<PeerId, Multiaddr>>() }; let public = if relaying.public { - usable(&book.public_relays) + let offers = book.public_relays.clone(); + usable(&mut book, offers) } else { HashMap::new() }; + let (configured, listed, members) = ( + book.named(Named::Configured), + book.named(Named::Listed), + book.relays.clone(), + ); ( !book.direct().is_empty(), - usable(&book.named(Named::Configured)), - usable(&book.named(Named::Listed)), - usable(&book.relays), + usable(&mut book, configured), + usable(&mut book, listed), + usable(&mut book, members), public, ) }; |
