litep2p/transport/mod.rs
1// Copyright 2023 litep2p developers
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
21//! Transport protocol implementations provided by [`Litep2p`](`crate::Litep2p`).
22
23use crate::{error::DialError, transport::manager::TransportHandle, types::ConnectionId, PeerId};
24
25use futures::Stream;
26use multiaddr::Multiaddr;
27
28use std::{fmt::Debug, time::Duration};
29
30pub(crate) mod common;
31#[cfg(feature = "quic")]
32pub mod quic;
33pub mod tcp;
34#[cfg(feature = "webrtc")]
35pub mod webrtc;
36#[cfg(feature = "websocket")]
37pub mod websocket;
38
39pub(crate) mod dummy;
40pub(crate) mod manager;
41
42pub use manager::limits::{ConnectionLimitsConfig, ConnectionLimitsError};
43
44/// Timeout for opening a connection.
45pub(crate) const CONNECTION_OPEN_TIMEOUT: Duration = Duration::from_secs(10);
46
47/// Timeout for opening a substream.
48pub(crate) const SUBSTREAM_OPEN_TIMEOUT: Duration = Duration::from_secs(5);
49
50/// Timeout for connection waiting new substreams.
51pub(crate) const KEEP_ALIVE_TIMEOUT: Duration = Duration::from_secs(5);
52
53/// Maximum number of parallel dial attempts.
54pub(crate) const MAX_PARALLEL_DIALS: usize = 8;
55
56/// Connection endpoint.
57#[derive(Debug, Clone, PartialEq, Eq)]
58pub enum Endpoint {
59 /// Successfully established outbound connection.
60 Dialer {
61 /// Address that was dialed.
62 address: Multiaddr,
63
64 /// Connection ID.
65 connection_id: ConnectionId,
66 },
67
68 /// Successfully established inbound connection.
69 Listener {
70 /// Local connection address.
71 address: Multiaddr,
72
73 /// Connection ID.
74 connection_id: ConnectionId,
75 },
76}
77
78impl Endpoint {
79 /// Get `Multiaddr` of the [`Endpoint`].
80 pub fn address(&self) -> &Multiaddr {
81 match self {
82 Self::Dialer { address, .. } => address,
83 Self::Listener { address, .. } => address,
84 }
85 }
86
87 /// Crate dialer.
88 pub(crate) fn dialer(address: Multiaddr, connection_id: ConnectionId) -> Self {
89 Endpoint::Dialer {
90 address,
91 connection_id,
92 }
93 }
94
95 /// Create listener.
96 pub(crate) fn listener(address: Multiaddr, connection_id: ConnectionId) -> Self {
97 Endpoint::Listener {
98 address,
99 connection_id,
100 }
101 }
102
103 /// Get `ConnectionId` of the `Endpoint`.
104 pub fn connection_id(&self) -> ConnectionId {
105 match self {
106 Self::Dialer { connection_id, .. } => *connection_id,
107 Self::Listener { connection_id, .. } => *connection_id,
108 }
109 }
110
111 /// Is this a listener endpoint?
112 pub fn is_listener(&self) -> bool {
113 std::matches!(self, Self::Listener { .. })
114 }
115}
116
117/// Transport event.
118#[derive(Debug)]
119pub(crate) enum TransportEvent {
120 /// Fully negotiated connection established to remote peer.
121 ConnectionEstablished {
122 /// Peer ID.
123 peer: PeerId,
124
125 /// Endpoint.
126 endpoint: Endpoint,
127 },
128
129 PendingInboundConnection {
130 /// Connection ID.
131 connection_id: ConnectionId,
132 },
133
134 /// Connection opened to remote but not yet negotiated.
135 ConnectionOpened {
136 /// Connection ID.
137 connection_id: ConnectionId,
138
139 /// Address that was dialed.
140 address: Multiaddr,
141 },
142
143 /// Connection closed to remote peer.
144 #[allow(unused)]
145 ConnectionClosed {
146 /// Peer ID.
147 peer: PeerId,
148
149 /// Connection ID.
150 connection_id: ConnectionId,
151 },
152
153 /// Failed to dial remote peer.
154 DialFailure {
155 /// Connection ID.
156 connection_id: ConnectionId,
157
158 /// Dialed address.
159 address: Multiaddr,
160
161 /// Error.
162 error: DialError,
163 },
164
165 /// Open failure for an unnegotiated set of connections.
166 OpenFailure {
167 /// Connection ID.
168 connection_id: ConnectionId,
169
170 /// Errors.
171 errors: Vec<(Multiaddr, DialError)>,
172 },
173}
174
175pub(crate) trait TransportBuilder {
176 type Config: Debug;
177 type Transport: Transport;
178
179 /// Create new [`Transport`] object.
180 fn new(context: TransportHandle, config: Self::Config) -> crate::Result<(Self, Vec<Multiaddr>)>
181 where
182 Self: Sized;
183}
184
185pub(crate) trait Transport: Stream + Unpin + Send {
186 /// Dial `address` and negotiate connection.
187 fn dial(&mut self, connection_id: ConnectionId, address: Multiaddr) -> crate::Result<()>;
188
189 /// Accept negotiated connection.
190 fn accept(&mut self, connection_id: ConnectionId) -> crate::Result<()>;
191
192 /// Accept pending connection.
193 fn accept_pending(&mut self, connection_id: ConnectionId) -> crate::Result<()>;
194
195 /// Reject pending connection.
196 fn reject_pending(&mut self, connection_id: ConnectionId) -> crate::Result<()>;
197
198 /// Reject negotiated connection.
199 fn reject(&mut self, connection_id: ConnectionId) -> crate::Result<()>;
200
201 /// Attempt to open connection to remote peer over one or more addresses.
202 ///
203 /// TODO: documentation
204 fn open(&mut self, connection_id: ConnectionId, addresses: Vec<Multiaddr>)
205 -> crate::Result<()>;
206
207 /// Negotiate opened connection.
208 ///
209 /// TODO: documentation
210 fn negotiate(&mut self, connection_id: ConnectionId) -> crate::Result<()>;
211
212 /// Cancel opening connections.
213 ///
214 /// This is a no-op for connections that have already succeeded/canceled.
215 fn cancel(&mut self, connection_id: ConnectionId);
216}