From 60e1490ed6c37991ec470cecb30615123ecbee05 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Thu, 28 Jan 2021 16:50:35 +0100 Subject: [PATCH] copy rrs (#4416) * Revert "make copies of RRs before returning them (#4409)" This reverts commit 8b2ff6c3889e0c23dceef4b10a1b1de58e463cb9. * Document copying responses See #4409 and the comments. This documents that issue, but doesn't change the in-tree plugins just yet. Signed-off-by: Miek Gieben * Update plugin.md Co-authored-by: Chris O'Haver Co-authored-by: Chris O'Haver --- plugin.md | 9 +++++++++ plugin/file/lookup.go | 7 +------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/plugin.md b/plugin.md index f7158651c..1973729f2 100644 --- a/plugin.md +++ b/plugin.md @@ -131,6 +131,15 @@ The `fallthrough` directive should optionally accept a list of zones. Only queri in one of those zones should be allowed to fallthrough. See `plugin/pkg/fallthrough` for the implementation. +## Mutating a Response + +Using a custom `ResponseWriter`, a plugin can mutate a response when another plugin further down the chain writes the response to the client. +If a plugin mutates a response it MUST make a copy of the entire response before doing so. A +response is a pointer to a `dns.Msg` and as such you will be manipulating the original response, +which could have been generated from a data store. E.g. the *file* plugin creates a response that +the *rewrite* plugin then rewrites; not copying the data, means it's **also** mutating the data of +the *file*'s data store. A response can be copied by using the `Copy()` method. + ## General Guidelines Some general guidelines: diff --git a/plugin/file/lookup.go b/plugin/file/lookup.go index cba1eec50..6eeb4c397 100644 --- a/plugin/file/lookup.go +++ b/plugin/file/lookup.go @@ -171,12 +171,7 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) return z.externalLookup(ctx, state, elem, rrs) } - treeRRs := elem.Type(qtype) - // make a copy of the element RRs to prevent response writers from mutating the tree - rrs := make([]dns.RR, len(treeRRs)) - for i, rr := range treeRRs { - rrs[i] = dns.Copy(rr) - } + rrs := elem.Type(qtype) // NODATA if len(rrs) == 0 {