Skip to content

Commit e441048

Browse files
authored
refactor(dns): make hickory module internal (#881)
1 parent 05c6db4 commit e441048

3 files changed

Lines changed: 36 additions & 66 deletions

File tree

src/client/http/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use super::{
5151
response::Response,
5252
};
5353
#[cfg(feature = "hickory-dns")]
54-
use crate::dns::hickory::{HickoryDnsResolver, LookupIpStrategy};
54+
use crate::dns::hickory::HickoryDnsResolver;
5555
use crate::{
5656
IntoUrl, Method, Proxy,
5757
client::{
@@ -254,9 +254,7 @@ impl ClientBuilder {
254254
let mut resolver: Arc<dyn Resolve> = match config.dns_resolver {
255255
Some(dns_resolver) => dns_resolver,
256256
#[cfg(feature = "hickory-dns")]
257-
None if config.hickory_dns => {
258-
Arc::new(HickoryDnsResolver::new(LookupIpStrategy::Ipv4thenIpv6)?)
259-
}
257+
None if config.hickory_dns => Arc::new(HickoryDnsResolver::new()),
260258
None => Arc::new(GaiResolver::new()),
261259
};
262260

src/core/client/connect/dns/hickory.rs

Lines changed: 31 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,54 @@
11
//! DNS resolution via the [hickory-resolver](https://github.com/hickory-dns/hickory-dns) crate
22
3-
use std::{net::SocketAddr, sync::Arc};
3+
use std::{net::SocketAddr, sync::LazyLock};
44

55
use hickory_resolver::{
66
TokioResolver,
7-
config::{LookupIpStrategy as HickoryLookupIpStrategy, ResolverConfig},
7+
config::{LookupIpStrategy, ResolverConfig},
88
lookup_ip::LookupIpIntoIter,
99
name_server::TokioConnectionProvider,
1010
};
1111

1212
use super::{Addrs, Name, Resolve, Resolving};
1313

14-
/// The lookup ip strategy
15-
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
16-
#[repr(u8)]
17-
pub enum LookupIpStrategy {
18-
/// Only query for A (Ipv4) records
19-
Ipv4Only,
20-
/// Only query for AAAA (Ipv6) records
21-
Ipv6Only,
22-
/// Query for A and AAAA in parallel
23-
#[default]
24-
Ipv4AndIpv6,
25-
/// Query for Ipv6 if that fails, query for Ipv4
26-
Ipv6thenIpv4,
27-
/// Query for Ipv4 if that fails, query for Ipv6
28-
Ipv4thenIpv6,
29-
}
30-
31-
impl LookupIpStrategy {
32-
const fn to_hickory(self) -> HickoryLookupIpStrategy {
33-
match self {
34-
LookupIpStrategy::Ipv4Only => HickoryLookupIpStrategy::Ipv4Only,
35-
LookupIpStrategy::Ipv6Only => HickoryLookupIpStrategy::Ipv6Only,
36-
LookupIpStrategy::Ipv4AndIpv6 => HickoryLookupIpStrategy::Ipv4AndIpv6,
37-
LookupIpStrategy::Ipv6thenIpv4 => HickoryLookupIpStrategy::Ipv6thenIpv4,
38-
LookupIpStrategy::Ipv4thenIpv6 => HickoryLookupIpStrategy::Ipv4thenIpv6,
39-
}
40-
}
41-
}
42-
43-
/// Wrapper around an `AsyncResolver`, which implements the `Resolve` trait.
14+
/// Wrapper around an [`TokioResolver`], which implements the `Resolve` trait.
4415
#[derive(Debug, Clone)]
4516
pub struct HickoryDnsResolver {
46-
/// Since we might not have been called in the context of a
47-
/// Tokio Runtime in initialization, so we must delay the actual
48-
/// construction of the resolver.
49-
state: Arc<TokioResolver>,
17+
/// Shared, lazily-initialized Tokio-based DNS resolver.
18+
///
19+
/// Backed by [`LazyLock`] to guarantee thread-safe, one-time creation.
20+
/// On initialization, it attempts to load the system's DNS configuration;
21+
/// if unavailable, it falls back to sensible default settings.
22+
resolver: &'static LazyLock<TokioResolver>,
5023
}
5124

5225
impl HickoryDnsResolver {
5326
/// Create a new resolver with the default configuration,
5427
/// which reads from `/etc/resolve.conf`. The options are
5528
/// overriden to look up for both IPv4 and IPv6 addresses
5629
/// to work with "happy eyeballs" algorithm.
57-
pub fn new<S>(strategy: S) -> crate::Result<Self>
58-
where
59-
S: Into<Option<LookupIpStrategy>>,
60-
{
61-
let mut resolver = match TokioResolver::builder_tokio() {
62-
Ok(resolver) => resolver,
63-
Err(_err) => {
64-
debug!("error reading DNS system conf: {}", _err);
65-
TokioResolver::builder_with_config(
66-
ResolverConfig::default(),
67-
TokioConnectionProvider::default(),
68-
)
69-
}
70-
};
71-
72-
resolver.options_mut().ip_strategy = strategy
73-
.into()
74-
.map(LookupIpStrategy::to_hickory)
75-
.unwrap_or_default();
30+
pub fn new() -> HickoryDnsResolver {
31+
static RESOLVER: LazyLock<TokioResolver> = LazyLock::new(|| {
32+
let mut builder = match TokioResolver::builder_tokio() {
33+
Ok(resolver) => {
34+
debug!("using system DNS configuration");
35+
resolver
36+
}
37+
Err(_err) => {
38+
debug!("error reading DNS system conf: {}, using defaults", _err);
39+
TokioResolver::builder_with_config(
40+
ResolverConfig::default(),
41+
TokioConnectionProvider::default(),
42+
)
43+
}
44+
};
45+
builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
46+
builder.build()
47+
});
7648

77-
Ok(Self {
78-
state: Arc::new(resolver.build()),
79-
})
49+
HickoryDnsResolver {
50+
resolver: &RESOLVER,
51+
}
8052
}
8153
}
8254

@@ -88,7 +60,7 @@ impl Resolve for HickoryDnsResolver {
8860
fn resolve(&self, name: Name) -> Resolving {
8961
let resolver = self.clone();
9062
Box::pin(async move {
91-
let lookup = resolver.state.lookup_ip(name.as_str()).await?;
63+
let lookup = resolver.resolver.lookup_ip(name.as_str()).await?;
9264
let addrs: Addrs = Box::new(SocketAddrs {
9365
iter: lookup.into_iter(),
9466
});

src/core/client/connect/dns/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! DNS resolution
22
3-
mod gai;
3+
pub(crate) mod gai;
44
#[cfg(feature = "hickory-dns")]
5-
pub mod hickory;
6-
mod resolve;
5+
pub(crate) mod hickory;
6+
pub(crate) mod resolve;
77

88
pub use resolve::{Addrs, Name, Resolve, Resolving};
99

0 commit comments

Comments
 (0)