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	let deny_list_active = self
78		.forbidden_remote_server_names
79		.is_empty()
80		.is_false();
81
82	let allow_list_active = self
83		.allowed_remote_server_names_experimental
84		.is_empty()
85		.is_false();
86
87	if deny_list_active
88		&& self
89			.forbidden_remote_server_names
90			.is_match(server_name.host())
91	{
92		return true;
93	}
94
95	if allow_list_active
96		&& !self
97			.allowed_remote_server_names_experimental
98			.is_match(server_name.host())
99	{
100		return true;
101	}
102
103	false
104}