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 #[cfg(feature = "amneziawg")]
99 #[cfg_attr(docsrs, doc(cfg(feature = "amneziawg")))]
100 #[builder(setter(strip_option), default)]
101 pub amnezia_settings: Option<AmneziaSettings>,
102}
103
104impl Peer {
105 #[must_use]
117 pub fn builder() -> PeerBuilder {
118 PeerBuilder::default()
119 }
120}
121
122impl PeerBuilder {
123 #[must_use]
135 pub fn new() -> Self {
136 Self::default()
137 }
138
139 pub fn private_key(&mut self, value: PrivateKey) -> &mut Self {
143 self.key = Some(Either::Left(value));
144 self
145 }
146
147 pub fn public_key(&mut self, value: PublicKey) -> &mut Self {
151 self.key = Some(Either::Right(value));
152 self
153 }
154
155 pub fn build(&self) -> Peer {
157 self.fallible_build().unwrap_or_else(|_| unreachable!())
158 }
159}
160
161impl Peer {
162 pub fn to_interface(
174 &self,
175 server_interface: &Interface,
176 options: ToInterfaceOptions,
177 ) -> WireguardResult<Interface> {
178 let Either::Left(private_key) = self.key.clone() else {
179 return Err(WireguardError::NoPrivateKeyProvided);
180 };
181
182 let assigned_ips: Vec<IpNet> = self
183 .allowed_ips
184 .iter()
185 .filter_map(|allowed_ip| {
186 for server_address in &server_interface.address {
187 if server_address.contains(allowed_ip) {
188 return IpNet::new(allowed_ip.addr(), server_address.prefix_len()).ok();
189 }
190 }
191
192 None
193 })
194 .collect();
195
196 if assigned_ips.is_empty() {
197 return Err(WireguardError::NoAssignedIP);
198 }
199
200 let mut client_interface = Interface {
201 endpoint: None,
202
203 address: assigned_ips.clone(),
204 listen_port: None,
205 private_key,
206 dns: server_interface.dns.clone(),
207
208 table: None,
209 mtu: None,
210
211 #[cfg(feature = "amneziawg")]
212 amnezia_settings: self.amnezia_settings.clone(),
213
214 pre_up: vec![],
215 pre_down: vec![],
216 post_up: vec![],
217 post_down: vec![],
218
219 peers: vec![server_interface.to_peer()],
220 };
221
222 if options.default_gateway {
223 client_interface.peers[0].allowed_ips = {
224 let mut allowed_ips = Vec::with_capacity(1);
225
226 if assigned_ips.iter().any(|ip| ip.addr().is_ipv4()) {
227 allowed_ips.push(IpNet::new_assert(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0));
228 }
229
230 if assigned_ips.iter().any(|ip| ip.addr().is_ipv6()) {
231 allowed_ips.push(IpNet::new_assert(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0));
232 }
233
234 allowed_ips
235 };
236 }
237
238 if options.persistent_keepalive != 0 {
239 client_interface.peers[0].persistent_keepalive = options.persistent_keepalive;
240 }
241
242 Ok(client_interface)
243 }
244}
245
246impl fmt::Display for Peer {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 writeln!(f, "[Peer]")?;
255 if let Some(endpoint) = self.endpoint.clone() {
256 writeln!(f, "Endpoint = {endpoint}")?;
257 }
258 writeln!(
259 f,
260 "AllowedIPs = {}",
261 self.allowed_ips
262 .iter()
263 .map(std::string::ToString::to_string)
264 .collect::<Vec<String>>()
265 .join(",")
266 )?;
267 writeln!(
268 f,
269 "PublicKey = {}",
270 self.key.clone().right_or_else(|key| PublicKey::from(&key))
271 )?;
272 if let Some(preshared_key) = &self.preshared_key {
273 writeln!(f, "PresharedKey = {preshared_key}")?;
274 }
275 if self.persistent_keepalive != 0 {
276 writeln!(f, "PersistentKeepalive = {}", self.persistent_keepalive)?;
277 }
278
279 Ok(())
280 }
281}