fix: forwarding rules override special-use NXDOMAIN #95

Merged
razvandimescu merged 7 commits from fix/forwarding-precedes-special-use into main 2026-04-13 14:37:19 +08:00
razvandimescu commented 2026-04-13 13:11:25 +08:00 (Migrated from github.com)

Summary

  • Explicit [[forwarding]] rules now take precedence over RFC 6303 special-use domain intercept — PTR queries for private ranges (e.g. 168.192.in-addr.arpa) are forwarded to the configured upstream instead of returning local NXDOMAIN
  • resolve_query returns (BytePacketBuffer, QueryPath) so callers and tests can inspect the resolution path directly
  • Shared test infrastructure in src/testutil.rs: test_ctx(), mock_upstream(), blackhole_upstream() — deduplicates ~120 lines of 30-field ServerCtx construction across ctx.rs, api.rs, dot.rs
  • Full-pipeline resolve_query tests covering every step: overrides, localhost, local zones, special-use, TLD proxy, blocklist, cache, forwarding (with mock upstream)

Closes #94

Test plan

  • 282 tests pass (cargo test), fmt/clippy/audit clean
  • special_use_private_ptr_returns_nxdomain — private PTR without forwarding rule returns NXDOMAIN
  • forwarding_rule_overrides_special_use_domain — same PTR with forwarding rule reaches upstream
  • pipeline_forwarding_returns_upstream_answer — forwarded response content (domain + IP) verified through mock
  • Pipeline tests for all 9 steps: override, localhost, localhost subdomain, local zone, special-use, TLD proxy, blocklist, cache, forwarding
  • Manual: configure [[forwarding]] with suffix = ["168.192.in-addr.arpa"] and verify drill -x 192.168.188.153 returns the upstream answer
## Summary - Explicit `[[forwarding]]` rules now take precedence over RFC 6303 special-use domain intercept — PTR queries for private ranges (e.g. `168.192.in-addr.arpa`) are forwarded to the configured upstream instead of returning local NXDOMAIN - `resolve_query` returns `(BytePacketBuffer, QueryPath)` so callers and tests can inspect the resolution path directly - Shared test infrastructure in `src/testutil.rs`: `test_ctx()`, `mock_upstream()`, `blackhole_upstream()` — deduplicates ~120 lines of 30-field `ServerCtx` construction across `ctx.rs`, `api.rs`, `dot.rs` - Full-pipeline `resolve_query` tests covering every step: overrides, localhost, local zones, special-use, TLD proxy, blocklist, cache, forwarding (with mock upstream) Closes #94 ## Test plan - [x] 282 tests pass (`cargo test`), fmt/clippy/audit clean - [x] `special_use_private_ptr_returns_nxdomain` — private PTR without forwarding rule returns NXDOMAIN - [x] `forwarding_rule_overrides_special_use_domain` — same PTR with forwarding rule reaches upstream - [x] `pipeline_forwarding_returns_upstream_answer` — forwarded response content (domain + IP) verified through mock - [x] Pipeline tests for all 9 steps: override, localhost, localhost subdomain, local zone, special-use, TLD proxy, blocklist, cache, forwarding - [x] Manual: configure `[[forwarding]]` with `suffix = ["168.192.in-addr.arpa"]` and verify `drill -x 192.168.188.153` returns the upstream answer
Sign in to join this conversation.