mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-23 23:01:33 +00:00
feat(swarm)!: allow NetworkBehaviour
s to manage connections
Previously, a `ConnectionHandler` was immediately requested from the `NetworkBehaviour` as soon as a new dial was initiated or a new incoming connection accepted. With this patch, we delay the creation of the handler until the connection is actually established and fully upgraded, i.e authenticated and multiplexed. As a consequence, `NetworkBehaviour::new_handler` is now deprecated in favor of a new set of callbacks: - `NetworkBehaviour::handle_pending_inbound_connection` - `NetworkBehaviour::handle_pending_outbound_connection` - `NetworkBehaviour::handle_established_inbound_connection` - `NetworkBehaviour::handle_established_outbound_connection` All callbacks are fallible, allowing the `NetworkBehaviour` to abort the connection either immediately or after it is fully established. All callbacks also receive a `ConnectionId` parameter which uniquely identifies the connection. For example, in case a `NetworkBehaviour` issues a dial via `NetworkBehaviourAction::Dial`, it can unambiguously detect this dial in these lifecycle callbacks via the `ConnectionId`. Finally, `NetworkBehaviour::handle_pending_outbound_connection` also replaces `NetworkBehaviour::addresses_of_peer` by allowing the behaviour to return more addresses to be used for the dial. Resolves #2824. Pull-Request: #3254.
This commit is contained in:
@ -28,11 +28,13 @@ pub use listen_addresses::ListenAddresses;
|
||||
|
||||
use crate::connection::ConnectionId;
|
||||
use crate::dial_opts::DialOpts;
|
||||
#[allow(deprecated)]
|
||||
use crate::handler::IntoConnectionHandler;
|
||||
use crate::{
|
||||
AddressRecord, AddressScore, DialError, ListenError, THandlerInEvent, THandlerOutEvent,
|
||||
AddressRecord, AddressScore, ConnectionDenied, DialError, ListenError, THandler,
|
||||
THandlerInEvent, THandlerOutEvent,
|
||||
};
|
||||
use libp2p_core::{transport::ListenerId, ConnectedPoint, Multiaddr, PeerId};
|
||||
use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId};
|
||||
use std::{task::Context, task::Poll};
|
||||
|
||||
/// A [`NetworkBehaviour`] defines the behaviour of the local node on the network.
|
||||
@ -119,6 +121,7 @@ use std::{task::Context, task::Poll};
|
||||
/// ```
|
||||
pub trait NetworkBehaviour: 'static {
|
||||
/// Handler for all the protocols the network behaviour supports.
|
||||
#[allow(deprecated)]
|
||||
type ConnectionHandler: IntoConnectionHandler;
|
||||
|
||||
/// Event generated by the `NetworkBehaviour` and that the swarm will report back.
|
||||
@ -141,7 +144,102 @@ pub trait NetworkBehaviour: 'static {
|
||||
///
|
||||
/// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and
|
||||
/// connection closing.
|
||||
fn new_handler(&mut self) -> Self::ConnectionHandler;
|
||||
#[deprecated(
|
||||
since = "0.42.0",
|
||||
note = "Use one or more of `NetworkBehaviour::{handle_pending_inbound_connection,handle_established_inbound_connection,handle_pending_outbound_connection,handle_established_outbound_connection}` instead."
|
||||
)]
|
||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
||||
panic!("You must implement `handle_established_inbound_connection` and `handle_established_outbound_connection`.")
|
||||
}
|
||||
|
||||
/// Callback that is invoked for every new inbound connection.
|
||||
///
|
||||
/// At this point in the connection lifecycle, only the remote's and our local address are known.
|
||||
/// We have also already allocated a [`ConnectionId`].
|
||||
///
|
||||
/// Any error returned from this function will immediately abort the dial attempt.
|
||||
fn handle_pending_inbound_connection(
|
||||
&mut self,
|
||||
_connection_id: ConnectionId,
|
||||
_local_addr: &Multiaddr,
|
||||
_remote_addr: &Multiaddr,
|
||||
) -> Result<(), ConnectionDenied> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Callback that is invoked for every established inbound connection.
|
||||
///
|
||||
/// This is invoked once another peer has successfully dialed us.
|
||||
///
|
||||
/// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
|
||||
/// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler).
|
||||
/// Returning an error will immediately close the connection.
|
||||
fn handle_established_inbound_connection(
|
||||
&mut self,
|
||||
_connection_id: ConnectionId,
|
||||
peer: PeerId,
|
||||
local_addr: &Multiaddr,
|
||||
remote_addr: &Multiaddr,
|
||||
) -> Result<THandler<Self>, ConnectionDenied> {
|
||||
#[allow(deprecated)]
|
||||
Ok(self.new_handler().into_handler(
|
||||
&peer,
|
||||
&ConnectedPoint::Listener {
|
||||
local_addr: local_addr.clone(),
|
||||
send_back_addr: remote_addr.clone(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// Callback that is invoked for every outbound connection attempt.
|
||||
///
|
||||
/// We have access to:
|
||||
///
|
||||
/// - The [`PeerId`], if known. Remember that we can dial without a [`PeerId`].
|
||||
/// - All addresses passed to [`DialOpts`] are passed in here too.
|
||||
/// - The effective [`Role`](Endpoint) of this peer in the dial attempt. Typically, this is set to [`Endpoint::Dialer`] except if we are attempting a hole-punch.
|
||||
/// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful.
|
||||
///
|
||||
/// Note that the addresses returned from this function are only used for dialing if [`WithPeerIdWithAddresses::extend_addresses_through_behaviour`](crate::dial_opts::WithPeerIdWithAddresses::extend_addresses_through_behaviour) is set.
|
||||
///
|
||||
/// Any error returned from this function will immediately abort the dial attempt.
|
||||
fn handle_pending_outbound_connection(
|
||||
&mut self,
|
||||
_connection_id: ConnectionId,
|
||||
maybe_peer: Option<PeerId>,
|
||||
_addresses: &[Multiaddr],
|
||||
_effective_role: Endpoint,
|
||||
) -> Result<Vec<Multiaddr>, ConnectionDenied> {
|
||||
#[allow(deprecated)]
|
||||
if let Some(peer_id) = maybe_peer {
|
||||
Ok(self.addresses_of_peer(&peer_id))
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
/// Callback that is invoked for every established outbound connection.
|
||||
///
|
||||
/// This is invoked once we have successfully dialed a peer.
|
||||
/// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
|
||||
/// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler).
|
||||
/// Returning an error will immediately close the connection.
|
||||
fn handle_established_outbound_connection(
|
||||
&mut self,
|
||||
_connection_id: ConnectionId,
|
||||
peer: PeerId,
|
||||
addr: &Multiaddr,
|
||||
role_override: Endpoint,
|
||||
) -> Result<THandler<Self>, ConnectionDenied> {
|
||||
#[allow(deprecated)]
|
||||
Ok(self.new_handler().into_handler(
|
||||
&peer,
|
||||
&ConnectedPoint::Dialer {
|
||||
address: addr.clone(),
|
||||
role_override,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// Addresses that this behaviour is aware of for this specific peer, and that may allow
|
||||
/// reaching the peer.
|
||||
@ -149,6 +247,7 @@ pub trait NetworkBehaviour: 'static {
|
||||
/// The addresses will be tried in the order returned by this function, which means that they
|
||||
/// should be ordered by decreasing likelihood of reachability. In other words, the first
|
||||
/// address should be the most likely to be reachable.
|
||||
#[deprecated(note = "Use `NetworkBehaviour::handle_pending_outbound_connection` instead.")]
|
||||
fn addresses_of_peer(&mut self, _: &PeerId) -> Vec<Multiaddr> {
|
||||
vec![]
|
||||
}
|
||||
@ -380,6 +479,7 @@ pub enum CloseConnection {
|
||||
|
||||
/// Enumeration with the list of the possible events
|
||||
/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event).
|
||||
#[allow(deprecated)]
|
||||
pub enum FromSwarm<'a, Handler: IntoConnectionHandler> {
|
||||
/// Informs the behaviour about a newly established connection to a peer.
|
||||
ConnectionEstablished(ConnectionEstablished<'a>),
|
||||
@ -434,6 +534,7 @@ pub struct ConnectionEstablished<'a> {
|
||||
/// This event is always paired with an earlier
|
||||
/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
|
||||
/// and endpoint.
|
||||
#[allow(deprecated)]
|
||||
pub struct ConnectionClosed<'a, Handler: IntoConnectionHandler> {
|
||||
pub peer_id: PeerId,
|
||||
pub connection_id: ConnectionId,
|
||||
@ -524,6 +625,7 @@ pub struct ExpiredExternalAddr<'a> {
|
||||
pub addr: &'a Multiaddr,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> {
|
||||
fn map_handler<NewHandler>(
|
||||
self,
|
||||
|
Reference in New Issue
Block a user