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}
32
33impl Default for LimitsConfig {
34 fn default() -> Self {
35 Self {
36 max_connections: 256,
37 max_peers: 128,
38 max_links: 256,
39 max_pending_inbound: 1000,
40 }
41 }
42}
43
44impl LimitsConfig {
45 fn default_max_connections() -> usize {
46 256
47 }
48 fn default_max_peers() -> usize {
49 128
50 }
51 fn default_max_links() -> usize {
52 256
53 }
54 fn default_max_pending_inbound() -> usize {
55 1000
56 }
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct ConnectedUdpConfig {
62 #[serde(default = "ConnectedUdpConfig::default_enabled")]
71 pub enabled: bool,
72
73 #[serde(default = "ConnectedUdpConfig::default_max_peers")]
81 pub max_peers: usize,
82
83 #[serde(default = "ConnectedUdpConfig::default_fd_reserve")]
91 pub fd_reserve: usize,
92}
93
94impl Default for ConnectedUdpConfig {
95 fn default() -> Self {
96 Self {
97 enabled: Self::default_enabled(),
98 max_peers: Self::default_max_peers(),
99 fd_reserve: Self::default_fd_reserve(),
100 }
101 }
102}
103
104impl ConnectedUdpConfig {
105 fn default_enabled() -> bool {
106 #[cfg(target_os = "macos")]
107 {
108 return false;
109 }
110
111 #[cfg(not(target_os = "macos"))]
112 true
113 }
114
115 fn default_max_peers() -> usize {
116 0
117 }
118
119 fn default_fd_reserve() -> usize {
120 128
121 }
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct RateLimitConfig {
127 #[serde(default = "RateLimitConfig::default_handshake_burst")]
129 pub handshake_burst: u32,
130 #[serde(default = "RateLimitConfig::default_handshake_rate")]
132 pub handshake_rate: f64,
133 #[serde(default = "RateLimitConfig::default_handshake_timeout_secs")]
135 pub handshake_timeout_secs: u64,
136 #[serde(default = "RateLimitConfig::default_handshake_resend_interval_ms")]
139 pub handshake_resend_interval_ms: u64,
140 #[serde(default = "RateLimitConfig::default_handshake_resend_backoff")]
142 pub handshake_resend_backoff: f64,
143 #[serde(default = "RateLimitConfig::default_handshake_max_resends")]
145 pub handshake_max_resends: u32,
146}
147
148impl Default for RateLimitConfig {
149 fn default() -> Self {
150 Self {
151 handshake_burst: 100,
152 handshake_rate: 10.0,
153 handshake_timeout_secs: 30,
154 handshake_resend_interval_ms: 1000,
155 handshake_resend_backoff: 2.0,
156 handshake_max_resends: 5,
157 }
158 }
159}
160
161impl RateLimitConfig {
162 fn default_handshake_burst() -> u32 {
163 100
164 }
165 fn default_handshake_rate() -> f64 {
166 10.0
167 }
168 fn default_handshake_timeout_secs() -> u64 {
169 30
170 }
171 fn default_handshake_resend_interval_ms() -> u64 {
172 1000
173 }
174 fn default_handshake_resend_backoff() -> f64 {
175 2.0
176 }
177 fn default_handshake_max_resends() -> u32 {
178 5
179 }
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct RetryConfig {
185 #[serde(default = "RetryConfig::default_max_retries")]
187 pub max_retries: u32,
188 #[serde(default = "RetryConfig::default_base_interval_secs")]
190 pub base_interval_secs: u64,
191 #[serde(default = "RetryConfig::default_max_backoff_secs")]
193 pub max_backoff_secs: u64,
194}
195
196impl Default for RetryConfig {
197 fn default() -> Self {
198 Self {
199 max_retries: 5,
200 base_interval_secs: 5,
201 max_backoff_secs: 300,
202 }
203 }
204}
205
206impl RetryConfig {
207 fn default_max_retries() -> u32 {
208 5
209 }
210 fn default_base_interval_secs() -> u64 {
211 5
212 }
213 fn default_max_backoff_secs() -> u64 {
214 300
215 }
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct CacheConfig {
221 #[serde(default = "CacheConfig::default_coord_size")]
223 pub coord_size: usize,
224 #[serde(default = "CacheConfig::default_coord_ttl_secs")]
226 pub coord_ttl_secs: u64,
227 #[serde(default = "CacheConfig::default_identity_size")]
229 pub identity_size: usize,
230}
231
232impl Default for CacheConfig {
233 fn default() -> Self {
234 Self {
235 coord_size: 50_000,
236 coord_ttl_secs: 300,
237 identity_size: 10_000,
238 }
239 }
240}
241
242impl CacheConfig {
243 fn default_coord_size() -> usize {
244 50_000
245 }
246 fn default_coord_ttl_secs() -> u64 {
247 300
248 }
249 fn default_identity_size() -> usize {
250 10_000
251 }
252}
253
254mod discovery;
255
256pub use discovery::{DiscoveryConfig, NostrDiscoveryConfig, NostrDiscoveryPolicy};
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
260pub struct TreeConfig {
261 #[serde(default = "TreeConfig::default_announce_min_interval_ms")]
263 pub announce_min_interval_ms: u64,
264 #[serde(default = "TreeConfig::default_parent_hysteresis")]
270 pub parent_hysteresis: f64,
271 #[serde(default = "TreeConfig::default_hold_down_secs")]
276 pub hold_down_secs: u64,
277 #[serde(default = "TreeConfig::default_reeval_interval_secs")]
283 pub reeval_interval_secs: u64,
284 #[serde(default = "TreeConfig::default_flap_threshold")]
286 pub flap_threshold: u32,
287 #[serde(default = "TreeConfig::default_flap_window_secs")]
289 pub flap_window_secs: u64,
290 #[serde(default = "TreeConfig::default_flap_dampening_secs")]
292 pub flap_dampening_secs: u64,
293}
294
295impl Default for TreeConfig {
296 fn default() -> Self {
297 Self {
298 announce_min_interval_ms: 500,
299 parent_hysteresis: 0.2,
300 hold_down_secs: 30,
301 reeval_interval_secs: 60,
302 flap_threshold: 4,
303 flap_window_secs: 60,
304 flap_dampening_secs: 120,
305 }
306 }
307}
308
309impl TreeConfig {
310 fn default_announce_min_interval_ms() -> u64 {
311 500
312 }
313 fn default_parent_hysteresis() -> f64 {
314 0.2
315 }
316 fn default_hold_down_secs() -> u64 {
317 30
318 }
319 fn default_reeval_interval_secs() -> u64 {
320 60
321 }
322 fn default_flap_threshold() -> u32 {
323 4
324 }
325 fn default_flap_window_secs() -> u64 {
326 60
327 }
328 fn default_flap_dampening_secs() -> u64 {
329 120
330 }
331}
332
333#[derive(Debug, Clone, Serialize, Deserialize)]
335pub struct RoutingConfig {
336 #[serde(default)]
338 pub mode: RoutingMode,
339 #[serde(default = "RoutingConfig::default_learned_ttl_secs")]
341 pub learned_ttl_secs: u64,
342 #[serde(default = "RoutingConfig::default_max_learned_routes_per_dest")]
346 pub max_learned_routes_per_dest: usize,
347 #[serde(default = "RoutingConfig::default_learned_fallback_explore_interval")]
350 pub learned_fallback_explore_interval: u64,
351}
352
353impl Default for RoutingConfig {
354 fn default() -> Self {
355 Self {
356 mode: RoutingMode::default(),
357 learned_ttl_secs: 300,
358 max_learned_routes_per_dest: 4,
359 learned_fallback_explore_interval: 16,
360 }
361 }
362}
363
364impl RoutingConfig {
365 fn default_learned_ttl_secs() -> u64 {
366 300
367 }
368
369 fn default_max_learned_routes_per_dest() -> usize {
370 4
371 }
372
373 fn default_learned_fallback_explore_interval() -> u64 {
374 16
375 }
376}
377
378#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
380#[serde(rename_all = "snake_case")]
381pub enum RoutingMode {
382 #[default]
384 Tree,
385 ReplyLearned,
390}
391
392impl std::fmt::Display for RoutingMode {
393 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
394 match self {
395 RoutingMode::Tree => write!(f, "tree"),
396 RoutingMode::ReplyLearned => write!(f, "reply_learned"),
397 }
398 }
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize)]
403pub struct BloomConfig {
404 #[serde(default = "BloomConfig::default_update_debounce_ms")]
406 pub update_debounce_ms: u64,
407 #[serde(default = "BloomConfig::default_max_inbound_fpr")]
415 pub max_inbound_fpr: f64,
416}
417
418impl Default for BloomConfig {
419 fn default() -> Self {
420 Self {
421 update_debounce_ms: 500,
422 max_inbound_fpr: 0.10,
423 }
424 }
425}
426
427impl BloomConfig {
428 fn default_update_debounce_ms() -> u64 {
429 500
430 }
431 fn default_max_inbound_fpr() -> f64 {
432 0.10
433 }
434}
435
436#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct SessionConfig {
439 #[serde(default = "SessionConfig::default_ttl")]
441 pub default_ttl: u8,
442 #[serde(default = "SessionConfig::default_pending_packets_per_dest")]
444 pub pending_packets_per_dest: usize,
445 #[serde(default = "SessionConfig::default_pending_max_destinations")]
447 pub pending_max_destinations: usize,
448 #[serde(default = "SessionConfig::default_idle_timeout_secs")]
452 pub idle_timeout_secs: u64,
453 #[serde(default = "SessionConfig::default_coords_warmup_packets")]
457 pub coords_warmup_packets: u8,
458 #[serde(default = "SessionConfig::default_coords_response_interval_ms")]
462 pub coords_response_interval_ms: u64,
463}
464
465impl Default for SessionConfig {
466 fn default() -> Self {
467 Self {
468 default_ttl: 64,
469 pending_packets_per_dest: 16,
470 pending_max_destinations: 256,
471 idle_timeout_secs: 90,
472 coords_warmup_packets: 5,
473 coords_response_interval_ms: 2000,
474 }
475 }
476}
477
478impl SessionConfig {
479 fn default_ttl() -> u8 {
480 64
481 }
482 fn default_pending_packets_per_dest() -> usize {
483 16
484 }
485 fn default_pending_max_destinations() -> usize {
486 256
487 }
488 fn default_idle_timeout_secs() -> u64 {
489 90
490 }
491 fn default_coords_warmup_packets() -> u8 {
492 5
493 }
494 fn default_coords_response_interval_ms() -> u64 {
495 2000
496 }
497}
498
499#[derive(Debug, Clone, Serialize, Deserialize)]
506pub struct SessionMmpConfig {
507 #[serde(default)]
509 pub mode: MmpMode,
510
511 #[serde(default = "SessionMmpConfig::default_log_interval_secs")]
513 pub log_interval_secs: u64,
514
515 #[serde(default = "SessionMmpConfig::default_owd_window_size")]
517 pub owd_window_size: usize,
518}
519
520impl Default for SessionMmpConfig {
521 fn default() -> Self {
522 Self {
523 mode: MmpMode::default(),
524 log_interval_secs: DEFAULT_LOG_INTERVAL_SECS,
525 owd_window_size: DEFAULT_OWD_WINDOW_SIZE,
526 }
527 }
528}
529
530impl SessionMmpConfig {
531 fn default_log_interval_secs() -> u64 {
532 DEFAULT_LOG_INTERVAL_SECS
533 }
534 fn default_owd_window_size() -> usize {
535 DEFAULT_OWD_WINDOW_SIZE
536 }
537}
538
539#[derive(Debug, Clone, Serialize, Deserialize)]
541pub struct ControlConfig {
542 #[serde(default = "ControlConfig::default_enabled")]
544 pub enabled: bool,
545 #[serde(default = "ControlConfig::default_socket_path")]
547 pub socket_path: String,
548}
549
550impl Default for ControlConfig {
551 fn default() -> Self {
552 Self {
553 enabled: true,
554 socket_path: Self::default_socket_path(),
555 }
556 }
557}
558
559impl ControlConfig {
560 fn default_enabled() -> bool {
561 true
562 }
563
564 fn default_socket_path() -> String {
571 #[cfg(unix)]
572 {
573 super::resolve_default_socket("control.sock")
574 }
575 #[cfg(windows)]
576 {
577 "21210".to_string()
578 }
579 }
580}
581
582const DEFAULT_PACKET_CHANNEL_CAPACITY: usize = 4096;
583
584#[derive(Debug, Clone, Serialize, Deserialize)]
586pub struct BuffersConfig {
587 #[serde(default = "BuffersConfig::default_packet_channel")]
592 pub packet_channel: usize,
593 #[serde(default = "BuffersConfig::default_tun_channel")]
595 pub tun_channel: usize,
596 #[serde(default = "BuffersConfig::default_dns_channel")]
598 pub dns_channel: usize,
599}
600
601impl Default for BuffersConfig {
602 fn default() -> Self {
603 Self {
604 packet_channel: DEFAULT_PACKET_CHANNEL_CAPACITY,
605 tun_channel: 1024,
606 dns_channel: 64,
607 }
608 }
609}
610
611impl BuffersConfig {
612 fn default_packet_channel() -> usize {
613 DEFAULT_PACKET_CHANNEL_CAPACITY
614 }
615 fn default_tun_channel() -> usize {
616 1024
617 }
618 fn default_dns_channel() -> usize {
619 64
620 }
621}
622
623const DEFAULT_REKEY_AFTER_MESSAGES: u64 = 1 << 48;
640
641#[derive(Debug, Clone, Serialize, Deserialize)]
642pub struct RekeyConfig {
643 #[serde(default = "RekeyConfig::default_enabled")]
645 pub enabled: bool,
646
647 #[serde(default = "RekeyConfig::default_after_secs")]
649 pub after_secs: u64,
650
651 #[serde(default = "RekeyConfig::default_after_messages")]
653 pub after_messages: u64,
654}
655
656impl Default for RekeyConfig {
657 fn default() -> Self {
658 Self {
659 enabled: true,
660 after_secs: 120,
661 after_messages: DEFAULT_REKEY_AFTER_MESSAGES,
662 }
663 }
664}
665
666impl RekeyConfig {
667 fn default_enabled() -> bool {
668 true
669 }
670 fn default_after_secs() -> u64 {
671 120
672 }
673 fn default_after_messages() -> u64 {
674 DEFAULT_REKEY_AFTER_MESSAGES
675 }
676}
677
678#[derive(Debug, Clone, Serialize, Deserialize)]
684pub struct EcnConfig {
685 #[serde(default = "EcnConfig::default_enabled")]
687 pub enabled: bool,
688
689 #[serde(default = "EcnConfig::default_loss_threshold")]
693 pub loss_threshold: f64,
694
695 #[serde(default = "EcnConfig::default_etx_threshold")]
699 pub etx_threshold: f64,
700}
701
702impl Default for EcnConfig {
703 fn default() -> Self {
704 Self {
705 enabled: true,
706 loss_threshold: 0.05,
707 etx_threshold: 3.0,
708 }
709 }
710}
711
712impl EcnConfig {
713 fn default_enabled() -> bool {
714 true
715 }
716 fn default_loss_threshold() -> f64 {
717 0.05
718 }
719 fn default_etx_threshold() -> f64 {
720 3.0
721 }
722}
723
724#[derive(Debug, Clone, Serialize, Deserialize)]
730pub struct NodeConfig {
731 #[serde(default)]
733 pub identity: IdentityConfig,
734
735 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
737 pub leaf_only: bool,
738
739 #[serde(default = "NodeConfig::default_tick_interval_secs")]
741 pub tick_interval_secs: u64,
742
743 #[serde(default = "NodeConfig::default_base_rtt_ms")]
745 pub base_rtt_ms: u64,
746
747 #[serde(default = "NodeConfig::default_heartbeat_interval_secs")]
749 pub heartbeat_interval_secs: u64,
750
751 #[serde(default = "NodeConfig::default_link_dead_timeout_secs")]
754 pub link_dead_timeout_secs: u64,
755
756 #[serde(default = "NodeConfig::default_fast_link_dead_timeout_secs")]
766 pub fast_link_dead_timeout_secs: u64,
767
768 #[serde(default)]
770 pub limits: LimitsConfig,
771
772 #[serde(default)]
774 pub connected_udp: ConnectedUdpConfig,
775
776 #[serde(default)]
778 pub rate_limit: RateLimitConfig,
779
780 #[serde(default)]
782 pub retry: RetryConfig,
783
784 #[serde(default)]
786 pub cache: CacheConfig,
787
788 #[serde(default)]
790 pub discovery: DiscoveryConfig,
791
792 #[serde(default)]
794 pub tree: TreeConfig,
795
796 #[serde(default)]
798 pub routing: RoutingConfig,
799
800 #[serde(default)]
802 pub bloom: BloomConfig,
803
804 #[serde(default)]
806 pub session: SessionConfig,
807
808 #[serde(default)]
810 pub buffers: BuffersConfig,
811
812 #[serde(default)]
814 pub control: ControlConfig,
815
816 #[serde(default)]
818 pub mmp: MmpConfig,
819
820 #[serde(default)]
822 pub session_mmp: SessionMmpConfig,
823
824 #[serde(default)]
826 pub ecn: EcnConfig,
827
828 #[serde(default)]
830 pub rekey: RekeyConfig,
831
832 #[serde(default = "NodeConfig::default_system_files_enabled")]
835 pub system_files_enabled: bool,
836
837 #[serde(default = "NodeConfig::default_worker_pools_enabled")]
842 pub worker_pools_enabled: bool,
843
844 #[serde(default)]
847 pub log_level: Option<String>,
848}
849
850impl Default for NodeConfig {
851 fn default() -> Self {
852 Self {
853 identity: IdentityConfig::default(),
854 leaf_only: false,
855 tick_interval_secs: 1,
856 base_rtt_ms: 100,
857 heartbeat_interval_secs: 10,
858 link_dead_timeout_secs: 30,
859 fast_link_dead_timeout_secs: 5,
860 limits: LimitsConfig::default(),
861 connected_udp: ConnectedUdpConfig::default(),
862 rate_limit: RateLimitConfig::default(),
863 retry: RetryConfig::default(),
864 cache: CacheConfig::default(),
865 discovery: DiscoveryConfig::default(),
866 tree: TreeConfig::default(),
867 routing: RoutingConfig::default(),
868 bloom: BloomConfig::default(),
869 session: SessionConfig::default(),
870 buffers: BuffersConfig::default(),
871 control: ControlConfig::default(),
872 mmp: MmpConfig::default(),
873 session_mmp: SessionMmpConfig::default(),
874 ecn: EcnConfig::default(),
875 rekey: RekeyConfig::default(),
876 system_files_enabled: true,
877 worker_pools_enabled: true,
878 log_level: None,
879 }
880 }
881}
882
883impl NodeConfig {
884 pub fn log_level(&self) -> tracing::Level {
886 match self
887 .log_level
888 .as_deref()
889 .map(|s| s.to_lowercase())
890 .as_deref()
891 {
892 Some("trace") => tracing::Level::TRACE,
893 Some("debug") => tracing::Level::DEBUG,
894 Some("warn") | Some("warning") => tracing::Level::WARN,
895 Some("error") => tracing::Level::ERROR,
896 _ => tracing::Level::INFO,
897 }
898 }
899
900 fn default_tick_interval_secs() -> u64 {
901 1
902 }
903 fn default_base_rtt_ms() -> u64 {
904 100
905 }
906 fn default_heartbeat_interval_secs() -> u64 {
907 10
908 }
909 fn default_link_dead_timeout_secs() -> u64 {
910 30
911 }
912 fn default_fast_link_dead_timeout_secs() -> u64 {
913 5
914 }
915 fn default_system_files_enabled() -> bool {
916 true
917 }
918 fn default_worker_pools_enabled() -> bool {
919 true
920 }
921}
922
923#[cfg(test)]
924mod tests;