Update axum-server to 0.8; switch to axum unix listener.

This commit is contained in:
dasha_uwu
2026-02-03 02:30:50 +05:00
committed by Jason Volk
parent 87faf818ff
commit bd5203b406
13 changed files with 231 additions and 390 deletions

View File

@@ -1,11 +1,10 @@
use std::env::consts::OS;
use either::Either;
use figment::Figment;
use itertools::Itertools;
use super::{DEPRECATED_KEYS, IdentityProvider};
use crate::{Config, Err, Result, Server, debug, debug_info, debug_warn, error, warn};
use crate::{Config, Err, Result, Server, debug, debug_info, error, warn};
/// Performs check() with additional checks specific to reloading old config
/// with new config.
@@ -24,9 +23,8 @@ pub fn reload(old: &Config, new: &Config) -> Result {
}
pub fn check(config: &Config) -> Result {
if cfg!(debug_assertions) {
warn!("Note: tuwunel was built without optimisations (i.e. debug build)");
}
#[cfg(debug_assertions)]
warn!("Note: tuwunel was built without optimisations (i.e. debug build)");
warn_deprecated(config);
warn_unknown_key(config)?;
@@ -38,14 +36,18 @@ pub fn check(config: &Config) -> Result {
));
}
if cfg!(all(feature = "hardened_malloc", feature = "jemalloc", not(target_env = "msvc"))) {
debug_warn!(
"hardened_malloc and jemalloc compile-time features are both enabled, this causes \
jemalloc to be used."
);
}
#[cfg(all(
feature = "hardened_malloc",
feature = "jemalloc",
not(target_env = "msvc")
))]
debug_warn!(
"hardened_malloc and jemalloc compile-time features are both enabled, this causes \
jemalloc to be used."
);
if cfg!(not(unix)) && config.unix_socket_path.is_some() {
#[cfg(not(unix))]
if config.unix_socket_path.is_some() {
return Err!(Config(
"unix_socket_path",
"UNIX socket support is only available on *nix platforms. Please remove \
@@ -53,12 +55,20 @@ pub fn check(config: &Config) -> Result {
));
}
if config.unix_socket_path.is_none() && config.get_bind_hosts().is_empty() {
return Err!(Config("address", "No TCP addresses were specified to listen on"));
if config.unix_socket_path.is_none() {
if config.get_bind_hosts().is_empty() {
return Err!(Config("address", "No TCP addresses were specified to listen on"));
}
if config.get_bind_ports().is_empty() {
return Err!(Config("port", "No ports were specified to listen on"));
}
}
if config.unix_socket_path.is_none() && config.get_bind_ports().is_empty() {
return Err!(Config("port", "No ports were specified to listen on"));
let certs_set = config.tls.certs.is_some();
let key_set = config.tls.key.is_some();
if certs_set ^ key_set {
return Err!(Config("tls", "tls.certs and tls.key must either both be set or unset"));
}
if !config.listening {
@@ -115,7 +125,8 @@ pub fn check(config: &Config) -> Result {
}
// yeah, unless the user built a debug build hopefully for local testing only
if cfg!(not(debug_assertions)) && config.server_name == "your.server.name" {
#[cfg(not(debug_assertions))]
if config.server_name == "your.server.name" {
return Err!(Config(
"server_name",
"You must specify a valid server name for production usage of tuwunel."
@@ -412,18 +423,3 @@ fn warn_unknown_key(config: &Config) -> Result {
Ok(())
}
}
/// Checks the presence of the `address` and `unix_socket_path` keys in the
/// raw_config, exiting the process if both keys were detected.
pub(super) fn is_dual_listening(raw_config: &Figment) -> Result {
let contains_address = raw_config.contains("address");
let contains_unix_socket = raw_config.contains("unix_socket_path");
if contains_address && contains_unix_socket {
return Err!(
"TOML keys \"address\" and \"unix_socket_path\" were both defined. Please specify \
only one option."
);
}
Ok(())
}

View File

@@ -105,8 +105,8 @@ pub struct Config {
/// "::1"]
///
/// default: ["127.0.0.1", "::1"]
#[serde(default = "default_address")]
address: ListeningAddr,
#[serde(default)]
address: Option<ListeningAddr>,
/// The port(s) tuwunel will listen on.
///
@@ -128,9 +128,6 @@ pub struct Config {
/// The UNIX socket tuwunel will listen on.
///
/// tuwunel cannot listen on both an IP address and a UNIX socket. If
/// listening on a UNIX socket, you MUST remove/comment the `address` key.
///
/// Remember to make sure that your reverse proxy has access to this socket
/// file, either by adding your reverse proxy to the 'tuwunel' group or
/// granting world R/W permissions with `unix_socket_perms` (666 minimum).
@@ -3010,18 +3007,24 @@ impl Config {
.extract::<Self>()
.map_err(|e| err!("There was a problem with your configuration file: {e}"))?;
// don't start if we're listening on both UNIX sockets and TCP at same time
check::is_dual_listening(raw_config)?;
Ok(config)
}
pub fn get_unix_socket_perms(&self) -> Result<u32> {
let octal_perms = self.unix_socket_perms.to_string();
let socket_perms = u32::from_str_radix(&octal_perms, 8).map_err(|_| {
err!(Config("unix_socket_perms", "failed to convert octal permissions"))
})?;
Ok(socket_perms)
}
#[must_use]
pub fn get_bind_addrs(&self) -> Vec<SocketAddr> {
let mut addrs = Vec::with_capacity(
self.get_bind_hosts()
.len()
.saturating_add(self.get_bind_ports().len()),
.saturating_mul(self.get_bind_ports().len()),
);
for host in &self.get_bind_hosts() {
for port in &self.get_bind_ports() {
@@ -3033,9 +3036,15 @@ impl Config {
}
fn get_bind_hosts(&self) -> Vec<IpAddr> {
match &self.address.addrs {
| Left(addr) => vec![*addr],
| Right(addrs) => addrs.clone(),
if let Some(address) = &self.address {
match &address.addrs {
| Left(addr) => vec![*addr],
| Right(addrs) => addrs.clone(),
}
} else if self.unix_socket_path.is_some() {
vec![]
} else {
vec![Ipv4Addr::LOCALHOST.into(), Ipv6Addr::LOCALHOST.into()]
}
}
@@ -3056,12 +3065,6 @@ fn default_server_name() -> OwnedServerName { ruma::owned_server_name!("localhos
fn default_database_path() -> PathBuf { "/var/lib/tuwunel".to_owned().into() }
fn default_address() -> ListeningAddr {
ListeningAddr {
addrs: Right(vec![Ipv4Addr::LOCALHOST.into(), Ipv6Addr::LOCALHOST.into()]),
}
}
fn default_port() -> ListeningPort { ListeningPort { ports: Left(8008) } }
fn default_unix_socket_perms() -> u32 { 660 }