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

@ -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<OwnedServerName, (FedDest, String)>;
pub type TlsNameMap = HashMap<String, (Vec<IpAddr>, u16)>;
pub struct Resolver {
inner: GaiResolver,
pub overrides: Arc<StdRwLock<TlsNameMap>>,
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 {
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<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) })
}))
})
.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<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)
})
}