fix(core): disable hickory dns on windows

This commit is contained in:
LynithDev 2026-08-01 00:42:16 +02:00
parent b35f258043
commit 5d0101b3aa
5 changed files with 28 additions and 44 deletions

1
Cargo.lock generated
View file

@ -4811,7 +4811,6 @@ dependencies = [
"tracing",
"url",
"uuid 1.23.1",
"webpki-root-certs",
]
[[package]]

View file

@ -92,8 +92,6 @@ reqwest = {version = "=0.13.3", default-features = false, features = [
"system-proxy",
]}
reqwest-websocket = {version = "=0.6.0"}
# Fallback trust roots for Windows. See `oneclient_net::service` for why.
webpki-root-certs = {version = "=1.0.9"}
tokio = {version = "=1.52.3", features = ["full"]}
tokio-stream = {version = "=0.1.18", features = ["full"]}
tokio-util = {version = "=0.7.18", features = ["full"]}

View file

@ -34,6 +34,3 @@ thiserror.workspace = true
tracing.workspace = true
url.workspace = true
uuid.workspace = true
[target.'cfg(windows)'.dependencies]
webpki-root-certs.workspace = true

View file

@ -81,36 +81,6 @@ fn apply_curseforge_auth(
Ok(())
}
/// Adds the bundled Mozilla roots as a fallback behind the Windows trust store.
///
/// This does not replace the system store. `rustls-platform-verifier` builds
/// the chain against Windows first and only retries with these roots when that
/// came back untrusted or partial, so an intercepting proxy or an
/// enterprise-installed CA still works exactly as before.
///
/// It matters because Windows populates its root store lazily from Windows
/// Update. On a machine where root auto-update is disabled by policy — routine
/// on managed school and workplace images — or on a trimmed-down install, a
/// root that the rest of the world has can simply be absent. Every other
/// client those users try carries its own roots (Chrome since 105, Firefox via
/// NSS, Java-based launchers via `cacerts`), so sign-in works everywhere
/// except here. macOS and Linux do not have this failure mode, and adding
/// roots there would be additive rather than a fallback, so this is Windows
/// only.
#[cfg(target_os = "windows")]
fn add_fallback_roots(mut builder: ClientBuilder) -> ClientBuilder {
for der in webpki_root_certs::TLS_SERVER_ROOT_CERTS {
match reqwest::Certificate::from_der(der) {
Ok(root) => builder = builder.add_root_certificate(root),
// A malformed entry would be a bug in the bundle, not something the
// user can act on. Dropping one root beats failing to build a client.
Err(err) => tracing::warn!("skipping malformed fallback root: {err}"),
}
}
builder
}
#[derive(Clone)]
pub struct RequestClient {
client: reqwest::Client,
@ -150,16 +120,26 @@ impl RequestClient {
env!("CARGO_PKG_HOMEPAGE")
));
// reqwest defaults this to `cfg!(feature = "hickory-dns")`, so enabling
// the feature turns hickory on for *every* platform. Leaving it unset
// on Windows does not opt out — it has to be switched off explicitly.
//
// It has to be off there because hickory reads UDP responses into a
// fixed buffer, and Windows fails an oversized datagram with
// WSAEMSGSIZE (10040) instead of truncating it the way Unix does. A DNS
// reply that Linux and macOS truncate and retry over TCP is an outright
// lookup failure on Windows, so sign-in broke for whichever users had a
// resolver returning large enough answers.
#[cfg(target_os = "windows")]
{
builder = builder.no_hickory_dns();
}
#[cfg(not(target_os = "windows"))]
{
builder = builder.hickory_dns(true);
}
#[cfg(target_os = "windows")]
{
builder = add_fallback_roots(builder);
}
let client = builder.build()?;
Ok(Self {

View file

@ -98,7 +98,8 @@ pub fn start(auth: Arc<oneclient_auth::AuthService>) {
}
fn build_client() -> Result<reqwest::Client, reqwest::Error> {
reqwest::Client::builder()
#[cfg_attr(not(target_os = "windows"), allow(unused_mut))]
let mut builder = reqwest::Client::builder()
.tcp_keepalive(Some(Duration::from_secs(15)))
.connect_timeout(Duration::from_secs(10))
// reqwest-websocket only supports Http <1.1
@ -108,8 +109,17 @@ fn build_client() -> Result<reqwest::Client, reqwest::Error> {
"OneClient {} ({})",
env!("CARGO_PKG_VERSION"),
env!("CARGO_PKG_HOMEPAGE")
))
.build()
));
// Same WSAEMSGSIZE problem as the main client; see `oneclient_net::service`.
// The `hickory-dns` feature is enabled workspace-wide, so every builder is
// opted in unless it says otherwise.
#[cfg(target_os = "windows")]
{
builder = builder.no_hickory_dns();
}
builder.build()
}
fn base_url() -> &'static str {