Reduce high volume of strings from FedDest and ActualDest in resolver.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-11-23 00:04:41 +00:00
parent 9e539d0a22
commit a748edd621
7 changed files with 59 additions and 56 deletions

View File

@@ -163,7 +163,7 @@ async fn into_http_response(
request_url = ?url, request_url = ?url,
response_url = ?response.url(), response_url = ?response.url(),
"Received response from {}", "Received response from {}",
actual.string(), actual.to_string(),
); );
let mut http_response_builder = http::Response::builder() let mut http_response_builder = http::Response::builder()
@@ -249,7 +249,7 @@ where
}; };
let mut request = request let mut request = request
.try_into_http_request::<Vec<u8>>(actual.string().as_str(), SATIR, &supported) .try_into_http_request::<Vec<u8>>(actual.to_string().as_str(), SATIR, &supported)
.map_err(|e| err!(BadServerResponse("Invalid destination: {e:?}")))?; .map_err(|e| err!(BadServerResponse("Invalid destination: {e:?}")))?;
if matches!(T::METADATA.authentication, AuthScheme::ServerSignatures) { if matches!(T::METADATA.authentication, AuthScheme::ServerSignatures) {

View File

@@ -10,19 +10,20 @@ use ruma::ServerName;
use tuwunel_core::{Err, Result, debug, debug_info, err, error, trace}; use tuwunel_core::{Err, Result, debug, debug_info, err, error, trace};
use super::{ use super::{
DestString, FedDest,
cache::{CachedDest, CachedOverride, MAX_IPS}, cache::{CachedDest, CachedOverride, MAX_IPS},
fed::{FedDest, PortString, add_port_to_hostname, get_ip_with_port}, fed::{PortString, add_port_to_hostname, get_ip_with_port},
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct ActualDest { pub(crate) struct ActualDest {
pub(crate) dest: FedDest, pub(crate) dest: FedDest,
pub(crate) host: String, pub(crate) host: DestString,
} }
impl ActualDest { impl ActualDest {
#[inline] #[inline]
pub(crate) fn string(&self) -> String { self.dest.https_string() } pub(crate) fn to_string(&self) -> DestString { self.dest.https_string() }
} }
impl super::Service { impl super::Service {
@@ -65,7 +66,7 @@ impl super::Service {
cache: bool, cache: bool,
) -> Result<CachedDest> { ) -> Result<CachedDest> {
self.validate_dest(dest)?; self.validate_dest(dest)?;
let mut host = dest.as_str().to_owned(); let mut host: DestString = dest.as_str().into();
let actual_dest = match get_ip_with_port(dest.as_str()) { let actual_dest = match get_ip_with_port(dest.as_str()) {
| Some(host_port) => Self::actual_dest_1(host_port)?, | Some(host_port) => Self::actual_dest_1(host_port)?,
| None => | None =>
@@ -77,7 +78,7 @@ impl super::Service {
self.services.server.check_running()?; self.services.server.check_running()?;
match self.request_well_known(dest.as_str()).await? { match self.request_well_known(dest.as_str()).await? {
| Some(delegated) => | Some(delegated) =>
self.actual_dest_3(&mut host, cache, delegated) self.actual_dest_3(&mut host, cache, &delegated)
.await?, .await?,
| _ => match self.query_srv_record(dest.as_str()).await? { | _ => match self.query_srv_record(dest.as_str()).await? {
| Some(overrider) => | Some(overrider) =>
@@ -94,16 +95,16 @@ impl super::Service {
let host = if let Ok(addr) = host.parse::<SocketAddr>() { let host = if let Ok(addr) = host.parse::<SocketAddr>() {
FedDest::Literal(addr) FedDest::Literal(addr)
} else if let Ok(addr) = host.parse::<IpAddr>() { } else if let Ok(addr) = host.parse::<IpAddr>() {
FedDest::Named(addr.to_string(), FedDest::default_port()) FedDest::Named(addr.to_string().into(), FedDest::default_port())
} else if let Some(pos) = host.find(':') { } else if let Some(pos) = host.find(':') {
let (host, port) = host.split_at(pos); let (host, port) = host.split_at(pos);
FedDest::Named( FedDest::Named(
host.to_owned(), host.into(),
port.try_into() port.try_into()
.unwrap_or_else(|_| FedDest::default_port()), .unwrap_or_else(|_| FedDest::default_port()),
) )
} else { } else {
FedDest::Named(host, FedDest::default_port()) FedDest::Named(host.as_str().into(), FedDest::default_port())
}; };
debug!("Actual destination: {actual_dest:?} hostname: {host:?}"); debug!("Actual destination: {actual_dest:?} hostname: {host:?}");
@@ -126,7 +127,7 @@ impl super::Service {
.await?; .await?;
Ok(FedDest::Named( Ok(FedDest::Named(
host.to_owned(), host.into(),
port.try_into() port.try_into()
.unwrap_or_else(|_| FedDest::default_port()), .unwrap_or_else(|_| FedDest::default_port()),
)) ))
@@ -134,20 +135,20 @@ impl super::Service {
async fn actual_dest_3( async fn actual_dest_3(
&self, &self,
host: &mut String, host: &mut DestString,
cache: bool, cache: bool,
delegated: String, delegated: &str,
) -> Result<FedDest> { ) -> Result<FedDest> {
debug!("3: A .well-known file is available"); debug!("3: A .well-known file is available");
*host = add_port_to_hostname(&delegated).uri_string(); *host = add_port_to_hostname(delegated).uri_string();
match get_ip_with_port(&delegated) { match get_ip_with_port(delegated) {
| Some(host_and_port) => Self::actual_dest_3_1(host_and_port), | Some(host_and_port) => Self::actual_dest_3_1(host_and_port),
| None => | None =>
if let Some(pos) = delegated.find(':') { if let Some(pos) = delegated.find(':') {
self.actual_dest_3_2(cache, delegated, pos).await self.actual_dest_3_2(cache, delegated, pos).await
} else { } else {
trace!("Delegated hostname has no port in this branch"); trace!("Delegated hostname has no port in this branch");
match self.query_srv_record(&delegated).await? { match self.query_srv_record(delegated).await? {
| Some(overrider) => | Some(overrider) =>
self.actual_dest_3_3(cache, delegated, overrider) self.actual_dest_3_3(cache, delegated, overrider)
.await, .await,
@@ -162,19 +163,14 @@ impl super::Service {
Ok(host_and_port) Ok(host_and_port)
} }
async fn actual_dest_3_2( async fn actual_dest_3_2(&self, cache: bool, delegated: &str, pos: usize) -> Result<FedDest> {
&self,
cache: bool,
delegated: String,
pos: usize,
) -> Result<FedDest> {
debug!("3.2: Hostname with port in .well-known file"); debug!("3.2: Hostname with port in .well-known file");
let (host, port) = delegated.split_at(pos); let (host, port) = delegated.split_at(pos);
self.conditional_query_and_cache(host, port.parse::<u16>().unwrap_or(8448), cache) self.conditional_query_and_cache(host, port.parse::<u16>().unwrap_or(8448), cache)
.await?; .await?;
Ok(FedDest::Named( Ok(FedDest::Named(
host.to_owned(), host.into(),
port.try_into() port.try_into()
.unwrap_or_else(|_| FedDest::default_port()), .unwrap_or_else(|_| FedDest::default_port()),
)) ))
@@ -183,13 +179,13 @@ impl super::Service {
async fn actual_dest_3_3( async fn actual_dest_3_3(
&self, &self,
cache: bool, cache: bool,
delegated: String, delegated: &str,
overrider: FedDest, overrider: FedDest,
) -> Result<FedDest> { ) -> Result<FedDest> {
debug!("3.3: SRV lookup successful"); debug!("3.3: SRV lookup successful");
let force_port = overrider.port(); let force_port = overrider.port();
self.conditional_query_and_cache_override( self.conditional_query_and_cache_override(
&delegated, delegated,
&overrider.hostname(), &overrider.hostname(),
force_port.unwrap_or(8448), force_port.unwrap_or(8448),
cache, cache,
@@ -198,7 +194,7 @@ impl super::Service {
if let Some(port) = force_port { if let Some(port) = force_port {
return Ok(FedDest::Named( return Ok(FedDest::Named(
delegated, delegated.into(),
format!(":{port}") format!(":{port}")
.as_str() .as_str()
.try_into() .try_into()
@@ -206,14 +202,15 @@ impl super::Service {
)); ));
} }
Ok(add_port_to_hostname(&delegated)) Ok(add_port_to_hostname(delegated))
} }
async fn actual_dest_3_4(&self, cache: bool, delegated: String) -> Result<FedDest> { async fn actual_dest_3_4(&self, cache: bool, delegated: &str) -> Result<FedDest> {
debug!("3.4: No SRV records, just use the hostname from .well-known"); debug!("3.4: No SRV records, just use the hostname from .well-known");
self.conditional_query_and_cache(&delegated, 8448, cache) self.conditional_query_and_cache(delegated, 8448, cache)
.await?; .await?;
Ok(add_port_to_hostname(&delegated))
Ok(add_port_to_hostname(delegated))
} }
async fn actual_dest_4( async fn actual_dest_4(
@@ -234,9 +231,8 @@ impl super::Service {
if let Some(port) = force_port { if let Some(port) = force_port {
let port = format!(":{port}"); let port = format!(":{port}");
return Ok(FedDest::Named( return Ok(FedDest::Named(
host.to_owned(), host.into(),
PortString::from(port.as_str()).unwrap_or_else(|_| FedDest::default_port()), PortString::from(port.as_str()).unwrap_or_else(|_| FedDest::default_port()),
)); ));
} }
@@ -334,7 +330,7 @@ impl super::Service {
.target() .target()
.to_string() .to_string()
.trim_end_matches('.') .trim_end_matches('.')
.to_owned(), .into(),
format!(":{}", result.port()) format!(":{}", result.port())
.as_str() .as_str()
.try_into() .try_into()

View File

@@ -11,7 +11,7 @@ use tuwunel_core::{
}; };
use tuwunel_database::{Cbor, Deserialized, Map}; use tuwunel_database::{Cbor, Deserialized, Map};
use super::fed::FedDest; use super::{DestString, FedDest};
pub struct Cache { pub struct Cache {
destinations: Arc<Map>, destinations: Arc<Map>,
@@ -21,7 +21,7 @@ pub struct Cache {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CachedDest { pub struct CachedDest {
pub dest: FedDest, pub dest: FedDest,
pub host: String, pub host: DestString,
pub expire: SystemTime, pub expire: SystemTime,
} }
@@ -30,7 +30,7 @@ pub struct CachedOverride {
pub ips: IpAddrs, pub ips: IpAddrs,
pub port: u16, pub port: u16,
pub expire: SystemTime, pub expire: SystemTime,
pub overriding: Option<String>, pub overriding: Option<DestString>,
} }
pub type IpAddrs = ArrayVec<IpAddr, MAX_IPS>; pub type IpAddrs = ArrayVec<IpAddr, MAX_IPS>;

View File

@@ -1,20 +1,24 @@
use std::{ use std::{
borrow::Cow,
fmt, fmt,
net::{IpAddr, SocketAddr}, net::{IpAddr, SocketAddr},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tuwunel_core::{arrayvec::ArrayString, utils::math::Expected}; use tuwunel_core::{arrayvec::ArrayString, smallstr::SmallString, utils::math::Expected};
use super::DestString;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum FedDest { pub enum FedDest {
Literal(SocketAddr), Literal(SocketAddr),
Named(String, PortString), Named(HostString, PortString),
} }
/// numeric or service-name /// FedDest::Named host domain
pub type PortString = ArrayString<16>; pub(super) type HostString = SmallString<[u8; 32]>;
/// FedDest::Named numeric or service-name
pub(super) type PortString = ArrayString<16>;
const DEFAULT_PORT: &str = ":8448"; const DEFAULT_PORT: &str = ":8448";
@@ -35,31 +39,31 @@ pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
}; };
FedDest::Named( FedDest::Named(
host.to_owned(), host.into(),
PortString::from(port).unwrap_or_else(|_| FedDest::default_port()), PortString::from(port).unwrap_or_else(|_| FedDest::default_port()),
) )
} }
impl FedDest { impl FedDest {
pub(crate) fn https_string(&self) -> String { pub(crate) fn https_string(&self) -> DestString {
match self { match self {
| Self::Literal(addr) => format!("https://{addr}"), | Self::Literal(addr) => format!("https://{addr}").into(),
| Self::Named(host, port) => format!("https://{host}{port}"), | Self::Named(host, port) => format!("https://{host}{port}").into(),
} }
} }
pub(crate) fn uri_string(&self) -> String { pub(crate) fn uri_string(&self) -> DestString {
match self { match self {
| Self::Literal(addr) => addr.to_string(), | Self::Literal(addr) => addr.to_string().into(),
| Self::Named(host, port) => format!("{host}{port}"), | Self::Named(host, port) => [host.as_str(), port.as_str()].concat().into(),
} }
} }
#[inline] #[inline]
pub(crate) fn hostname(&self) -> Cow<'_, str> { pub(crate) fn hostname(&self) -> HostString {
match &self { match &self {
| Self::Literal(addr) => addr.ip().to_string().into(), | Self::Literal(addr) => addr.ip().to_string().into(),
| Self::Named(host, _) => host.into(), | Self::Named(host, _) => host.clone(),
} }
} }

View File

@@ -9,9 +9,9 @@ mod well_known;
use std::sync::Arc; use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use tuwunel_core::{Result, arrayvec::ArrayString, utils::MutexMap}; use tuwunel_core::{Result, arrayvec::ArrayString, smallstr::SmallString, utils::MutexMap};
use self::{cache::Cache, dns::Resolver}; use self::{cache::Cache, dns::Resolver, fed::FedDest};
pub struct Service { pub struct Service {
pub cache: Arc<Cache>, pub cache: Arc<Cache>,
@@ -20,6 +20,7 @@ pub struct Service {
services: Arc<crate::services::OnceServices>, services: Arc<crate::services::OnceServices>,
} }
pub(crate) type DestString = SmallString<[u8; 40]>;
type Resolving = MutexMap<NameBuf, ()>; type Resolving = MutexMap<NameBuf, ()>;
type NameBuf = ArrayString<256>; type NameBuf = ArrayString<256>;

View File

@@ -28,7 +28,7 @@ fn ips_keep_custom_ports() {
fn hostnames_get_default_ports() { fn hostnames_get_default_ports() {
assert_eq!( assert_eq!(
add_port_to_hostname("example.com"), add_port_to_hostname("example.com"),
FedDest::Named(String::from("example.com"), ":8448".try_into().unwrap()) FedDest::Named("example.com".into(), ":8448".try_into().unwrap())
); );
} }
@@ -36,6 +36,6 @@ fn hostnames_get_default_ports() {
fn hostnames_keep_custom_ports() { fn hostnames_keep_custom_ports() {
assert_eq!( assert_eq!(
add_port_to_hostname("example.com:1337"), add_port_to_hostname("example.com:1337"),
FedDest::Named(String::from("example.com"), ":1337".try_into().unwrap()) FedDest::Named("example.com".into(), ":1337".try_into().unwrap())
); );
} }

View File

@@ -1,8 +1,10 @@
use tuwunel_core::{Result, debug, debug_error, debug_info, debug_warn, implement, trace}; use tuwunel_core::{Result, debug, debug_error, debug_info, debug_warn, implement, trace};
use super::DestString;
#[implement(super::Service)] #[implement(super::Service)]
#[tracing::instrument(name = "well-known", level = "debug", skip(self, dest))] #[tracing::instrument(name = "well-known", level = "debug", skip(self, dest))]
pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<String>> { pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<DestString>> {
trace!("Requesting well known for {dest}"); trace!("Requesting well known for {dest}");
let response = self let response = self
.services .services
@@ -45,5 +47,5 @@ pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<Strin
} }
debug_info!("{dest:?} found at {m_server:?}"); debug_info!("{dest:?} found at {m_server:?}");
Ok(Some(m_server.to_owned())) Ok(Some(m_server.into()))
} }