use std::net::SocketAddr;
use hickory_resolver::{
TokioResolver,
config::{LookupIpStrategy, ResolverConfig},
net::runtime::TokioRuntimeProvider,
};
use super::{Addrs, Name, Resolve, Resolving};
#[derive(Debug, Clone)]
pub struct HickoryDnsResolver {
resolver: TokioResolver,
}
impl HickoryDnsResolver {
pub fn new() -> crate::Result<HickoryDnsResolver> {
let mut builder = match TokioResolver::builder_tokio() {
Ok(resolver) => {
debug!("using system DNS configuration");
resolver
}
Err(_err) => {
debug!("error reading DNS system conf: {_err}, using defaults");
TokioResolver::builder_with_config(
ResolverConfig::default(),
TokioRuntimeProvider::default(),
)
}
};
builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
let resolver = builder.build().map_err(crate::Error::builder)?;
Ok(HickoryDnsResolver { resolver })
}
}
impl Resolve for HickoryDnsResolver {
fn resolve(&self, name: Name) -> Resolving {
let resolver = self.clone();
Box::pin(async move {
let lookup = resolver.resolver.lookup_ip(name.as_str()).await?;
let addrs: Addrs = Box::new(
lookup
.iter()
.map(|ip_addr| SocketAddr::new(ip_addr, 0))
.collect::<Vec<_>>()
.into_iter(),
);
Ok(addrs)
})
}
}