1#[cfg(feature = "nat")]
4use crate::nat::NatConfig;
5use serde::{Deserialize, Serialize};
6use std::net::{IpAddr, Ipv4Addr, SocketAddr};
7use std::time::Duration;
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
11pub struct OverlayConfig {
12 pub local_endpoint: SocketAddr,
14
15 pub private_key: String,
17
18 #[serde(default = "OverlayConfig::default_public_key")]
20 pub public_key: String,
21
22 #[serde(default = "OverlayConfig::default_cidr")]
24 pub overlay_cidr: String,
25
26 #[serde(default = "OverlayConfig::default_discovery")]
28 pub peer_discovery_interval: Duration,
29
30 #[cfg(feature = "nat")]
32 #[serde(default)]
33 pub nat: NatConfig,
34}
35
36impl OverlayConfig {
37 fn default_public_key() -> String {
38 String::new()
39 }
40
41 fn default_cidr() -> String {
42 "10.0.0.0/8".to_string()
43 }
44
45 fn default_discovery() -> Duration {
46 Duration::from_secs(30)
47 }
48}
49
50impl Default for OverlayConfig {
51 fn default() -> Self {
52 Self {
53 local_endpoint: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 51820),
54 private_key: String::new(),
55 public_key: String::new(),
56 overlay_cidr: "10.0.0.0/8".to_string(),
57 peer_discovery_interval: Duration::from_secs(30),
58 #[cfg(feature = "nat")]
59 nat: NatConfig::default(),
60 }
61 }
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
66pub struct PeerInfo {
67 pub public_key: String,
69
70 pub endpoint: SocketAddr,
72
73 pub allowed_ips: String,
75
76 pub persistent_keepalive_interval: Duration,
78}
79
80impl PeerInfo {
81 #[must_use]
83 pub fn new(
84 public_key: String,
85 endpoint: SocketAddr,
86 allowed_ips: &str,
87 persistent_keepalive_interval: Duration,
88 ) -> Self {
89 Self {
90 public_key,
91 endpoint,
92 allowed_ips: allowed_ips.to_string(),
93 persistent_keepalive_interval,
94 }
95 }
96
97 #[must_use]
99 pub fn to_peer_config(&self) -> String {
100 format!(
101 "[Peer]\n\
102 PublicKey = {}\n\
103 Endpoint = {}\n\
104 AllowedIPs = {}\n\
105 PersistentKeepalive = {}\n",
106 self.public_key,
107 self.endpoint,
108 self.allowed_ips,
109 self.persistent_keepalive_interval.as_secs()
110 )
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_peer_info_to_peer_config() {
120 let peer = PeerInfo::new(
121 "public_key_here".to_string(),
122 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 51820),
123 "10.0.0.2/32",
124 Duration::from_secs(25),
125 );
126
127 let config = peer.to_peer_config();
128 assert!(config.contains("PublicKey = public_key_here"));
129 assert!(config.contains("Endpoint = 192.168.1.1:51820"));
130 }
131
132 #[test]
133 fn test_overlay_config_default() {
134 let config = OverlayConfig::default();
135 assert_eq!(config.local_endpoint.port(), 51820);
136 assert_eq!(config.overlay_cidr, "10.0.0.0/8");
137 }
138
139 #[test]
140 fn test_peer_info_to_peer_config_v6() {
141 use std::net::Ipv6Addr;
142
143 let peer = PeerInfo::new(
144 "public_key_here".to_string(),
145 SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 51820),
146 "fd00::2/128",
147 Duration::from_secs(25),
148 );
149
150 let config = peer.to_peer_config();
151 assert!(config.contains("PublicKey = public_key_here"));
152 assert!(config.contains("Endpoint = [::1]:51820"));
153 assert!(config.contains("AllowedIPs = fd00::2/128"));
154 }
155
156 #[test]
157 fn test_overlay_config_accepts_ipv6_cidr() {
158 let config = OverlayConfig {
159 overlay_cidr: "fd00:200::/48".to_string(),
160 ..OverlayConfig::default()
161 };
162 assert_eq!(config.overlay_cidr, "fd00:200::/48");
163 }
164}