-
Notifications
You must be signed in to change notification settings - Fork 1.7k
DNS performance degradation: DnsQueryRaw bypasses Windows DNS cache, negative responses never cached by systemd-resolved #14571
Description
Summary
WSL's DNS tunneling suffers from significant performance degradation because DnsQueryRaw bypasses the Windows DNS cache (by injecting DNS_QUERY_BYPASS_CACHE internally), and systemd-resolved — the only remaining caching layer — is compiled with Cache=no-negative on several major distros (Ubuntu 24.04, etc.). This means NODATA/NXDOMAIN responses (e.g., AAAA lookups for IPv4-only hosts) are never cached, causing every dual-stack lookup to pay a full DNS tunnel round-trip for the uncached negative response.
Reproduction Steps
- Use WSL 2 with Ubuntu 24.04 (systemd 255)
- Run
resolvectl statisticsto observe cache state - Run
dig github.commultiple times - Observe that AAAA NODATA responses are never cached — cache misses remain high
Expected Behavior
Negative DNS responses (NODATA/NXDOMAIN) should be cached by systemd-resolved so that repeated lookups for the same hostname don't pay a full round-trip through the DNS tunnel each time.
Actual Behavior
Every AAAA lookup for an IPv4-only hostname results in a cache miss because systemd-resolved is configured (at compile time on Ubuntu) with Cache=no-negative, and since DnsQueryRaw bypasses the Windows DNS cache, there is no caching layer at all for these responses.
Benchmark Data (Ubuntu 24.04, systemd 255, WSL 2.7.1.0)
| Metric | Cache=no-negative (default) | Cache=yes (fix) |
|---|---|---|
| Avg latency (10 queries) | 24.0 ms | 10.1 ms |
| Cache hits / misses | 9 / 11 | 18 / 3 |
| Cache entries | 1 (A only) | 2 (A + AAAA NODATA) |
2.3× faster average, 9× fewer cache misses.
Root Cause Analysis
DnsResolver.cppline 207 explicitly notes: "// N.B. All DNS requests will bypass the Windows DNS cache"DnsQueryRawinjectsDNS_QUERY_BYPASS_CACHEinternally — this is documented Microsoft API behavior- Ubuntu 24.04 compiles systemd-resolved with
Cache=no-negative(visible viaresolvectl statistics) - With the Windows cache bypassed and negative caching disabled, every dual-stack lookup (A + AAAA) for an IPv4-only host sends the AAAA query through the full tunnel every time
Proposed Fix
Write a systemd-resolved drop-in configuration at /run/systemd/resolved.conf.d/wsl-dns-cache.conf with Cache=yes during GenerateSystemdUnits() in init.cpp. This:
- Uses the same
UtilMkdirPath()+WriteToFile()pattern already used inHardenMirroredNetworkingSettingsAgainstSystemd() - Is non-persistent (
/runis tmpfs, cleared on reboot) - Is non-fatal (failure to write is silently ignored)
- Is distro-agnostic (only affects distros using systemd-resolved)
- Has zero impact on distros that don't use systemd-resolved
Related Issues
- DNS resolver sets TTL for all answers to
0#9423 — DNS resolution performance - WSL DNS tunnel nameserver appends search suffixes to IPv6 queries for domains without AAAA records, causing timeouts and mismatches #13415 — DNS latency/timeout complaints
Environment
- WSL version: 2.7.1.0
- Windows version: Windows 11
- Distro: Ubuntu 24.04 (systemd 255)
- DNS tunneling: enabled (default)