Migrate to hickory 0.26.1 (#6751)

* Migrate to hickory 0.26.1
This commit is contained in:
Andrej Mihajlov
2026-05-08 20:25:07 +02:00
committed by GitHub
parent e9f6d1d47a
commit b501ddd534
5 changed files with 295 additions and 176 deletions
Generated
+196 -40
View File
@@ -57,7 +57,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
"cpufeatures 0.2.17",
]
[[package]]
@@ -253,7 +253,7 @@ checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
dependencies = [
"base64ct",
"blake2 0.10.6",
"cpufeatures",
"cpufeatures 0.2.17",
"password-hash",
]
@@ -1309,7 +1309,18 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
"cpufeatures 0.2.17",
]
[[package]]
name = "chacha20"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
"cfg-if",
"cpufeatures 0.3.0",
"rand_core 0.10.1",
]
[[package]]
@@ -1319,7 +1330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
"aead",
"chacha20",
"chacha20 0.9.1",
"cipher",
"poly1305",
"zeroize",
@@ -1831,6 +1842,15 @@ dependencies = [
"libc",
]
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "3.3.0"
@@ -2095,7 +2115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"curve25519-dalek-derive",
"digest 0.10.7",
"fiat-crypto",
@@ -2799,18 +2819,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "enum-as-inner"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]]
name = "env_filter"
version = "0.1.3"
@@ -3271,6 +3279,7 @@ dependencies = [
"cfg-if",
"libc",
"r-efi",
"rand_core 0.10.1",
"wasip2",
"wasip3",
]
@@ -3630,26 +3639,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0"
[[package]]
name = "hickory-proto"
version = "0.25.2"
name = "hickory-net"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502"
checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183"
dependencies = [
"async-trait",
"bytes",
"cfg-if",
"data-encoding",
"enum-as-inner",
"futures-channel",
"futures-io",
"futures-util",
"h2 0.4.11",
"hickory-proto",
"http 1.3.1",
"idna",
"ipnet",
"once_cell",
"rand 0.9.2",
"ring",
"jni 0.22.4",
"rand 0.10.1",
"rustls 0.23.37",
"thiserror 2.0.12",
"tinyvec",
@@ -3657,31 +3665,56 @@ dependencies = [
"tokio-rustls 0.26.2",
"tracing",
"url",
"webpki-roots 0.26.11",
"webpki-roots 1.0.2",
]
[[package]]
name = "hickory-proto"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643"
dependencies = [
"data-encoding",
"idna",
"ipnet",
"jni 0.22.4",
"once_cell",
"prefix-trie",
"rand 0.10.1",
"ring",
"thiserror 2.0.12",
"tinyvec",
"tracing",
"url",
]
[[package]]
name = "hickory-resolver"
version = "0.25.2"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a"
checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c"
dependencies = [
"cfg-if",
"futures-util",
"hickory-net",
"hickory-proto",
"ipconfig",
"ipnet",
"jni 0.22.4",
"moka",
"ndk-context",
"once_cell",
"parking_lot",
"rand 0.9.2",
"rand 0.10.1",
"resolv-conf",
"rustls 0.23.37",
"smallvec",
"system-configuration 0.7.0",
"thiserror 2.0.12",
"tokio",
"tokio-rustls 0.26.2",
"tracing",
"webpki-roots 0.26.11",
"webpki-roots 1.0.2",
]
[[package]]
@@ -4409,6 +4442,9 @@ name = "ipnet"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
dependencies = [
"serde",
]
[[package]]
name = "ipnetwork"
@@ -4503,19 +4539,68 @@ dependencies = [
"cesu8",
"cfg-if",
"combine",
"jni-sys",
"jni-sys 0.3.0",
"log",
"thiserror 1.0.69",
"walkdir",
"windows-sys 0.45.0",
]
[[package]]
name = "jni"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
dependencies = [
"cfg-if",
"combine",
"jni-macros",
"jni-sys 0.4.1",
"log",
"simd_cesu8",
"thiserror 2.0.12",
"walkdir",
"windows-link 0.2.1",
]
[[package]]
name = "jni-macros"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
dependencies = [
"proc-macro2",
"quote",
"rustc_version 0.4.1",
"simd_cesu8",
"syn 2.0.106",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jni-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
dependencies = [
"jni-sys-macros",
]
[[package]]
name = "jni-sys-macros"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
"quote",
"syn 2.0.106",
]
[[package]]
name = "jobserver"
version = "0.1.33"
@@ -4582,7 +4667,7 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
dependencies = [
"cpufeatures",
"cpufeatures 0.2.17",
]
[[package]]
@@ -5359,6 +5444,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "ndk-context"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]]
name = "netlink-packet-core"
version = "0.8.1"
@@ -7769,7 +7860,7 @@ name = "nym-outfox"
version = "1.20.4"
dependencies = [
"blake3",
"chacha20",
"chacha20 0.9.1",
"chacha20poly1305",
"fastrand",
"sphinx-packet",
@@ -9451,7 +9542,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [
"cpufeatures",
"cpufeatures 0.2.17",
"opaque-debug 0.3.1",
"universal-hash",
]
@@ -9463,7 +9554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"opaque-debug 0.3.1",
"universal-hash",
]
@@ -9542,6 +9633,17 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "prefix-trie"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90f561214012d3fc240a1f9c817cc4d57f5310910d066069c1b093f766bb5966"
dependencies = [
"either",
"ipnet",
"num-traits",
]
[[package]]
name = "pretty_assertions"
version = "1.4.1"
@@ -9839,6 +9941,17 @@ dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "rand"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [
"chacha20 0.10.0",
"getrandom 0.4.1",
"rand_core 0.10.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@@ -9877,6 +9990,12 @@ dependencies = [
"getrandom 0.3.3",
]
[[package]]
name = "rand_core"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
[[package]]
name = "rand_distr"
version = "0.4.3"
@@ -10006,7 +10125,7 @@ dependencies = [
"serde_json",
"serde_urlencoded",
"sync_wrapper 0.1.2",
"system-configuration",
"system-configuration 0.5.1",
"tokio",
"tokio-rustls 0.24.1",
"tower-service",
@@ -10429,7 +10548,7 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [
"core-foundation 0.10.1",
"core-foundation-sys",
"jni",
"jni 0.21.1",
"log",
"once_cell",
"rustls 0.23.37",
@@ -11016,7 +11135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"digest 0.10.7",
]
@@ -11028,7 +11147,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"digest 0.9.0",
"opaque-debug 0.3.1",
]
@@ -11040,7 +11159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"digest 0.10.7",
]
@@ -11121,6 +11240,22 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "simd_cesu8"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
dependencies = [
"rustc_version 0.4.1",
"simdutf8",
]
[[package]]
name = "simdutf8"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "siphasher"
version = "0.3.11"
@@ -11722,7 +11857,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation 0.9.4",
"system-configuration-sys",
"system-configuration-sys 0.5.0",
]
[[package]]
name = "system-configuration"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
"bitflags 2.9.1",
"core-foundation 0.9.4",
"system-configuration-sys 0.6.0",
]
[[package]]
@@ -11735,6 +11881,16 @@ dependencies = [
"libc",
]
[[package]]
name = "system-configuration-sys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "tagptr"
version = "0.2.0"
+3 -3
View File
@@ -280,8 +280,8 @@ getrandom03 = { package = "getrandom", version = "=0.3.3" }
glob = "0.3"
handlebars = "3.5.5"
hex = "0.4.3"
hickory-proto = "0.25.2"
hickory-resolver = "0.25.2"
hickory-proto = "0.26.1"
hickory-resolver = "0.26.1"
hkdf = "0.12.3"
hmac = "0.12.1"
http = "1"
@@ -411,7 +411,7 @@ libcrux-chacha20poly1305 = "0.0.7"
libcrux-psq = "0.0.8"
libcrux-ml-kem = "0.0.8"
libcrux-sha3 = "0.0.8"
libcrux-traits = "0.0.8"
libcrux-traits = "0.0.6"
# Workspace dep definitions required by crates.io publication - we need a workspace version since `cargo workspaces` doesn't work with path imports from crate manifests
nym-api-requests = { version = "1.20.4", path = "nym-api/nym-api-requests" }
+74 -113
View File
@@ -55,8 +55,8 @@ use std::{
use hickory_resolver::{
TokioResolver,
config::{NameServerConfig, NameServerConfigGroup, ResolverConfig, ResolverOpts},
name_server::TokioConnectionProvider,
config::{CLOUDFLARE, NameServerConfig, QUAD9, ResolverConfig, ResolverOpts},
net::{NetError, runtime::TokioRuntimeProvider},
};
use once_cell::sync::OnceCell;
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
@@ -112,7 +112,7 @@ pub enum ResolveError {
#[error("invalid name: {0}")]
InvalidNameError(String),
#[error("hickory-dns resolver error: {0}")]
ResolveError(#[from] hickory_resolver::ResolveError),
ResolveError(#[from] NetError),
#[error("high level lookup timed out")]
Timeout,
#[error("hostname not found in static lookup table")]
@@ -122,7 +122,10 @@ pub enum ResolveError {
impl ResolveError {
/// Returns true if the error is a timeout.
pub fn is_timeout(&self) -> bool {
matches!(self, ResolveError::Timeout)
matches!(
self,
ResolveError::Timeout | ResolveError::ResolveError(NetError::Timeout)
)
}
}
@@ -166,18 +169,17 @@ impl Resolve for HickoryDnsResolver {
fn resolve(&self, name: Name) -> Resolving {
let use_system = self.use_system.load(std::sync::atomic::Ordering::Relaxed);
let use_shared = self.use_shared;
let resolver = if use_system {
match self
.system_resolver
let result = if use_system {
self.system_resolver
.get_or_try_init(|| HickoryDnsResolver::new_resolver_system(use_shared))
{
Ok(r) => r.clone(),
Err(e) => return Box::pin(return_err(e)),
}
} else {
self.state
.get_or_init(|| HickoryDnsResolver::new_resolver(use_shared))
.clone()
.get_or_try_init(|| HickoryDnsResolver::new_resolver(use_shared))
};
let resolver = match result {
Ok(r) => r.clone(),
Err(err) => return Box::pin(return_err(err)),
};
let maybe_static = self.static_base.clone();
@@ -228,7 +230,7 @@ async fn resolve(
Ok(Ok(lookup)) => {
// Shuffle so that successive connection attempts cycle through all
// returned IPs rather than always hitting the same first address.
let mut ips: Vec<IpAddr> = lookup.into_iter().collect();
let mut ips = Vec::from_iter(lookup.iter());
fastrand::shuffle(&mut ips);
let addrs: Addrs = Box::new(ips.into_iter().map(|ip| SocketAddr::new(ip, 0)));
return Ok(addrs);
@@ -277,7 +279,7 @@ impl HickoryDnsResolver {
.clone()
} else {
self.state
.get_or_init(|| HickoryDnsResolver::new_resolver(self.use_shared))
.get_or_try_init(|| HickoryDnsResolver::new_resolver(self.use_shared))?
.clone()
};
@@ -300,11 +302,11 @@ impl HickoryDnsResolver {
}
}
fn new_resolver(use_shared: bool) -> TokioResolver {
fn new_resolver(use_shared: bool) -> Result<TokioResolver, ResolveError> {
// using a closure here is slightly gross, but this makes sure that if the
// lazy-init returns an error it can be handled by the client
if use_shared {
SHARED_RESOLVER.state.get_or_init(new_resolver).clone()
SHARED_RESOLVER.state.get_or_try_init(new_resolver).cloned()
} else {
new_resolver()
}
@@ -356,7 +358,7 @@ impl HickoryDnsResolver {
/// Clear entries from the static table that would return entries during the pre-resolve stage.
/// This means that all lookups will attempt to use the network resolver again before the static
/// table is consulted.
///
///
/// Entries elevated to pre-resolve from fallback (added from default or using
/// [`set_fallback`]`) will have their cache timeout cleared. Entries added directly to
/// pre-resolve (using [`Self::set_static_preresolve`]) will be removed.
@@ -427,20 +429,7 @@ impl HickoryDnsResolver {
/// Get the list of currently available nameserver configs.
pub fn all_configured_name_servers(&self) -> Vec<NameServerConfig> {
default_nameserver_group().to_vec()
}
/// Get the list of currently used nameserver configs.
pub fn active_name_servers(&self) -> Vec<NameServerConfig> {
if !self.use_shared {
return self
.state
.get()
.map(|r| r.config().name_servers().to_vec())
.unwrap_or(self.all_configured_name_servers());
}
SHARED_RESOLVER.active_name_servers()
default_nameserver_group()
}
/// Do a trial resolution using each nameserver individually to test which are working and which
@@ -466,65 +455,60 @@ impl HickoryDnsResolver {
///
/// Caches successfully resolved addresses for 30 minutes to prevent continual use of remote lookup.
/// This resolver is intended to be used for OUR API endpoints that do not rapidly rotate IPs.
fn new_resolver() -> TokioResolver {
fn new_resolver() -> Result<TokioResolver, ResolveError> {
let name_servers = default_nameserver_group_ipv4_only();
configure_and_build_resolver(name_servers)
}
fn configure_and_build_resolver<G>(name_servers: G) -> TokioResolver
where
G: Into<NameServerConfigGroup>,
{
fn configure_and_build_resolver(
name_servers: Vec<NameServerConfig>,
) -> Result<TokioResolver, ResolveError> {
let options = HickoryDnsResolver::default_options();
let name_servers: NameServerConfigGroup = name_servers.into();
info!("building new configured resolver");
debug!("configuring resolver with {options:?}, {name_servers:?}");
let config = ResolverConfig::from_parts(None, Vec::new(), name_servers);
let mut resolver_builder =
TokioResolver::builder_with_config(config, TokioConnectionProvider::default());
TokioResolver::builder_with_config(config, TokioRuntimeProvider::default());
resolver_builder = resolver_builder.with_options(options);
resolver_builder.build()
Ok(resolver_builder.build()?)
}
fn filter_ipv4(nameservers: impl AsRef<[NameServerConfig]>) -> Vec<NameServerConfig> {
fn filter_ipv4(nameservers: impl IntoIterator<Item = NameServerConfig>) -> Vec<NameServerConfig> {
nameservers
.as_ref()
.iter()
.filter(|ns| ns.socket_addr.is_ipv4())
.cloned()
.into_iter()
.filter(|ns| ns.ip.is_ipv4())
.collect()
}
#[allow(unused)]
fn filter_ipv6(nameservers: impl AsRef<[NameServerConfig]>) -> Vec<NameServerConfig> {
fn filter_ipv6(nameservers: impl IntoIterator<Item = NameServerConfig>) -> Vec<NameServerConfig> {
nameservers
.as_ref()
.iter()
.filter(|ns| ns.socket_addr.is_ipv6())
.cloned()
.into_iter()
.filter(|ns| ns.ip.is_ipv6())
.collect()
}
#[allow(unused)]
fn default_nameserver_group() -> NameServerConfigGroup {
let mut name_servers = NameServerConfigGroup::quad9_tls();
name_servers.merge(NameServerConfigGroup::quad9_https());
name_servers.merge(NameServerConfigGroup::cloudflare_tls());
name_servers.merge(NameServerConfigGroup::cloudflare_https());
name_servers
fn default_nameserver_group() -> Vec<NameServerConfig> {
QUAD9
.tls()
.chain(QUAD9.https())
.chain(CLOUDFLARE.tls())
.chain(CLOUDFLARE.https())
.collect()
}
fn default_nameserver_group_ipv4_only() -> NameServerConfigGroup {
filter_ipv4(&default_nameserver_group() as &[NameServerConfig]).into()
fn default_nameserver_group_ipv4_only() -> Vec<NameServerConfig> {
filter_ipv4(default_nameserver_group())
}
#[allow(unused)]
fn default_nameserver_group_ipv6_only() -> NameServerConfigGroup {
filter_ipv6(&default_nameserver_group() as &[NameServerConfig]).into()
fn default_nameserver_group_ipv6_only() -> Vec<NameServerConfig> {
filter_ipv6(default_nameserver_group())
}
/// Create a new resolver with the default configuration, which reads from the system DNS config
@@ -539,7 +523,7 @@ fn new_resolver_system() -> Result<TokioResolver, ResolveError> {
resolver_builder = resolver_builder.with_options(options);
Ok(resolver_builder.build())
Ok(resolver_builder.build()?)
}
fn new_default_static_fallback() -> StaticResolver {
@@ -566,7 +550,7 @@ async fn trial_nameservers_inner(
async fn trial_lookup(name_server: NameServerConfig, query: &str) -> Result<(), ResolveError> {
debug!("running ns trial {name_server:?} query={query}");
let resolver = configure_and_build_resolver(vec![name_server]);
let resolver = configure_and_build_resolver(vec![name_server])?;
match tokio::time::timeout(DEFAULT_OVERALL_LOOKUP_TIMEOUT, resolver.ipv4_lookup(query)).await {
Ok(Ok(_)) => Ok(()),
@@ -579,8 +563,10 @@ async fn trial_lookup(name_server: NameServerConfig, query: &str) -> Result<(),
mod test {
use super::*;
use itertools::Itertools;
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::{
collections::HashMap,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
};
/// IP addresses guaranteed to fail attempts to resolve
///
@@ -659,26 +645,16 @@ mod test {
let mut ns_ips = GUARANTEED_BROKEN_IPS_1.to_vec();
ns_ips.push(good_cf_ip);
let broken_ns_https = NameServerConfigGroup::from_ips_https(
&ns_ips,
443,
"cloudflare-dns.com".to_string(),
true,
);
let domain = Arc::<str>::from("cloudflare-dns.com");
let path = Arc::<str>::from("/dns-query");
let broken_ns_https = GUARANTEED_BROKEN_IPS_1
.iter()
.chain([&good_cf_ip])
.map(|ip| NameServerConfig::https(*ip, domain.clone(), Some(path.clone())))
.collect::<Vec<_>>();
let inner = configure_and_build_resolver(broken_ns_https);
// create a new resolver that won't mess with the shared resolver used by other tests
let resolver = HickoryDnsResolver {
use_shared: false,
state: Arc::new(OnceCell::with_value(inner)),
static_base: Some(Default::default()),
..Default::default()
};
let name_servers = resolver.state.get().unwrap().config().name_servers();
for (ns, result) in trial_nameservers_inner(name_servers).await {
if ns.socket_addr.ip() == good_cf_ip {
for (ns, result) in trial_nameservers_inner(&broken_ns_https).await {
if ns.ip == good_cf_ip {
assert!(result.is_ok())
} else {
assert!(result.is_err())
@@ -694,21 +670,20 @@ mod test {
fn build_broken_resolver() -> Result<TokioResolver, ResolveError> {
info!("building new faulty resolver");
let mut broken_ns_group = NameServerConfigGroup::from_ips_tls(
GUARANTEED_BROKEN_IPS_1,
853,
"cloudflare-dns.com".to_string(),
true,
);
let broken_ns_https = NameServerConfigGroup::from_ips_https(
GUARANTEED_BROKEN_IPS_1,
443,
"cloudflare-dns.com".to_string(),
true,
);
broken_ns_group.merge(broken_ns_https);
let domain = Arc::<str>::from("cloudflare-dns.com");
let path = Arc::<str>::from("/dns-query");
let broken_ns_group = GUARANTEED_BROKEN_IPS_1
.iter()
.map(|ip| NameServerConfig::tls(*ip, domain.clone()))
.chain(
GUARANTEED_BROKEN_IPS_1
.iter()
.map(|ip| NameServerConfig::https(*ip, domain.clone(), Some(path.clone())))
.collect::<Vec<_>>(),
)
.collect::<Vec<_>>();
Ok(configure_and_build_resolver(broken_ns_group))
configure_and_build_resolver(broken_ns_group)
}
#[tokio::test]
@@ -729,7 +704,7 @@ mod test {
build_broken_resolver()?;
let domain = "ifconfig.me";
let result = resolver.resolve_str(domain).await;
assert!(result.is_err_and(|e| matches!(e, ResolveError::Timeout)));
assert!(result.is_err_and(|e| e.is_timeout()));
let duration = time_start.elapsed();
assert!(duration < resolver.overall_dns_timeout + Duration::from_secs(1));
@@ -763,25 +738,11 @@ mod test {
// unsuccessful lookup - primary times out, and not in static table
let domain = "non-existent.nymtech.net";
let result = resolver.resolve_str(domain).await;
assert!(result.is_err_and(|e| matches!(e, ResolveError::Timeout)));
assert!(result.is_err_and(|e| e.is_timeout()));
Ok(())
}
#[test]
fn default_resolver_uses_ipv4_only_nameservers() {
let resolver = HickoryDnsResolver::thread_resolver();
resolver
.active_name_servers()
.iter()
.all(|cfg| cfg.socket_addr.is_ipv4());
SHARED_RESOLVER
.active_name_servers()
.iter()
.all(|cfg| cfg.socket_addr.is_ipv4());
}
#[tokio::test]
#[cfg(any())] // #[ignore] we run --ignore in CI/CD assuming it just means slow -_-
// This test impacts the state of the shared resolver and as such is disabled to avoid
+13 -13
View File
@@ -141,9 +141,7 @@
use http::header::USER_AGENT;
pub use inventory;
pub use reqwest;
pub use reqwest::ClientBuilder as ReqwestClientBuilder;
pub use reqwest::StatusCode;
pub use reqwest::{self, ClientBuilder as ReqwestClientBuilder, StatusCode};
use std::error::Error;
pub mod registry;
@@ -152,19 +150,21 @@ use crate::path::RequestPath;
use async_trait::async_trait;
use bytes::Bytes;
use cfg_if::cfg_if;
use http::HeaderMap;
use http::header::{ACCEPT, CONTENT_TYPE};
use http::{
HeaderMap,
header::{ACCEPT, CONTENT_TYPE},
};
use itertools::Itertools;
use mime::Mime;
use reqwest::header::HeaderValue;
use reqwest::{RequestBuilder, Response};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use reqwest::{RequestBuilder, Response, header::HeaderValue};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
#[cfg(not(target_arch = "wasm32"))]
use std::io::ErrorKind;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
use std::{
fmt::Display,
sync::atomic::{AtomicUsize, Ordering},
time::Duration,
};
use thiserror::Error;
use tracing::{debug, instrument, warn};
@@ -1274,7 +1274,7 @@ pub(crate) fn might_be_network_interference(err: &reqwest::Error) -> bool {
} else if let Some(_tls_err) = e.downcast_ref::<rustls::Error>() {
// try downcast to TLS error
return true;
} else if let Some(resolve_err) = e.downcast_ref::<hickory_resolver::ResolveError>() {
} else if let Some(resolve_err) = e.downcast_ref::<hickory_resolver::net::NetError>() {
// try downcast to DNS error
return resolve_err.is_nx_domain();
} else {
+9 -7
View File
@@ -11,8 +11,10 @@
use std::net::Ipv4Addr;
use hickory_proto::op::{Message, Query};
use hickory_proto::rr::{Name, RData, RecordType};
use hickory_proto::{
op::{Message, Query},
rr::{Name, RData, RecordType},
};
use hickory_resolver::TokioResolver;
use smolmix::Tunnel;
use tracing::info;
@@ -27,7 +29,7 @@ async fn main() -> Result<(), BoxError> {
// Clearnet baseline via hickory-resolver
info!("Clearnet DNS lookup for '{domain}'...");
let resolver = TokioResolver::builder_tokio()?.build();
let resolver = TokioResolver::builder_tokio()?.build()?;
let clearnet_start = tokio::time::Instant::now();
let lookup = resolver.lookup_ip(domain).await?;
let clearnet_ips: Vec<Ipv4Addr> = lookup
@@ -55,8 +57,8 @@ async fn main() -> Result<(), BoxError> {
let udp = tunnel.udp_socket().await?;
let mut query = Message::new();
query.set_recursion_desired(true);
let mut query = Message::query();
query.metadata.recursion_desired = true;
query.add_query(Query::query(Name::from_ascii(domain)?, RecordType::A));
let query_bytes = query.to_vec()?;
@@ -73,9 +75,9 @@ async fn main() -> Result<(), BoxError> {
let response = Message::from_vec(&buf[..n])?;
let mixnet_ips: Vec<Ipv4Addr> = response
.answers()
.answers
.iter()
.filter_map(|r| match r.data() {
.filter_map(|r| match r.data {
RData::A(a) => Some(a.0),
_ => None,
})