diff --git a/src/service/client/dns_resolver.rs b/src/service/client/dns_resolver.rs index 84be16dcd..97c534704 100644 --- a/src/service/client/dns_resolver.rs +++ b/src/service/client/dns_resolver.rs @@ -4,18 +4,20 @@ use std::{ }; use hickory_resolver::{Resolver, net::runtime::TokioRuntimeProvider}; -use reqwest::dns::{Addrs, Name, Resolve, Resolving}; +use reqwest::dns::{Addrs, Resolving}; /// A simple struct to implement reqwest::dns::Resolve, as that is what's /// required by the reqwest client builder. Most code is based on /// reqwest::dns::HickoryDnsResolver, which we here have to almost re-create /// because it's pub(crate) instead of pub: -pub(crate) struct DnsResolver { - resolver: Arc>, +pub struct DnsResolver { + resolver: Arc, } +type TokioResolver = Resolver; + impl DnsResolver { - pub(crate) fn new(resolver: Arc>) -> Self { Self { resolver } } + pub(crate) fn new(resolver: Arc) -> Self { Self { resolver } } } struct SocketAddrs { @@ -30,8 +32,23 @@ impl Iterator for SocketAddrs { } } -impl Resolve for DnsResolver { - fn resolve(&self, name: Name) -> Resolving { +impl reqwest::dns::Resolve for DnsResolver { + fn resolve(&self, name: reqwest::dns::Name) -> Resolving { + let resolver = self.resolver.clone(); + Box::pin(async move { + let lookup = resolver.lookup_ip(name.as_str()).await?; + let addrs: Addrs = Box::new(SocketAddrs { + iter: lookup.iter().collect::>().into_iter(), + }); + Ok(addrs) + }) + } +} + +// openidconnect is weird and vendors reqwest (?), therefore we have to +// completely re-implement Resolve with different types +impl openidconnect::reqwest::dns::Resolve for DnsResolver { + fn resolve(&self, name: openidconnect::reqwest::dns::Name) -> Resolving { let resolver = self.resolver.clone(); Box::pin(async move { let lookup = resolver.lookup_ip(name.as_str()).await?; diff --git a/src/service/client/mod.rs b/src/service/client/mod.rs index 7d84a87ac..703e15f03 100644 --- a/src/service/client/mod.rs +++ b/src/service/client/mod.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use conduwuit::{ Config, Result, Server, debug, err, info, trace, utils::response::LimitReadExt, warn, }; -use dns_resolver::DnsResolver; +pub(crate) use dns_resolver::DnsResolver; use either::Either; use hickory_resolver::{ TokioResolver, @@ -25,6 +25,9 @@ pub struct Service { /// Regular DNS resolver pub dns_resolver: Arc, + /// Tokio system resolver wrapped + pub reqwest_resolver: Arc, + /// Matrix server resolver according to server resolution spec pub matrix_resolver: Arc, @@ -97,6 +100,7 @@ impl crate::Service for Service { Ok(Arc::new(Self { matrix_resolver, matrix_http_client, + reqwest_resolver: reqwest_dns_resolver.clone(), dns_resolver: tokio_dns_resolver, diff --git a/src/service/oidc/mod.rs b/src/service/oidc/mod.rs index d0369cf5e..220b29891 100644 --- a/src/service/oidc/mod.rs +++ b/src/service/oidc/mod.rs @@ -32,7 +32,7 @@ use tokio::{runtime, sync::SetOnce}; use url::Url; use crate::{ - Dep, config, globals, media, + Dep, client, config, globals, media, oauth::grant::AuthorizationCodeResponse, threepid, users::{self, AccountStatus, ProfileFieldChange}, @@ -163,6 +163,7 @@ impl crate::Service for Service { machine: SetOnce::new(), // This isn't in the client service because it has to use the `reqwest` shipped by `openidconnect` client: reqwest::ClientBuilder::new() + .dns_resolver(args.depend::("client").reqwest_resolver.clone()) .connect_timeout(Duration::from_secs(args.server.config.request_conn_timeout)) .read_timeout(Duration::from_secs(args.server.config.request_timeout)) .timeout(Duration::from_secs(args.server.config.request_total_timeout))