tuwunel_core/config/
net.rs1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
2
3use either::{
4 Either,
5 Either::{Left, Right},
6};
7use ruma::ServerName;
8use serde::Deserialize;
9
10use crate::{Result, err, implement, utils::BoolExt};
11
12#[derive(Deserialize, Clone, Debug)]
13#[serde(transparent)]
14pub(super) struct ListeningPort {
15 #[serde(with = "either::serde_untagged")]
16 pub(super) ports: Either<u16, Vec<u16>>,
17}
18
19#[derive(Deserialize, Clone, Debug)]
20#[serde(transparent)]
21pub(super) struct ListeningAddr {
22 #[serde(with = "either::serde_untagged")]
23 pub(super) addrs: Either<IpAddr, Vec<IpAddr>>,
24}
25
26#[implement(super::Config)]
31pub fn get_unix_socket_perms(&self) -> Result<u32> {
32 let octal_perms = self.unix_socket_perms.to_string();
33 let socket_perms = u32::from_str_radix(&octal_perms, 8)
34 .map_err(|_| err!(Config("unix_socket_perms", "failed to convert octal permissions")))?;
35
36 Ok(socket_perms)
37}
38
39#[must_use]
45#[implement(super::Config)]
46pub fn get_bind_addrs(&self) -> Vec<SocketAddr> {
47 let mut addrs = Vec::with_capacity(
48 self.get_bind_hosts()
49 .len()
50 .saturating_mul(self.get_bind_ports().len()),
51 );
52 for host in &self.get_bind_hosts() {
53 for port in &self.get_bind_ports() {
54 addrs.push(SocketAddr::new(*host, *port));
55 }
56 }
57
58 addrs
59}
60
61#[implement(super::Config)]
62fn get_bind_hosts(&self) -> Vec<IpAddr> {
63 self.address.as_ref().map_or_else(
64 || {
65 self.unix_socket_path
66 .is_none()
67 .then(|| vec![Ipv4Addr::LOCALHOST.into(), Ipv6Addr::LOCALHOST.into()])
68 .unwrap_or_default()
69 },
70 |address| match &address.addrs {
71 | Left(addr) => vec![*addr],
72 | Right(addrs) => addrs.clone(),
73 },
74 )
75}
76
77#[implement(super::Config)]
78fn get_bind_ports(&self) -> Vec<u16> {
79 match &self.port.ports {
80 | Left(port) => vec![*port],
81 | Right(ports) => ports.clone(),
82 }
83}
84
85#[implement(super::Config)]
91#[inline]
92#[must_use]
93pub fn is_address_defaulted(&self) -> bool { self.address.is_none() }
94
95#[implement(super::Config)]
100#[must_use]
101pub fn is_forbidden_remote_server_name(&self, server_name: &ServerName) -> bool {
102 if server_name == self.server_name {
103 return false;
104 }
105
106 let deny_list_active = self
107 .forbidden_remote_server_names
108 .is_empty()
109 .is_false();
110
111 let allow_list_active = self
112 .allowed_remote_server_names_experimental
113 .is_empty()
114 .is_false();
115
116 if deny_list_active
117 && self
118 .forbidden_remote_server_names
119 .is_match(server_name.host())
120 {
121 return true;
122 }
123
124 if allow_list_active
125 && !self
126 .allowed_remote_server_names_experimental
127 .is_match(server_name.host())
128 {
129 return true;
130 }
131
132 false
133}