libp2p_swarm/
keep_alive.rs

1use crate::behaviour::{FromSwarm, NetworkBehaviour, PollParameters, ToSwarm};
2use crate::connection::ConnectionId;
3use crate::handler::{
4    ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound,
5    KeepAlive, SubstreamProtocol,
6};
7use crate::{ConnectionDenied, THandler, THandlerInEvent, THandlerOutEvent};
8use libp2p_core::upgrade::DeniedUpgrade;
9use libp2p_core::{Endpoint, Multiaddr};
10use libp2p_identity::PeerId;
11use std::task::{Context, Poll};
12use void::Void;
13
14/// Implementation of [`NetworkBehaviour`] that doesn't do anything other than keep all connections alive.
15///
16/// This is primarily useful for test code. In can however occasionally be useful for production code too.
17/// The caveat is that open connections consume system resources and should thus be shutdown when
18/// they are not in use. Connections can also fail at any time so really, your application should be
19/// designed to establish them when necessary, making the use of this behaviour likely redundant.
20#[derive(Default)]
21pub struct Behaviour;
22
23impl NetworkBehaviour for Behaviour {
24    type ConnectionHandler = ConnectionHandler;
25    type ToSwarm = Void;
26
27    fn handle_established_inbound_connection(
28        &mut self,
29        _: ConnectionId,
30        _: PeerId,
31        _: &Multiaddr,
32        _: &Multiaddr,
33    ) -> Result<THandler<Self>, ConnectionDenied> {
34        Ok(ConnectionHandler)
35    }
36
37    fn handle_established_outbound_connection(
38        &mut self,
39        _: ConnectionId,
40        _: PeerId,
41        _: &Multiaddr,
42        _: Endpoint,
43    ) -> Result<THandler<Self>, ConnectionDenied> {
44        Ok(ConnectionHandler)
45    }
46
47    fn on_connection_handler_event(
48        &mut self,
49        _: PeerId,
50        _: ConnectionId,
51        event: THandlerOutEvent<Self>,
52    ) {
53        void::unreachable(event)
54    }
55
56    fn poll(
57        &mut self,
58        _: &mut Context<'_>,
59        _: &mut impl PollParameters,
60    ) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
61        Poll::Pending
62    }
63
64    fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
65        match event {
66            FromSwarm::ConnectionEstablished(_)
67            | FromSwarm::ConnectionClosed(_)
68            | FromSwarm::AddressChange(_)
69            | FromSwarm::DialFailure(_)
70            | FromSwarm::ListenFailure(_)
71            | FromSwarm::NewListener(_)
72            | FromSwarm::NewListenAddr(_)
73            | FromSwarm::ExpiredListenAddr(_)
74            | FromSwarm::ListenerError(_)
75            | FromSwarm::ListenerClosed(_)
76            | FromSwarm::NewExternalAddrCandidate(_)
77            | FromSwarm::ExternalAddrExpired(_)
78            | FromSwarm::ExternalAddrConfirmed(_) => {}
79        }
80    }
81}
82
83/// Implementation of [`ConnectionHandler`] that doesn't handle anything but keeps the connection alive.
84#[derive(Clone, Debug)]
85pub struct ConnectionHandler;
86
87impl crate::handler::ConnectionHandler for ConnectionHandler {
88    type FromBehaviour = Void;
89    type ToBehaviour = Void;
90    type Error = Void;
91    type InboundProtocol = DeniedUpgrade;
92    type OutboundProtocol = DeniedUpgrade;
93    type InboundOpenInfo = ();
94    type OutboundOpenInfo = Void;
95
96    fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo> {
97        SubstreamProtocol::new(DeniedUpgrade, ())
98    }
99
100    fn on_behaviour_event(&mut self, v: Self::FromBehaviour) {
101        void::unreachable(v)
102    }
103
104    fn connection_keep_alive(&self) -> KeepAlive {
105        KeepAlive::Yes
106    }
107
108    #[allow(deprecated)]
109    fn poll(
110        &mut self,
111        _: &mut Context<'_>,
112    ) -> Poll<
113        ConnectionHandlerEvent<
114            Self::OutboundProtocol,
115            Self::OutboundOpenInfo,
116            Self::ToBehaviour,
117            Self::Error,
118        >,
119    > {
120        Poll::Pending
121    }
122
123    fn on_connection_event(
124        &mut self,
125        event: ConnectionEvent<
126            Self::InboundProtocol,
127            Self::OutboundProtocol,
128            Self::InboundOpenInfo,
129            Self::OutboundOpenInfo,
130        >,
131    ) {
132        match event {
133            ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound {
134                protocol, ..
135            }) => void::unreachable(protocol),
136            ConnectionEvent::FullyNegotiatedOutbound(FullyNegotiatedOutbound {
137                protocol, ..
138            }) => void::unreachable(protocol),
139            ConnectionEvent::DialUpgradeError(_)
140            | ConnectionEvent::ListenUpgradeError(_)
141            | ConnectionEvent::AddressChange(_)
142            | ConnectionEvent::LocalProtocolsChange(_)
143            | ConnectionEvent::RemoteProtocolsChange(_) => {}
144        }
145    }
146}