eliminate gai resolver.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-03-24 23:52:31 -07:00 committed by June
parent f5da75e476
commit 21874f8ab7
2 changed files with 70 additions and 40 deletions

View File

@ -17,13 +17,22 @@ pub struct Client {
impl Client { impl Client {
pub fn new(config: &Config, resolver: &Arc<resolver::Resolver>) -> Client { pub fn new(config: &Config, resolver: &Arc<resolver::Resolver>) -> Client {
Client { Client {
default: Self::base(config).unwrap().build().unwrap(), default: Self::base(config)
.unwrap()
.dns_resolver(resolver.clone())
.build()
.unwrap(),
url_preview: Self::base(config).unwrap().redirect(redirect::Policy::limited(3)).build().unwrap(), url_preview: Self::base(config)
.unwrap()
.dns_resolver(resolver.clone())
.redirect(redirect::Policy::limited(3))
.build()
.unwrap(),
well_known: Self::base(config) well_known: Self::base(config)
.unwrap() .unwrap()
.dns_resolver(resolver.clone()) .dns_resolver(resolver.hooked.clone())
.connect_timeout(Duration::from_secs(config.well_known_conn_timeout)) .connect_timeout(Duration::from_secs(config.well_known_conn_timeout))
.timeout(Duration::from_secs(config.well_known_timeout)) .timeout(Duration::from_secs(config.well_known_timeout))
.pool_max_idle_per_host(0) .pool_max_idle_per_host(0)
@ -33,7 +42,7 @@ impl Client {
federation: Self::base(config) federation: Self::base(config)
.unwrap() .unwrap()
.dns_resolver(resolver.clone()) .dns_resolver(resolver.hooked.clone())
.timeout(Duration::from_secs(config.federation_timeout)) .timeout(Duration::from_secs(config.federation_timeout))
.pool_max_idle_per_host(config.federation_idle_per_host.into()) .pool_max_idle_per_host(config.federation_idle_per_host.into())
.pool_idle_timeout(Duration::from_secs(config.federation_idle_timeout)) .pool_idle_timeout(Duration::from_secs(config.federation_idle_timeout))
@ -43,7 +52,7 @@ impl Client {
sender: Self::base(config) sender: Self::base(config)
.unwrap() .unwrap()
.dns_resolver(resolver.clone()) .dns_resolver(resolver.hooked.clone())
.timeout(Duration::from_secs(config.sender_timeout)) .timeout(Duration::from_secs(config.sender_timeout))
.pool_max_idle_per_host(1) .pool_max_idle_per_host(1)
.pool_idle_timeout(Duration::from_secs(config.sender_idle_timeout)) .pool_idle_timeout(Duration::from_secs(config.sender_idle_timeout))
@ -53,6 +62,7 @@ impl Client {
appservice: Self::base(config) appservice: Self::base(config)
.unwrap() .unwrap()
.dns_resolver(resolver.clone())
.connect_timeout(Duration::from_secs(5)) .connect_timeout(Duration::from_secs(5))
.timeout(Duration::from_secs(config.appservice_timeout)) .timeout(Duration::from_secs(config.appservice_timeout))
.pool_max_idle_per_host(1) .pool_max_idle_per_host(1)
@ -63,6 +73,7 @@ impl Client {
pusher: Self::base(config) pusher: Self::base(config)
.unwrap() .unwrap()
.dns_resolver(resolver.clone())
.pool_max_idle_per_host(1) .pool_max_idle_per_host(1)
.pool_idle_timeout(Duration::from_secs(config.pusher_idle_timeout)) .pool_idle_timeout(Duration::from_secs(config.pusher_idle_timeout))
.redirect(redirect::Policy::limited(2)) .redirect(redirect::Policy::limited(2))

View File

@ -1,18 +1,12 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
error::Error as StdError, future, iter,
future::{self},
iter,
net::{IpAddr, SocketAddr}, net::{IpAddr, SocketAddr},
sync::{Arc, RwLock as StdRwLock}, sync::{Arc, RwLock as StdRwLock},
}; };
use futures_util::FutureExt;
use hickory_resolver::TokioAsyncResolver; use hickory_resolver::TokioAsyncResolver;
use hyper::{ use hyper::client::connect::dns::Name;
client::connect::dns::{GaiResolver, Name},
service::Service as HyperService,
};
use reqwest::dns::{Addrs, Resolve, Resolving}; use reqwest::dns::{Addrs, Resolve, Resolving};
use ruma::OwnedServerName; use ruma::OwnedServerName;
use tokio::sync::RwLock; use tokio::sync::RwLock;
@ -24,49 +18,74 @@ pub type WellKnownMap = HashMap<OwnedServerName, (FedDest, String)>;
pub type TlsNameMap = HashMap<String, (Vec<IpAddr>, u16)>; pub type TlsNameMap = HashMap<String, (Vec<IpAddr>, u16)>;
pub struct Resolver { pub struct Resolver {
inner: GaiResolver,
pub overrides: Arc<StdRwLock<TlsNameMap>>,
pub destinations: Arc<RwLock<WellKnownMap>>, // actual_destination, host pub destinations: Arc<RwLock<WellKnownMap>>, // actual_destination, host
pub resolver: TokioAsyncResolver, pub overrides: Arc<StdRwLock<TlsNameMap>>,
pub resolver: Arc<TokioAsyncResolver>,
pub hooked: Arc<Hooked>,
}
pub struct Hooked {
pub overrides: Arc<StdRwLock<TlsNameMap>>,
pub resolver: Arc<TokioAsyncResolver>,
} }
impl Resolver { impl Resolver {
pub(crate) fn new(_config: &Config) -> Self { pub(crate) fn new(_config: &Config) -> Self {
let overrides = Arc::new(StdRwLock::new(TlsNameMap::new()));
let resolver = Arc::new(TokioAsyncResolver::tokio_from_system_conf().map_err(|e| {
error!("Failed to set up trust dns resolver with system config: {}", e);
Error::bad_config("Failed to set up trust dns resolver with system config.")
})
.unwrap());
Resolver { Resolver {
inner: GaiResolver::new(),
overrides: Arc::new(StdRwLock::new(TlsNameMap::new())),
destinations: Arc::new(RwLock::new(WellKnownMap::new())), destinations: Arc::new(RwLock::new(WellKnownMap::new())),
resolver: TokioAsyncResolver::tokio_from_system_conf() overrides: overrides.clone(),
.map_err(|e| { resolver: resolver.clone(),
error!("Failed to set up trust dns resolver with system config: {}", e); hooked: Arc::new(Hooked {
Error::bad_config("Failed to set up trust dns resolver with system config.") overrides,
}) resolver,
.unwrap(), }),
} }
} }
} }
impl Resolve for Resolver { impl Resolve for Resolver {
fn resolve(&self, name: Name) -> Resolving {
resolve_to_reqwest(self.resolver.clone(), name)
}
}
impl Resolve for Hooked {
fn resolve(&self, name: Name) -> Resolving { fn resolve(&self, name: Name) -> Resolving {
self.overrides self.overrides
.read() .read()
.unwrap() .unwrap()
.get(name.as_str()) .get(name.as_str())
.and_then(|(override_name, port)| { .map(|(override_name, port)| cached_to_reqwest(override_name, *port))
override_name.first().map(|first_name| { .unwrap_or_else(|| resolve_to_reqwest(self.resolver.clone(), name))
let x: Box<dyn Iterator<Item = SocketAddr> + Send> =
Box::new(iter::once(SocketAddr::new(*first_name, *port)));
let x: Resolving = Box::pin(future::ready(Ok(x)));
x
})
})
.unwrap_or_else(|| {
let this = &mut self.inner.clone();
Box::pin(HyperService::<Name>::call(this, name).map(|result| {
result
.map(|addrs| -> Addrs { Box::new(addrs) })
.map_err(|err| -> Box<dyn StdError + Send + Sync> { Box::new(err) })
}))
})
} }
} }
fn cached_to_reqwest(override_name: &[IpAddr], port: u16) -> Resolving {
override_name
.first()
.map(|first_name| -> Resolving {
let saddr = SocketAddr::new(*first_name, port);
let result: Box<dyn Iterator<Item = SocketAddr> + Send> = Box::new(iter::once(saddr));
Box::pin(future::ready(Ok(result)))
})
.unwrap()
}
fn resolve_to_reqwest(resolver: Arc<TokioAsyncResolver>, name: Name) -> Resolving {
Box::pin(async move {
let results = resolver
.lookup_ip(name.as_str())
.await?
.into_iter()
.map(|ip| SocketAddr::new(ip, 0));
Ok(Box::new(results) as Addrs)
})
}