diff --git a/iroh-dns-server/examples/resolve.rs b/iroh-dns-server/examples/resolve.rs index 11299405d85..444c5b9d31c 100644 --- a/iroh-dns-server/examples/resolve.rs +++ b/iroh-dns-server/examples/resolve.rs @@ -54,7 +54,7 @@ async fn main() -> anyhow::Result<()> { DnsResolver::with_nameserver(addr) } else { match args.env { - Env::Staging | Env::Prod => DnsResolver::new(), + Env::Staging | Env::Prod => DnsResolver::default(), Env::Dev => { DnsResolver::with_nameserver(DEV_DNS_SERVER.parse().expect("valid address")) } diff --git a/iroh-dns-server/src/lib.rs b/iroh-dns-server/src/lib.rs index 25708fabec6..832fc0c7321 100644 --- a/iroh-dns-server/src/lib.rs +++ b/iroh-dns-server/src/lib.rs @@ -116,25 +116,25 @@ mod tests { // resolve root record let name = Name::from_utf8(format!("{pubkey}."))?; let res = resolver.lookup_txt(name, DNS_TIMEOUT).await?; - let records = res.into_iter().map(|t| t.to_string()).collect::>(); + let records = res.map(|t| t.to_string()).collect::>(); assert_eq!(records, vec!["hi0".to_string()]); // resolve level one record let name = Name::from_utf8(format!("_hello.{pubkey}."))?; let res = resolver.lookup_txt(name, DNS_TIMEOUT).await?; - let records = res.into_iter().map(|t| t.to_string()).collect::>(); + let records = res.map(|t| t.to_string()).collect::>(); assert_eq!(records, vec!["hi1".to_string()]); // resolve level two record let name = Name::from_utf8(format!("_hello.world.{pubkey}."))?; let res = resolver.lookup_txt(name, DNS_TIMEOUT).await?; - let records = res.into_iter().map(|t| t.to_string()).collect::>(); + let records = res.map(|t| t.to_string()).collect::>(); assert_eq!(records, vec!["hi2".to_string()]); // resolve multiple records for same name let name = Name::from_utf8(format!("multiple.{pubkey}."))?; let res = resolver.lookup_txt(name, DNS_TIMEOUT).await?; - let records = res.into_iter().map(|t| t.to_string()).collect::>(); + let records = res.map(|t| t.to_string()).collect::>(); assert_eq!(records, vec!["hi3".to_string(), "hi4".to_string()]); // resolve A record diff --git a/iroh-relay/src/dns.rs b/iroh-relay/src/dns.rs index 1d179393b2d..d60d8a53729 100644 --- a/iroh-relay/src/dns.rs +++ b/iroh-relay/src/dns.rs @@ -3,36 +3,73 @@ use std::{ fmt::{self, Write}, future::Future, - net::{IpAddr, Ipv6Addr, SocketAddr}, + net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, + sync::Arc, }; use anyhow::{bail, Context, Result}; use hickory_resolver::{name_server::TokioConnectionProvider, TokioResolver}; use iroh_base::NodeId; use n0_future::{ + boxed::BoxFuture, time::{self, Duration}, StreamExt, }; use url::Url; -use crate::node_info::NodeInfo; +use crate::{ + defaults::timeouts::DNS_TIMEOUT, + node_info::{self, NodeInfo}, +}; /// The n0 testing DNS node origin, for production. pub const N0_DNS_NODE_ORIGIN_PROD: &str = "dns.iroh.link"; /// The n0 testing DNS node origin, for testing. pub const N0_DNS_NODE_ORIGIN_STAGING: &str = "staging-dns.iroh.link"; -/// The DNS resolver used throughout `iroh`. +/// Trait for DNS resolvers used in iroh. +pub trait Resolver: fmt::Debug + Send + Sync + 'static { + /// Looks up an IPv4 address. + fn lookup_ipv4(&self, host: String) -> BoxFuture>>; + + /// Looks up an IPv6 address. + fn lookup_ipv6(&self, host: String) -> BoxFuture>>; + + /// Looks up TXT records. + fn lookup_txt(&self, host: String) -> BoxFuture>>; + + /// Clears the internal cache. + fn clear_cache(&self); +} + +/// Boxed iterator alias. +pub type BoxIter = Box + Send + 'static>; + +/// DNS resolver for use in iroh. +/// +/// This internally contains a [`dyn Resolver`]. See the public methods for how to construct +/// a [`DnsResolver`] with sensible defaults or with a custom resolver. #[derive(Debug, Clone)] -pub struct DnsResolver(TokioResolver); +pub struct DnsResolver(Arc); impl DnsResolver { - /// Create a new DNS resolver with sensible cross-platform defaults. + /// Creates a new [`DnsResolver`] from a struct that implements [`Resolver`]. + /// + /// [`Resolver`] is implemented for [`hickory_resolver::TokioResolver`], so you can construct + /// a [`TokioResolver`] and pass that to this function. + /// + /// To use a different DNS resolver, you need to implement [`Resolver`] for your custom resolver + /// and then pass to this function. + pub fn new(resolver: impl Resolver) -> Self { + Self(Arc::new(resolver)) + } + + /// Creates a new DNS resolver with sensible cross-platform defaults. /// /// We first try to read the system's resolver from `/etc/resolv.conf`. /// This does not work at least on some Androids, therefore we fallback - /// to the default `ResolverConfig` which uses eg. to google's `8.8.8.8` or `8.8.4.4`. - pub fn new() -> Self { + /// to the default `ResolverConfig` which uses Google's `8.8.8.8` or `8.8.4.4`. + pub fn new_with_system_defaults() -> Self { let (system_config, mut options) = hickory_resolver::system_conf::read_system_conf().unwrap_or_default(); @@ -57,10 +94,10 @@ impl DnsResolver { let mut builder = TokioResolver::builder_with_config(config, TokioConnectionProvider::default()); *builder.options_mut() = options; - DnsResolver(builder.build()) + Self::new(builder.build()) } - /// Create a new DNS resolver configured with a single UDP DNS nameserver. + /// Creates a new DNS resolver configured with a single UDP DNS nameserver. pub fn with_nameserver(nameserver: SocketAddr) -> Self { let mut config = hickory_resolver::config::ResolverConfig::new(); let nameserver_config = hickory_resolver::config::NameServerConfig::new( @@ -71,44 +108,40 @@ impl DnsResolver { let builder = TokioResolver::builder_with_config(config, TokioConnectionProvider::default()); - DnsResolver(builder.build()) + Self::new(builder.build()) } - /// Removes all entries from the cache. - pub fn clear_cache(&self) { - self.0.clear_cache(); - } - - /// Lookup a TXT record. - pub async fn lookup_txt(&self, host: impl ToString, timeout: Duration) -> Result { - let host = host.to_string(); - let res = time::timeout(timeout, self.0.txt_lookup(host)).await??; - Ok(TxtLookup(res)) + /// Performs a TXT lookup with a timeout. + pub async fn lookup_txt( + &self, + host: impl ToString, + timeout: Duration, + ) -> Result> { + let res = time::timeout(timeout, self.0.lookup_txt(host.to_string())).await??; + Ok(res) } - /// Perform an ipv4 lookup with a timeout. + /// Performs an IPv4 lookup with a timeout. pub async fn lookup_ipv4( &self, host: impl ToString, timeout: Duration, ) -> Result> { - let host = host.to_string(); - let addrs = time::timeout(timeout, self.0.ipv4_lookup(host)).await??; - Ok(addrs.into_iter().map(|ip| IpAddr::V4(ip.0))) + let addrs = time::timeout(timeout, self.0.lookup_ipv4(host.to_string())).await??; + Ok(addrs.map(IpAddr::V4)) } - /// Perform an ipv6 lookup with a timeout. + /// Performs an IPv6 lookup with a timeout. pub async fn lookup_ipv6( &self, host: impl ToString, timeout: Duration, ) -> Result> { - let host = host.to_string(); - let addrs = time::timeout(timeout, self.0.ipv6_lookup(host)).await??; - Ok(addrs.into_iter().map(|ip| IpAddr::V6(ip.0))) + let addrs = time::timeout(timeout, self.0.lookup_ipv6(host.to_string())).await??; + Ok(addrs.map(IpAddr::V6)) } - /// Resolve IPv4 and IPv6 in parallel with a timeout. + /// Resolves IPv4 and IPv6 in parallel with a timeout. /// /// `LookupIpStrategy::Ipv4AndIpv6` will wait for ipv6 resolution timeout, even if it is /// not usable on the stack, so we manually query both lookups concurrently and time them out @@ -134,7 +167,7 @@ impl DnsResolver { } } - /// Resolve a hostname from a URL to an IP address. + /// Resolves a hostname from a URL to an IP address. pub async fn resolve_host( &self, url: &Url, @@ -164,7 +197,7 @@ impl DnsResolver { } } - /// Perform an ipv4 lookup with a timeout in a staggered fashion. + /// Performs an IPv4 lookup with a timeout in a staggered fashion. /// /// From the moment this function is called, each lookup is scheduled after the delays in /// `delays_ms` with the first call being done immediately. `[200ms, 300ms]` results in calls @@ -181,7 +214,7 @@ impl DnsResolver { stagger_call(f, delays_ms).await } - /// Perform an ipv6 lookup with a timeout in a staggered fashion. + /// Performs an IPv6 lookup with a timeout in a staggered fashion. /// /// From the moment this function is called, each lookup is scheduled after the delays in /// `delays_ms` with the first call being done immediately. `[200ms, 300ms]` results in calls @@ -198,7 +231,7 @@ impl DnsResolver { stagger_call(f, delays_ms).await } - /// Race an ipv4 and ipv6 lookup with a timeout in a staggered fashion. + /// Races an IPv4 and IPv6 lookup with a timeout in a staggered fashion. /// /// From the moment this function is called, each lookup is scheduled after the delays in /// `delays_ms` with the first call being done immediately. `[200ms, 300ms]` results in calls @@ -221,21 +254,17 @@ impl DnsResolver { /// To lookup nodes that published their node info to the DNS servers run by n0, /// pass [`N0_DNS_NODE_ORIGIN_PROD`] as `origin`. pub async fn lookup_node_by_id(&self, node_id: &NodeId, origin: &str) -> Result { - let attrs = crate::node_info::TxtAttrs::::lookup_by_id( - self, node_id, origin, - ) - .await?; - let info = attrs.into(); - Ok(info) + let name = node_info::node_domain(node_id, origin); + let name = node_info::ensure_iroh_txt_label(name); + let lookup = self.lookup_txt(name.clone(), DNS_TIMEOUT).await?; + NodeInfo::from_txt_lookup(name, lookup) } /// Looks up node info by DNS name. pub async fn lookup_node_by_domain_name(&self, name: &str) -> Result { - let attrs = - crate::node_info::TxtAttrs::::lookup_by_name(self, name) - .await?; - let info = attrs.into(); - Ok(info) + let name = node_info::ensure_iroh_txt_label(name.to_string()); + let lookup = self.lookup_txt(name.clone(), DNS_TIMEOUT).await?; + NodeInfo::from_txt_lookup(name, lookup) } /// Looks up node info by DNS name in a staggered fashion. @@ -268,54 +297,96 @@ impl DnsResolver { let f = || self.lookup_node_by_id(node_id, origin); stagger_call(f, delays_ms).await } + + /// Removes all entries from the cache. + pub fn clear_cache(&self) { + self.0.clear_cache(); + } } impl Default for DnsResolver { fn default() -> Self { - Self::new() + Self::new_with_system_defaults() } } -impl From for DnsResolver { - fn from(resolver: TokioResolver) -> Self { - DnsResolver(resolver) +/// Implementation of [`Resolver`] for [`hickory_resolver::TokioResolver`]. +impl Resolver for TokioResolver { + fn lookup_ipv4(&self, host: String) -> BoxFuture>> { + let this = self.clone(); + Box::pin(async move { + let addrs = this.ipv4_lookup(host).await?; + let iter: BoxIter = Box::new(addrs.into_iter().map(Ipv4Addr::from)); + Ok(iter) + }) } -} -/// TXT records returned from [`DnsResolver::lookup_txt`] -#[derive(Debug, Clone)] -pub struct TxtLookup(pub(crate) hickory_resolver::lookup::TxtLookup); - -impl From for TxtLookup { - fn from(value: hickory_resolver::lookup::TxtLookup) -> Self { - Self(value) + fn lookup_ipv6(&self, host: String) -> BoxFuture>> { + let this = self.clone(); + Box::pin(async move { + let addrs = this.ipv6_lookup(host).await?; + let iter: BoxIter = Box::new(addrs.into_iter().map(Ipv6Addr::from)); + Ok(iter) + }) } -} - -impl IntoIterator for TxtLookup { - type Item = TXT; - type IntoIter = Box>; + fn lookup_txt(&self, host: String) -> BoxFuture>> { + let this = self.clone(); + Box::pin(async move { + let lookup = this.txt_lookup(host).await?; + let iter: BoxIter = Box::new( + lookup + .into_iter() + .map(|txt| TxtRecordData::from_iter(txt.iter().cloned())), + ); + Ok(iter) + }) + } - fn into_iter(self) -> Self::IntoIter { - Box::new(self.0.into_iter().map(TXT)) + fn clear_cache(&self) { + self.clear_cache(); } } -/// Record data for a TXT record +/// Record data for a TXT record. +/// +/// This contains a list of character strings, as defined in [RFC 1035 Section 3.3.14]. +/// +/// [`TxtRecordData`] implements [`fmt::Display`], so you can call [`ToString::to_string`] to +/// convert the record data into a string. This will parse each character string with +/// [`String::from_utf8_lossy`] and then concatenate all strings without a separator. +/// +/// If you want to process each character string individually, use [`Self::iter`]. +/// +/// [RFC 1035 Section 3.3.14]: https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 #[derive(Debug, Clone)] -pub struct TXT(hickory_resolver::proto::rr::rdata::TXT); +pub struct TxtRecordData(Box<[Box<[u8]>]>); -impl TXT { - /// Returns the raw character strings of this TXT record. - pub fn txt_data(&self) -> &[Box<[u8]>] { - self.0.txt_data() +impl TxtRecordData { + /// Returns an iterator over the character strings contained in this TXT record. + pub fn iter(&self) -> impl Iterator { + self.0.iter().map(|x| x.as_ref()) } } -impl fmt::Display for TXT { +impl fmt::Display for TxtRecordData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) + for s in self.iter() { + write!(f, "{}", &String::from_utf8_lossy(s))? + } + Ok(()) + } +} + +impl FromIterator> for TxtRecordData { + fn from_iter>>(iter: T) -> Self { + Self(iter.into_iter().collect()) + } +} + +impl From>> for TxtRecordData { + fn from(value: Vec>) -> Self { + Self(value.into_boxed_slice()) } } diff --git a/iroh-relay/src/node_info.rs b/iroh-relay/src/node_info.rs index 47e082fadfb..3e8180e19e5 100644 --- a/iroh-relay/src/node_info.rs +++ b/iroh-relay/src/node_info.rs @@ -41,16 +41,9 @@ use std::{ }; use anyhow::{anyhow, Result}; -#[cfg(not(wasm_browser))] -use hickory_resolver::{proto::ProtoError, Name}; use iroh_base::{NodeAddr, NodeId, RelayUrl, SecretKey}; -#[cfg(not(wasm_browser))] -use tracing::warn; use url::Url; -#[cfg(not(wasm_browser))] -use crate::{defaults::timeouts::DNS_TIMEOUT, dns::DnsResolver}; - /// The DNS name for the iroh TXT record. pub const IROH_TXT_NAME: &str = "_iroh"; @@ -347,11 +340,14 @@ impl NodeInfo { self.into() } - #[cfg(not(wasm_browser))] /// Parses a [`NodeInfo`] from a TXT records lookup. - pub fn from_txt_lookup(lookup: crate::dns::TxtLookup) -> Result { - let attrs = TxtAttrs::from_txt_lookup(lookup)?; - Ok(attrs.into()) + #[cfg(not(wasm_browser))] + pub(crate) fn from_txt_lookup( + name: String, + lookup: impl Iterator, + ) -> Result { + let attrs = TxtAttrs::from_txt_lookup(name, lookup)?; + Ok(Self::from(attrs)) } /// Parses a [`NodeInfo`] from a [`pkarr::SignedPacket`]. @@ -396,16 +392,13 @@ impl std::ops::DerefMut for NodeInfo { /// [`IROH_TXT_NAME`] and the second label to be a z32 encoded [`NodeId`]. Ignores /// subsequent labels. #[cfg(not(wasm_browser))] -fn node_id_from_hickory_name(name: &hickory_resolver::proto::rr::Name) -> Option { - if name.num_labels() < 2 { - return None; - } - let mut labels = name.iter(); - let label = std::str::from_utf8(labels.next().expect("num_labels checked")).ok()?; +fn node_id_from_txt_name(name: &str) -> Option { + let mut labels = name.split("."); + let label = labels.next()?; if label != IROH_TXT_NAME { return None; } - let label = std::str::from_utf8(labels.next().expect("num_labels checked")).ok()?; + let label = labels.next()?; let node_id = NodeId::from_z32(label).ok()?; Some(node_id) } @@ -482,32 +475,6 @@ impl TxtAttrs { Ok(Self { attrs, node_id }) } - #[cfg(not(wasm_browser))] - async fn lookup(resolver: &DnsResolver, name: Name) -> Result { - let name = ensure_iroh_txt_label(name)?; - let lookup = resolver.lookup_txt(name, DNS_TIMEOUT).await?; - let attrs = Self::from_txt_lookup(lookup)?; - Ok(attrs) - } - - /// Looks up attributes by [`NodeId`] and origin domain. - #[cfg(not(wasm_browser))] - pub(crate) async fn lookup_by_id( - resolver: &DnsResolver, - node_id: &NodeId, - origin: &str, - ) -> Result { - let name = node_domain(node_id, origin)?; - TxtAttrs::lookup(resolver, name).await - } - - /// Looks up attributes by DNS name. - #[cfg(not(wasm_browser))] - pub(crate) async fn lookup_by_name(resolver: &DnsResolver, name: &str) -> Result { - let name = Name::from_str(name)?; - TxtAttrs::lookup(resolver, name).await - } - /// Returns the parsed attributes. pub(crate) fn attrs(&self) -> &BTreeMap> { &self.attrs @@ -544,43 +511,13 @@ impl TxtAttrs { /// Parses a TXT records lookup. #[cfg(not(wasm_browser))] - pub(crate) fn from_txt_lookup(lookup: crate::dns::TxtLookup) -> Result { - let queried_node_id = node_id_from_hickory_name(lookup.0.query().name()) + pub(crate) fn from_txt_lookup( + name: String, + lookup: impl Iterator, + ) -> Result { + let queried_node_id = node_id_from_txt_name(&name) .ok_or_else(|| anyhow!("invalid DNS answer: not a query for _iroh.z32encodedpubkey"))?; - - let strings = lookup.0.as_lookup().record_iter().filter_map(|record| { - match node_id_from_hickory_name(record.name()) { - // Filter out only TXT record answers that match the node_id we searched for. - Some(n) if n == queried_node_id => match record.data().as_txt() { - Some(txt) => Some(txt.to_string()), - None => { - warn!( - ?queried_node_id, - data = ?record.data(), - "unexpected record type for DNS discovery query" - ); - None - } - }, - Some(answered_node_id) => { - warn!( - ?queried_node_id, - ?answered_node_id, - "unexpected node ID answered for DNS query" - ); - None - } - None => { - warn!( - ?queried_node_id, - name = ?record.name(), - "unexpected answer record name for DNS query" - ); - None - } - } - }); - + let strings = lookup.map(|record| record.to_string()); Self::from_strings(queried_node_id, strings) } @@ -614,19 +551,18 @@ impl TxtAttrs { } #[cfg(not(wasm_browser))] -fn ensure_iroh_txt_label(name: Name) -> Result { - if name.iter().next() == Some(IROH_TXT_NAME.as_bytes()) { - Ok(name) +pub(crate) fn ensure_iroh_txt_label(name: String) -> String { + let mut parts = name.split("."); + if parts.next() == Some(IROH_TXT_NAME) { + name } else { - Name::parse(IROH_TXT_NAME, Some(&name)) + format!("{}.{}", IROH_TXT_NAME, name) } } #[cfg(not(wasm_browser))] -fn node_domain(node_id: &NodeId, origin: &str) -> Result { - let domain = format!("{}.{}", NodeId::to_z32(node_id), origin); - let domain = Name::from_str(&domain)?; - Ok(domain) +pub(crate) fn node_domain(node_id: &NodeId, origin: &str) -> String { + format!("{}.{}", NodeId::to_z32(node_id), origin) } #[cfg(test)] @@ -648,6 +584,7 @@ mod tests { use testresult::TestResult; use super::{NodeData, NodeIdExt, NodeInfo}; + use crate::dns::TxtRecordData; #[test] fn txt_attr_roundtrip() { @@ -738,8 +675,11 @@ mod tests { ]; let lookup = Lookup::new_with_max_ttl(query, Arc::new(records)); let lookup = hickory_resolver::lookup::TxtLookup::from(lookup); + let lookup = lookup + .into_iter() + .map(|txt| TxtRecordData::from_iter(txt.iter().cloned())); - let node_info = NodeInfo::from_txt_lookup(lookup.into())?; + let node_info = NodeInfo::from_txt_lookup(name.to_string(), lookup)?; let expected_node_info = NodeInfo::new(NodeId::from_str( "1992d53c02cdc04566e5c0edb1ce83305cd550297953a047a445ea3264b54b18", diff --git a/iroh-relay/src/server.rs b/iroh-relay/src/server.rs index ca8d4935cbc..29365fc9728 100644 --- a/iroh-relay/src/server.rs +++ b/iroh-relay/src/server.rs @@ -869,7 +869,7 @@ mod tests { } fn dns_resolver() -> DnsResolver { - DnsResolver::new() + DnsResolver::default() } #[tokio::test] diff --git a/iroh-relay/src/server/http_server.rs b/iroh-relay/src/server/http_server.rs index ca4ea755edb..248d44f8315 100644 --- a/iroh-relay/src/server/http_server.rs +++ b/iroh-relay/src/server/http_server.rs @@ -840,8 +840,8 @@ mod tests { async fn create_test_client(key: SecretKey, server_url: Url) -> Result<(PublicKey, Client)> { let public_key = key.public(); - let client = - ClientBuilder::new(server_url, key, DnsResolver::new()).insecure_skip_cert_verify(true); + let client = ClientBuilder::new(server_url, key, DnsResolver::default()) + .insecure_skip_cert_verify(true); let client = client.connect().await?; Ok((public_key, client)) diff --git a/iroh/src/dns.rs b/iroh/src/dns.rs index 260cd85ea66..a74aa38f8d2 100644 --- a/iroh/src/dns.rs +++ b/iroh/src/dns.rs @@ -7,7 +7,7 @@ //! See the [`node_info`](crate::node_info) module documentation for details on how //! iroh node records are structured. -pub use iroh_relay::dns::{DnsResolver, N0_DNS_NODE_ORIGIN_PROD, N0_DNS_NODE_ORIGIN_STAGING}; +pub use iroh_relay::dns::*; #[cfg(test)] pub(crate) mod tests { @@ -24,7 +24,7 @@ pub(crate) mod tests { #[tokio::test] #[traced_test] async fn test_dns_lookup_ipv4_ipv6() { - let resolver = DnsResolver::new(); + let resolver = DnsResolver::default(); let res: Vec<_> = resolver .lookup_ipv4_ipv6_staggered(NA_RELAY_HOSTNAME, TIMEOUT, STAGGERING_DELAYS) .await diff --git a/iroh/src/endpoint.rs b/iroh/src/endpoint.rs index ba948f1fadf..8df217d86ea 100644 --- a/iroh/src/endpoint.rs +++ b/iroh/src/endpoint.rs @@ -1991,7 +1991,7 @@ impl Connection { /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for /// details on the returned value. /// - /// [`Connection::handshake_data()`]: crate::Connecting::handshake_data + /// [`Connection::handshake_data()`]: crate::endpoint::Connecting::handshake_data #[inline] pub fn handshake_data(&self) -> Option> { self.inner.handshake_data() diff --git a/iroh/src/magicsock.rs b/iroh/src/magicsock.rs index 21936aa2cbf..265d52ee72b 100644 --- a/iroh/src/magicsock.rs +++ b/iroh/src/magicsock.rs @@ -3455,7 +3455,6 @@ mod tests { use super::*; use crate::{ defaults::staging::{self, EU_RELAY_HOSTNAME}, - dns::DnsResolver, tls, watcher::Watcher as _, Endpoint, RelayMode, @@ -3477,7 +3476,7 @@ mod tests { node_map: None, discovery: None, proxy_url: None, - dns_resolver: DnsResolver::new(), + dns_resolver: DnsResolver::default(), server_config, #[cfg(any(test, feature = "test-utils"))] insecure_skip_relay_cert_verify: false, @@ -4080,7 +4079,7 @@ mod tests { let mut server_config = ServerConfig::with_crypto(Arc::new(quic_server_config)); server_config.transport_config(Arc::new(quinn::TransportConfig::default())); - let dns_resolver = DnsResolver::new(); + let dns_resolver = DnsResolver::default(); let opts = Options { addr_v4: None, addr_v6: None, diff --git a/iroh/src/magicsock/relay_actor.rs b/iroh/src/magicsock/relay_actor.rs index d603724fe19..1cc89b294e0 100644 --- a/iroh/src/magicsock/relay_actor.rs +++ b/iroh/src/magicsock/relay_actor.rs @@ -1288,7 +1288,7 @@ mod tests { use tracing_test::traced_test; use super::*; - use crate::{dns::DnsResolver, test_utils}; + use crate::test_utils; #[test] fn test_packetize_iter() { @@ -1341,7 +1341,7 @@ mod tests { relay_datagrams_recv, connection_opts: RelayConnectionOptions { secret_key, - dns_resolver: DnsResolver::new(), + dns_resolver: DnsResolver::default(), proxy_url: None, prefer_ipv6: Arc::new(AtomicBool::new(true)), insecure_skip_cert_verify: true, diff --git a/iroh/src/net_report/dns.rs b/iroh/src/net_report/dns.rs index 1a46b339436..d477b5e0437 100644 --- a/iroh/src/net_report/dns.rs +++ b/iroh/src/net_report/dns.rs @@ -7,6 +7,6 @@ pub(crate) mod tests { /// Get a DNS resolver suitable for testing. pub fn resolver() -> DnsResolver { - DnsResolver::new() + DnsResolver::default() } }