diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index a5bf0e06f06..887d1a11231 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -152,39 +152,91 @@ pub trait NetworkBehaviour: 'static { vec![] } + /// Informs the behaviour about an event from the [`Swarm`](crate::Swarm). + fn on_swarm_event(&mut self, _event: InEvent) {} + + /// Informs the behaviour about an event generated by the [`ConnectionHandler`] dedicated to the + /// peer identified by `peer_id`. for the behaviour. + /// + /// The [`PeerId`] is guaranteed to be in a connected state. In other words, + /// [`InEvent::ConnectionEstablished`] has previously been received with this [`PeerId`]. + fn on_connection_handler_event( + &mut self, + _peer_id: PeerId, + _connection_id: ConnectionId, + // TODO: Instead of the type alias THandlerOutEvent the full definition might be more + // intuitive for users outside of libp2p-swarm. + _event: crate::THandlerOutEvent, + ) { + } + /// Informs the behaviour about a newly established connection to a peer. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ConnectionEstablished` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_connection_established( &mut self, - _peer_id: &PeerId, - _connection_id: &ConnectionId, - _endpoint: &ConnectedPoint, - _failed_addresses: Option<&Vec>, - _other_established: usize, + peer_id: &PeerId, + connection_id: &ConnectionId, + endpoint: &ConnectedPoint, + failed_addresses: Option<&Vec>, + other_established: usize, ) { + self.on_swarm_event(InEvent::ConnectionEstablished { + peer_id: *peer_id, + connection_id: *connection_id, + endpoint, + failed_addresses: failed_addresses + .map(|v| v.as_slice()) + .unwrap_or_else(|| &[]), + other_established, + }); } /// Informs the behaviour about a closed connection to a peer. /// /// A call to this method is always paired with an earlier call to /// [`NetworkBehaviour::inject_connection_established`] with the same peer ID, connection ID and endpoint. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ConnectionClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_connection_closed( &mut self, - _: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - _: ::Handler, - _remaining_established: usize, + peer_id: &PeerId, + connection_id: &ConnectionId, + endpoint: &ConnectedPoint, + handler: ::Handler, + remaining_established: usize, ) { + self.on_swarm_event(InEvent::ConnectionClosed { + peer_id: *peer_id, + connection_id: *connection_id, + endpoint, + handler, + remaining_established, + }); } /// Informs the behaviour that the [`ConnectedPoint`] of an existing connection has changed. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::AddressChange` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_address_change( &mut self, - _: &PeerId, - _: &ConnectionId, - _old: &ConnectedPoint, - _new: &ConnectedPoint, + peer_id: &PeerId, + connection_id: &ConnectionId, + old: &ConnectedPoint, + new: &ConnectedPoint, ) { + self.on_swarm_event(InEvent::AddressChange { + peer_id: *peer_id, + connection_id: *connection_id, + old, + new, + }); } /// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`. @@ -192,20 +244,35 @@ pub trait NetworkBehaviour: 'static { /// /// The `peer_id` is guaranteed to be in a connected state. In other words, /// [`NetworkBehaviour::inject_connection_established`] has previously been called with this `PeerId`. + #[deprecated( + since = "0.39.0", + note = "Implement `NetworkBehaviour::on_connection_handler_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_event( &mut self, peer_id: PeerId, connection: ConnectionId, event: <::Handler as ConnectionHandler>::OutEvent, - ); + ) { + self.on_connection_handler_event(peer_id, connection, event); + } /// Indicates to the behaviour that the dial to a known or unknown node failed. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::DialFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_dial_failure( &mut self, - _peer_id: Option, - _handler: Self::ConnectionHandler, - _error: &DialError, + peer_id: Option, + handler: Self::ConnectionHandler, + error: &DialError, ) { + self.on_swarm_event(InEvent::DialFailure { + peer_id, + handler, + error, + }); } /// Indicates to the behaviour that an error happened on an incoming connection during its @@ -213,36 +280,98 @@ pub trait NetworkBehaviour: 'static { /// /// This can include, for example, an error during the handshake of the encryption layer, or the /// connection unexpectedly closed. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ListenFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_listen_failure( &mut self, - _local_addr: &Multiaddr, - _send_back_addr: &Multiaddr, - _handler: Self::ConnectionHandler, + local_addr: &Multiaddr, + send_back_addr: &Multiaddr, + handler: Self::ConnectionHandler, ) { + self.on_swarm_event(InEvent::ListenFailure { + local_addr, + send_back_addr, + handler, + }); } /// Indicates to the behaviour that a new listener was created. - fn inject_new_listener(&mut self, _id: ListenerId) {} + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::NewListener` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_listener(&mut self, id: ListenerId) { + self.on_swarm_event(InEvent::NewListener { listener_id: id }); + } /// Indicates to the behaviour that we have started listening on a new multiaddr. - fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {} + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::NewListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { + self.on_swarm_event(InEvent::NewListenAddr { + listener_id: id, + addr, + }); + } /// Indicates to the behaviour that a multiaddr we were listening on has expired, - /// which means that we are no longer listening in it. - fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {} + /// which means that we are no longer listening on it. + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ExpiredListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { + self.on_swarm_event(InEvent::ExpiredListenAddr { + listener_id: id, + addr, + }); + } /// A listener experienced an error. - fn inject_listener_error(&mut self, _id: ListenerId, _err: &(dyn std::error::Error + 'static)) { + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ListenerError` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { + self.on_swarm_event(InEvent::ListenerError { + listener_id: id, + err, + }); } /// A listener closed. - fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {} + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ListenerClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { + self.on_swarm_event(InEvent::ListenerClosed { + listener_id: id, + reason, + }); + } /// Indicates to the behaviour that we have discovered a new external address for us. - fn inject_new_external_addr(&mut self, _addr: &Multiaddr) {} + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::NewExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_external_addr(&mut self, addr: &Multiaddr) { + self.on_swarm_event(InEvent::NewExternalAddr { addr }); + } /// Indicates to the behaviour that an external address was removed. - fn inject_expired_external_addr(&mut self, _addr: &Multiaddr) {} + #[deprecated( + since = "0.39.0", + note = "Handle `InEvent::ExpiredExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { + self.on_swarm_event(InEvent::ExpiredExternalAddr { addr }); + } /// Polls for things that swarm should do. /// @@ -721,3 +850,182 @@ impl Default for CloseConnection { CloseConnection::All } } + +// TODO: Rename to FromSwarm +pub enum InEvent<'a, Handler: IntoConnectionHandler> { + /// Informs the behaviour about a newly established connection to a peer. + ConnectionEstablished { + peer_id: PeerId, + connection_id: ConnectionId, + endpoint: &'a ConnectedPoint, + failed_addresses: &'a [Multiaddr], + other_established: usize, + }, + /// Informs the behaviour about a closed connection to a peer. + /// + /// This event is always paired with an earlier + /// [`InEvent::ConnectionEstablished`] with the same peer ID, connection ID + /// and endpoint. + ConnectionClosed { + peer_id: PeerId, + connection_id: ConnectionId, + endpoint: &'a ConnectedPoint, + handler: ::Handler, + remaining_established: usize, + }, + /// Informs the behaviour that the [`ConnectedPoint`] of an existing + /// connection has changed. + AddressChange { + peer_id: PeerId, + connection_id: ConnectionId, + old: &'a ConnectedPoint, + new: &'a ConnectedPoint, + }, + /// Indicates to the behaviour that the dial to a known or unknown node failed. + DialFailure { + peer_id: Option, + handler: Handler, + error: &'a DialError, + }, + /// Indicates to the behaviour that an error happened on an incoming connection during its + /// initial handshake. + /// + /// This can include, for example, an error during the handshake of the encryption layer, or the + /// connection unexpectedly closed. + ListenFailure { + local_addr: &'a Multiaddr, + send_back_addr: &'a Multiaddr, + handler: Handler, + }, + /// Indicates to the behaviour that a new listener was created. + NewListener { listener_id: ListenerId }, + /// Indicates to the behaviour that we have started listening on a new multiaddr. + NewListenAddr { + listener_id: ListenerId, + addr: &'a Multiaddr, + }, + /// Indicates to the behaviour that a multiaddr we were listening on has expired, + /// which means that we are no longer listening on it. + ExpiredListenAddr { + listener_id: ListenerId, + addr: &'a Multiaddr, + }, + /// A listener experienced an error. + ListenerError { + listener_id: ListenerId, + err: &'a (dyn std::error::Error + 'static), + }, + /// A listener closed. + ListenerClosed { + listener_id: ListenerId, + reason: Result<(), &'a std::io::Error>, + }, + /// Indicates to the behaviour that we have discovered a new external address for us. + NewExternalAddr { addr: &'a Multiaddr }, + /// Indicates to the behaviour that an external address was removed. + ExpiredExternalAddr { addr: &'a Multiaddr }, +} + +impl<'a, Handler: IntoConnectionHandler> InEvent<'a, Handler> { + fn map_handler( + self, + map_into_handler: impl FnOnce(Handler) -> NewHandler, + map_handler: impl FnOnce( + ::Handler, + ) -> ::Handler, + ) -> InEvent<'a, NewHandler> + where + NewHandler: IntoConnectionHandler, + { + self.maybe_map_handler(|h| Some(map_into_handler(h)), |h| Some(map_handler(h))) + .expect("To return Some as all closures return Some.") + } + + fn maybe_map_handler( + self, + map_into_handler: impl FnOnce(Handler) -> Option, + map_handler: impl FnOnce( + ::Handler, + ) -> Option<::Handler>, + ) -> Option> + where + NewHandler: IntoConnectionHandler, + { + match self { + InEvent::ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + } => Some(InEvent::ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler: map_handler(handler)?, + remaining_established, + }), + InEvent::ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + } => Some(InEvent::ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + }), + InEvent::AddressChange { + peer_id, + connection_id, + old, + new, + } => Some(InEvent::AddressChange { + peer_id, + connection_id, + old, + new, + }), + InEvent::DialFailure { + peer_id, + handler, + error, + } => Some(InEvent::DialFailure { + peer_id, + handler: map_into_handler(handler)?, + error, + }), + InEvent::ListenFailure { + local_addr, + send_back_addr, + handler, + } => Some(InEvent::ListenFailure { + local_addr, + send_back_addr, + handler: map_into_handler(handler)?, + }), + InEvent::NewListener { listener_id } => Some(InEvent::NewListener { listener_id }), + InEvent::NewListenAddr { listener_id, addr } => { + Some(InEvent::NewListenAddr { listener_id, addr }) + } + InEvent::ExpiredListenAddr { listener_id, addr } => { + Some(InEvent::ExpiredListenAddr { listener_id, addr }) + } + InEvent::ListenerError { listener_id, err } => { + Some(InEvent::ListenerError { listener_id, err }) + } + InEvent::ListenerClosed { + listener_id, + reason, + } => Some(InEvent::ListenerClosed { + listener_id, + reason, + }), + InEvent::NewExternalAddr { addr } => Some(InEvent::NewExternalAddr { addr }), + InEvent::ExpiredExternalAddr { addr } => Some(InEvent::ExpiredExternalAddr { addr }), + } + } +} diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 6bb1d95a519..59bc0f389e1 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,12 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler}; -use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::behaviour::{self, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::handler::either::IntoEitherHandler; use either::Either; -use libp2p_core::{ - connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, -}; +use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. @@ -49,173 +47,42 @@ where } } - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, - ) { + fn on_swarm_event(&mut self, event: behaviour::InEvent) { match self { - Either::Left(a) => a.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ), - Either::Right(b) => b.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ), - } - } - - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, - ) { - match (self, handler) { - (Either::Left(behaviour), Either::Left(handler)) => behaviour.inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, - ), - (Either::Right(behaviour), Either::Right(handler)) => behaviour - .inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, - ), - _ => unreachable!(), + Either::Left(b) => b.on_swarm_event(event.map_handler( + |h| h.unwrap_left(), + |h| match h { + Either::Left(h) => h, + Either::Right(_) => unreachable!(), + }, + )), + Either::Right(b) => b.on_swarm_event(event.map_handler( + |h| h.unwrap_right(), + |h| match h { + Either::Right(h) => h, + Either::Left(_) => unreachable!(), + }, + )), } } - fn inject_address_change( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, - ) { - match self { - Either::Left(a) => a.inject_address_change(peer_id, connection, old, new), - Either::Right(b) => b.inject_address_change(peer_id, connection, old, new), - } - } - - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, - connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + connection_id: libp2p_core::connection::ConnectionId, + event: crate::THandlerOutEvent, ) { match (self, event) { - (Either::Left(behaviour), Either::Left(event)) => { - behaviour.inject_event(peer_id, connection, event) - } - (Either::Right(behaviour), Either::Right(event)) => { - behaviour.inject_event(peer_id, connection, event) - } - _ => unreachable!(), - } - } - - fn inject_dial_failure( - &mut self, - peer_id: Option, - handler: Self::ConnectionHandler, - error: &DialError, - ) { - match (self, handler) { - (Either::Left(behaviour), IntoEitherHandler::Left(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, error) - } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, error) - } - _ => unreachable!(), - } - } - - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { - match (self, handler) { - (Either::Left(behaviour), IntoEitherHandler::Left(handler)) => { - behaviour.inject_listen_failure(local_addr, send_back_addr, handler) + (Either::Left(left), Either::Left(event)) => { + left.on_connection_handler_event(peer_id, connection_id, event) } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_listen_failure(local_addr, send_back_addr, handler) + (Either::Right(right), Either::Right(event)) => { + right.on_connection_handler_event(peer_id, connection_id, event) } _ => unreachable!(), } } - fn inject_new_listener(&mut self, id: ListenerId) { - match self { - Either::Left(a) => a.inject_new_listener(id), - Either::Right(b) => b.inject_new_listener(id), - } - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_new_listen_addr(id, addr), - Either::Right(b) => b.inject_new_listen_addr(id, addr), - } - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_expired_listen_addr(id, addr), - Either::Right(b) => b.inject_expired_listen_addr(id, addr), - } - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_new_external_addr(addr), - Either::Right(b) => b.inject_new_external_addr(addr), - } - } - - fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_expired_external_addr(addr), - Either::Right(b) => b.inject_expired_external_addr(addr), - } - } - - fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - match self { - Either::Left(a) => a.inject_listener_error(id, err), - Either::Right(b) => b.inject_listener_error(id, err), - } - } - - fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { - match self { - Either::Left(a) => a.inject_listener_closed(id, reason), - Either::Right(b) => b.inject_listener_closed(id, reason), - } - } - fn poll( &mut self, cx: &mut Context<'_>, diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 07a15d56da9..ea5a2d736ed 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -23,12 +23,10 @@ use crate::handler::{ KeepAlive, SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; -use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; use libp2p_core::{ - connection::ConnectionId, either::{EitherError, EitherOutput}, - transport::ListenerId, upgrade::{DeniedUpgrade, EitherUpgrade}, ConnectedPoint, Multiaddr, PeerId, }; @@ -84,134 +82,22 @@ where .unwrap_or_else(Vec::new) } - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, - ) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ) - } - } - - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, - ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, - ) + fn on_swarm_event(&mut self, event: super::InEvent) { + if let Some(behaviour) = &mut self.inner { + if let Some(event) = event.maybe_map_handler(|h| h.inner, |h| h.inner) { + behaviour.on_swarm_event(event); } } } - fn inject_address_change( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, - ) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_address_change(peer_id, connection, old, new) - } - } - - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, - connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, - ) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_event(peer_id, connection, event); - } - } - - fn inject_dial_failure( - &mut self, - peer_id: Option, - handler: Self::ConnectionHandler, - error: &DialError, + connection_id: libp2p_core::connection::ConnectionId, + event: crate::THandlerOutEvent, ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_dial_failure(peer_id, handler, error) - } - } - } - - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_listen_failure(local_addr, send_back_addr, handler) - } - } - } - - fn inject_new_listener(&mut self, id: ListenerId) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_listener(id) - } - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_listen_addr(id, addr) - } - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_expired_listen_addr(id, addr) - } - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_external_addr(addr) - } - } - - fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_expired_external_addr(addr) - } - } - - fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_listener_error(id, err) - } - } - - fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_listener_closed(id, reason) + if let Some(behaviour) = &mut self.inner { + behaviour.on_connection_handler_event(peer_id, connection_id, event) } } diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 21d386ec56a..2823b6ed824 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -64,6 +64,29 @@ where } } +// Taken from https://github.com/bluss/either. +impl IntoEitherHandler { + /// Returns the left value. + pub fn unwrap_left(self) -> L { + match self { + IntoEitherHandler::Left(l) => l, + IntoEitherHandler::Right(_) => { + panic!("called `IntoEitherHandler::unwrap_left()` on a `Right` value.",) + } + } + } + + /// Returns the right value. + pub fn unwrap_right(self) -> R { + match self { + IntoEitherHandler::Right(r) => r, + IntoEitherHandler::Left(_) => { + panic!("called `IntoEitherHandler::unwrap_right()` on a `Left` value.",) + } + } + } +} + /// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`] /// implementations. impl ConnectionHandler for Either diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 7faaa43b44d..b37715442ba 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -63,6 +63,7 @@ pub mod behaviour; pub mod dial_opts; pub mod handler; +use behaviour::InEvent; pub use behaviour::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -327,6 +328,7 @@ where /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { let id = self.transport.listen_on(addr)?; + #[allow(deprecated)] self.behaviour.inject_new_listener(id); Ok(id) } @@ -403,6 +405,7 @@ where PeerCondition::Always => true, }; if !condition_matched { + #[allow(deprecated)] self.behaviour.inject_dial_failure( Some(peer_id), handler, @@ -415,6 +418,7 @@ where // Check if peer is banned. if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; + #[allow(deprecated)] self.behaviour .inject_dial_failure(Some(peer_id), handler, &error); return Err(error); @@ -452,6 +456,7 @@ where if addresses.is_empty() { let error = DialError::NoAddresses; + #[allow(deprecated)] self.behaviour .inject_dial_failure(Some(peer_id), handler, &error); return Err(error); @@ -535,6 +540,7 @@ where Ok(_connection_id) => Ok(()), Err((connection_limit, handler)) => { let error = DialError::ConnectionLimit(connection_limit); + #[allow(deprecated)] self.behaviour.inject_dial_failure(None, handler, &error); Err(error) } @@ -576,12 +582,14 @@ where let result = self.external_addrs.add(a.clone(), s); let expired = match &result { AddAddressResult::Inserted { expired } => { + #[allow(deprecated)] self.behaviour.inject_new_external_addr(&a); expired } AddAddressResult::Updated { expired } => expired, }; for a in expired { + #[allow(deprecated)] self.behaviour.inject_expired_external_addr(&a.addr); } result @@ -595,6 +603,7 @@ where /// otherwise. pub fn remove_external_address(&mut self, addr: &Multiaddr) -> bool { if self.external_addrs.remove(addr) { + #[allow(deprecated)] self.behaviour.inject_expired_external_addr(addr); true } else { @@ -701,6 +710,7 @@ where let failed_addresses = concurrent_dial_errors .as_ref() .map(|es| es.iter().map(|(a, _)| a).cloned().collect()); + #[allow(deprecated)] self.behaviour.inject_connection_established( &peer_id, &id, @@ -724,6 +734,7 @@ where } => { let error = error.into(); + #[allow(deprecated)] self.behaviour.inject_dial_failure(peer, handler, &error); if let Some(peer) = peer { @@ -745,6 +756,7 @@ where handler, } => { log::debug!("Incoming connection failed: {:?}", error); + #[allow(deprecated)] self.behaviour .inject_listen_failure(&local_addr, &send_back_addr, handler); return Some(SwarmEvent::IncomingConnectionError { @@ -785,6 +797,7 @@ where .into_iter() .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) .count(); + #[allow(deprecated)] self.behaviour.inject_connection_closed( &peer_id, &id, @@ -804,6 +817,7 @@ where if self.banned_peer_connections.contains(&id) { log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); } else { + #[allow(deprecated)] self.behaviour.inject_event(peer_id, id, event); } } @@ -814,6 +828,7 @@ where old_endpoint, } => { if !self.banned_peer_connections.contains(&id) { + #[allow(deprecated)] self.behaviour.inject_address_change( &peer_id, &id, @@ -857,6 +872,7 @@ where }); } Err((connection_limit, handler)) => { + #[allow(deprecated)] self.behaviour .inject_listen_failure(&local_addr, &send_back_addr, handler); log::warn!("Incoming connection rejected: {:?}", connection_limit); @@ -872,6 +888,7 @@ where if !addrs.contains(&listen_addr) { addrs.push(listen_addr.clone()) } + #[allow(deprecated)] self.behaviour .inject_new_listen_addr(listener_id, &listen_addr); return Some(SwarmEvent::NewListenAddr { @@ -891,6 +908,7 @@ where if let Some(addrs) = self.listened_addrs.get_mut(&listener_id) { addrs.retain(|a| a != &listen_addr); } + #[allow(deprecated)] self.behaviour .inject_expired_listen_addr(listener_id, &listen_addr); return Some(SwarmEvent::ExpiredListenAddr { @@ -905,8 +923,10 @@ where log::debug!("Listener {:?}; Closed by {:?}.", listener_id, reason); let addrs = self.listened_addrs.remove(&listener_id).unwrap_or_default(); for addr in addrs.iter() { + #[allow(deprecated)] self.behaviour.inject_expired_listen_addr(listener_id, addr); } + #[allow(deprecated)] self.behaviour.inject_listener_closed( listener_id, match &reason { @@ -921,6 +941,7 @@ where }); } TransportEvent::ListenerError { listener_id, error } => { + #[allow(deprecated)] self.behaviour.inject_listener_error(listener_id, &error); return Some(SwarmEvent::ListenerError { listener_id, error }); } @@ -1542,11 +1563,65 @@ impl NetworkBehaviour for DummyBehaviour { } } - fn inject_event( + fn on_swarm_event(&mut self, event: InEvent) { + match event { + InEvent::ConnectionEstablished { + peer_id: _, + connection_id: _, + endpoint: _, + failed_addresses: _, + other_established: _, + } => {} + InEvent::ConnectionClosed { + peer_id: _, + connection_id: _, + endpoint: _, + handler: _, + remaining_established: _, + } => {} + InEvent::AddressChange { + peer_id: _, + connection_id: _, + old: _, + new: _, + } => {} + InEvent::DialFailure { + peer_id: _, + handler: _, + error: _, + } => {} + InEvent::ListenFailure { + local_addr: _, + send_back_addr: _, + handler: _, + } => {} + InEvent::NewListener { listener_id: _ } => {} + InEvent::NewListenAddr { + listener_id: _, + addr: _, + } => {} + InEvent::ExpiredListenAddr { + listener_id: _, + addr: _, + } => {} + InEvent::ListenerError { + listener_id: _, + err: _, + } => {} + InEvent::ListenerClosed { + listener_id: _, + reason: _, + } => {} + InEvent::NewExternalAddr { addr: _ } => {} + InEvent::ExpiredExternalAddr { addr: _ } => {} + } + } + + fn on_connection_handler_event( &mut self, - _: PeerId, - _: ConnectionId, - event: ::OutEvent, + _peer_id: PeerId, + _connection_id: ConnectionId, + event: crate::THandlerOutEvent, ) { void::unreachable(event) }