--- a/crates/trippy-dns/src/lazy_resolver.rs
+++ b/crates/trippy-dns/src/lazy_resolver.rs
@@ -1,2 +1 @@
-use crate::config::Config;
-use crate::resolver::{DnsEntry, ResolvedIpAddrs, Resolver, Result};
+use crate::config::Config; use crate::resolver::{DnsEntry, ResolvedIpAddrs, Resolver, Result};
@@ -98,3 +97,2 @@
-    use hickory_resolver::error::{ResolveError, ResolveErrorKind};
-    use hickory_resolver::proto::error::ProtoError;
-    use hickory_resolver::proto::rr::RecordType;
+    use hickory_resolver::proto::ProtoError;
+    use hickory_resolver::proto::rr::{Name, RData, RecordType};
@@ -102 +100 @@
-    use hickory_resolver::{Name, Resolver};
+    use hickory_resolver::{TokioResolver, Resolver};
@@ -104,0 +103 @@
+    use tokio::runtime::Runtime;
@@ -143 +142 @@
-        TrustDns(Arc<Resolver>),
+        TrustDns(Arc<(TokioResolver, Runtime)>),
@@ -183 +182 @@
-                        let (resolver_cfg, mut options) = read_system_conf()?;
+                        let (resolver_cfg, mut options) = read_system_conf().map_err(std::io::Error::other)?;
@@ -186 +185 @@
-                        Resolver::new(resolver_cfg, options)
+                        Resolver::builder_with_config(resolver_cfg, Default::default()).with_options(options).build()
@@ -188 +187,6 @@
-                    ResolveMethod::Google => Resolver::new(ResolverConfig::google(), options),
+                    ResolveMethod::Google => Resolver::builder_with_config(
+                        ResolverConfig::udp_and_tcp(&hickory_resolver::config::GOOGLE),
+                        Default::default(),
+                    )
+                    .with_options(options)
+                    .build(),
@@ -190 +194,6 @@
-                        Resolver::new(ResolverConfig::cloudflare(), options)
+                        Resolver::builder_with_config(
+                            ResolverConfig::udp_and_tcp(&hickory_resolver::config::CLOUDFLARE),
+                            Default::default(),
+                        )
+                        .with_options(options)
+                        .build()
@@ -193,2 +202,3 @@
-                }?;
-                let resolver = Arc::new(res);
+                }
+                .map_err(std::io::Error::other)?;
+                let resolver = Arc::new((res, tokio::runtime::Runtime::new()?));
@@ -225 +235 @@
-                    .lookup_ip(hostname)
+                    .1.block_on(resolver.0.lookup_ip(hostname))
@@ -392 +402 @@
-            DnsProvider::TrustDns(resolver) => match resolver.reverse_lookup(addr) {
+            DnsProvider::TrustDns(resolver) => match resolver.1.block_on(resolver.0.reverse_lookup(addr)) {
@@ -395 +405,2 @@
-                        .into_iter()
+                        .answers().iter()
+                        .filter_map(|record| match &record.data { RData::PTR(name) => Some(name.clone()), _ => None })
@@ -412,2 +423,2 @@
-                Err(err) => match err.kind() {
-                    ResolveErrorKind::NoRecordsFound { .. } => {
+                Err(err) => match err {
+                    err if err.is_no_records_found() => {
@@ -424 +435 @@
-                    ResolveErrorKind::Timeout => CacheEntry::new(DnsEntry::Timeout(addr), now),
+                    hickory_resolver::net::NetError::Timeout => CacheEntry::new(DnsEntry::Timeout(addr), now),
@@ -432 +443 @@
-    fn lookup_asinfo(resolver: &Arc<Resolver>, addr: IpAddr) -> Result<AsInfo> {
+    fn lookup_asinfo(resolver: &Arc<(hickory_resolver::TokioResolver, tokio::runtime::Runtime)>, addr: IpAddr) -> Result<AsInfo> {
@@ -451 +462 @@
-    fn query_asn_ipv4(resolver: &Arc<Resolver>, addr: Ipv4Addr) -> Result<String> {
+    fn query_asn_ipv4(resolver: &Arc<(hickory_resolver::TokioResolver, tokio::runtime::Runtime)>, addr: Ipv4Addr) -> Result<String> {
@@ -458 +469 @@
-            .lookup(name, RecordType::TXT)
+            .1.block_on(resolver.0.lookup(name, RecordType::TXT))
@@ -461,2 +472,2 @@
-            .iter()
-            .next()
+            .answers()
+            .first()
@@ -464 +475 @@
-        let bytes = data.as_txt().ok_or_else(|| Error::QueryAsnOriginFailed)?;
+        let RData::TXT(bytes) = &data.data else { return Err(Error::QueryAsnOriginFailed); };
@@ -469 +480 @@
-    fn query_asn_ipv6(resolver: &Arc<Resolver>, addr: Ipv6Addr) -> Result<String> {
+    fn query_asn_ipv6(resolver: &Arc<(hickory_resolver::TokioResolver, tokio::runtime::Runtime)>, addr: Ipv6Addr) -> Result<String> {
@@ -480 +491 @@
-            .lookup(name, RecordType::TXT)
+            .1.block_on(resolver.0.lookup(name, RecordType::TXT))
@@ -483,2 +494,2 @@
-            .iter()
-            .next()
+            .answers()
+            .first()
@@ -486 +497 @@
-        let bytes = data.as_txt().ok_or_else(|| Error::QueryAsnOriginFailed)?;
+        let RData::TXT(bytes) = &data.data else { return Err(Error::QueryAsnOriginFailed); };
@@ -491 +502 @@
-    fn query_asn_name(resolver: &Arc<Resolver>, asn: &str) -> Result<String> {
+    fn query_asn_name(resolver: &Arc<(hickory_resolver::TokioResolver, tokio::runtime::Runtime)>, asn: &str) -> Result<String> {
@@ -495 +506 @@
-            .lookup(name, RecordType::TXT)
+            .1.block_on(resolver.0.lookup(name, RecordType::TXT))
@@ -498,2 +509,2 @@
-            .iter()
-            .next()
+            .answers()
+            .first()
@@ -501 +512 @@
-        let bytes = data.as_txt().ok_or_else(|| Error::QueryAsnFailed)?;
+        let RData::TXT(bytes) = &data.data else { return Err(Error::QueryAsnFailed); };
@@ -549,2 +560,2 @@
-    /// Convert a `ResolveError` to an `Error::LookupFailed`.
-    fn resolve_error(err: ResolveError) -> Error {
+    /// Convert a `NetError` to an `Error::LookupFailed`.
+    fn resolve_error(err: hickory_resolver::net::NetError) -> Error {
--- a/crates/trippy-dns/Cargo.toml
+++ b/crates/trippy-dns/Cargo.toml
@@ -21,0 +22 @@
+tokio.workspace = true
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -50 +50 @@
-hickory-resolver = "0.24.4"
+hickory-resolver = "0.26"
