Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(swarm)!: Allow NetworkBehaviours to manage incoming connections #3099

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d501019
Introduce `NetworkBehaviour::DialPayload`
thomaseizinger Nov 9, 2022
77c85f6
WIP Migrate production code
thomaseizinger Nov 9, 2022
118ffb6
Deprecate `new_handler`
thomaseizinger Nov 9, 2022
377c351
WIP: Completely remove `IntoConnectionHandler`
thomaseizinger Nov 14, 2022
9972eb4
Set supported protocols upon connection establishment
thomaseizinger Nov 15, 2022
fb9cdbc
Remove TODOs
thomaseizinger Nov 15, 2022
a96780d
Fix bad boolean logic
thomaseizinger Nov 15, 2022
3c9d98e
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 15, 2022
900edef
Fix gossipsub tests
thomaseizinger Nov 15, 2022
d1eea3a
Fix clippy warning
thomaseizinger Nov 15, 2022
98bf927
Update docs
thomaseizinger Nov 15, 2022
1cef941
Reduce diff
thomaseizinger Nov 15, 2022
ca3ef3e
Fix clippy errors
thomaseizinger Nov 15, 2022
a7f0685
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 16, 2022
d95b038
Update swarm/src/behaviour.rs
thomaseizinger Nov 16, 2022
edbbe41
Add changelog entry
thomaseizinger Nov 17, 2022
fef8d85
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 18, 2022
a942248
Remove unnecessary bounds
thomaseizinger Nov 18, 2022
0578134
Remove old example
thomaseizinger Nov 18, 2022
f7def2b
fmt
thomaseizinger Nov 18, 2022
a5a728b
Make `new_handler` fallible
thomaseizinger Nov 18, 2022
27e1b2d
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 19, 2022
19348e9
Allow each `NetworkBehaviour` to have their own `ConnectionDenied` re…
thomaseizinger Nov 22, 2022
9c55601
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 23, 2022
527eeda
Merge branch 'master' into 2824-remove-into-connection-handler
thomaseizinger Nov 29, 2022
a269e9d
Revert "Allow each `NetworkBehaviour` to have their own `ConnectionDe…
thomaseizinger Dec 7, 2022
dcb4f96
Always box cause for denied connection
thomaseizinger Dec 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 15 additions & 23 deletions protocols/autonat/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ use libp2p_request_response::{
handler::RequestResponseHandlerEvent, ProtocolSupport, RequestId, RequestResponse,
RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
};
use libp2p_swarm::{
DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
};
use libp2p_swarm::behaviour::THandlerInEvent;
use libp2p_swarm::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
use std::{
collections::{HashMap, VecDeque},
iter,
Expand Down Expand Up @@ -356,7 +355,7 @@ impl NetworkBehaviour for Behaviour {
peer: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
handler: Self::ConnectionHandler,
remaining_established: usize,
) {
self.inner
Expand All @@ -369,14 +368,9 @@ impl NetworkBehaviour for Behaviour {
}
}

fn inject_dial_failure(
&mut self,
peer: Option<PeerId>,
handler: Self::ConnectionHandler,
error: &DialError,
) {
self.inner.inject_dial_failure(peer, handler, error);
if let Some(event) = self.as_server().on_outbound_dial_error(peer, error) {
fn inject_dial_failure(&mut self, peer_id: Option<PeerId>, error: &DialError) {
self.inner.inject_dial_failure(peer_id, error);
if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) {
self.pending_out_events
.push_back(Event::InboundProbe(event));
}
Expand Down Expand Up @@ -470,8 +464,12 @@ impl NetworkBehaviour for Behaviour {
}
}

fn new_handler(&mut self) -> Self::ConnectionHandler {
self.inner.new_handler()
fn new_handler(
&mut self,
peer: &PeerId,
connected_point: &ConnectedPoint,
) -> Self::ConnectionHandler {
self.inner.new_handler(peer, connected_point)
}

fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec<Multiaddr> {
Expand All @@ -487,14 +485,8 @@ impl NetworkBehaviour for Behaviour {
self.inner.inject_event(peer_id, conn, event)
}

fn inject_listen_failure(
&mut self,
local_addr: &Multiaddr,
send_back_addr: &Multiaddr,
handler: Self::ConnectionHandler,
) {
self.inner
.inject_listen_failure(local_addr, send_back_addr, handler)
fn inject_listen_failure(&mut self, local_addr: &Multiaddr, send_back_addr: &Multiaddr) {
self.inner.inject_listen_failure(local_addr, send_back_addr)
}

fn inject_new_listener(&mut self, id: ListenerId) {
Expand All @@ -512,7 +504,7 @@ impl NetworkBehaviour for Behaviour {

type Action = NetworkBehaviourAction<
<Behaviour as NetworkBehaviour>::OutEvent,
<Behaviour as NetworkBehaviour>::ConnectionHandler,
THandlerInEvent<<Behaviour as NetworkBehaviour>::ConnectionHandler>,
>;

// Trait implemented for `AsClient` as `AsServer` to handle events from the inner [`RequestResponse`] Protocol.
Expand Down
3 changes: 1 addition & 2 deletions protocols/autonat/src/behaviour/as_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use libp2p_request_response::{
};
use libp2p_swarm::{
dial_opts::{DialOpts, PeerCondition},
DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
DialError, NetworkBehaviourAction, PollParameters,
};
use std::{
collections::{HashMap, HashSet, VecDeque},
Expand Down Expand Up @@ -137,7 +137,6 @@ impl<'a> HandleInnerEvent for AsServer<'a> {
.override_dial_concurrency_factor(NonZeroU8::new(1).expect("1 > 0"))
.addresses(addrs)
.build(),
handler: self.inner.new_handler(),
});
}
Err((status_text, error)) => {
Expand Down
161 changes: 108 additions & 53 deletions protocols/dcutr/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ use either::Either;
use libp2p_core::connection::{ConnectedPoint, ConnectionId};
use libp2p_core::multiaddr::Protocol;
use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::behaviour::THandlerInEvent;
use libp2p_swarm::dial_opts::{self, DialOpts};
use libp2p_swarm::{
ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler,
NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
dummy, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, NetworkBehaviour,
NetworkBehaviourAction, NotifyHandler, PollParameters,
};
use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet, VecDeque};
use std::task::{Context, Poll};
use thiserror::Error;
Expand Down Expand Up @@ -72,23 +74,82 @@ pub struct Behaviour {

/// All direct (non-relayed) connections.
direct_connections: HashMap<PeerId, HashSet<ConnectionId>>,

awaiting_direct_inbound_connections: HashMap<PeerId, ConnectionId>,

awaiting_direct_outbound_connections: HashMap<PeerId, (ConnectionId, u8)>,
}

type Handler =
Either<handler::relayed::Handler, Either<handler::direct::Handler, dummy::ConnectionHandler>>;

impl Behaviour {
pub fn new() -> Self {
Behaviour {
queued_actions: Default::default(),
direct_connections: Default::default(),
awaiting_direct_inbound_connections: Default::default(),
awaiting_direct_outbound_connections: Default::default(),
}
}
}

impl NetworkBehaviour for Behaviour {
type ConnectionHandler = handler::Prototype;
type ConnectionHandler = Handler;
type OutEvent = Event;

fn new_handler(&mut self) -> Self::ConnectionHandler {
handler::Prototype::UnknownConnection
fn new_handler(
&mut self,
peer: &PeerId,
connected_point: &ConnectedPoint,
) -> Self::ConnectionHandler {
match (
self.awaiting_direct_inbound_connections.entry(*peer),
self.awaiting_direct_outbound_connections.entry(*peer),
) {
(Entry::Vacant(_), Entry::Occupied(occupied)) => {
if connected_point.is_relayed() {
log::debug!(
"Unexpected relay connection whilst awaiting direct outbound connection"
);

return Either::Left(handler::relayed::Handler::new(connected_point.clone()));
}

let (relayed_connection_id, _) = occupied.remove();

Either::Right(Either::Left(handler::direct::Handler::new(
relayed_connection_id,
)))
}
(Entry::Occupied(occupied), Entry::Vacant(_)) => {
if connected_point.is_relayed() {
log::debug!(
"Unexpected relay connection whilst awaiting direct inbound connection"
);

return Either::Left(handler::relayed::Handler::new(connected_point.clone()));
}

let relayed_connection_id = occupied.remove();

Either::Right(Either::Left(handler::direct::Handler::new(
relayed_connection_id,
)))
}
(Entry::Vacant(_), Entry::Vacant(_)) => {
if connected_point.is_relayed() {
Either::Left(handler::relayed::Handler::new(connected_point.clone()))
} else {
Either::Right(Either::Right(dummy::ConnectionHandler))
}
}
(Entry::Occupied(_), Entry::Occupied(_)) => {
debug_assert!(false, "Should not have a pending outbound and pending inbound connection to same peer simultaneously");

Either::Right(Either::Right(dummy::ConnectionHandler))
}
}
}

fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec<Multiaddr> {
Expand Down Expand Up @@ -140,41 +201,38 @@ impl NetworkBehaviour for Behaviour {
}
}

fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
handler: Self::ConnectionHandler,
_error: &DialError,
) {
if let handler::Prototype::DirectConnection {
relayed_connection_id,
role: handler::Role::Initiator { attempt },
} = handler
{
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 {
fn inject_dial_failure(&mut self, maybe_peer_id: Option<PeerId>, _error: &DialError) {
let peer_id = match maybe_peer_id {
Some(peer_id) => peer_id,
None => return,
};

let (relayed_connection_id, attempt) =
match self.awaiting_direct_outbound_connections.remove(&peer_id) {
Some((relayed_connection_id, attempt)) => (relayed_connection_id, attempt),
None => return,
};

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,
});
} else {
self.queued_actions.extend([
NetworkBehaviourAction::NotifyHandler {
peer_id,
handler: NotifyHandler::One(relayed_connection_id),
attempt: attempt + 1,
});
} else {
self.queued_actions.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: UpgradeError::Dial,
})
.into(),
]);
}
event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive),
}
.into(),
NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed {
remote_peer_id: peer_id,
error: UpgradeError::Dial,
})
.into(),
]);
}
}

Expand All @@ -183,7 +241,7 @@ impl NetworkBehaviour for Behaviour {
peer_id: &PeerId,
connection_id: &ConnectionId,
connected_point: &ConnectedPoint,
_handler: <<Self as NetworkBehaviour>::ConnectionHandler as IntoConnectionHandler>::Handler,
_handler: Self::ConnectionHandler,
_remaining_established: usize,
) {
if !connected_point.is_relayed() {
Expand All @@ -205,7 +263,7 @@ impl NetworkBehaviour for Behaviour {
&mut self,
event_source: PeerId,
connection: ConnectionId,
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
handler_event: <Self::ConnectionHandler as ConnectionHandler>::OutEvent,
) {
match handler_event {
Either::Left(handler::relayed::Event::InboundConnectRequest {
Expand Down Expand Up @@ -243,13 +301,11 @@ impl NetworkBehaviour for Behaviour {
.addresses(remote_addrs)
.condition(dial_opts::PeerCondition::Always)
.build(),
handler: handler::Prototype::DirectConnection {
relayed_connection_id: connection,
role: handler::Role::Listener,
},
}
.into(),
);
self.awaiting_direct_inbound_connections
.insert(event_source, connection);
}
Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => {
self.queued_actions.push_back(
Expand All @@ -271,13 +327,11 @@ impl NetworkBehaviour for Behaviour {
.addresses(remote_addrs)
.override_role()
.build(),
handler: handler::Prototype::DirectConnection {
relayed_connection_id: connection,
role: handler::Role::Initiator { attempt },
},
}
.into(),
);
self.awaiting_direct_outbound_connections
.insert(event_source, (connection, attempt));
}
Either::Right(Either::Left(
handler::direct::Event::DirectConnectionUpgradeSucceeded {
Expand Down Expand Up @@ -309,7 +363,8 @@ impl NetworkBehaviour for Behaviour {
&mut self,
_cx: &mut Context<'_>,
poll_parameters: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
) -> Poll<NetworkBehaviourAction<Self::OutEvent, THandlerInEvent<Self::ConnectionHandler>>>
{
if let Some(action) = self.queued_actions.pop_front() {
return Poll::Ready(action.build(poll_parameters));
}
Expand All @@ -321,7 +376,7 @@ impl NetworkBehaviour for Behaviour {
/// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`]
/// before being returned in [`Behaviour::poll`].
enum ActionBuilder {
Done(NetworkBehaviourAction<Event, handler::Prototype>),
Done(NetworkBehaviourAction<Event, THandlerInEvent<Handler>>),
Connect {
attempt: u8,
handler: NotifyHandler,
Expand All @@ -334,8 +389,8 @@ enum ActionBuilder {
},
}

impl From<NetworkBehaviourAction<Event, handler::Prototype>> for ActionBuilder {
fn from(action: NetworkBehaviourAction<Event, handler::Prototype>) -> Self {
impl From<NetworkBehaviourAction<Event, THandlerInEvent<Handler>>> for ActionBuilder {
fn from(action: NetworkBehaviourAction<Event, THandlerInEvent<Handler>>) -> Self {
Self::Done(action)
}
}
Expand All @@ -344,7 +399,7 @@ impl ActionBuilder {
fn build(
self,
poll_parameters: &mut impl PollParameters,
) -> NetworkBehaviourAction<Event, handler::Prototype> {
) -> NetworkBehaviourAction<Event, THandlerInEvent<Handler>> {
let obs_addrs = || {
poll_parameters
.external_addresses()
Expand Down
Loading