1use serde::{Deserialize, Serialize};
8
9use super::IdentityConfig;
10use crate::mmp::{DEFAULT_LOG_INTERVAL_SECS, DEFAULT_OWD_WINDOW_SIZE, MmpConfig, MmpMode};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct LimitsConfig {
19 #[serde(default = "LimitsConfig::default_max_connections")]
21 pub max_connections: usize,
22 #[serde(default = "LimitsConfig::default_max_peers")]
24 pub max_peers: usize,
25 #[serde(default = "LimitsConfig::default_max_links")]
27 pub max_links: usize,
28 #[serde(default = "LimitsConfig::default_max_pending_inbound")]
30 pub max_pending_inbound: usize,
31 #[serde(default = "LimitsConfig::default_max_sessions")]
37 pub max_sessions: usize,
38}
39
40impl Default for LimitsConfig {
41 fn default() -> Self {
42 Self {
43 max_connections: 256,
44 max_peers: 128,
45 max_links: 256,
46 max_pending_inbound: 1000,
47 max_sessions: 1024,
48 }
49 }
50}
51
52impl LimitsConfig {
53 fn default_max_connections() -> usize {
54 256
55 }
56 fn default_max_peers() -> usize {
57 128
58 }
59 fn default_max_links() -> usize {
60 256
61 }
62 fn default_max_pending_inbound() -> usize {
63 1000
64 }
65 fn default_max_sessions() -> usize {
66 1024
67 }
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct RateLimitConfig {
73 #[serde(default = "RateLimitConfig::default_handshake_burst")]
75 pub handshake_burst: u32,
76 #[serde(default = "RateLimitConfig::default_handshake_rate")]
78 pub handshake_rate: f64,
79 #[serde(default = "RateLimitConfig::default_handshake_timeout_secs")]
81 pub handshake_timeout_secs: u64,
82 #[serde(default = "RateLimitConfig::default_handshake_resend_interval_ms")]
85 pub handshake_resend_interval_ms: u64,
86 #[serde(default = "RateLimitConfig::default_handshake_resend_backoff")]
88 pub handshake_resend_backoff: f64,
89 #[serde(default = "RateLimitConfig::default_handshake_max_resends")]
91 pub handshake_max_resends: u32,
92}
93
94impl Default for RateLimitConfig {
95 fn default() -> Self {
96 Self {
97 handshake_burst: 100,
98 handshake_rate: 10.0,
99 handshake_timeout_secs: 30,
100 handshake_resend_interval_ms: 1000,
101 handshake_resend_backoff: 2.0,
102 handshake_max_resends: 5,
103 }
104 }
105}
106
107impl RateLimitConfig {
108 fn default_handshake_burst() -> u32 {
109 100
110 }
111 fn default_handshake_rate() -> f64 {
112 10.0
113 }
114 fn default_handshake_timeout_secs() -> u64 {
115 30
116 }
117 fn default_handshake_resend_interval_ms() -> u64 {
118 1000
119 }
120 fn default_handshake_resend_backoff() -> f64 {
121 2.0
122 }
123 fn default_handshake_max_resends() -> u32 {
124 5
125 }
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct RetryConfig {
131 #[serde(default = "RetryConfig::default_max_retries")]
133 pub max_retries: u32,
134 #[serde(default = "RetryConfig::default_base_interval_secs")]
136 pub base_interval_secs: u64,
137 #[serde(default = "RetryConfig::default_max_backoff_secs")]
139 pub max_backoff_secs: u64,
140}
141
142impl Default for RetryConfig {
143 fn default() -> Self {
144 Self {
145 max_retries: 5,
146 base_interval_secs: 5,
147 max_backoff_secs: 300,
148 }
149 }
150}
151
152impl RetryConfig {
153 fn default_max_retries() -> u32 {
154 5
155 }
156 fn default_base_interval_secs() -> u64 {
157 5
158 }
159 fn default_max_backoff_secs() -> u64 {
160 300
161 }
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct CacheConfig {
167 #[serde(default = "CacheConfig::default_coord_size")]
169 pub coord_size: usize,
170 #[serde(default = "CacheConfig::default_coord_ttl_secs")]
172 pub coord_ttl_secs: u64,
173 #[serde(default = "CacheConfig::default_identity_size")]
175 pub identity_size: usize,
176}
177
178impl Default for CacheConfig {
179 fn default() -> Self {
180 Self {
181 coord_size: 50_000,
182 coord_ttl_secs: 300,
183 identity_size: 10_000,
184 }
185 }
186}
187
188impl CacheConfig {
189 fn default_coord_size() -> usize {
190 50_000
191 }
192 fn default_coord_ttl_secs() -> u64 {
193 300
194 }
195 fn default_identity_size() -> usize {
196 10_000
197 }
198}
199
200mod discovery;
201
202pub use discovery::{
203 DiscoveryConfig, NostrDiscoveryConfig, NostrDiscoveryPolicy, NostrPeerfindingSource,
204};
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct TreeConfig {
209 #[serde(default = "TreeConfig::default_announce_min_interval_ms")]
211 pub announce_min_interval_ms: u64,
212 #[serde(default = "TreeConfig::default_parent_hysteresis")]
218 pub parent_hysteresis: f64,
219 #[serde(default = "TreeConfig::default_hold_down_secs")]
224 pub hold_down_secs: u64,
225 #[serde(default = "TreeConfig::default_reeval_interval_secs")]
231 pub reeval_interval_secs: u64,
232 #[serde(default = "TreeConfig::default_flap_threshold")]
234 pub flap_threshold: u32,
235 #[serde(default = "TreeConfig::default_flap_window_secs")]
237 pub flap_window_secs: u64,
238 #[serde(default = "TreeConfig::default_flap_dampening_secs")]
240 pub flap_dampening_secs: u64,
241}
242
243impl Default for TreeConfig {
244 fn default() -> Self {
245 Self {
246 announce_min_interval_ms: 500,
247 parent_hysteresis: 0.2,
248 hold_down_secs: 30,
249 reeval_interval_secs: 60,
250 flap_threshold: 4,
251 flap_window_secs: 60,
252 flap_dampening_secs: 120,
253 }
254 }
255}
256
257impl TreeConfig {
258 fn default_announce_min_interval_ms() -> u64 {
259 500
260 }
261 fn default_parent_hysteresis() -> f64 {
262 0.2
263 }
264 fn default_hold_down_secs() -> u64 {
265 30
266 }
267 fn default_reeval_interval_secs() -> u64 {
268 60
269 }
270 fn default_flap_threshold() -> u32 {
271 4
272 }
273 fn default_flap_window_secs() -> u64 {
274 60
275 }
276 fn default_flap_dampening_secs() -> u64 {
277 120
278 }
279}
280
281#[derive(Debug, Clone, Serialize, Deserialize)]
283pub struct RoutingConfig {
284 #[serde(default)]
286 pub mode: RoutingMode,
287 #[serde(default = "RoutingConfig::default_learned_ttl_secs")]
289 pub learned_ttl_secs: u64,
290 #[serde(default = "RoutingConfig::default_max_learned_routes_per_dest")]
294 pub max_learned_routes_per_dest: usize,
295 #[serde(default = "RoutingConfig::default_learned_fallback_explore_interval")]
298 pub learned_fallback_explore_interval: u64,
299}
300
301impl Default for RoutingConfig {
302 fn default() -> Self {
303 Self {
304 mode: RoutingMode::default(),
305 learned_ttl_secs: 300,
306 max_learned_routes_per_dest: 4,
307 learned_fallback_explore_interval: 16,
308 }
309 }
310}
311
312impl RoutingConfig {
313 fn default_learned_ttl_secs() -> u64 {
314 300
315 }
316
317 fn default_max_learned_routes_per_dest() -> usize {
318 4
319 }
320
321 fn default_learned_fallback_explore_interval() -> u64 {
322 16
323 }
324}
325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
328#[serde(rename_all = "snake_case")]
329pub enum RoutingMode {
330 #[default]
332 Tree,
333 ReplyLearned,
338}
339
340impl std::fmt::Display for RoutingMode {
341 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
342 match self {
343 RoutingMode::Tree => write!(f, "tree"),
344 RoutingMode::ReplyLearned => write!(f, "reply_learned"),
345 }
346 }
347}
348
349#[derive(Debug, Clone, Serialize, Deserialize)]
351pub struct BloomConfig {
352 #[serde(default = "BloomConfig::default_update_debounce_ms")]
354 pub update_debounce_ms: u64,
355 #[serde(default = "BloomConfig::default_max_inbound_fpr")]
363 pub max_inbound_fpr: f64,
364}
365
366impl Default for BloomConfig {
367 fn default() -> Self {
368 Self {
369 update_debounce_ms: Self::default_update_debounce_ms(),
370 max_inbound_fpr: Self::default_max_inbound_fpr(),
371 }
372 }
373}
374
375impl BloomConfig {
376 fn default_update_debounce_ms() -> u64 {
377 500
378 }
379 fn default_max_inbound_fpr() -> f64 {
380 0.20
381 }
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct SessionConfig {
387 #[serde(default = "SessionConfig::default_ttl")]
389 pub default_ttl: u8,
390 #[serde(default = "SessionConfig::default_pending_packets_per_dest")]
392 pub pending_packets_per_dest: usize,
393 #[serde(default = "SessionConfig::default_pending_max_destinations")]
395 pub pending_max_destinations: usize,
396 #[serde(default = "SessionConfig::default_idle_timeout_secs")]
400 pub idle_timeout_secs: u64,
401 #[serde(default = "SessionConfig::default_coords_warmup_packets")]
405 pub coords_warmup_packets: u8,
406 #[serde(default = "SessionConfig::default_coords_response_interval_ms")]
410 pub coords_response_interval_ms: u64,
411}
412
413impl Default for SessionConfig {
414 fn default() -> Self {
415 Self {
416 default_ttl: 64,
417 pending_packets_per_dest: 16,
418 pending_max_destinations: 256,
419 idle_timeout_secs: 90,
420 coords_warmup_packets: 5,
421 coords_response_interval_ms: 2000,
422 }
423 }
424}
425
426impl SessionConfig {
427 fn default_ttl() -> u8 {
428 64
429 }
430 fn default_pending_packets_per_dest() -> usize {
431 16
432 }
433 fn default_pending_max_destinations() -> usize {
434 256
435 }
436 fn default_idle_timeout_secs() -> u64 {
437 90
438 }
439 fn default_coords_warmup_packets() -> u8 {
440 5
441 }
442 fn default_coords_response_interval_ms() -> u64 {
443 2000
444 }
445}
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
454pub struct SessionMmpConfig {
455 #[serde(default)]
457 pub mode: MmpMode,
458
459 #[serde(default = "SessionMmpConfig::default_log_interval_secs")]
461 pub log_interval_secs: u64,
462
463 #[serde(default = "SessionMmpConfig::default_owd_window_size")]
465 pub owd_window_size: usize,
466}
467
468impl Default for SessionMmpConfig {
469 fn default() -> Self {
470 Self {
471 mode: MmpMode::default(),
472 log_interval_secs: DEFAULT_LOG_INTERVAL_SECS,
473 owd_window_size: DEFAULT_OWD_WINDOW_SIZE,
474 }
475 }
476}
477
478impl SessionMmpConfig {
479 fn default_log_interval_secs() -> u64 {
480 DEFAULT_LOG_INTERVAL_SECS
481 }
482 fn default_owd_window_size() -> usize {
483 DEFAULT_OWD_WINDOW_SIZE
484 }
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize)]
489pub struct ControlConfig {
490 #[serde(default = "ControlConfig::default_enabled")]
492 pub enabled: bool,
493 #[serde(default = "ControlConfig::default_socket_path")]
495 pub socket_path: String,
496}
497
498impl Default for ControlConfig {
499 fn default() -> Self {
500 Self {
501 enabled: true,
502 socket_path: Self::default_socket_path(),
503 }
504 }
505}
506
507impl ControlConfig {
508 fn default_enabled() -> bool {
509 true
510 }
511
512 fn default_socket_path() -> String {
519 #[cfg(unix)]
520 {
521 super::resolve_default_socket("control.sock")
522 }
523 #[cfg(windows)]
524 {
525 "21210".to_string()
526 }
527 }
528}
529
530const DEFAULT_PACKET_CHANNEL_CAPACITY: usize = 16_384;
531
532#[derive(Debug, Clone, Serialize, Deserialize)]
534pub struct BuffersConfig {
535 #[serde(default = "BuffersConfig::default_packet_channel")]
540 pub packet_channel: usize,
541 #[serde(default = "BuffersConfig::default_tun_channel")]
543 pub tun_channel: usize,
544 #[serde(default = "BuffersConfig::default_dns_channel")]
546 pub dns_channel: usize,
547}
548
549impl Default for BuffersConfig {
550 fn default() -> Self {
551 Self {
552 packet_channel: DEFAULT_PACKET_CHANNEL_CAPACITY,
553 tun_channel: 1024,
554 dns_channel: 64,
555 }
556 }
557}
558
559impl BuffersConfig {
560 fn default_packet_channel() -> usize {
561 DEFAULT_PACKET_CHANNEL_CAPACITY
562 }
563 fn default_tun_channel() -> usize {
564 1024
565 }
566 fn default_dns_channel() -> usize {
567 64
568 }
569}
570
571const DEFAULT_REKEY_AFTER_MESSAGES: u64 = 1 << 16;
585
586#[derive(Debug, Clone, Serialize, Deserialize)]
587pub struct RekeyConfig {
588 #[serde(default = "RekeyConfig::default_enabled")]
590 pub enabled: bool,
591
592 #[serde(default = "RekeyConfig::default_after_secs")]
594 pub after_secs: u64,
595
596 #[serde(default = "RekeyConfig::default_after_messages")]
598 pub after_messages: u64,
599}
600
601impl Default for RekeyConfig {
602 fn default() -> Self {
603 Self {
604 enabled: true,
605 after_secs: 120,
606 after_messages: DEFAULT_REKEY_AFTER_MESSAGES,
607 }
608 }
609}
610
611impl RekeyConfig {
612 fn default_enabled() -> bool {
613 true
614 }
615 fn default_after_secs() -> u64 {
616 120
617 }
618 fn default_after_messages() -> u64 {
619 DEFAULT_REKEY_AFTER_MESSAGES
620 }
621}
622
623#[derive(Debug, Clone, Serialize, Deserialize)]
629pub struct EcnConfig {
630 #[serde(default = "EcnConfig::default_enabled")]
632 pub enabled: bool,
633
634 #[serde(default = "EcnConfig::default_loss_threshold")]
638 pub loss_threshold: f64,
639
640 #[serde(default = "EcnConfig::default_etx_threshold")]
644 pub etx_threshold: f64,
645}
646
647impl Default for EcnConfig {
648 fn default() -> Self {
649 Self {
650 enabled: true,
651 loss_threshold: 0.05,
652 etx_threshold: 3.0,
653 }
654 }
655}
656
657impl EcnConfig {
658 fn default_enabled() -> bool {
659 true
660 }
661 fn default_loss_threshold() -> f64 {
662 0.05
663 }
664 fn default_etx_threshold() -> f64 {
665 3.0
666 }
667}
668
669#[derive(Debug, Clone, Serialize, Deserialize)]
675pub struct NodeConfig {
676 #[serde(default)]
678 pub identity: IdentityConfig,
679
680 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
682 pub leaf_only: bool,
683
684 #[serde(default = "NodeConfig::default_tick_interval_secs")]
686 pub tick_interval_secs: u64,
687
688 #[serde(default = "NodeConfig::default_base_rtt_ms")]
690 pub base_rtt_ms: u64,
691
692 #[serde(default = "NodeConfig::default_heartbeat_interval_secs")]
694 pub heartbeat_interval_secs: u64,
695
696 #[serde(default = "NodeConfig::default_link_dead_timeout_secs")]
699 pub link_dead_timeout_secs: u64,
700
701 #[serde(default = "NodeConfig::default_fast_link_dead_timeout_secs")]
711 pub fast_link_dead_timeout_secs: u64,
712
713 #[serde(default)]
715 pub limits: LimitsConfig,
716
717 #[serde(default)]
719 pub rate_limit: RateLimitConfig,
720
721 #[serde(default)]
723 pub retry: RetryConfig,
724
725 #[serde(default)]
727 pub cache: CacheConfig,
728
729 #[serde(default)]
731 pub discovery: DiscoveryConfig,
732
733 #[serde(default)]
735 pub tree: TreeConfig,
736
737 #[serde(default)]
739 pub routing: RoutingConfig,
740
741 #[serde(default)]
743 pub bloom: BloomConfig,
744
745 #[serde(default)]
747 pub session: SessionConfig,
748
749 #[serde(default)]
751 pub buffers: BuffersConfig,
752
753 #[serde(default)]
755 pub control: ControlConfig,
756
757 #[serde(default)]
759 pub mmp: MmpConfig,
760
761 #[serde(default)]
763 pub session_mmp: SessionMmpConfig,
764
765 #[serde(default)]
767 pub ecn: EcnConfig,
768
769 #[serde(default)]
771 pub rekey: RekeyConfig,
772
773 #[serde(default = "NodeConfig::default_system_files_enabled")]
776 pub system_files_enabled: bool,
777
778 #[serde(default)]
781 pub log_level: Option<String>,
782}
783
784impl Default for NodeConfig {
785 fn default() -> Self {
786 Self {
787 identity: IdentityConfig::default(),
788 leaf_only: false,
789 tick_interval_secs: 1,
790 base_rtt_ms: 100,
791 heartbeat_interval_secs: 10,
792 link_dead_timeout_secs: 30,
793 fast_link_dead_timeout_secs: 5,
794 limits: LimitsConfig::default(),
795 rate_limit: RateLimitConfig::default(),
796 retry: RetryConfig::default(),
797 cache: CacheConfig::default(),
798 discovery: DiscoveryConfig::default(),
799 tree: TreeConfig::default(),
800 routing: RoutingConfig::default(),
801 bloom: BloomConfig::default(),
802 session: SessionConfig::default(),
803 buffers: BuffersConfig::default(),
804 control: ControlConfig::default(),
805 mmp: MmpConfig::default(),
806 session_mmp: SessionMmpConfig::default(),
807 ecn: EcnConfig::default(),
808 rekey: RekeyConfig::default(),
809 system_files_enabled: true,
810 log_level: None,
811 }
812 }
813}
814
815impl NodeConfig {
816 pub fn log_level(&self) -> tracing::Level {
818 match self
819 .log_level
820 .as_deref()
821 .map(|s| s.to_lowercase())
822 .as_deref()
823 {
824 Some("trace") => tracing::Level::TRACE,
825 Some("debug") => tracing::Level::DEBUG,
826 Some("warn") | Some("warning") => tracing::Level::WARN,
827 Some("error") => tracing::Level::ERROR,
828 _ => tracing::Level::INFO,
829 }
830 }
831
832 fn default_tick_interval_secs() -> u64 {
833 1
834 }
835 fn default_base_rtt_ms() -> u64 {
836 100
837 }
838 fn default_heartbeat_interval_secs() -> u64 {
839 10
840 }
841 fn default_link_dead_timeout_secs() -> u64 {
842 30
843 }
844 fn default_fast_link_dead_timeout_secs() -> u64 {
845 5
846 }
847 fn default_system_files_enabled() -> bool {
848 true
849 }
850}
851
852#[cfg(test)]
853mod tests;