use crate::{LookupService, ServiceDefinition};
use hickory_resolver::TokioResolver;
use std::{collections::HashSet, net::SocketAddr};
pub struct DnsResolver {
dns: TokioResolver,
}
impl DnsResolver {
pub async fn from_system_config() -> Result<Self, anyhow::Error> {
let mut builder = TokioResolver::builder_tokio()?;
let opts = builder.options_mut();
opts.cache_size = 0;
Ok(Self {
dns: builder.build()?,
})
}
}
#[async_trait::async_trait]
impl LookupService for DnsResolver {
#[tracing::instrument(level = "debug", skip(self))]
async fn resolve_service_endpoints(
&self,
definition: &ServiceDefinition,
) -> Result<HashSet<SocketAddr>, anyhow::Error> {
match self.dns.lookup_ip(definition.hostname()).await {
Ok(lookup) => {
tracing::debug!("dns query expires in: {:?}", lookup.valid_until());
Ok(lookup
.iter()
.map(|ip_addr| {
tracing::debug!("result: ip {}", ip_addr);
(ip_addr, definition.port()).into()
})
.collect())
}
Err(err) => Err(err.into()),
}
}
}