feat: DNS-over-HTTPS (DoH) upstream forwarding #14

Merged
razvandimescu merged 3 commits from feat/doh-upstream into main 2026-03-24 06:39:58 +08:00
razvandimescu commented 2026-03-24 06:36:57 +08:00 (Migrated from github.com)

Summary

  • Encrypt upstream DNS queries via DoH — ISPs see HTTPS on port 443, not plaintext DNS on port 53
  • URL scheme determines transport: https:// = DoH, bare IP = plain UDP
  • Falls back to Quad9 DoH when system resolver cannot be detected
  • Upstream enum with Display, PartialEq, Clone — dispatches to UDP or DoH transport
  • BytePacketBuffer::from_bytes constructor for cleaner buffer initialization
  • reqwest http2 feature for DoH server compatibility (required by Quad9, Cloudflare)
  • network_watch_loop guards against DoH→UDP silent downgrade
  • Config: address = "https://9.9.9.9/dns-query" in [upstream] section

Test plan

  • 5 new tests: mock DoH server round-trip, HTTP error propagation, timeout handling, Display/PartialEq
  • 27 total tests pass
  • make all green (fmt, clippy, audit, build)
  • Smoke tested: Numa with Quad9 DoH resolves google.com (52ms first query, 16ms reuse, 0ms cached)
  • Verified via /stats endpoint: upstream shows https://9.9.9.9/dns-query
  • Verify with tcpdump that no port 53 traffic leaves the host

🤖 Generated with Claude Code

## Summary - Encrypt upstream DNS queries via DoH — ISPs see HTTPS on port 443, not plaintext DNS on port 53 - URL scheme determines transport: `https://` = DoH, bare IP = plain UDP - Falls back to Quad9 DoH when system resolver cannot be detected - `Upstream` enum with `Display`, `PartialEq`, `Clone` — dispatches to UDP or DoH transport - `BytePacketBuffer::from_bytes` constructor for cleaner buffer initialization - `reqwest` `http2` feature for DoH server compatibility (required by Quad9, Cloudflare) - `network_watch_loop` guards against DoH→UDP silent downgrade - Config: `address = "https://9.9.9.9/dns-query"` in `[upstream]` section ## Test plan - [x] 5 new tests: mock DoH server round-trip, HTTP error propagation, timeout handling, Display/PartialEq - [x] 27 total tests pass - [x] `make all` green (fmt, clippy, audit, build) - [x] Smoke tested: Numa with Quad9 DoH resolves google.com (52ms first query, 16ms reuse, 0ms cached) - [x] Verified via `/stats` endpoint: upstream shows `https://9.9.9.9/dns-query` - [ ] Verify with `tcpdump` that no port 53 traffic leaves the host 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.