wireguard_conf/models/
peer.rs1use derive_builder::Builder;
2use either::Either;
3use ipnet::IpNet;
4
5use std::fmt;
6use std::net::{IpAddr, Ipv6Addr};
7use std::{convert::Infallible, net::Ipv4Addr};
8
9#[cfg(feature = "serde")]
10#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
11use serde::{Deserialize, Serialize};
12
13use crate::prelude::*;
14
15#[derive(Clone, Copy, Debug, PartialEq, Default)]
17#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
18pub struct ToInterfaceOptions {
19 default_gateway: bool,
21
22 persistent_keepalive: u16,
24}
25
26impl ToInterfaceOptions {
27 #[must_use]
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 #[must_use]
37 pub fn default_gateway(mut self, value: bool) -> Self {
38 self.default_gateway = value;
39 self
40 }
41
42 #[must_use]
45 pub fn persistent_keepalive(mut self, value: u16) -> Self {
46 self.persistent_keepalive = value;
47 self
48 }
49}
50
51#[must_use]
55#[derive(Clone, Debug, PartialEq, Builder)]
56#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
57#[builder(build_fn(private, name = "fallible_build", error = "Infallible"))]
58pub struct Peer {
59 #[builder(setter(into, strip_option), default)]
63 pub endpoint: Option<String>,
64
65 #[builder(setter(into), default)]
71 pub allowed_ips: Vec<IpNet>,
72
73 #[builder(default)]
82 pub persistent_keepalive: u16,
83
84 #[builder(default = Either::Left(PrivateKey::random()))]
89 pub key: Either<PrivateKey, PublicKey>,
90
91 #[builder(setter(strip_option), default)]
93 pub preshared_key: Option<PresharedKey>,
94}
95
96impl Peer {
97 #[must_use]
109 pub fn builder() -> PeerBuilder {
110 PeerBuilder::default()
111 }
112}
113
114impl PeerBuilder {
115 #[must_use]
127 pub fn new() -> Self {
128 Self::default()
129 }
130
131 pub fn private_key(&mut self, value: PrivateKey) -> &mut Self {
135 self.key = Some(Either::Left(value));
136 self
137 }
138
139 pub fn public_key(&mut self, value: PublicKey) -> &mut Self {
143 self.key = Some(Either::Right(value));
144 self
145 }
146
147 pub fn build(&self) -> Peer {
149 self.fallible_build().unwrap_or_else(|_| unreachable!())
150 }
151}
152
153impl Peer {
154 pub fn to_interface(
166 &self,
167 server_interface: &Interface,
168 options: ToInterfaceOptions,
169 ) -> WireguardResult<Interface> {
170 let Either::Left(private_key) = self.key.clone() else {
171 return Err(WireguardError::NoPrivateKeyProvided);
172 };
173
174 let assigned_ips: Vec<IpNet> = self
175 .allowed_ips
176 .iter()
177 .filter_map(|allowed_ip| {
178 for server_address in &server_interface.address {
179 if server_address.contains(allowed_ip) {
180 return IpNet::new(allowed_ip.addr(), server_address.prefix_len()).ok();
181 }
182 }
183
184 None
185 })
186 .collect();
187
188 if assigned_ips.is_empty() {
189 return Err(WireguardError::NoAssignedIP);
190 }
191
192 let mut client_interface = Interface {
193 endpoint: None,
194
195 address: assigned_ips.clone(),
196 listen_port: None,
197 private_key,
198 dns: server_interface.dns.clone(),
199
200 table: None,
201 mtu: None,
202
203 #[cfg(feature = "amneziawg")]
204 amnezia_settings: server_interface.amnezia_settings.clone(),
205
206 pre_up: vec![],
207 pre_down: vec![],
208 post_up: vec![],
209 post_down: vec![],
210
211 peers: vec![server_interface.to_peer()],
212 };
213
214 if options.default_gateway {
215 client_interface.peers[0].allowed_ips = {
216 let mut allowed_ips = Vec::with_capacity(1);
217
218 if assigned_ips.iter().any(|ip| ip.addr().is_ipv4()) {
219 allowed_ips.push(IpNet::new_assert(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0));
220 }
221
222 if assigned_ips.iter().any(|ip| ip.addr().is_ipv6()) {
223 allowed_ips.push(IpNet::new_assert(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0));
224 }
225
226 allowed_ips
227 };
228 }
229
230 if options.persistent_keepalive != 0 {
231 client_interface.peers[0].persistent_keepalive = options.persistent_keepalive;
232 }
233
234 Ok(client_interface)
235 }
236}
237
238impl fmt::Display for Peer {
245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 writeln!(f, "[Peer]")?;
247 if let Some(endpoint) = self.endpoint.clone() {
248 writeln!(f, "Endpoint = {endpoint}")?;
249 }
250 writeln!(
251 f,
252 "AllowedIPs = {}",
253 self.allowed_ips
254 .iter()
255 .map(std::string::ToString::to_string)
256 .collect::<Vec<String>>()
257 .join(",")
258 )?;
259 writeln!(
260 f,
261 "PublicKey = {}",
262 self.key.clone().right_or_else(|key| PublicKey::from(&key))
263 )?;
264 if let Some(preshared_key) = &self.preshared_key {
265 writeln!(f, "PresharedKey = {preshared_key}")?;
266 }
267 if self.persistent_keepalive != 0 {
268 writeln!(f, "PersistentKeepalive = {}", self.persistent_keepalive)?;
269 }
270
271 Ok(())
272 }
273}