Skip to main content

tuwunel_core/config/
net.rs

1use 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)]
27pub fn get_unix_socket_perms(&self) -> Result<u32> {
28	let octal_perms = self.unix_socket_perms.to_string();
29	let socket_perms = u32::from_str_radix(&octal_perms, 8)
30		.map_err(|_| err!(Config("unix_socket_perms", "failed to convert octal permissions")))?;
31
32	Ok(socket_perms)
33}
34
35#[must_use]
36#[implement(super::Config)]
37pub fn get_bind_addrs(&self) -> Vec<SocketAddr> {
38	let mut addrs = Vec::with_capacity(
39		self.get_bind_hosts()
40			.len()
41			.saturating_mul(self.get_bind_ports().len()),
42	);
43	for host in &self.get_bind_hosts() {
44		for port in &self.get_bind_ports() {
45			addrs.push(SocketAddr::new(*host, *port));
46		}
47	}
48
49	addrs
50}
51
52#[implement(super::Config)]
53fn get_bind_hosts(&self) -> Vec<IpAddr> {
54	if let Some(address) = &self.address {
55		match &address.addrs {
56			| Left(addr) => vec![*addr],
57			| Right(addrs) => addrs.clone(),
58		}
59	} else if self.unix_socket_path.is_some() {
60		vec![]
61	} else {
62		vec![Ipv4Addr::LOCALHOST.into(), Ipv6Addr::LOCALHOST.into()]
63	}
64}
65
66#[implement(super::Config)]
67fn get_bind_ports(&self) -> Vec<u16> {
68	match &self.port.ports {
69		| Left(port) => vec![*port],
70		| Right(ports) => ports.clone(),
71	}
72}
73
74#[implement(super::Config)]
75#[must_use]
76pub fn is_forbidden_remote_server_name(&self, server_name: &ServerName) -> bool {
77	if server_name == self.server_name {
78		return false;
79	}
80
81	let deny_list_active = self
82		.forbidden_remote_server_names
83		.is_empty()
84		.is_false();
85
86	let allow_list_active = self
87		.allowed_remote_server_names_experimental
88		.is_empty()
89		.is_false();
90
91	if deny_list_active
92		&& self
93			.forbidden_remote_server_names
94			.is_match(server_name.host())
95	{
96		return true;
97	}
98
99	if allow_list_active
100		&& !self
101			.allowed_remote_server_names_experimental
102			.is_match(server_name.host())
103	{
104		return true;
105	}
106
107	false
108}