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}