fix(linux): consult resolvectl when resolv.conf only shows the stub #52
Reference in New Issue
Block a user
Delete Branch "fix/systemd-resolved-discovery"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
On modern Linux desktops (Arch, Ubuntu 22.04+, Fedora) using NetworkManager + systemd-resolved,
/etc/resolv.confis a symlink tostub-resolv.confcontaining onlynameserver 127.0.0.53. The real upstream DNS servers live inside systemd-resolved's per-link state, exposed viaresolvectl status.discover_linux()was parsing/etc/resolv.conf, correctly filtering the stub address, and then falling through todetect_dhcp_dns()— which iscfg(target_os = "macos")-only and returnsNoneon Linux. Net effect: on a large chunk of Linux installs, numa silently defaulted to the hardcoded Quad9 DoH fallback instead of the user's actual DNS.How this surfaced
Visible in @CaseyLabs's AUR test banner during #33:
```
║ Upstream https://9.9.9.9/dns-query ║
```
His Arch machine had working router DNS the whole time — numa just couldn't see past the systemd-resolved stub.
Fix
resolvectl_dns_server()already exists insystem_dns.rs— it was introduced for cloud VPC forwarding-rule discovery and shells out to `resolvectl status --no-pager` to find the active DNS server. This PR wires it into the default-upstream fallback chain, between the primary resolv.conf parse and the `~/.numa/original-resolv.conf` backup:```rust
let default_upstream = if let Some(ns) = upstream {
info!("detected system upstream: {}", ns);
Some(ns)
} else if let Some(ns) = resolvectl_dns_server() {
info!("detected system upstream via resolvectl: {}", ns);
Some(ns)
} else {
// existing backup-file fallback
...
};
```
Three lines, no new code — just wiring an existing helper into a path it should have been in from day one.
Test plan
Upstreamrow instead ofhttps://9.9.9.9/dns-query.resolv.confwith real nameservers), confirm the existing path still wins — log line should saydetected system upstream:notdetected system upstream via resolvectl:.#[cfg(target_os = "linux")]).🤖 Generated with Claude Code