libp2p_swarm/behaviour.rs
1// Copyright 2019 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21mod either;
22mod external_addresses;
23mod listen_addresses;
24mod peer_addresses;
25pub mod toggle;
26
27pub use external_addresses::ExternalAddresses;
28pub use listen_addresses::ListenAddresses;
29pub use peer_addresses::PeerAddresses;
30
31use crate::connection::ConnectionId;
32use crate::dial_opts::DialOpts;
33use crate::listen_opts::ListenOpts;
34use crate::{
35 ConnectionDenied, ConnectionHandler, DialError, ListenError, THandler, THandlerInEvent,
36 THandlerOutEvent,
37};
38use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr};
39use libp2p_identity::PeerId;
40use std::{task::Context, task::Poll};
41
42/// A [`NetworkBehaviour`] defines the behaviour of the local node on the network.
43///
44/// In contrast to [`Transport`](libp2p_core::Transport) which defines **how** to send bytes on the
45/// network, [`NetworkBehaviour`] defines **what** bytes to send and **to whom**.
46///
47/// Each protocol (e.g. `libp2p-ping`, `libp2p-identify` or `libp2p-kad`) implements
48/// [`NetworkBehaviour`]. Multiple implementations of [`NetworkBehaviour`] can be composed into a
49/// hierarchy of [`NetworkBehaviour`]s where parent implementations delegate to child
50/// implementations. Finally the root of the [`NetworkBehaviour`] hierarchy is passed to
51/// [`Swarm`](crate::Swarm) where it can then control the behaviour of the local node on a libp2p
52/// network.
53///
54/// # Hierarchy of [`NetworkBehaviour`]
55///
56/// To compose multiple [`NetworkBehaviour`] implementations into a single [`NetworkBehaviour`]
57/// implementation, potentially building a multi-level hierarchy of [`NetworkBehaviour`]s, one can
58/// use one of the [`NetworkBehaviour`] combinators, and/or use the [`NetworkBehaviour`] derive
59/// macro.
60///
61/// ## Combinators
62///
63/// [`NetworkBehaviour`] combinators wrap one or more [`NetworkBehaviour`] implementations and
64/// implement [`NetworkBehaviour`] themselves. Example is the
65/// [`Toggle`](crate::behaviour::toggle::Toggle) [`NetworkBehaviour`].
66///
67/// ``` rust
68/// # use libp2p_swarm::dummy;
69/// # use libp2p_swarm::behaviour::toggle::Toggle;
70/// let my_behaviour = dummy::Behaviour;
71/// let my_toggled_behaviour = Toggle::from(Some(my_behaviour));
72/// ```
73///
74/// ## Custom [`NetworkBehaviour`] with the Derive Macro
75///
76/// One can derive [`NetworkBehaviour`] for a custom `struct` via the `#[derive(NetworkBehaviour)]`
77/// proc macro re-exported by the `libp2p` crate. The macro generates a delegating `trait`
78/// implementation for the custom `struct`. Each [`NetworkBehaviour`] trait method is simply
79/// delegated to each `struct` member in the order the `struct` is defined. For example for
80/// [`NetworkBehaviour::poll`] it will first poll the first `struct` member until it returns
81/// [`Poll::Pending`] before moving on to later members.
82///
83/// Events ([`NetworkBehaviour::ToSwarm`]) returned by each `struct` member are wrapped in a new
84/// `enum` event, with an `enum` variant for each `struct` member. Users can define this event
85/// `enum` themselves and provide the name to the derive macro via `#[behaviour(to_swarm =
86/// "MyCustomOutEvent")]`. If the user does not specify an `to_swarm`, the derive macro generates
87/// the event definition itself, naming it `<STRUCT_NAME>Event`.
88///
89/// The aforementioned conversion of each of the event types generated by the struct members to the
90/// custom `to_swarm` is handled by [`From`] implementations which the user needs to define in
91/// addition to the event `enum` itself.
92///
93/// ``` rust
94/// # use libp2p_identify as identify;
95/// # use libp2p_ping as ping;
96/// # use libp2p_swarm_derive::NetworkBehaviour;
97/// #[derive(NetworkBehaviour)]
98/// #[behaviour(to_swarm = "Event")]
99/// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")]
100/// struct MyBehaviour {
101/// identify: identify::Behaviour,
102/// ping: ping::Behaviour,
103/// }
104///
105/// enum Event {
106/// Identify(identify::Event),
107/// Ping(ping::Event),
108/// }
109///
110/// impl From<identify::Event> for Event {
111/// fn from(event: identify::Event) -> Self {
112/// Self::Identify(event)
113/// }
114/// }
115///
116/// impl From<ping::Event> for Event {
117/// fn from(event: ping::Event) -> Self {
118/// Self::Ping(event)
119/// }
120/// }
121/// ```
122pub trait NetworkBehaviour: 'static {
123 /// Handler for all the protocols the network behaviour supports.
124 type ConnectionHandler: ConnectionHandler;
125
126 /// Event generated by the `NetworkBehaviour` and that the swarm will report back.
127 type ToSwarm: Send + 'static;
128
129 /// Callback that is invoked for every new inbound connection.
130 ///
131 /// At this point in the connection lifecycle, only the remote's and our local address are known.
132 /// We have also already allocated a [`ConnectionId`].
133 ///
134 /// Any error returned from this function will immediately abort the dial attempt.
135 fn handle_pending_inbound_connection(
136 &mut self,
137 _connection_id: ConnectionId,
138 _local_addr: &Multiaddr,
139 _remote_addr: &Multiaddr,
140 ) -> Result<(), ConnectionDenied> {
141 Ok(())
142 }
143
144 /// Callback that is invoked for every established inbound connection.
145 ///
146 /// This is invoked once another peer has successfully dialed us.
147 ///
148 /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
149 /// In order to actually use this connection, this function must return a [`ConnectionHandler`].
150 /// Returning an error will immediately close the connection.
151 fn handle_established_inbound_connection(
152 &mut self,
153 _connection_id: ConnectionId,
154 peer: PeerId,
155 local_addr: &Multiaddr,
156 remote_addr: &Multiaddr,
157 ) -> Result<THandler<Self>, ConnectionDenied>;
158
159 /// Callback that is invoked for every outbound connection attempt.
160 ///
161 /// We have access to:
162 ///
163 /// - The [`PeerId`], if known. Remember that we can dial without a [`PeerId`].
164 /// - All addresses passed to [`DialOpts`] are passed in here too.
165 /// - 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.
166 /// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful.
167 ///
168 /// 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.
169 ///
170 /// Any error returned from this function will immediately abort the dial attempt.
171 fn handle_pending_outbound_connection(
172 &mut self,
173 _connection_id: ConnectionId,
174 _maybe_peer: Option<PeerId>,
175 _addresses: &[Multiaddr],
176 _effective_role: Endpoint,
177 ) -> Result<Vec<Multiaddr>, ConnectionDenied> {
178 Ok(vec![])
179 }
180
181 /// Callback that is invoked for every established outbound connection.
182 ///
183 /// This is invoked once we have successfully dialed a peer.
184 /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
185 /// In order to actually use this connection, this function must return a [`ConnectionHandler`].
186 /// Returning an error will immediately close the connection.
187 fn handle_established_outbound_connection(
188 &mut self,
189 _connection_id: ConnectionId,
190 peer: PeerId,
191 addr: &Multiaddr,
192 role_override: Endpoint,
193 ) -> Result<THandler<Self>, ConnectionDenied>;
194
195 /// Informs the behaviour about an event from the [`Swarm`](crate::Swarm).
196 fn on_swarm_event(&mut self, event: FromSwarm);
197
198 /// Informs the behaviour about an event generated by the [`ConnectionHandler`]
199 /// dedicated to the peer identified by `peer_id`. for the behaviour.
200 ///
201 /// The [`PeerId`] is guaranteed to be in a connected state. In other words,
202 /// [`FromSwarm::ConnectionEstablished`] has previously been received with this [`PeerId`].
203 fn on_connection_handler_event(
204 &mut self,
205 _peer_id: PeerId,
206 _connection_id: ConnectionId,
207 _event: THandlerOutEvent<Self>,
208 );
209
210 /// Polls for things that swarm should do.
211 ///
212 /// This API mimics the API of the `Stream` trait. The method may register the current task in
213 /// order to wake it up at a later point in time.
214 fn poll(&mut self, cx: &mut Context<'_>)
215 -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>>;
216}
217
218/// A command issued from a [`NetworkBehaviour`] for the [`Swarm`].
219///
220/// [`Swarm`]: super::Swarm
221#[derive(Debug)]
222#[non_exhaustive]
223pub enum ToSwarm<TOutEvent, TInEvent> {
224 /// Instructs the `Swarm` to return an event when it is being polled.
225 GenerateEvent(TOutEvent),
226
227 /// Instructs the swarm to start a dial.
228 ///
229 /// On success, [`NetworkBehaviour::on_swarm_event`] with `ConnectionEstablished` is invoked.
230 /// On failure, [`NetworkBehaviour::on_swarm_event`] with `DialFailure` is invoked.
231 ///
232 /// [`DialOpts`] provides access to the [`ConnectionId`] via [`DialOpts::connection_id`].
233 /// This [`ConnectionId`] will be used throughout the connection's lifecycle to associate events with it.
234 /// This allows a [`NetworkBehaviour`] to identify a connection that resulted out of its own dial request.
235 Dial { opts: DialOpts },
236
237 /// Instructs the [`Swarm`](crate::Swarm) to listen on the provided address.
238 ListenOn { opts: ListenOpts },
239
240 /// Instructs the [`Swarm`](crate::Swarm) to remove the listener.
241 RemoveListener { id: ListenerId },
242
243 /// Instructs the `Swarm` to send an event to the handler dedicated to a
244 /// connection with a peer.
245 ///
246 /// If the `Swarm` is connected to the peer, the message is delivered to the [`ConnectionHandler`]
247 /// instance identified by the peer ID and connection ID.
248 ///
249 /// If the specified connection no longer exists, the event is silently dropped.
250 ///
251 /// Typically the connection ID given is the same as the one passed to
252 /// [`NetworkBehaviour::on_connection_handler_event`], i.e. whenever the behaviour wishes to
253 /// respond to a request on the same connection (and possibly the same
254 /// substream, as per the implementation of [`ConnectionHandler`]).
255 ///
256 /// Note that even if the peer is currently connected, connections can get closed
257 /// at any time and thus the event may not reach a handler.
258 NotifyHandler {
259 /// The peer for whom a [`ConnectionHandler`] should be notified.
260 peer_id: PeerId,
261 /// The options w.r.t. which connection handler to notify of the event.
262 handler: NotifyHandler,
263 /// The event to send.
264 event: TInEvent,
265 },
266
267 /// Reports a **new** candidate for an external address to the [`Swarm`](crate::Swarm).
268 ///
269 /// The emphasis on a **new** candidate is important.
270 /// Protocols MUST take care to only emit a candidate once per "source".
271 /// For example, the observed address of a TCP connection does not change throughout its lifetime.
272 /// Thus, only one candidate should be emitted per connection.
273 ///
274 /// This makes the report frequency of an address a meaningful data-point for consumers of this event.
275 /// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::NewExternalAddrCandidate`].
276 ///
277 /// This address could come from a variety of sources:
278 /// - A protocol such as identify obtained it from a remote.
279 /// - The user provided it based on configuration.
280 /// - We made an educated guess based on one of our listen addresses.
281 NewExternalAddrCandidate(Multiaddr),
282
283 /// Indicates to the [`Swarm`](crate::Swarm) that the provided address is confirmed to be externally reachable.
284 ///
285 /// This is intended to be issued in response to a [`FromSwarm::NewExternalAddrCandidate`] if we are indeed externally reachable on this address.
286 /// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::ExternalAddrConfirmed`].
287 ExternalAddrConfirmed(Multiaddr),
288
289 /// Indicates to the [`Swarm`](crate::Swarm) that we are no longer externally reachable under the provided address.
290 ///
291 /// This expires an address that was earlier confirmed via [`ToSwarm::ExternalAddrConfirmed`].
292 /// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::ExternalAddrExpired`].
293 ExternalAddrExpired(Multiaddr),
294
295 /// Instructs the `Swarm` to initiate a graceful close of one or all connections with the given peer.
296 ///
297 /// Closing a connection via [`ToSwarm::CloseConnection`] will poll [`ConnectionHandler::poll_close`] to completion.
298 /// In most cases, stopping to "use" a connection is enough to have it closed.
299 /// The keep-alive algorithm will close a connection automatically once all [`ConnectionHandler`]s are idle.
300 ///
301 /// Use this command if you want to close a connection _despite_ it still being in use by one or more handlers.
302 CloseConnection {
303 /// The peer to disconnect.
304 peer_id: PeerId,
305 /// Whether to close a specific or all connections to the given peer.
306 connection: CloseConnection,
307 },
308
309 /// Reports external address of a remote peer to the [`Swarm`](crate::Swarm) and through that to other [`NetworkBehaviour`]s.
310 NewExternalAddrOfPeer { peer_id: PeerId, address: Multiaddr },
311}
312
313impl<TOutEvent, TInEventOld> ToSwarm<TOutEvent, TInEventOld> {
314 /// Map the handler event.
315 pub fn map_in<TInEventNew>(
316 self,
317 f: impl FnOnce(TInEventOld) -> TInEventNew,
318 ) -> ToSwarm<TOutEvent, TInEventNew> {
319 match self {
320 ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(e),
321 ToSwarm::Dial { opts } => ToSwarm::Dial { opts },
322 ToSwarm::ListenOn { opts } => ToSwarm::ListenOn { opts },
323 ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id },
324 ToSwarm::NotifyHandler {
325 peer_id,
326 handler,
327 event,
328 } => ToSwarm::NotifyHandler {
329 peer_id,
330 handler,
331 event: f(event),
332 },
333 ToSwarm::CloseConnection {
334 peer_id,
335 connection,
336 } => ToSwarm::CloseConnection {
337 peer_id,
338 connection,
339 },
340 ToSwarm::NewExternalAddrCandidate(addr) => ToSwarm::NewExternalAddrCandidate(addr),
341 ToSwarm::ExternalAddrConfirmed(addr) => ToSwarm::ExternalAddrConfirmed(addr),
342 ToSwarm::ExternalAddrExpired(addr) => ToSwarm::ExternalAddrExpired(addr),
343 ToSwarm::NewExternalAddrOfPeer {
344 address: addr,
345 peer_id,
346 } => ToSwarm::NewExternalAddrOfPeer {
347 address: addr,
348 peer_id,
349 },
350 }
351 }
352}
353
354impl<TOutEvent, THandlerIn> ToSwarm<TOutEvent, THandlerIn> {
355 /// Map the event the swarm will return.
356 pub fn map_out<E>(self, f: impl FnOnce(TOutEvent) -> E) -> ToSwarm<E, THandlerIn> {
357 match self {
358 ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(f(e)),
359 ToSwarm::Dial { opts } => ToSwarm::Dial { opts },
360 ToSwarm::ListenOn { opts } => ToSwarm::ListenOn { opts },
361 ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id },
362 ToSwarm::NotifyHandler {
363 peer_id,
364 handler,
365 event,
366 } => ToSwarm::NotifyHandler {
367 peer_id,
368 handler,
369 event,
370 },
371 ToSwarm::NewExternalAddrCandidate(addr) => ToSwarm::NewExternalAddrCandidate(addr),
372 ToSwarm::ExternalAddrConfirmed(addr) => ToSwarm::ExternalAddrConfirmed(addr),
373 ToSwarm::ExternalAddrExpired(addr) => ToSwarm::ExternalAddrExpired(addr),
374 ToSwarm::CloseConnection {
375 peer_id,
376 connection,
377 } => ToSwarm::CloseConnection {
378 peer_id,
379 connection,
380 },
381 ToSwarm::NewExternalAddrOfPeer {
382 address: addr,
383 peer_id,
384 } => ToSwarm::NewExternalAddrOfPeer {
385 address: addr,
386 peer_id,
387 },
388 }
389 }
390}
391
392/// The options w.r.t. which connection handler to notify of an event.
393#[derive(Debug, Clone)]
394pub enum NotifyHandler {
395 /// Notify a particular connection handler.
396 One(ConnectionId),
397 /// Notify an arbitrary connection handler.
398 Any,
399}
400
401/// The options which connections to close.
402#[derive(Debug, Clone, Default)]
403pub enum CloseConnection {
404 /// Disconnect a particular connection.
405 One(ConnectionId),
406 /// Disconnect all connections.
407 #[default]
408 All,
409}
410
411/// Enumeration with the list of the possible events
412/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event).
413#[derive(Debug, Clone, Copy)]
414#[non_exhaustive]
415pub enum FromSwarm<'a> {
416 /// Informs the behaviour about a newly established connection to a peer.
417 ConnectionEstablished(ConnectionEstablished<'a>),
418 /// Informs the behaviour about a closed connection to a peer.
419 ///
420 /// This event is always paired with an earlier
421 /// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
422 /// and endpoint.
423 ConnectionClosed(ConnectionClosed<'a>),
424 /// Informs the behaviour that the [`ConnectedPoint`] of an existing
425 /// connection has changed.
426 AddressChange(AddressChange<'a>),
427 /// Informs the behaviour that the dial to a known
428 /// or unknown node failed.
429 DialFailure(DialFailure<'a>),
430 /// Informs the behaviour that an error
431 /// happened on an incoming connection during its initial handshake.
432 ///
433 /// This can include, for example, an error during the handshake of the encryption layer, or the
434 /// connection unexpectedly closed.
435 ListenFailure(ListenFailure<'a>),
436 /// Informs the behaviour that a new listener was created.
437 NewListener(NewListener),
438 /// Informs the behaviour that we have started listening on a new multiaddr.
439 NewListenAddr(NewListenAddr<'a>),
440 /// Informs the behaviour that a multiaddr
441 /// we were listening on has expired,
442 /// which means that we are no longer listening on it.
443 ExpiredListenAddr(ExpiredListenAddr<'a>),
444 /// Informs the behaviour that a listener experienced an error.
445 ListenerError(ListenerError<'a>),
446 /// Informs the behaviour that a listener closed.
447 ListenerClosed(ListenerClosed<'a>),
448 /// Informs the behaviour that we have discovered a new candidate for an external address for us.
449 NewExternalAddrCandidate(NewExternalAddrCandidate<'a>),
450 /// Informs the behaviour that an external address of the local node was confirmed.
451 ExternalAddrConfirmed(ExternalAddrConfirmed<'a>),
452 /// Informs the behaviour that an external address of the local node expired, i.e. is no-longer confirmed.
453 ExternalAddrExpired(ExternalAddrExpired<'a>),
454 /// Informs the behaviour that we have discovered a new external address for a remote peer.
455 NewExternalAddrOfPeer(NewExternalAddrOfPeer<'a>),
456}
457
458/// [`FromSwarm`] variant that informs the behaviour about a newly established connection to a peer.
459#[derive(Debug, Clone, Copy)]
460pub struct ConnectionEstablished<'a> {
461 pub peer_id: PeerId,
462 pub connection_id: ConnectionId,
463 pub endpoint: &'a ConnectedPoint,
464 pub failed_addresses: &'a [Multiaddr],
465 pub other_established: usize,
466}
467
468/// [`FromSwarm`] variant that informs the behaviour about a closed connection to a peer.
469///
470/// This event is always paired with an earlier
471/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
472/// and endpoint.
473#[derive(Debug, Clone, Copy)]
474pub struct ConnectionClosed<'a> {
475 pub peer_id: PeerId,
476 pub connection_id: ConnectionId,
477 pub endpoint: &'a ConnectedPoint,
478 pub remaining_established: usize,
479}
480
481/// [`FromSwarm`] variant that informs the behaviour that the [`ConnectedPoint`] of an existing
482/// connection has changed.
483#[derive(Debug, Clone, Copy)]
484pub struct AddressChange<'a> {
485 pub peer_id: PeerId,
486 pub connection_id: ConnectionId,
487 pub old: &'a ConnectedPoint,
488 pub new: &'a ConnectedPoint,
489}
490
491/// [`FromSwarm`] variant that informs the behaviour that the dial to a known
492/// or unknown node failed.
493#[derive(Debug, Clone, Copy)]
494pub struct DialFailure<'a> {
495 pub peer_id: Option<PeerId>,
496 pub error: &'a DialError,
497 pub connection_id: ConnectionId,
498}
499
500/// [`FromSwarm`] variant that informs the behaviour that an error
501/// happened on an incoming connection during its initial handshake.
502///
503/// This can include, for example, an error during the handshake of the encryption layer, or the
504/// connection unexpectedly closed.
505#[derive(Debug, Clone, Copy)]
506pub struct ListenFailure<'a> {
507 pub local_addr: &'a Multiaddr,
508 pub send_back_addr: &'a Multiaddr,
509 pub error: &'a ListenError,
510 pub connection_id: ConnectionId,
511}
512
513/// [`FromSwarm`] variant that informs the behaviour that a new listener was created.
514#[derive(Debug, Clone, Copy)]
515pub struct NewListener {
516 pub listener_id: ListenerId,
517}
518
519/// [`FromSwarm`] variant that informs the behaviour
520/// that we have started listening on a new multiaddr.
521#[derive(Debug, Clone, Copy)]
522pub struct NewListenAddr<'a> {
523 pub listener_id: ListenerId,
524 pub addr: &'a Multiaddr,
525}
526
527/// [`FromSwarm`] variant that informs the behaviour that a multiaddr
528/// we were listening on has expired,
529/// which means that we are no longer listening on it.
530#[derive(Debug, Clone, Copy)]
531pub struct ExpiredListenAddr<'a> {
532 pub listener_id: ListenerId,
533 pub addr: &'a Multiaddr,
534}
535
536/// [`FromSwarm`] variant that informs the behaviour that a listener experienced an error.
537#[derive(Debug, Clone, Copy)]
538pub struct ListenerError<'a> {
539 pub listener_id: ListenerId,
540 pub err: &'a (dyn std::error::Error + 'static),
541}
542
543/// [`FromSwarm`] variant that informs the behaviour that a listener closed.
544#[derive(Debug, Clone, Copy)]
545pub struct ListenerClosed<'a> {
546 pub listener_id: ListenerId,
547 pub reason: Result<(), &'a std::io::Error>,
548}
549
550/// [`FromSwarm`] variant that informs the behaviour about a new candidate for an external address for us.
551#[derive(Debug, Clone, Copy)]
552pub struct NewExternalAddrCandidate<'a> {
553 pub addr: &'a Multiaddr,
554}
555
556/// [`FromSwarm`] variant that informs the behaviour that an external address was confirmed.
557#[derive(Debug, Clone, Copy)]
558pub struct ExternalAddrConfirmed<'a> {
559 pub addr: &'a Multiaddr,
560}
561
562/// [`FromSwarm`] variant that informs the behaviour that an external address was removed.
563#[derive(Debug, Clone, Copy)]
564pub struct ExternalAddrExpired<'a> {
565 pub addr: &'a Multiaddr,
566}
567
568/// [`FromSwarm`] variant that informs the behaviour that a new external address for a remote peer was detected.
569#[derive(Clone, Copy, Debug)]
570pub struct NewExternalAddrOfPeer<'a> {
571 pub peer_id: PeerId,
572 pub addr: &'a Multiaddr,
573}