plugin/rewrite: apply rcode rewrites to responses with no records (#8421)

* plugin/rewrite: apply rcode rewrites to record-less responses

An rcode rewrite rewrites the message-level RCODE, but the reverter only ran
response rules from inside the per-record loops in WriteMsg. When a response
carries no answer, authority or additional records - for example a bare
SERVFAIL that a downstream plugin returns to a non-EDNS client - none of the
loops iterate, so the rcode rewrite was silently skipped and the client
received the original RCODE.

Apply message-level response rules once when the response has no records, using
a small marker interface that mirrors the existing requestExtraRevertRule
pattern. This fixes the plugin's documented SERVFAIL-to-NOERROR use case for
responses without records.

Signed-off-by: Sueun Cho <sueun.dev@gmail.com>

* plugin/rewrite: apply fallback rcode rewrites for continue

Signed-off-by: Sueun Cho <sueun.dev@gmail.com>

---------

Signed-off-by: Sueun Cho <sueun.dev@gmail.com>
This commit is contained in:
Sueun Cho
2026-08-18 12:12:32 +09:00
committed by GitHub
parent 897b4ce643
commit 9a623cdeed
5 changed files with 99 additions and 13 deletions

View File

@@ -24,6 +24,10 @@ func (r *rcodeResponseRule) RewriteResponse(res *dns.Msg, _rr dns.RR) {
}
}
// rewriteMsg marks rcodeResponseRule as a message-level rule so it is applied
// even when the response carries no resource records.
func (r *rcodeResponseRule) rewriteMsg() {}
type rcodeRuleBase struct {
nextAction string
response rcodeResponseRule