From 7a6eda9ca3abcb64bd41a6b85ea56a5b3f8b0b51 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 1 Nov 2026 13:30:12 +0100 Subject: libp2p: one Book::usable for all dials --- src/transport/libp2p/book.rs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'src/transport/libp2p/book.rs') diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index 087cd17..c5a73c4 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -493,18 +493,20 @@ impl Book { /// (`left_out`), or without a route from here (`routes`), directly or through a /// relay there. pub(super) fn left_out(&mut self, address: &Multiaddr) -> bool { - if left_out(&self.ignored, address) { - return true; - } - let at = if is_relayed(address) { - address - .iter() - .take_while(|protocol| !matches!(protocol, Protocol::P2pCircuit)) - .collect::() - } else { - address.clone() + excluded(&self.ignored, &mut self.routes, address) + } + + /// Where `peer` can be dialled: its known addresses, but those through this node, + /// and those left out (`left_out`). What every dial of ours goes to (connecting, + /// upgrading a relayed connection, retrying a hole punch), so none dials into a + /// range left out. + pub(super) fn usable(&mut self, peer: &PeerId, local: PeerId) -> Vec { + let Some(known) = self.addresses.get(peer) else { + return Vec::new(); }; - ip_of(&at).is_some_and(|ip| !self.routes.routable(ip)) + let mut usable = dialable(known, local); + usable.retain(|address| !excluded(&self.ignored, &mut self.routes, address)); + usable } /// Asks again which ranges have a route (`Routes::recheck`); the addresses in those @@ -698,6 +700,22 @@ pub(super) fn book_connection( /// The addresses of `known` this node can dial: not those through itself as the relay /// (a relay reaches the nodes it relays for only while they are connected to it). +/// `Book::left_out`, by the fields it needs, for where the book is borrowed in parts. +pub(super) fn excluded(ignored: &[IpRange], routes: &mut Routes, address: &Multiaddr) -> bool { + if left_out(ignored, address) { + return true; + } + let at = if is_relayed(address) { + address + .iter() + .take_while(|protocol| !matches!(protocol, Protocol::P2pCircuit)) + .collect::() + } else { + address.clone() + }; + ip_of(&at).is_some_and(|ip| !routes.routable(ip)) +} + pub(super) fn dialable(known: &[Multiaddr], local: PeerId) -> Vec { known .iter() -- cgit v1.3.1