litep2p/
config.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//! [`Litep2p`](`crate::Litep2p`) configuration.
22
23use crate::{
24    crypto::ed25519::Keypair,
25    executor::{DefaultExecutor, Executor},
26    protocol::{
27        libp2p::{bitswap, identify, kademlia, ping},
28        mdns::Config as MdnsConfig,
29        notification, request_response, UserProtocol,
30    },
31    transport::{
32        manager::limits::ConnectionLimitsConfig, tcp::config::Config as TcpConfig,
33        KEEP_ALIVE_TIMEOUT, MAX_PARALLEL_DIALS,
34    },
35    types::protocol::ProtocolName,
36    PeerId,
37};
38
39#[cfg(feature = "quic")]
40use crate::transport::quic::config::Config as QuicConfig;
41#[cfg(feature = "webrtc")]
42use crate::transport::webrtc::config::Config as WebRtcConfig;
43#[cfg(feature = "websocket")]
44use crate::transport::websocket::config::Config as WebSocketConfig;
45
46use multiaddr::Multiaddr;
47
48use std::{collections::HashMap, sync::Arc, time::Duration};
49
50/// Connection role.
51#[derive(Debug, Copy, Clone)]
52pub enum Role {
53    /// Dialer.
54    Dialer,
55
56    /// Listener.
57    Listener,
58}
59
60impl From<Role> for crate::yamux::Mode {
61    fn from(value: Role) -> Self {
62        match value {
63            Role::Dialer => crate::yamux::Mode::Client,
64            Role::Listener => crate::yamux::Mode::Server,
65        }
66    }
67}
68
69/// Configuration builder for [`Litep2p`](`crate::Litep2p`).
70pub struct ConfigBuilder {
71    // TCP transport configuration.
72    tcp: Option<TcpConfig>,
73
74    /// QUIC transport config.
75    #[cfg(feature = "quic")]
76    quic: Option<QuicConfig>,
77
78    /// WebRTC transport config.
79    #[cfg(feature = "webrtc")]
80    webrtc: Option<WebRtcConfig>,
81
82    /// WebSocket transport config.
83    #[cfg(feature = "websocket")]
84    websocket: Option<WebSocketConfig>,
85
86    /// Keypair.
87    keypair: Option<Keypair>,
88
89    /// Ping protocol config.
90    ping: Option<ping::Config>,
91
92    /// Identify protocol config.
93    identify: Option<identify::Config>,
94
95    /// Kademlia protocol config.
96    kademlia: Option<kademlia::Config>,
97
98    /// Bitswap protocol config.
99    bitswap: Option<bitswap::Config>,
100
101    /// Notification protocols.
102    notification_protocols: HashMap<ProtocolName, notification::Config>,
103
104    /// Request-response protocols.
105    request_response_protocols: HashMap<ProtocolName, request_response::Config>,
106
107    /// User protocols.
108    user_protocols: HashMap<ProtocolName, Box<dyn UserProtocol>>,
109
110    /// mDNS configuration.
111    mdns: Option<MdnsConfig>,
112
113    /// Known addresess.
114    known_addresses: Vec<(PeerId, Vec<Multiaddr>)>,
115
116    /// Executor for running futures.
117    executor: Option<Arc<dyn Executor>>,
118
119    /// Maximum number of parallel dial attempts.
120    max_parallel_dials: usize,
121
122    /// Connection limits config.
123    connection_limits: ConnectionLimitsConfig,
124
125    /// Close the connection if no substreams are open within this time frame.
126    keep_alive_timeout: Duration,
127}
128
129impl Default for ConfigBuilder {
130    fn default() -> Self {
131        Self::new()
132    }
133}
134
135impl ConfigBuilder {
136    /// Create empty [`ConfigBuilder`].
137    pub fn new() -> Self {
138        Self {
139            tcp: None,
140            #[cfg(feature = "quic")]
141            quic: None,
142            #[cfg(feature = "webrtc")]
143            webrtc: None,
144            #[cfg(feature = "websocket")]
145            websocket: None,
146            keypair: None,
147            ping: None,
148            identify: None,
149            kademlia: None,
150            bitswap: None,
151            mdns: None,
152            executor: None,
153            max_parallel_dials: MAX_PARALLEL_DIALS,
154            user_protocols: HashMap::new(),
155            notification_protocols: HashMap::new(),
156            request_response_protocols: HashMap::new(),
157            known_addresses: Vec::new(),
158            connection_limits: ConnectionLimitsConfig::default(),
159            keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
160        }
161    }
162
163    /// Add TCP transport configuration, enabling the transport.
164    pub fn with_tcp(mut self, config: TcpConfig) -> Self {
165        self.tcp = Some(config);
166        self
167    }
168
169    /// Add QUIC transport configuration, enabling the transport.
170    #[cfg(feature = "quic")]
171    pub fn with_quic(mut self, config: QuicConfig) -> Self {
172        self.quic = Some(config);
173        self
174    }
175
176    /// Add WebRTC transport configuration, enabling the transport.
177    #[cfg(feature = "webrtc")]
178    pub fn with_webrtc(mut self, config: WebRtcConfig) -> Self {
179        self.webrtc = Some(config);
180        self
181    }
182
183    /// Add WebSocket transport configuration, enabling the transport.
184    #[cfg(feature = "websocket")]
185    pub fn with_websocket(mut self, config: WebSocketConfig) -> Self {
186        self.websocket = Some(config);
187        self
188    }
189
190    /// Add keypair.
191    ///
192    /// If no keypair is specified, litep2p creates a new keypair.
193    pub fn with_keypair(mut self, keypair: Keypair) -> Self {
194        self.keypair = Some(keypair);
195        self
196    }
197
198    /// Enable notification protocol.
199    pub fn with_notification_protocol(mut self, config: notification::Config) -> Self {
200        self.notification_protocols.insert(config.protocol_name().clone(), config);
201        self
202    }
203
204    /// Enable IPFS Ping protocol.
205    pub fn with_libp2p_ping(mut self, config: ping::Config) -> Self {
206        self.ping = Some(config);
207        self
208    }
209
210    /// Enable IPFS Identify protocol.
211    pub fn with_libp2p_identify(mut self, config: identify::Config) -> Self {
212        self.identify = Some(config);
213        self
214    }
215
216    /// Enable IPFS Kademlia protocol.
217    pub fn with_libp2p_kademlia(mut self, config: kademlia::Config) -> Self {
218        self.kademlia = Some(config);
219        self
220    }
221
222    /// Enable IPFS Bitswap protocol.
223    pub fn with_libp2p_bitswap(mut self, config: bitswap::Config) -> Self {
224        self.bitswap = Some(config);
225        self
226    }
227
228    /// Enable request-response protocol.
229    pub fn with_request_response_protocol(mut self, config: request_response::Config) -> Self {
230        self.request_response_protocols.insert(config.protocol_name().clone(), config);
231        self
232    }
233
234    /// Enable user protocol.
235    pub fn with_user_protocol(mut self, protocol: Box<dyn UserProtocol>) -> Self {
236        self.user_protocols.insert(protocol.protocol(), protocol);
237        self
238    }
239
240    /// Enable mDNS for peer discoveries in the local network.
241    pub fn with_mdns(mut self, config: MdnsConfig) -> Self {
242        self.mdns = Some(config);
243        self
244    }
245
246    /// Add known address(es) for one or more peers.
247    pub fn with_known_addresses(
248        mut self,
249        addresses: impl Iterator<Item = (PeerId, Vec<Multiaddr>)>,
250    ) -> Self {
251        self.known_addresses = addresses.collect();
252        self
253    }
254
255    /// Add executor for running futures spawned by `litep2p`.
256    ///
257    /// If no executor is specified, `litep2p` defaults to calling `tokio::spawn()`.
258    pub fn with_executor(mut self, executor: Arc<dyn Executor>) -> Self {
259        self.executor = Some(executor);
260        self
261    }
262
263    /// How many addresses should litep2p attempt to dial in parallel.
264    pub fn with_max_parallel_dials(mut self, max_parallel_dials: usize) -> Self {
265        self.max_parallel_dials = max_parallel_dials;
266        self
267    }
268
269    /// Set connection limits configuration.
270    pub fn with_connection_limits(mut self, config: ConnectionLimitsConfig) -> Self {
271        self.connection_limits = config;
272        self
273    }
274
275    /// Set keep alive timeout for connections.
276    pub fn with_keep_alive_timeout(mut self, timeout: Duration) -> Self {
277        self.keep_alive_timeout = timeout;
278        self
279    }
280
281    /// Build [`Litep2pConfig`].
282    pub fn build(mut self) -> Litep2pConfig {
283        let keypair = match self.keypair {
284            Some(keypair) => keypair,
285            None => Keypair::generate(),
286        };
287
288        Litep2pConfig {
289            keypair,
290            tcp: self.tcp.take(),
291            mdns: self.mdns.take(),
292            #[cfg(feature = "quic")]
293            quic: self.quic.take(),
294            #[cfg(feature = "webrtc")]
295            webrtc: self.webrtc.take(),
296            #[cfg(feature = "websocket")]
297            websocket: self.websocket.take(),
298            ping: self.ping.take(),
299            identify: self.identify.take(),
300            kademlia: self.kademlia.take(),
301            bitswap: self.bitswap.take(),
302            max_parallel_dials: self.max_parallel_dials,
303            executor: self.executor.map_or(Arc::new(DefaultExecutor {}), |executor| executor),
304            user_protocols: self.user_protocols,
305            notification_protocols: self.notification_protocols,
306            request_response_protocols: self.request_response_protocols,
307            known_addresses: self.known_addresses,
308            connection_limits: self.connection_limits,
309            keep_alive_timeout: self.keep_alive_timeout,
310        }
311    }
312}
313
314/// Configuration for [`Litep2p`](`crate::Litep2p`).
315pub struct Litep2pConfig {
316    // TCP transport configuration.
317    pub(crate) tcp: Option<TcpConfig>,
318
319    /// QUIC transport config.
320    #[cfg(feature = "quic")]
321    pub(crate) quic: Option<QuicConfig>,
322
323    /// WebRTC transport config.
324    #[cfg(feature = "webrtc")]
325    pub(crate) webrtc: Option<WebRtcConfig>,
326
327    /// WebSocket transport config.
328    #[cfg(feature = "websocket")]
329    pub(crate) websocket: Option<WebSocketConfig>,
330
331    /// Keypair.
332    pub(crate) keypair: Keypair,
333
334    /// Ping protocol configuration, if enabled.
335    pub(crate) ping: Option<ping::Config>,
336
337    /// Identify protocol configuration, if enabled.
338    pub(crate) identify: Option<identify::Config>,
339
340    /// Kademlia protocol configuration, if enabled.
341    pub(crate) kademlia: Option<kademlia::Config>,
342
343    /// Bitswap protocol configuration, if enabled.
344    pub(crate) bitswap: Option<bitswap::Config>,
345
346    /// Notification protocols.
347    pub(crate) notification_protocols: HashMap<ProtocolName, notification::Config>,
348
349    /// Request-response protocols.
350    pub(crate) request_response_protocols: HashMap<ProtocolName, request_response::Config>,
351
352    /// User protocols.
353    pub(crate) user_protocols: HashMap<ProtocolName, Box<dyn UserProtocol>>,
354
355    /// mDNS configuration.
356    pub(crate) mdns: Option<MdnsConfig>,
357
358    /// Executor.
359    pub(crate) executor: Arc<dyn Executor>,
360
361    /// Maximum number of parallel dial attempts.
362    pub(crate) max_parallel_dials: usize,
363
364    /// Known addresses.
365    pub(crate) known_addresses: Vec<(PeerId, Vec<Multiaddr>)>,
366
367    /// Connection limits config.
368    pub(crate) connection_limits: ConnectionLimitsConfig,
369
370    /// Close the connection if no substreams are open within this time frame.
371    pub(crate) keep_alive_timeout: Duration,
372}