fix: Add DNS resolver to oidc crate as well

Because openidconnect vendors reqwest (??), we have to re-implement
the entire Resolve trait.

No I don't like it, but I can't think of a better solution.
This commit is contained in:
theS1LV3R authored and Ellis Git committed 2026-11-08 19:40:49 +00:00
1 parent 60a0784a36
commit 144777dab0
3 files changed
+30 -8

No files matched your search

+23 -6
View File
@@ -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<Resolver<TokioRuntimeProvider>>,
pub struct DnsResolver {
resolver: Arc<TokioResolver>,
}
type TokioResolver = Resolver<TokioRuntimeProvider>;
impl DnsResolver {
pub(crate) fn new(resolver: Arc<Resolver<TokioRuntimeProvider>>) -> Self { Self { resolver } }
pub(crate) fn new(resolver: Arc<TokioResolver>) -> 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::<Vec<_>>().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?;
+5 -1
View File
@@ -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<TokioResolver>,
/// Tokio system resolver wrapped
pub reqwest_resolver: Arc<DnsResolver>,
/// Matrix server resolver according to server resolution spec
pub matrix_resolver: Arc<MatrixResolver>,
@@ -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,
+2 -1
View File
@@ -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::Service>("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))