Add config option for dns passthru for appservices. (#158)

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-09-10 01:01:00 +00:00
parent a9f1926654
commit bf8aa57d03
4 changed files with 41 additions and 5 deletions

View File

@@ -378,6 +378,13 @@ pub struct Config {
#[serde(default, with = "serde_regex")]
pub dns_passthru_domains: RegexSet,
/// Whether to resolve appservices via the alternative path; setting this is
/// superior to providing domains in `dns_passthru_domains` if all
/// appservices intend to be matched anyway. The overhead of matching regex
/// and maintaining the list of domains can be avoided.
#[serde(default)]
pub dns_passthru_appservices: bool,
/// Max request size for file uploads in bytes. Defaults to 20MB.
///
/// default: 20971520

View File

@@ -5,7 +5,7 @@ use std::{
use either::Either;
use ipaddress::IPAddress;
use reqwest::redirect;
use reqwest::{dns::Resolve, redirect};
use tuwunel_core::{Config, Result, err, implement, trace};
use crate::{service, services::OnceServices};
@@ -98,7 +98,7 @@ impl crate::Service for Service {
.redirect(redirect::Policy::limited(2))),
appservice: create_client!(config, services; base(config)?
.dns_resolver2(Arc::clone(&services.resolver.resolver))
.dns_resolver2(appservice_resolver(&services))
.connect_timeout(Duration::from_secs(5))
.read_timeout(Duration::from_secs(config.appservice_timeout))
.timeout(Duration::from_secs(config.appservice_timeout))
@@ -220,6 +220,14 @@ fn builder_interface(
}
}
fn appservice_resolver(services: &Arc<OnceServices>) -> Arc<dyn Resolve> {
if services.server.config.dns_passthru_appservices {
services.resolver.resolver.passthru.clone()
} else {
services.resolver.resolver.clone()
}
}
#[inline]
#[must_use]
#[implement(Service)]

View File

@@ -13,7 +13,7 @@ use super::cache::{Cache, CachedOverride};
pub struct Resolver {
pub(crate) resolver: Arc<TokioResolver>,
pub(crate) passthru: Arc<TokioResolver>,
pub(crate) passthru: Arc<Passthru>,
pub(crate) hooked: Arc<Hooked>,
server: Arc<Server>,
}
@@ -24,6 +24,11 @@ pub(crate) struct Hooked {
server: Arc<Server>,
}
pub(crate) struct Passthru {
resolver: Arc<TokioResolver>,
server: Arc<Server>,
}
type ResolvingResult = Result<Addrs, Box<dyn std::error::Error + Send + Sync>>;
impl Resolver {
@@ -47,9 +52,12 @@ impl Resolver {
resolver: resolver.clone(),
cache,
}),
passthru: Arc::new(Passthru {
server: server.clone(),
resolver: passthru,
}),
server: server.clone(),
resolver,
passthru,
}))
}
@@ -137,7 +145,7 @@ impl Resolve for Resolver {
.dns_passthru_domains
.is_match(name.as_str())
{
&self.passthru
&self.passthru.resolver
} else {
&self.resolver
};
@@ -146,6 +154,12 @@ impl Resolve for Resolver {
}
}
impl Resolve for Passthru {
fn resolve(&self, name: Name) -> Resolving {
resolve_to_reqwest(self.server.clone(), self.resolver.clone(), name).boxed()
}
}
impl Resolve for Hooked {
fn resolve(&self, name: Name) -> Resolving {
hooked_resolve(self.cache.clone(), self.server.clone(), self.resolver.clone(), name)

View File

@@ -295,6 +295,13 @@
#
#dns_passthru_domains = []
# Whether to resolve appservices via the alternative path; setting this is
# superior to providing domains in `dns_passthru_domains` if all
# appservices intend to be matched anyway. The overhead of matching regex
# and maintaining the list of domains can be avoided.
#
#dns_passthru_appservices = false
# Max request size for file uploads in bytes. Defaults to 20MB.
#
#max_request_size = 20971520