dns: preserve TTL values and enable systemd-resolved caching#14572
dns: preserve TTL values and enable systemd-resolved caching#14572syed-dawood wants to merge 2 commits intomicrosoft:masterfrom
Conversation
|
cc @benhillis @OneBlue @craigloewen-msft @jstarks @damanm24 — requesting review on this DNS performance fix. This addresses the
Both changes were empirically validated. See the PR description for detailed test results and safety analysis. |
There was a problem hiding this comment.
Pull request overview
This PR improves DNS performance in WSL’s DNS tunneling path by (1) preserving upstream TTL values in tunneled DNS responses and (2) enabling systemd-resolved to cache negative responses, reducing repeated high-latency lookups (notably AAAA→NODATA on IPv4-only networks).
Changes:
- Set
DNS_QUERY_DONT_RESET_TTL_VALUESonDnsQueryRawrequests so returned DNS responses carry decremented TTLs. - Generate a
/run/systemd/resolved.conf.d/drop-in to setsystemd-resolvedCache=yesduring systemd boot.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/windows/common/DnsResolver.cpp |
Adds a DNS query option to preserve real TTLs in tunneled DNS responses and updates the related comment. |
src/linux/init/init.cpp |
Writes a systemd-resolved drop-in under /run/ to enable positive + negative DNS caching. |
DnsQueryRaw internally bypasses the Windows DNS cache, causing all DNS responses tunneled to WSL to carry reset TTL values. This breaks downstream caching in systemd-resolved, leading to repeated wire queries for every DNS lookup — including negative (NODATA) responses for unsupported record types like AAAA on IPv4-only networks. This commit applies two complementary fixes: 1. Add DNS_QUERY_DONT_RESET_TTL_VALUES flag to DnsQueryRaw requests (DnsResolver.cpp) so that responses carry real decremented TTL values from upstream resolvers instead of reset-to-original values. 2. Write a systemd-resolved drop-in config enabling Cache=yes (init.cpp) to cache both positive and negative DNS responses. The default Cache=no-negative discards NODATA/NXDOMAIN answers, causing repeated wire queries for record types that will never resolve. Together these changes restore effective DNS caching for WSL, reducing redundant network round-trips and improving DNS resolution latency. Fixes: microsoft#14568 Related: microsoft#9423, microsoft#13415
9f6ea31 to
ab7c069
Compare
|
@microsoft-github-policy-service agree |
Summary of the Pull Request
DnsQueryRawinternally injectsDNS_QUERY_BYPASS_CACHE, causing all DNS responses tunneled through WSL to bypass the Windows DNS cache. This results in:Cache=no-negative, negative responses (NODATA/NXDOMAIN) are never cached, causing repeated wire queries for unsupported record types (e.g. AAAA on IPv4-only networks)This PR adds
DNS_QUERY_DONT_RESET_TTL_VALUESto preserve real TTL values, and enables full DNS caching in systemd-resolved via a drop-in config.PR Checklist
Detailed Description of the Pull Request / Additional comments
Root Cause
DnsQueryRaw(dnsapi.dll) always addsDNS_QUERY_BYPASS_CACHEtoqueryOptionsinternally. This was confirmed empirically by callingDnsQueryRawvia P/Invoke and inspecting the returnedqueryOptionsinDNS_QUERY_RAW_RESULT— the0x8flag is always present regardless of input flags.This means:
DNS_PROTOCOL_NO_WIREis never returnedChanges
1.
src/windows/common/DnsResolver.cpp— AddDNS_QUERY_DONT_RESET_TTL_VALUESSets the
DNS_QUERY_DONT_RESET_TTL_VALUES(0x00100000) flag alongside the existingDNS_QUERY_NO_MULTICAST. This tells the Windows DNS client to preserve real decremented TTL values from upstream resolvers, enabling systemd-resolved to cache responses with meaningful lifetimes.This is safe because
HandleDnsQueryCompletionperforms a rawCopyMemoryof response bytes — no WSL code inspects or modifies TTL values in the DNS response.2.
src/linux/init/init.cpp— EnableCache=yesin systemd-resolvedWrites a drop-in config to
/run/systemd/resolved.conf.d/wsl-dns-cache.confchanging systemd-resolved fromCache=no-negative(default) toCache=yes. This enables caching of both positive and negative DNS responses./run/(tmpfs) so it's regenerated each boot and user overrides in/etc/take precedenceUtilMkdirPath()/WriteToFile()pattern from the same functionRelated Issues
0#9423 — TTL=0 in DNS responsesValidation Steps Performed
Empirical DnsQueryRaw testing (Windows)
A C# test program calling
DnsQueryRawvia P/Invoke confirmed:NO_MULTICASTonly0x80000800+ DONT_RESET_TTL0x80100800NO_WIRE_QUERYERROR_INVALID_PARAMETERDNS benchmarking (WSL)
Dual-stack DNS benchmark (
dig A+dig AAAAfor 7 domains):