From b501ddd534522e20fd0ad94931693b82b231fd95 Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Fri, 8 May 2026 20:25:07 +0200 Subject: [PATCH] Migrate to hickory 0.26.1 (#6751) * Migrate to hickory 0.26.1 --- Cargo.lock | 236 +++++++++++++++++++++++++----- Cargo.toml | 6 +- common/http-api-client/src/dns.rs | 187 ++++++++++------------- common/http-api-client/src/lib.rs | 26 ++-- smolmix/core/examples/udp.rs | 16 +- 5 files changed, 295 insertions(+), 176 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f37d6ed8c7..99019e079c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 1d1db9f1da..14ab79e00a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" } diff --git a/common/http-api-client/src/dns.rs b/common/http-api-client/src/dns.rs index 8c0f28e550..df57b3c309 100644 --- a/common/http-api-client/src/dns.rs +++ b/common/http-api-client/src/dns.rs @@ -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 = 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 { // 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 { - default_nameserver_group().to_vec() - } - - /// Get the list of currently used nameserver configs. - pub fn active_name_servers(&self) -> Vec { - 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 { let name_servers = default_nameserver_group_ipv4_only(); configure_and_build_resolver(name_servers) } -fn configure_and_build_resolver(name_servers: G) -> TokioResolver -where - G: Into, -{ +fn configure_and_build_resolver( + name_servers: Vec, +) -> Result { 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 { +fn filter_ipv4(nameservers: impl IntoIterator) -> Vec { 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 { +fn filter_ipv6(nameservers: impl IntoIterator) -> Vec { 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 { + 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 { + 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 { + 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 { 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::::from("cloudflare-dns.com"); + let path = Arc::::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::>(); - 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 { 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::::from("cloudflare-dns.com"); + let path = Arc::::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::>(), + ) + .collect::>(); - 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 diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index 856b2ad0e7..b0a5a3d30a 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -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::() { // try downcast to TLS error return true; - } else if let Some(resolve_err) = e.downcast_ref::() { + } else if let Some(resolve_err) = e.downcast_ref::() { // try downcast to DNS error return resolve_err.is_nx_domain(); } else { diff --git a/smolmix/core/examples/udp.rs b/smolmix/core/examples/udp.rs index 6600fe6e8b..3cedf06c45 100644 --- a/smolmix/core/examples/udp.rs +++ b/smolmix/core/examples/udp.rs @@ -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 = 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 = response - .answers() + .answers .iter() - .filter_map(|r| match r.data() { + .filter_map(|r| match r.data { RData::A(a) => Some(a.0), _ => None, })