diff options
| author | tv <tv@krebsco.de> | 2026-10-31 22:05:01 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-31 22:05:01 +0100 |
| commit | 661deff21ebddaa3a94fafea99f7d8cfaae790dc (patch) | |
| tree | 1bf3c3f2c7c609f19fb24fa55d3b739690f49d7f /src | |
| parent | f2cfe1f9e033c6d514e8335d8fb82ba925339c58 (diff) | |
libp2p: don't relay through ignored
Diffstat (limited to 'src')
| -rw-r--r-- | src/transport/libp2p/book.rs | 6 | ||||
| -rw-r--r-- | src/transport/libp2p/ignore.rs | 15 | ||||
| -rw-r--r-- | src/transport/libp2p/mod.rs | 2 | ||||
| -rw-r--r-- | src/transport/libp2p/tests.rs | 14 |
4 files changed, 31 insertions, 6 deletions
diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index e5bfa9e..44b2694 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -451,14 +451,14 @@ impl Book { /// `peer` is at `address` (without its `/p2p` part): kept first. Not a direct /// address the peer's identify left out (`identified`): one it no longer has, or /// one it doesn't publish (`Libp2pConfig::ignore`). Nor one in a range this node - /// leaves out (`ignored`): never dialled, it would only take a place, and be passed - /// on. + /// leaves out, directly or through a relay there (`left_out`): never dialled, it + /// would only take a place, and be passed on. 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 { return; } - if ignored(&self.ignored, &address) { + if left_out(&self.ignored, &address) { return; } if self diff --git a/src/transport/libp2p/ignore.rs b/src/transport/libp2p/ignore.rs index 51e1f45..ab59a3e 100644 --- a/src/transport/libp2p/ignore.rs +++ b/src/transport/libp2p/ignore.rs @@ -78,6 +78,21 @@ pub(super) fn ignored(ranges: &[IpRange], address: &Multiaddr) -> bool { ranges.iter().any(|range| range.contains(ip)) } +/// Whether `address` can only be reached over a range of `ranges`: a direct address +/// there, or one through a relay whose own address is there (dialling the relay is +/// refused, `Ignoring`). For what's kept and dialled; connections are judged by +/// `ignored`. +pub(super) fn left_out(ranges: &[IpRange], address: &Multiaddr) -> bool { + if !is_relayed(address) { + return ignored(ranges, address); + } + let relay: Multiaddr = address + .iter() + .take_while(|protocol| !matches!(protocol, Protocol::P2pCircuit)) + .collect(); + ignored(ranges, &without_peer(relay)) +} + /// Keeps connections off the address ranges `libp2p-ignore` names, whoever dialled: /// hole punching and identify bring addresses there too, and a peer may dial us there. pub(super) struct Ignoring { diff --git a/src/transport/libp2p/mod.rs b/src/transport/libp2p/mod.rs index 0e15a09..293558b 100644 --- a/src/transport/libp2p/mod.rs +++ b/src/transport/libp2p/mod.rs @@ -284,7 +284,7 @@ impl Libp2pTransport { .get(&peer) .map(|known| dialable(known, self.peer_id)) .unwrap_or_default(); - known.retain(|address| !ignored(&book.ignored, address)); + known.retain(|address| !left_out(&book.ignored, address)); if known.is_empty() { book.through_relays(peer, self.peer_id) } else { diff --git a/src/transport/libp2p/tests.rs b/src/transport/libp2p/tests.rs index bf538cd..3d11913 100644 --- a/src/transport/libp2p/tests.rs +++ b/src/transport/libp2p/tests.rs @@ -680,10 +680,20 @@ fn ignored_addresses_not_kept() { let them = peer(); let vpn: Multiaddr = "/ip4/10.244.3.2/tcp/9661".parse().unwrap(); let lan: Multiaddr = "/ip4/10.23.1.144/tcp/9661".parse().unwrap(); + let relay = peer(); + // Through a relay there: dialling the relay is refused. + let via_vpn: Multiaddr = format!("/ip4/10.244.0.1/tcp/9661/p2p/{relay}/p2p-circuit") + .parse() + .unwrap(); + let via_lan: Multiaddr = format!("/ip4/10.23.0.1/tcp/9661/p2p/{relay}/p2p-circuit") + .parse() + .unwrap(); book.remember(them, vpn.clone()); - book.identified(them, vec![vpn.clone(), lan.clone()]); - assert!(book.knows(them, &[lan])); + book.remember(them, via_vpn.clone()); + book.identified(them, vec![vpn.clone(), lan.clone(), via_lan.clone()]); + assert!(book.knows(them, &[lan, via_lan])); assert!(!book.knows(them, &[vpn])); + assert!(!book.knows(them, &[via_vpn])); } /// Peers nobody mentions any more are forgotten, but connected ones. |
