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