fix(core): disable hickory dns on windows
This commit is contained in:
parent
b35f258043
commit
5d0101b3aa
5 changed files with 28 additions and 44 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -4811,7 +4811,6 @@ dependencies = [
|
|||
"tracing",
|
||||
"url",
|
||||
"uuid 1.23.1",
|
||||
"webpki-root-certs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -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"]}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue