Skip to main content

ferripfs_config/
swarm.rs

1// Ported from: kubo/config/swarm.go
2// Kubo version: v0.39.0
3// Original: https://github.com/ipfs/kubo/blob/v0.39.0/config/swarm.go
4//
5// Original work: Copyright (c) Protocol Labs, Inc.
6// Port: Copyright (c) 2026 ferripfs contributors
7// SPDX-License-Identifier: MIT OR Apache-2.0
8
9//! Swarm configuration for libp2p networking.
10
11use crate::{Flag, OptionalDuration, OptionalInteger, OptionalString, Priority};
12use serde::{Deserialize, Serialize};
13
14/// Swarm configuration section
15#[derive(Debug, Clone, Default, Serialize, Deserialize)]
16#[serde(rename_all = "PascalCase")]
17pub struct SwarmConfig {
18    /// Address filters (multiaddr filters to block)
19    #[serde(default)]
20    pub addr_filters: Vec<String>,
21
22    /// Disable bandwidth metrics collection
23    #[serde(default)]
24    pub disable_bandwidth_metrics: bool,
25
26    /// Disable NAT port mapping
27    #[serde(default)]
28    pub disable_nat_port_map: bool,
29
30    /// Relay client configuration
31    #[serde(default)]
32    pub relay_client: RelayClient,
33
34    /// Relay service configuration
35    #[serde(default)]
36    pub relay_service: RelayService,
37
38    /// Enable hole punching
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub enable_hole_punching: Option<Flag>,
41
42    /// Transport configuration
43    #[serde(default)]
44    pub transports: Transports,
45
46    /// Connection manager configuration
47    #[serde(default)]
48    pub conn_mgr: ConnMgr,
49
50    /// Resource manager configuration
51    #[serde(default)]
52    pub resource_mgr: ResourceMgr,
53}
54
55/// Relay client configuration
56#[derive(Debug, Clone, Default, Serialize, Deserialize)]
57#[serde(rename_all = "PascalCase")]
58pub struct RelayClient {
59    /// Enable relay client
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub enabled: Option<Flag>,
62
63    /// Static relay addresses
64    #[serde(default, skip_serializing_if = "Option::is_none")]
65    pub static_relays: Option<Vec<String>>,
66}
67
68/// Relay service configuration
69#[derive(Debug, Clone, Default, Serialize, Deserialize)]
70#[serde(rename_all = "PascalCase")]
71pub struct RelayService {
72    /// Enable relay service
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub enabled: Option<Flag>,
75
76    /// Connection duration limit
77    #[serde(default, skip_serializing_if = "Option::is_none")]
78    pub connection_duration_limit: Option<OptionalDuration>,
79
80    /// Connection data limit
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub connection_data_limit: Option<OptionalInteger>,
83
84    /// Reservation TTL
85    #[serde(
86        default,
87        skip_serializing_if = "Option::is_none",
88        rename = "ReservationTTL"
89    )]
90    pub reservation_ttl: Option<OptionalDuration>,
91
92    /// Maximum reservations
93    #[serde(default, skip_serializing_if = "Option::is_none")]
94    pub max_reservations: Option<OptionalInteger>,
95
96    /// Maximum circuits
97    #[serde(default, skip_serializing_if = "Option::is_none")]
98    pub max_circuits: Option<OptionalInteger>,
99
100    /// Buffer size
101    #[serde(default, skip_serializing_if = "Option::is_none")]
102    pub buffer_size: Option<OptionalInteger>,
103
104    /// Maximum reservations per IP
105    #[serde(
106        default,
107        skip_serializing_if = "Option::is_none",
108        rename = "MaxReservationsPerIP"
109    )]
110    pub max_reservations_per_ip: Option<OptionalInteger>,
111
112    /// Maximum reservations per ASN
113    #[serde(
114        default,
115        skip_serializing_if = "Option::is_none",
116        rename = "MaxReservationsPerASN"
117    )]
118    pub max_reservations_per_asn: Option<OptionalInteger>,
119}
120
121/// Transport configuration
122#[derive(Debug, Clone, Default, Serialize, Deserialize)]
123#[serde(rename_all = "PascalCase")]
124pub struct Transports {
125    /// Network transports
126    #[serde(default)]
127    pub network: NetworkTransports,
128
129    /// Security transports
130    #[serde(default)]
131    pub security: SecurityTransports,
132
133    /// Multiplexer transports
134    #[serde(default)]
135    pub multiplexers: MultiplexerTransports,
136}
137
138/// Network transport configuration
139#[derive(Debug, Clone, Default, Serialize, Deserialize)]
140#[serde(rename_all = "PascalCase")]
141pub struct NetworkTransports {
142    /// QUIC transport
143    #[serde(default, skip_serializing_if = "Option::is_none", rename = "QUIC")]
144    pub quic: Option<Flag>,
145
146    /// TCP transport
147    #[serde(default, skip_serializing_if = "Option::is_none", rename = "TCP")]
148    pub tcp: Option<Flag>,
149
150    /// WebSocket transport
151    #[serde(default, skip_serializing_if = "Option::is_none")]
152    pub websocket: Option<Flag>,
153
154    /// Relay transport
155    #[serde(default, skip_serializing_if = "Option::is_none")]
156    pub relay: Option<Flag>,
157
158    /// WebTransport
159    #[serde(default, skip_serializing_if = "Option::is_none")]
160    pub web_transport: Option<Flag>,
161
162    /// WebRTC Direct
163    #[serde(
164        default,
165        skip_serializing_if = "Option::is_none",
166        rename = "WebRTCDirect"
167    )]
168    pub web_rtc_direct: Option<Flag>,
169}
170
171/// Security transport configuration
172#[derive(Debug, Clone, Default, Serialize, Deserialize)]
173#[serde(rename_all = "PascalCase")]
174pub struct SecurityTransports {
175    /// TLS priority (default: 100)
176    #[serde(default, skip_serializing_if = "Option::is_none", rename = "TLS")]
177    pub tls: Option<Priority>,
178
179    /// Noise priority (default: 300)
180    #[serde(default, skip_serializing_if = "Option::is_none")]
181    pub noise: Option<Priority>,
182}
183
184/// Multiplexer transport configuration
185#[derive(Debug, Clone, Default, Serialize, Deserialize)]
186#[serde(rename_all = "PascalCase")]
187pub struct MultiplexerTransports {
188    /// Yamux priority (default: 100)
189    #[serde(default, skip_serializing_if = "Option::is_none")]
190    pub yamux: Option<Priority>,
191}
192
193/// Connection manager configuration
194#[derive(Debug, Clone, Default, Serialize, Deserialize)]
195#[serde(rename_all = "PascalCase")]
196pub struct ConnMgr {
197    /// Connection manager type
198    #[serde(default, skip_serializing_if = "Option::is_none")]
199    pub r#type: Option<OptionalString>,
200
201    /// Low water mark for connections
202    #[serde(default, skip_serializing_if = "Option::is_none")]
203    pub low_water: Option<OptionalInteger>,
204
205    /// High water mark for connections
206    #[serde(default, skip_serializing_if = "Option::is_none")]
207    pub high_water: Option<OptionalInteger>,
208
209    /// Grace period before disconnecting
210    #[serde(default, skip_serializing_if = "Option::is_none")]
211    pub grace_period: Option<OptionalDuration>,
212
213    /// Silence period
214    #[serde(default, skip_serializing_if = "Option::is_none")]
215    pub silence_period: Option<OptionalDuration>,
216}
217
218impl ConnMgr {
219    /// Default low water mark
220    pub const DEFAULT_LOW_WATER: i64 = 32;
221
222    /// Default high water mark
223    pub const DEFAULT_HIGH_WATER: i64 = 96;
224
225    /// Default grace period in seconds
226    pub const DEFAULT_GRACE_PERIOD: &'static str = "1m";
227}
228
229/// Resource manager configuration
230#[derive(Debug, Clone, Default, Serialize, Deserialize)]
231#[serde(rename_all = "PascalCase")]
232pub struct ResourceMgr {
233    /// Enable resource manager
234    #[serde(default, skip_serializing_if = "Option::is_none")]
235    pub enabled: Option<Flag>,
236
237    /// Maximum memory
238    #[serde(default, skip_serializing_if = "Option::is_none")]
239    pub max_memory: Option<OptionalString>,
240
241    /// Maximum file descriptors
242    #[serde(default, skip_serializing_if = "Option::is_none")]
243    pub max_file_descriptors: Option<OptionalInteger>,
244
245    /// Allowlist of peer IDs
246    #[serde(default, skip_serializing_if = "Option::is_none")]
247    pub allowlist: Option<Vec<String>>,
248}
249
250#[cfg(test)]
251mod tests {
252    use super::*;
253
254    #[test]
255    fn test_swarm_config_default() {
256        let swarm = SwarmConfig::default();
257        assert!(!swarm.disable_bandwidth_metrics);
258        assert!(!swarm.disable_nat_port_map);
259    }
260
261    #[test]
262    fn test_conn_mgr_defaults() {
263        assert_eq!(ConnMgr::DEFAULT_LOW_WATER, 32);
264        assert_eq!(ConnMgr::DEFAULT_HIGH_WATER, 96);
265    }
266}