aboutsummaryrefslogtreecommitdiff
path: root/plugin/cache/dnssec.go
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2020-09-28 16:53:00 +0200
committerGravatar GitHub <noreply@github.com> 2020-09-28 07:53:00 -0700
commit35b40a84f212223b6da8bae103471f67e3eedac5 (patch)
tree9b9773c21cd214c37dce3936e9ff20ca0186713d /plugin/cache/dnssec.go
parent1a1ce9a9c8eadd0e6154dd473a6e22b1f9e37ca2 (diff)
downloadcoredns-35b40a84f212223b6da8bae103471f67e3eedac5.tar.gz
coredns-35b40a84f212223b6da8bae103471f67e3eedac5.tar.zst
coredns-35b40a84f212223b6da8bae103471f67e3eedac5.zip
plugin/cache: Fix filtering (#4148)
The filtering of DNSSEC records in the cache plugin was not done correctly. Also the change to introduced this bug didn't take into account that the cache - by virtue of differentiating between DNSSEC and no-DNSSEC - relied on not copying the data from the cache. This change copies and then filters the data and factors the filtering into a function that is used in two places (albeit with on ugly boolean parameters to prevent copying things twice). Add tests, do_test.go is moved to test/cache_test.go because the OPT handing is done outside of the cache plugin. The core server re-attaches the correct OPT when replying, so that makes for a better e2e test. Added small unit test for filterRRslice and an explicit test that asks for DNSSEC first and then plain, and vice versa to test cache behavior. Fixes: #4146 Signed-off-by: Miek Gieben <miek@miek.nl>
Diffstat (limited to 'plugin/cache/dnssec.go')
-rw-r--r--plugin/cache/dnssec.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/plugin/cache/dnssec.go b/plugin/cache/dnssec.go
new file mode 100644
index 000000000..72520e345
--- /dev/null
+++ b/plugin/cache/dnssec.go
@@ -0,0 +1,43 @@
+package cache
+
+import "github.com/miekg/dns"
+
+// isDNSSEC returns true if r is a DNSSEC record. NSEC,NSEC3,DS and RRSIG/SIG
+// are DNSSEC records. DNSKEYs is not in this list on the assumption that the
+// client explictly asked for it.
+func isDNSSEC(r dns.RR) bool {
+ switch r.Header().Rrtype {
+ case dns.TypeNSEC:
+ return true
+ case dns.TypeNSEC3:
+ return true
+ case dns.TypeDS:
+ return true
+ case dns.TypeRRSIG:
+ return true
+ case dns.TypeSIG:
+ return true
+ }
+ return false
+}
+
+// filterRRSlice filters rrs and removes DNSSEC RRs when do is false. In the returned slice
+// the TTLs are set to ttl. If dup is true the RRs in rrs are _copied_ into the slice that is
+// returned.
+func filterRRSlice(rrs []dns.RR, ttl uint32, do, dup bool) []dns.RR {
+ j := 0
+ rs := make([]dns.RR, len(rrs), len(rrs))
+ for _, r := range rrs {
+ if !do && isDNSSEC(r) {
+ continue
+ }
+ r.Header().Ttl = ttl
+ if dup {
+ rs[j] = dns.Copy(r)
+ } else {
+ rs[j] = r
+ }
+ j++
+ }
+ return rs[:j]
+}