Skip to content

Managed DnsResolver does not support EDNS(0), limiting UDP responses to 512 bytes #132276

Description

@rzikm

Description

The managed DnsResolver stub resolver (DnsResolverPal.Managed.cs), used on Linux and — as of #132216 — all other Unix platforms, does not implement EDNS(0) (RFC 6891). Queries are sent without an OPT pseudo-record, so the resolver is stuck with the original RFC 1035 512-byte UDP payload limit.

In DnsResolverPal.Managed.cs:

private const int MaxUdpResponseSize = 512;

and the UDP receive buffer is rented at exactly that size. No OPT record is ever appended to the additional section of an outgoing query — AdditionalCount is only ever read when parsing a response.

Impact

Any response larger than 512 bytes comes back with the TC (truncation) bit set, which sends us down the TCP fallback path (ValidateResponse returns ResponseValidation.TcpFallback). That costs a full extra round trip plus a TCP connection setup, versus a single UDP exchange for a resolver that advertises a larger payload size.

This is not an edge case. Responses that routinely exceed 512 bytes include:

  • Domains with many A/AAAA records (large CDN or load-balanced pools)
  • TXT lookups — SPF/DKIM/DMARC records are frequently well over 512 bytes
  • MX and NS sets with a lot of additional-section glue
  • Anything DNSSEC-signed (RRSIG records are large)

glibc's stub resolver has enabled EDNS0 by default since 2.26 (RES_DFLT_OPTIONS), with a 1232-byte buffer, so today we pay a TCP round trip in cases where the platform resolver would not.

Proposal

Append an OPT record to the additional section of outgoing queries, advertising a sensible UDP payload size, and grow the receive buffer to match. 1232 bytes is the value recommended by DNS Flag Day 2020 — it is chosen to stay under the smallest plausible path MTU and avoid IP fragmentation, which is a reliability and security problem for DNS.

Additionally, ResolvConf.cs currently parses only nameserver lines and ignores options entirely. If EDNS0 is added, it would be reasonable to honour the related knobs:

  • options edns0 / options no-edns0
  • options bufsize:N (glibc does not support this one, but other resolvers do)

Care is needed around resolvers that mishandle OPT: the conventional mitigation is to retry without EDNS0 when a server responds FORMERR/NOTIMP or does not answer at all.

Notes

This is a pre-existing gap, not a regression — the resolver behaves correctly today, just with an extra round trip on large responses. Filing as a follow-up from the discussion on #132216.

Related: #132212 (Android DNS server discovery), #132215 (WASI support).

Another gap noticed in the same area, filed here for visibility rather than as part of this request: ResolvConf also ignores search and domain lines, so short/unqualified names that resolve via Dns.GetHostEntry will return NXDOMAIN through Dns.ResolveAddresses. Happy to split that into its own issue if preferred.

Note

This issue was drafted by GitHub Copilot.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions