aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-01 13:27:28 +0100
committertv <tv@krebsco.de>2026-11-01 13:27:28 +0100
commit12fbf8bf78408abbfde0ec1802f39307def4a0ee (patch)
treec3251256b854f20d1c31d6024fd937c8b2d5491b /src/transport
parentc945e63f619bca888f203ab8eafce6b10cb59a3c (diff)
libp2p: relays use address ignore/route filter
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/libp2p/book.rs4
-rw-r--r--src/transport/libp2p/errors.rs2
-rw-r--r--src/transport/libp2p/mod.rs5
-rw-r--r--src/transport/libp2p/relays.rs25
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,
)
};