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