1#[cfg(feature = "nat")]
4use crate::nat::NatConfig;
5use serde::{Deserialize, Serialize};
6use std::net::{IpAddr, Ipv4Addr, SocketAddr};
7use std::path::PathBuf;
8use std::time::Duration;
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct OverlayConfig {
13 pub local_endpoint: SocketAddr,
15
16 pub private_key: String,
18
19 #[serde(default = "OverlayConfig::default_public_key")]
21 pub public_key: String,
22
23 #[serde(default = "OverlayConfig::default_cidr")]
29 pub overlay_cidr: String,
30
31 #[serde(default)]
40 pub cluster_cidr: Option<String>,
41
42 #[serde(default = "OverlayConfig::default_discovery")]
44 pub peer_discovery_interval: Duration,
45
46 #[cfg(feature = "nat")]
48 #[serde(default)]
49 pub nat: NatConfig,
50
51 #[serde(default = "OverlayConfig::default_uapi_sock_dir")]
57 pub uapi_sock_dir: PathBuf,
58}
59
60impl OverlayConfig {
61 fn default_public_key() -> String {
62 String::new()
63 }
64
65 fn default_cidr() -> String {
66 "10.0.0.0/8".to_string()
67 }
68
69 fn default_discovery() -> Duration {
70 Duration::from_secs(30)
71 }
72
73 fn default_uapi_sock_dir() -> PathBuf {
81 PathBuf::from("/var/run/wireguard")
82 }
83}
84
85impl Default for OverlayConfig {
86 fn default() -> Self {
87 Self {
88 local_endpoint: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 51820),
89 private_key: String::new(),
90 public_key: String::new(),
91 overlay_cidr: "10.0.0.0/8".to_string(),
92 cluster_cidr: None,
93 peer_discovery_interval: Duration::from_secs(30),
94 #[cfg(feature = "nat")]
95 nat: NatConfig::default(),
96 uapi_sock_dir: Self::default_uapi_sock_dir(),
97 }
98 }
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
103pub struct PeerInfo {
104 pub public_key: String,
106
107 pub endpoint: SocketAddr,
109
110 pub allowed_ips: String,
112
113 pub persistent_keepalive_interval: Duration,
115}
116
117impl PeerInfo {
118 #[must_use]
120 pub fn new(
121 public_key: String,
122 endpoint: SocketAddr,
123 allowed_ips: &str,
124 persistent_keepalive_interval: Duration,
125 ) -> Self {
126 Self {
127 public_key,
128 endpoint,
129 allowed_ips: allowed_ips.to_string(),
130 persistent_keepalive_interval,
131 }
132 }
133
134 #[must_use]
136 pub fn to_peer_config(&self) -> String {
137 format!(
138 "[Peer]\n\
139 PublicKey = {}\n\
140 Endpoint = {}\n\
141 AllowedIPs = {}\n\
142 PersistentKeepalive = {}\n",
143 self.public_key,
144 self.endpoint,
145 self.allowed_ips,
146 self.persistent_keepalive_interval.as_secs()
147 )
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_peer_info_to_peer_config() {
157 let peer = PeerInfo::new(
158 "public_key_here".to_string(),
159 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 51820),
160 "10.0.0.2/32",
161 Duration::from_secs(25),
162 );
163
164 let config = peer.to_peer_config();
165 assert!(config.contains("PublicKey = public_key_here"));
166 assert!(config.contains("Endpoint = 192.168.1.1:51820"));
167 }
168
169 #[test]
170 fn test_overlay_config_default() {
171 let config = OverlayConfig::default();
172 assert_eq!(config.local_endpoint.port(), 51820);
173 assert_eq!(config.overlay_cidr, "10.0.0.0/8");
174 }
175
176 #[test]
177 fn test_peer_info_to_peer_config_v6() {
178 use std::net::Ipv6Addr;
179
180 let peer = PeerInfo::new(
181 "public_key_here".to_string(),
182 SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 51820),
183 "fd00::2/128",
184 Duration::from_secs(25),
185 );
186
187 let config = peer.to_peer_config();
188 assert!(config.contains("PublicKey = public_key_here"));
189 assert!(config.contains("Endpoint = [::1]:51820"));
190 assert!(config.contains("AllowedIPs = fd00::2/128"));
191 }
192
193 #[test]
194 fn test_overlay_config_accepts_ipv6_cidr() {
195 let config = OverlayConfig {
196 overlay_cidr: "fd00:200::/48".to_string(),
197 ..OverlayConfig::default()
198 };
199 assert_eq!(config.overlay_cidr, "fd00:200::/48");
200 }
201}