diff --git a/src/service/resolver/actual.rs b/src/service/resolver/actual.rs index 9fd8af449..7eaeb96ab 100644 --- a/src/service/resolver/actual.rs +++ b/src/service/resolver/actual.rs @@ -5,7 +5,10 @@ use std::{ use conduwuit::{Err, Result, debug, debug_info, err, error, trace}; use futures::{FutureExt, TryFutureExt}; -use hickory_resolver::ResolveError; +use hickory_resolver::{ + net::{DnsError, NetError}, + proto::rr::rdata::SRV, +}; use ipaddress::IPAddress; use ruma::ServerName; @@ -289,7 +292,7 @@ impl super::Service { | Err(e) => Self::handle_resolve_error(&e, hostname), | Ok(override_ip) => { self.cache.set_override(untername, &CachedOverride { - ips: override_ip.into_iter().take(MAX_IPS).collect(), + ips: override_ip.iter().take(MAX_IPS).collect(), port, expire: CachedOverride::default_expire(), overriding: (hostname != untername) @@ -315,10 +318,16 @@ impl super::Service { match self.resolver.resolver.srv_lookup(hostname).await { | Err(e) => Self::handle_resolve_error(&e, hostname)?, | Ok(result) => { - return Ok(result.iter().next().map(|result| { + return Ok(result.answers().iter().next().map(|result| { + let data = result.try_borrow::().expect("should be SRV response"); + FedDest::Named( - result.target().to_string().trim_end_matches('.').to_owned(), - format!(":{}", result.port()) + data.data() + .target + .to_string() + .trim_end_matches('.') + .to_owned(), + format!(":{}", data.data().port) .as_str() .try_into() .unwrap_or_else(|_| FedDest::default_port()), @@ -331,31 +340,24 @@ impl super::Service { Ok(None) } - fn handle_resolve_error(e: &ResolveError, host: &'_ str) -> Result<()> { - use hickory_resolver::{ResolveErrorKind::Proto, proto::ProtoErrorKind}; + fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> { + match err { + | NetError::NoConnections => { + error!( + "Your DNS server is overloaded and has ran out of connections. It is \ + strongly recommended you remediate this issue to ensure proper federation \ + connectivity." + ); - match e.kind() { - | Proto(e) => match e.kind() { - | ProtoErrorKind::NoRecordsFound { .. } => { - // Raise to debug_warn if we can find out the result wasn't from cache - debug!(%host, "No DNS records found: {e}"); - Ok(()) - }, - | ProtoErrorKind::Timeout => { - Err!(warn!(%host, "DNS {e}")) - }, - | ProtoErrorKind::NoConnections => { - error!( - "Your DNS server is overloaded and has ran out of connections. It is \ - strongly recommended you remediate this issue to ensure proper \ - federation connectivity." - ); - - Err!(error!(%host, "DNS error: {e}")) - }, - | _ => Err!(error!(%host, "DNS error: {e}")), + Err!(error!(%host, "DNS error: {err}")) }, - | _ => Err!(error!(%host, "DNS error: {e}")), + | NetError::Timeout => Err!(error!(%host, "DNS query timed out")), + | NetError::Dns(DnsError::NoRecordsFound(..)) => { + // Raise to debug_warn if we can find out the result wasn't from cache + debug!(%host, "No DNS records found: {err}"); + Ok(()) + }, + | _ => Err!(error!(%host, "DNS error: {err}")), } } diff --git a/src/service/resolver/dns.rs b/src/service/resolver/dns.rs index e9336f814..ac20930cd 100644 --- a/src/service/resolver/dns.rs +++ b/src/service/resolver/dns.rs @@ -2,7 +2,10 @@ use std::{net::SocketAddr, sync::Arc, time::Duration}; use conduwuit::{Result, Server, err}; use futures::FutureExt; -use hickory_resolver::{TokioResolver, lookup_ip::LookupIp}; +use hickory_resolver::{ + TokioResolver, config::ConnectionConfig, lookup_ip::LookupIp, + net::runtime::TokioRuntimeProvider, +}; use reqwest::dns::{Addrs, Name, Resolve, Resolving}; use super::cache::{Cache, CachedOverride}; @@ -28,7 +31,7 @@ impl Resolver { let (sys_conf, mut opts) = hickory_resolver::system_conf::read_system_conf() .map_err(|e| err!(error!("Failed to configure DNS resolver from system: {e}")))?; - let mut conf = hickory_resolver::config::ResolverConfig::new(); + let mut conf = hickory_resolver::config::ResolverConfig::default(); if let Some(domain) = sys_conf.domain() { conf.set_domain(domain.clone()); @@ -42,7 +45,7 @@ impl Resolver { let mut ns = sys_conf.clone(); if config.query_over_tcp_only { - ns.protocol = hickory_resolver::proto::xfer::Protocol::Tcp; + ns.connections = vec![ConnectionConfig::tcp()]; } ns.trust_negative_responses = !config.query_all_nameservers; @@ -50,7 +53,7 @@ impl Resolver { conf.add_name_server(ns); } - opts.cache_size = config.dns_cache_entries as usize; + opts.cache_size = config.dns_cache_entries as u64; opts.preserve_intermediates = true; opts.negative_min_ttl = Some(Duration::from_secs(config.dns_min_ttl_nxdomain)); opts.negative_max_ttl = Some(Duration::from_hours(720)); @@ -70,11 +73,10 @@ impl Resolver { | _ => hickory_resolver::config::LookupIpStrategy::Ipv4thenIpv6, }; - let rt_prov = hickory_resolver::proto::runtime::TokioRuntimeProvider::new(); - let conn_prov = hickory_resolver::name_server::TokioConnectionProvider::new(rt_prov); - let mut builder = TokioResolver::builder_with_config(conf, conn_prov); + let runtime_provider = TokioRuntimeProvider::new(); + let mut builder = TokioResolver::builder_with_config(conf, runtime_provider); *builder.options_mut() = opts; - let resolver = Arc::new(builder.build()); + let resolver = Arc::new(builder.build().expect("failed to build resolver :(")); Ok(Arc::new(Self { resolver: resolver.clone(), @@ -139,8 +141,15 @@ async fn resolve_to_reqwest( use std::{io, io::ErrorKind::Interrupted}; let handle_shutdown = || Box::new(io::Error::new(Interrupted, "Server shutting down")); - let handle_results = - |results: LookupIp| Box::new(results.into_iter().map(|ip| SocketAddr::new(ip, 0))); + let handle_results = |results: LookupIp| { + Box::new( + results + .iter() + .collect::>() + .into_iter() + .map(|ip| SocketAddr::new(ip, 0)), + ) + }; tokio::select! { results = resolver.lookup_ip(name.as_str()) => Ok(handle_results(results?)),