diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 1f7592cd..d4cae973 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -21,7 +21,6 @@ //! [`NetworkBehaviour`] to act as a direct connection upgrade through relay node. use crate::handler; -use crate::protocol; use either::Either; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; @@ -68,7 +67,7 @@ pub enum Error { pub struct Behaviour { /// Queue of actions to return when polled. - queued_actions: VecDeque, + queued_events: VecDeque>, /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -81,13 +80,22 @@ pub struct Behaviour { impl Behaviour { pub fn new(local_peer_id: PeerId) -> Self { Behaviour { - queued_actions: Default::default(), + queued_events: Default::default(), direct_connections: Default::default(), external_addresses: Default::default(), local_peer_id, } } + fn observed_addreses(&self) -> Vec { + self.external_addresses + .iter() + .cloned() + .filter(|a| !a.iter().any(|p| p == Protocol::P2pCircuit)) + .map(|a| a.with(Protocol::P2p(self.local_peer_id.into()))) + .collect() + } + fn on_connection_established( &mut self, ConnectionEstablished { @@ -108,11 +116,14 @@ impl Behaviour { // connection upgrade by initiating a direct connection to A. // // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol - self.queued_actions.extend([ - ActionBuilder::Connect { + self.queued_events.extend([ + NetworkBehaviourAction::NotifyHandler { peer_id, - attempt: 1, handler: NotifyHandler::One(connection_id), + event: Either::Left(handler::relayed::Command::Connect { + obs_addrs: self.observed_addreses(), + attempt: 1, + }), }, NetworkBehaviourAction::GenerateEvent( Event::InitiatedDirectConnectionUpgrade { @@ -122,8 +133,7 @@ impl Behaviour { ConnectedPoint::Dialer { .. } => unreachable!("Due to outer if."), }, }, - ) - .into(), + ), ]); } } else { @@ -147,26 +157,28 @@ impl Behaviour { { let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_actions.push_back(ActionBuilder::Connect { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - attempt: attempt + 1, - }); + self.queued_events + .push_back(NetworkBehaviourAction::NotifyHandler { + handler: NotifyHandler::One(relayed_connection_id), + peer_id, + event: Either::Left(handler::relayed::Command::Connect { + attempt: attempt + 1, + obs_addrs: self.observed_addreses(), + }), + }) } else { - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(relayed_connection_id), event: Either::Left( handler::relayed::Command::UpgradeFinishedDontKeepAlive, ), - } - .into(), + }, NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { remote_peer_id: peer_id, error: Error::Dial, - }) - .into(), + }), ]); } } @@ -217,93 +229,87 @@ impl NetworkBehaviour for Behaviour { inbound_connect, remote_addr, }) => { - self.queued_actions.extend([ - ActionBuilder::AcceptInboundConnect { - peer_id: event_source, + self.queued_events.extend([ + NetworkBehaviourAction::NotifyHandler { handler: NotifyHandler::One(connection), - inbound_connect, + peer_id: event_source, + event: Either::Left(handler::relayed::Command::AcceptInboundConnect { + inbound_connect, + obs_addrs: self.observed_addreses(), + }), }, NetworkBehaviourAction::GenerateEvent( Event::RemoteInitiatedDirectConnectionUpgrade { remote_peer_id: event_source, remote_relayed_addr: remote_addr, }, - ) - .into(), + ), ]); } Either::Left(handler::relayed::Event::InboundNegotiationFailed { error }) => { - self.queued_actions.push_back( - NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - remote_peer_id: event_source, - error: Error::Handler(error), - }) - .into(), - ); + self.queued_events + .push_back(NetworkBehaviourAction::GenerateEvent( + Event::DirectConnectionUpgradeFailed { + remote_peer_id: event_source, + error: Error::Handler(error), + }, + )); } Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { - self.queued_actions.push_back( - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .addresses(remote_addrs) - .condition(dial_opts::PeerCondition::Always) - .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Listener, - }, - } - .into(), - ); + self.queued_events.push_back(NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(event_source) + .addresses(remote_addrs) + .condition(dial_opts::PeerCondition::Always) + .build(), + handler: handler::Prototype::DirectConnection { + relayed_connection_id: connection, + role: handler::Role::Listener, + }, + }); } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { - self.queued_actions.push_back( - NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - remote_peer_id: event_source, - error: Error::Handler(error), - }) - .into(), - ); + self.queued_events + .push_back(NetworkBehaviourAction::GenerateEvent( + Event::DirectConnectionUpgradeFailed { + remote_peer_id: event_source, + error: Error::Handler(error), + }, + )); } Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs, attempt, }) => { - self.queued_actions.push_back( - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .condition(dial_opts::PeerCondition::Always) - .addresses(remote_addrs) - .override_role() - .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Initiator { attempt }, - }, - } - .into(), - ); + self.queued_events.push_back(NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(event_source) + .condition(dial_opts::PeerCondition::Always) + .addresses(remote_addrs) + .override_role() + .build(), + handler: handler::Prototype::DirectConnection { + relayed_connection_id: connection, + role: handler::Role::Initiator { attempt }, + }, + }); } Either::Right(Either::Left( handler::direct::Event::DirectConnectionUpgradeSucceeded { relayed_connection_id, }, )) => { - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, handler: NotifyHandler::One(relayed_connection_id), event: Either::Left( handler::relayed::Command::UpgradeFinishedDontKeepAlive, ), - } - .into(), + }, NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeSucceeded { remote_peer_id: event_source, }, - ) - .into(), + ), ]); } Either::Right(Either::Right(event)) => void::unreachable(event), @@ -315,8 +321,8 @@ impl NetworkBehaviour for Behaviour { _cx: &mut Context<'_>, _: &mut impl PollParameters, ) -> Poll> { - if let Some(action) = self.queued_actions.pop_front() { - return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses)); + if let Some(event) = self.queued_events.pop_front() { + return Poll::Ready(event); } Poll::Pending @@ -345,70 +351,3 @@ impl NetworkBehaviour for Behaviour { } } } - -/// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`] -/// before being returned in [`Behaviour::poll`]. -enum ActionBuilder { - Done(NetworkBehaviourAction), - Connect { - attempt: u8, - handler: NotifyHandler, - peer_id: PeerId, - }, - AcceptInboundConnect { - inbound_connect: Box, - handler: NotifyHandler, - peer_id: PeerId, - }, -} - -impl From> for ActionBuilder { - fn from(action: NetworkBehaviourAction) -> Self { - Self::Done(action) - } -} - -impl ActionBuilder { - fn build( - self, - local_peer_id: PeerId, - external_addresses: &ExternalAddresses, - ) -> NetworkBehaviourAction { - let obs_addrs = || { - external_addresses - .iter() - .cloned() - .filter(|a| !a.iter().any(|p| p == Protocol::P2pCircuit)) - .map(|a| a.with(Protocol::P2p(local_peer_id.into()))) - .collect() - }; - - match self { - ActionBuilder::Done(action) => action, - ActionBuilder::AcceptInboundConnect { - inbound_connect, - handler, - peer_id, - } => NetworkBehaviourAction::NotifyHandler { - handler, - peer_id, - event: Either::Left(handler::relayed::Command::AcceptInboundConnect { - inbound_connect, - obs_addrs: obs_addrs(), - }), - }, - ActionBuilder::Connect { - attempt, - handler, - peer_id, - } => NetworkBehaviourAction::NotifyHandler { - handler, - peer_id, - event: Either::Left(handler::relayed::Command::Connect { - attempt, - obs_addrs: obs_addrs(), - }), - }, - } - } -}