Skip to content

Fix TCP fallback for truncated DNS responses#11

Merged
retlehs merged 2 commits intoretlehs:mainfrom
timdittler:fix/tcp-fallback-truncated-dns
Apr 12, 2026
Merged

Fix TCP fallback for truncated DNS responses#11
retlehs merged 2 commits intoretlehs:mainfrom
timdittler:fix/tcp-fallback-truncated-dns

Conversation

@timdittler
Copy link
Copy Markdown
Contributor

Summary

  • Bug: query() in both internal/dns and internal/mail uses UDP only. Domains with many TXT records (e.g. 9+ records, >512 bytes) cause the DNS server to set the TC (truncated) flag. Records near the end of the response — often SPF — are silently dropped.
  • Fix: Check resp.Truncated after the UDP exchange and retry over TCP, matching the behavior of dig and other standard resolvers.
  • Tests: Added mail_test.go and dns_test.go with local mock DNS servers that simulate truncation, verifying the TCP fallback path and the no-truncation fast path.

Reproduction

# Shows SPF is present:
dig +short TXT staffbase.com | grep spf

# Shows empty SPF field — response is 603 bytes, truncated over UDP:
quien mail staffbase.com | jq .SPF

Test plan

  • go test ./internal/mail/ -run TestQuery -v — TCP fallback and UDP-only paths pass
  • go test ./internal/dns/ -run TestQuery -v — same
  • go test ./... — full suite (147 tests), zero failures

🤖 Generated with Claude Code

The query() functions in both internal/dns and internal/mail use UDP by
default but never retry over TCP when the response is truncated. Domains
with many TXT records (e.g. staffbase.com with 9 TXT records, ~603 bytes)
exceed the 512-byte UDP limit, causing the server to set the TC flag and
return a partial answer. Records near the end of the response — often SPF
— are silently dropped.

Check resp.Truncated after the initial UDP exchange and retry with a TCP
client, matching the behavior of dig and other resolvers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@timdittler timdittler marked this pull request as ready for review April 12, 2026 10:34
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner

@retlehs retlehs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@retlehs retlehs merged commit f40a3a7 into retlehs:main Apr 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants