From 21874f8ab77f23611d1c3025c79c4025b0a1a2a5 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sun, 24 Mar 2024 23:52:31 -0700 Subject: [PATCH] eliminate gai resolver. Signed-off-by: Jason Volk --- src/service/globals/client.rs | 21 ++++++-- src/service/globals/resolver.rs | 89 ++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/src/service/globals/client.rs b/src/service/globals/client.rs index 0d05efa1..c3c098d8 100644 --- a/src/service/globals/client.rs +++ b/src/service/globals/client.rs @@ -17,13 +17,22 @@ pub struct Client { impl Client { pub fn new(config: &Config, resolver: &Arc) -> 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) .unwrap() - .dns_resolver(resolver.clone()) + .dns_resolver(resolver.hooked.clone()) .connect_timeout(Duration::from_secs(config.well_known_conn_timeout)) .timeout(Duration::from_secs(config.well_known_timeout)) .pool_max_idle_per_host(0) @@ -33,7 +42,7 @@ impl Client { federation: Self::base(config) .unwrap() - .dns_resolver(resolver.clone()) + .dns_resolver(resolver.hooked.clone()) .timeout(Duration::from_secs(config.federation_timeout)) .pool_max_idle_per_host(config.federation_idle_per_host.into()) .pool_idle_timeout(Duration::from_secs(config.federation_idle_timeout)) @@ -43,7 +52,7 @@ impl Client { sender: Self::base(config) .unwrap() - .dns_resolver(resolver.clone()) + .dns_resolver(resolver.hooked.clone()) .timeout(Duration::from_secs(config.sender_timeout)) .pool_max_idle_per_host(1) .pool_idle_timeout(Duration::from_secs(config.sender_idle_timeout)) @@ -53,6 +62,7 @@ impl Client { appservice: Self::base(config) .unwrap() + .dns_resolver(resolver.clone()) .connect_timeout(Duration::from_secs(5)) .timeout(Duration::from_secs(config.appservice_timeout)) .pool_max_idle_per_host(1) @@ -63,6 +73,7 @@ impl Client { pusher: Self::base(config) .unwrap() + .dns_resolver(resolver.clone()) .pool_max_idle_per_host(1) .pool_idle_timeout(Duration::from_secs(config.pusher_idle_timeout)) .redirect(redirect::Policy::limited(2)) diff --git a/src/service/globals/resolver.rs b/src/service/globals/resolver.rs index a8f90894..1745c931 100644 --- a/src/service/globals/resolver.rs +++ b/src/service/globals/resolver.rs @@ -1,18 +1,12 @@ use std::{ collections::HashMap, - error::Error as StdError, - future::{self}, - iter, + future, iter, net::{IpAddr, SocketAddr}, sync::{Arc, RwLock as StdRwLock}, }; -use futures_util::FutureExt; use hickory_resolver::TokioAsyncResolver; -use hyper::{ - client::connect::dns::{GaiResolver, Name}, - service::Service as HyperService, -}; +use hyper::client::connect::dns::Name; use reqwest::dns::{Addrs, Resolve, Resolving}; use ruma::OwnedServerName; use tokio::sync::RwLock; @@ -24,49 +18,74 @@ pub type WellKnownMap = HashMap; pub type TlsNameMap = HashMap, u16)>; pub struct Resolver { - inner: GaiResolver, - pub overrides: Arc>, pub destinations: Arc>, // actual_destination, host - pub resolver: TokioAsyncResolver, + pub overrides: Arc>, + pub resolver: Arc, + pub hooked: Arc, +} + +pub struct Hooked { + pub overrides: Arc>, + pub resolver: Arc, } impl Resolver { 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 { - inner: GaiResolver::new(), - overrides: Arc::new(StdRwLock::new(TlsNameMap::new())), destinations: Arc::new(RwLock::new(WellKnownMap::new())), - resolver: 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(), + overrides: overrides.clone(), + resolver: resolver.clone(), + hooked: Arc::new(Hooked { + overrides, + 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 { self.overrides .read() .unwrap() .get(name.as_str()) - .and_then(|(override_name, port)| { - override_name.first().map(|first_name| { - let x: Box + 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::::call(this, name).map(|result| { - result - .map(|addrs| -> Addrs { Box::new(addrs) }) - .map_err(|err| -> Box { Box::new(err) }) - })) - }) + .map(|(override_name, port)| cached_to_reqwest(override_name, *port)) + .unwrap_or_else(|| resolve_to_reqwest(self.resolver.clone(), name)) } } + +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 + Send> = Box::new(iter::once(saddr)); + Box::pin(future::ready(Ok(result))) + }) + .unwrap() +} + +fn resolve_to_reqwest(resolver: Arc, 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) + }) +}