The bundled DNS server in Sources/DNSServer/DNSServer.swift is UDP-only today. Two TODO markers in the source flag this as known-incomplete:
DNSServer.swift:39 // TODO: TCP server
DNSServer.swift:62 // TODO: TCP server
RFC 7766 ("DNS Transport over TCP - Implementation Requirements") requires modern resolvers to support TCP both as a fallback when UDP responses exceed 512 bytes (TC bit set) and as a primary transport. Without TCP, these query classes return truncated data or fail inside containers:
- DNSSEC-signed responses (RRSIG records push past 512 bytes regularly)
- Large AAAA / SRV / TXT records
- SPF / DKIM TXT chains (
_spf.google.com is a common offender)
This shows up in the wild as "DNS sometimes works" bugs that are hard to attribute to the bundled resolver.
Proposed scope: add a TCP listener bound to the same address as the UDP socket, parse RFC 1035 length-prefixed messages, dispatch to the existing Handlers/ stack, write the response back with the length prefix. Reuses the parser and handlers - transport-layer change only. ~200 lines including tests.
Happy to put up a PR if this fits the project's direction. Filing the issue first since I didn't see one tracking it.
The bundled DNS server in
Sources/DNSServer/DNSServer.swiftis UDP-only today. Two TODO markers in the source flag this as known-incomplete:DNSServer.swift:39// TODO: TCP serverDNSServer.swift:62// TODO: TCP serverRFC 7766 ("DNS Transport over TCP - Implementation Requirements") requires modern resolvers to support TCP both as a fallback when UDP responses exceed 512 bytes (TC bit set) and as a primary transport. Without TCP, these query classes return truncated data or fail inside containers:
_spf.google.comis a common offender)This shows up in the wild as "DNS sometimes works" bugs that are hard to attribute to the bundled resolver.
Proposed scope: add a TCP listener bound to the same address as the UDP socket, parse RFC 1035 length-prefixed messages, dispatch to the existing
Handlers/stack, write the response back with the length prefix. Reuses the parser and handlers - transport-layer change only. ~200 lines including tests.Happy to put up a PR if this fits the project's direction. Filing the issue first since I didn't see one tracking it.