diff --git a/Cargo.lock b/Cargo.lock index 7f37b652c306..2be3418f7187 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3206,7 +3206,7 @@ dependencies = [ [[package]] name = "libp2p-relay" -version = "0.18.0" +version = "0.18.1" dependencies = [ "asynchronous-codec", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 8d63ac3ee1ee..51947ff5f19e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,7 +97,7 @@ libp2p-ping = { version = "0.45.0", path = "protocols/ping" } libp2p-plaintext = { version = "0.42.0", path = "transports/plaintext" } libp2p-pnet = { version = "0.25.0", path = "transports/pnet" } libp2p-quic = { version = "0.11.1", path = "transports/quic" } -libp2p-relay = { version = "0.18.0", path = "protocols/relay" } +libp2p-relay = { version = "0.18.1", path = "protocols/relay" } libp2p-rendezvous = { version = "0.15.0", path = "protocols/rendezvous" } libp2p-request-response = { version = "0.27.0", path = "protocols/request-response" } libp2p-server = { version = "0.12.7", path = "misc/server" } diff --git a/protocols/relay/CHANGELOG.md b/protocols/relay/CHANGELOG.md index fc71ccedad5d..63ea4481beae 100644 --- a/protocols/relay/CHANGELOG.md +++ b/protocols/relay/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.18.1 + +- Fix relayed `ExternalAddr` not expiring when stopping to listen through relay. + See [PR 5577](https://github.com/libp2p/rust-libp2p/pull/5577). + ## 0.18.0 diff --git a/protocols/relay/Cargo.toml b/protocols/relay/Cargo.toml index 084fec07efdb..16449f57df5b 100644 --- a/protocols/relay/Cargo.toml +++ b/protocols/relay/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-relay" edition = "2021" rust-version = { workspace = true } description = "Communications relaying for libp2p" -version = "0.18.0" +version = "0.18.1" authors = ["Parity Technologies ", "Max Inden "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index f8d1d9c9eb23..4cbfc4f70f6c 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -40,8 +40,9 @@ use libp2p_identity::PeerId; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - dummy, ConnectionDenied, ConnectionHandler, ConnectionId, DialFailure, NetworkBehaviour, - NotifyHandler, Stream, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, + dummy, ConnectionDenied, ConnectionHandler, ConnectionId, DialFailure, ExpiredListenAddr, + NetworkBehaviour, NewListenAddr, NotifyHandler, Stream, THandler, THandlerInEvent, + THandlerOutEvent, ToSwarm, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -71,12 +72,6 @@ pub enum Event { }, } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -enum ReservationStatus { - Pending, - Confirmed, -} - /// [`NetworkBehaviour`] implementation of the relay client /// functionality of the circuit relay v2 protocol. pub struct Behaviour { @@ -87,11 +82,6 @@ pub struct Behaviour { /// connection. directly_connected_peers: HashMap>, - /// Stores the address of a pending or confirmed reservation. - /// - /// This is indexed by the [`ConnectionId`] to a relay server and the address is the `/p2p-circuit` address we reserved on it. - reservation_addresses: HashMap, - /// Queue of actions to return when polled. queued_actions: VecDeque>>, @@ -105,7 +95,6 @@ pub fn new(local_peer_id: PeerId) -> (Transport, Behaviour) { local_peer_id, from_transport, directly_connected_peers: Default::default(), - reservation_addresses: Default::default(), queued_actions: Default::default(), pending_handler_commands: Default::default(), }; @@ -140,12 +129,6 @@ impl Behaviour { unreachable!("`on_connection_closed` for unconnected peer.") } }; - if let Some((addr, ReservationStatus::Confirmed)) = - self.reservation_addresses.remove(&connection_id) - { - self.queued_actions - .push_back(ToSwarm::ExternalAddrExpired(addr)); - } } } } @@ -220,8 +203,31 @@ impl NetworkBehaviour for Behaviour { FromSwarm::ConnectionClosed(connection_closed) => { self.on_connection_closed(connection_closed) } + FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => { + if addr.is_relayed() { + // like all listen addresses, remove trailing /p2p/ + let mut addr = addr.clone(); + if matches!(addr.iter().last(), Some(Protocol::P2p(_))) { + addr.pop(); + } + + self.queued_actions + .push_back(ToSwarm::ExternalAddrConfirmed(addr)); + } + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => { + if addr.is_relayed() { + // like all listen addresses, remove trailing /p2p/ + let mut addr = addr.clone(); + if matches!(addr.iter().last(), Some(Protocol::P2p(_))) { + addr.pop(); + } + + self.queued_actions + .push_back(ToSwarm::ExternalAddrExpired(addr)); + } + } FromSwarm::DialFailure(DialFailure { connection_id, .. }) => { - self.reservation_addresses.remove(&connection_id); self.pending_handler_commands.remove(&connection_id); } _ => {} @@ -231,7 +237,7 @@ impl NetworkBehaviour for Behaviour { fn on_connection_handler_event( &mut self, event_source: PeerId, - connection: ConnectionId, + _: ConnectionId, handler_event: THandlerOutEvent, ) { let handler_event = match handler_event { @@ -241,17 +247,6 @@ impl NetworkBehaviour for Behaviour { let event = match handler_event { handler::Event::ReservationReqAccepted { renewal, limit } => { - let (addr, status) = self - .reservation_addresses - .get_mut(&connection) - .expect("Relay connection exist"); - - if !renewal && *status == ReservationStatus::Pending { - *status = ReservationStatus::Confirmed; - self.queued_actions - .push_back(ToSwarm::ExternalAddrConfirmed(addr.clone())); - } - Event::ReservationReqAccepted { relay_peer_id: event_source, renewal, @@ -292,24 +287,11 @@ impl NetworkBehaviour for Behaviour { .get(&relay_peer_id) .and_then(|cs| cs.first()) { - Some(connection_id) => { - self.reservation_addresses.insert( - *connection_id, - ( - relay_addr - .with(Protocol::P2p(relay_peer_id)) - .with(Protocol::P2pCircuit) - .with(Protocol::P2p(self.local_peer_id)), - ReservationStatus::Pending, - ), - ); - - ToSwarm::NotifyHandler { - peer_id: relay_peer_id, - handler: NotifyHandler::One(*connection_id), - event: Either::Left(handler::In::Reserve { to_listener }), - } - } + Some(connection_id) => ToSwarm::NotifyHandler { + peer_id: relay_peer_id, + handler: NotifyHandler::One(*connection_id), + event: Either::Left(handler::In::Reserve { to_listener }), + }, None => { let opts = DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr.clone()]) @@ -317,17 +299,6 @@ impl NetworkBehaviour for Behaviour { .build(); let relayed_connection_id = opts.connection_id(); - self.reservation_addresses.insert( - relayed_connection_id, - ( - relay_addr - .with(Protocol::P2p(relay_peer_id)) - .with(Protocol::P2pCircuit) - .with(Protocol::P2p(self.local_peer_id)), - ReservationStatus::Pending, - ), - ); - self.pending_handler_commands .insert(relayed_connection_id, handler::In::Reserve { to_listener }); ToSwarm::Dial { opts }