Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions src/dns/hickory.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! DNS resolution via the [hickory-resolver](https://github.com/hickory-dns/hickory-dns) crate

use hickory_resolver::{
config::LookupIpStrategy, lookup_ip::LookupIpIntoIter, ResolveError, TokioResolver,
config::{LookupIpStrategy, ResolverConfig},
lookup_ip::LookupIpIntoIter,
name_server::TokioConnectionProvider,
TokioResolver,
};
use once_cell::sync::OnceCell;

use std::fmt;
use std::net::SocketAddr;
use std::sync::Arc;

Expand All @@ -24,14 +26,11 @@ struct SocketAddrs {
iter: LookupIpIntoIter,
}

#[derive(Debug)]
struct HickoryDnsSystemConfError(ResolveError);

impl Resolve for HickoryDnsResolver {
fn resolve(&self, name: Name) -> Resolving {
let resolver = self.clone();
Box::pin(async move {
let resolver = resolver.state.get_or_try_init(new_resolver)?;
let resolver = resolver.state.get_or_init(new_resolver);

let lookup = resolver.lookup_ip(name.as_str()).await?;
let addrs: Addrs = Box::new(SocketAddrs {
Expand All @@ -51,23 +50,17 @@ impl Iterator for SocketAddrs {
}

/// Create a new resolver with the default configuration,
/// which reads from `/etc/resolve.conf`. The options are
/// overridden to look up for both IPv4 and IPv6 addresses
/// which reads from `/etc/resolve.conf`. If reading `/etc/resolv.conf` fails,
/// it fallbacks to hickory_resolver's default config.
/// The options are overridden to look up for both IPv4 and IPv6 addresses
/// to work with "happy eyeballs" algorithm.
fn new_resolver() -> Result<TokioResolver, HickoryDnsSystemConfError> {
let mut builder = TokioResolver::builder_tokio().map_err(HickoryDnsSystemConfError)?;
fn new_resolver() -> TokioResolver {
let mut builder = TokioResolver::builder_tokio().unwrap_or_else(|_| {
TokioResolver::builder_with_config(
ResolverConfig::default(),
TokioConnectionProvider::default(),
)
});
builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
Ok(builder.build())
}

impl fmt::Display for HickoryDnsSystemConfError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("error reading DNS system conf for hickory-dns")
}
}

impl std::error::Error for HickoryDnsSystemConfError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.0)
}
builder.build()
}