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: Vec<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    /// Use system's DNS config.
129    use_system_dns_config: bool,
130}
131
132impl Default for ConfigBuilder {
133    fn default() -> Self {
134        Self::new()
135    }
136}
137
138impl ConfigBuilder {
139    /// Create empty [`ConfigBuilder`].
140    pub fn new() -> Self {
141        Self {
142            tcp: None,
143            #[cfg(feature = "quic")]
144            quic: None,
145            #[cfg(feature = "webrtc")]
146            webrtc: None,
147            #[cfg(feature = "websocket")]
148            websocket: None,
149            keypair: None,
150            ping: None,
151            identify: None,
152            kademlia: Vec::new(),
153            bitswap: None,
154            mdns: None,
155            executor: None,
156            max_parallel_dials: MAX_PARALLEL_DIALS,
157            user_protocols: HashMap::new(),
158            notification_protocols: HashMap::new(),
159            request_response_protocols: HashMap::new(),
160            known_addresses: Vec::new(),
161            connection_limits: ConnectionLimitsConfig::default(),
162            keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
163            use_system_dns_config: false,
164        }
165    }
166
167    /// Add TCP transport configuration, enabling the transport.
168    pub fn with_tcp(mut self, config: TcpConfig) -> Self {
169        self.tcp = Some(config);
170        self
171    }
172
173    /// Add QUIC transport configuration, enabling the transport.
174    #[cfg(feature = "quic")]
175    pub fn with_quic(mut self, config: QuicConfig) -> Self {
176        self.quic = Some(config);
177        self
178    }
179
180    /// Add WebRTC transport configuration, enabling the transport.
181    #[cfg(feature = "webrtc")]
182    pub fn with_webrtc(mut self, config: WebRtcConfig) -> Self {
183        self.webrtc = Some(config);
184        self
185    }
186
187    /// Add WebSocket transport configuration, enabling the transport.
188    #[cfg(feature = "websocket")]
189    pub fn with_websocket(mut self, config: WebSocketConfig) -> Self {
190        self.websocket = Some(config);
191        self
192    }
193
194    /// Add keypair.
195    ///
196    /// If no keypair is specified, litep2p creates a new keypair.
197    pub fn with_keypair(mut self, keypair: Keypair) -> Self {
198        self.keypair = Some(keypair);
199        self
200    }
201
202    /// Enable notification protocol.
203    pub fn with_notification_protocol(mut self, config: notification::Config) -> Self {
204        self.notification_protocols.insert(config.protocol_name().clone(), config);
205        self
206    }
207
208    /// Enable IPFS Ping protocol.
209    pub fn with_libp2p_ping(mut self, config: ping::Config) -> Self {
210        self.ping = Some(config);
211        self
212    }
213
214    /// Enable IPFS Identify protocol.
215    pub fn with_libp2p_identify(mut self, config: identify::Config) -> Self {
216        self.identify = Some(config);
217        self
218    }
219
220    /// Enable IPFS Kademlia protocol.
221    pub fn with_libp2p_kademlia(mut self, config: kademlia::Config) -> Self {
222        self.kademlia.push(config);
223        self
224    }
225
226    /// Enable IPFS Bitswap protocol.
227    pub fn with_libp2p_bitswap(mut self, config: bitswap::Config) -> Self {
228        self.bitswap = Some(config);
229        self
230    }
231
232    /// Enable request-response protocol.
233    pub fn with_request_response_protocol(mut self, config: request_response::Config) -> Self {
234        self.request_response_protocols.insert(config.protocol_name().clone(), config);
235        self
236    }
237
238    /// Enable user protocol.
239    pub fn with_user_protocol(mut self, protocol: Box<dyn UserProtocol>) -> Self {
240        self.user_protocols.insert(protocol.protocol(), protocol);
241        self
242    }
243
244    /// Enable mDNS for peer discoveries in the local network.
245    pub fn with_mdns(mut self, config: MdnsConfig) -> Self {
246        self.mdns = Some(config);
247        self
248    }
249
250    /// Add known address(es) for one or more peers.
251    pub fn with_known_addresses(
252        mut self,
253        addresses: impl Iterator<Item = (PeerId, Vec<Multiaddr>)>,
254    ) -> Self {
255        self.known_addresses = addresses.collect();
256        self
257    }
258
259    /// Add executor for running futures spawned by `litep2p`.
260    ///
261    /// If no executor is specified, `litep2p` defaults to calling `tokio::spawn()`.
262    pub fn with_executor(mut self, executor: Arc<dyn Executor>) -> Self {
263        self.executor = Some(executor);
264        self
265    }
266
267    /// How many addresses should litep2p attempt to dial in parallel.
268    pub fn with_max_parallel_dials(mut self, max_parallel_dials: usize) -> Self {
269        self.max_parallel_dials = max_parallel_dials;
270        self
271    }
272
273    /// Set connection limits configuration.
274    pub fn with_connection_limits(mut self, config: ConnectionLimitsConfig) -> Self {
275        self.connection_limits = config;
276        self
277    }
278
279    /// Set keep alive timeout for connections.
280    pub fn with_keep_alive_timeout(mut self, timeout: Duration) -> Self {
281        self.keep_alive_timeout = timeout;
282        self
283    }
284
285    /// Set DNS resolver according to system configuration instead of default (Google).
286    pub fn with_system_resolver(mut self) -> Self {
287        self.use_system_dns_config = true;
288        self
289    }
290
291    /// Build [`Litep2pConfig`].
292    pub fn build(mut self) -> Litep2pConfig {
293        let keypair = match self.keypair {
294            Some(keypair) => keypair,
295            None => Keypair::generate(),
296        };
297
298        Litep2pConfig {
299            keypair,
300            tcp: self.tcp.take(),
301            mdns: self.mdns.take(),
302            #[cfg(feature = "quic")]
303            quic: self.quic.take(),
304            #[cfg(feature = "webrtc")]
305            webrtc: self.webrtc.take(),
306            #[cfg(feature = "websocket")]
307            websocket: self.websocket.take(),
308            ping: self.ping.take(),
309            identify: self.identify.take(),
310            kademlia: self.kademlia,
311            bitswap: self.bitswap.take(),
312            max_parallel_dials: self.max_parallel_dials,
313            executor: self.executor.map_or(Arc::new(DefaultExecutor {}), |executor| executor),
314            user_protocols: self.user_protocols,
315            notification_protocols: self.notification_protocols,
316            request_response_protocols: self.request_response_protocols,
317            known_addresses: self.known_addresses,
318            connection_limits: self.connection_limits,
319            keep_alive_timeout: self.keep_alive_timeout,
320            use_system_dns_config: self.use_system_dns_config,
321        }
322    }
323}
324
325/// Configuration for [`Litep2p`](`crate::Litep2p`).
326pub struct Litep2pConfig {
327    // TCP transport configuration.
328    pub(crate) tcp: Option<TcpConfig>,
329
330    /// QUIC transport config.
331    #[cfg(feature = "quic")]
332    pub(crate) quic: Option<QuicConfig>,
333
334    /// WebRTC transport config.
335    #[cfg(feature = "webrtc")]
336    pub(crate) webrtc: Option<WebRtcConfig>,
337
338    /// WebSocket transport config.
339    #[cfg(feature = "websocket")]
340    pub(crate) websocket: Option<WebSocketConfig>,
341
342    /// Keypair.
343    pub(crate) keypair: Keypair,
344
345    /// Ping protocol configuration, if enabled.
346    pub(crate) ping: Option<ping::Config>,
347
348    /// Identify protocol configuration, if enabled.
349    pub(crate) identify: Option<identify::Config>,
350
351    /// Kademlia protocol configuration, if enabled.
352    pub(crate) kademlia: Vec<kademlia::Config>,
353
354    /// Bitswap protocol configuration, if enabled.
355    pub(crate) bitswap: Option<bitswap::Config>,
356
357    /// Notification protocols.
358    pub(crate) notification_protocols: HashMap<ProtocolName, notification::Config>,
359
360    /// Request-response protocols.
361    pub(crate) request_response_protocols: HashMap<ProtocolName, request_response::Config>,
362
363    /// User protocols.
364    pub(crate) user_protocols: HashMap<ProtocolName, Box<dyn UserProtocol>>,
365
366    /// mDNS configuration.
367    pub(crate) mdns: Option<MdnsConfig>,
368
369    /// Executor.
370    pub(crate) executor: Arc<dyn Executor>,
371
372    /// Maximum number of parallel dial attempts.
373    pub(crate) max_parallel_dials: usize,
374
375    /// Known addresses.
376    pub(crate) known_addresses: Vec<(PeerId, Vec<Multiaddr>)>,
377
378    /// Connection limits config.
379    pub(crate) connection_limits: ConnectionLimitsConfig,
380
381    /// Close the connection if no substreams are open within this time frame.
382    pub(crate) keep_alive_timeout: Duration,
383
384    /// Use system's DNS config.
385    pub(crate) use_system_dns_config: bool,
386}