feat(swarm): allow NetworkBehaviours to create and remove listeners

This extends `ToSwarm` to add `ToSwarm::ListenOn` and `ToSwarm::RemoveListener`, which allows creating and removing listeners from a `NetworkBehaviour`.

Resolves https://github.com/libp2p/rust-libp2p/issues/3291.

Pull-Request: #3292.
This commit is contained in:
Darius Clark
2023-06-08 21:34:33 -04:00
committed by GitHub
parent 4532302917
commit c2230f9948
6 changed files with 231 additions and 6 deletions

View File

@ -68,6 +68,7 @@ pub mod dial_opts;
pub mod dummy;
pub mod handler;
pub mod keep_alive;
mod listen_opts;
/// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro.
#[doc(hidden)]
@ -121,6 +122,7 @@ pub use handler::{
};
#[cfg(feature = "macros")]
pub use libp2p_swarm_derive::NetworkBehaviour;
pub use listen_opts::ListenOpts;
pub use stream::Stream;
pub use stream_protocol::{InvalidProtocol, StreamProtocol};
@ -370,12 +372,9 @@ where
/// Listeners report their new listening addresses as [`SwarmEvent::NewListenAddr`].
/// Depending on the underlying transport, one listener may have multiple listening addresses.
pub fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<io::Error>> {
let id = ListenerId::next();
self.transport.listen_on(id, addr)?;
self.behaviour
.on_swarm_event(FromSwarm::NewListener(behaviour::NewListener {
listener_id: id,
}));
let opts = ListenOpts::new(addr);
let id = opts.listener_id();
self.add_listener(opts)?;
Ok(id)
}
@ -542,6 +541,28 @@ where
self.confirmed_external_addr.iter()
}
fn add_listener(&mut self, opts: ListenOpts) -> Result<(), TransportError<io::Error>> {
let addr = opts.address();
let listener_id = opts.listener_id();
if let Err(e) = self.transport.listen_on(listener_id, addr.clone()) {
self.behaviour
.on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError {
listener_id,
err: &e,
}));
return Err(e);
}
self.behaviour
.on_swarm_event(FromSwarm::NewListener(behaviour::NewListener {
listener_id,
}));
Ok(())
}
/// Add a **confirmed** external address for the local node.
///
/// This function should only be called with addresses that are guaranteed to be reachable.
@ -1014,6 +1035,13 @@ where
});
}
}
ToSwarm::ListenOn { opts } => {
// Error is dispatched internally, safe to ignore.
let _ = self.add_listener(opts);
}
ToSwarm::RemoveListener { id } => {
self.remove_listener(id);
}
ToSwarm::NotifyHandler {
peer_id,
handler,