aboutsummaryrefslogtreecommitdiff
path: root/plugin/cache/cache.go
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2020-09-17 16:28:43 +0200
committerGravatar GitHub <noreply@github.com> 2020-09-17 07:28:43 -0700
commitacf9a0fa19928e605ac8ac3314890c9fef73e16b (patch)
treea442ad2a7894d86b462eade46c44db4572016333 /plugin/cache/cache.go
parent22b68466262219284a47063e7f7bf9a833d21b61 (diff)
downloadcoredns-acf9a0fa19928e605ac8ac3314890c9fef73e16b.tar.gz
coredns-acf9a0fa19928e605ac8ac3314890c9fef73e16b.tar.zst
coredns-acf9a0fa19928e605ac8ac3314890c9fef73e16b.zip
cache: default to DNSSEC (#4085)
* cache: default to DNSSEC This change does away with the DNS/DNSSEC distinction the cache currently makes. Cache will always make coredns perform a DNSSEC query and store that result. If a client just needs plain DNS, the DNSSEC records are stripped from the response. It should also be more memory efficient, because we store a reply once and not one DNS and another for DNSSEC. Fixes: #3836 Signed-off-by: Miek Gieben <miek@miek.nl> * Change OPT RR when one is present in the msg. Signed-off-by: Miek Gieben <miek@miek.nl> * Fix comment for isDNSSEC Signed-off-by: Miek Gieben <miek@miek.nl> * Update plugin/cache/handler.go Co-authored-by: Chris O'Haver <cohaver@infoblox.com> * Update plugin/cache/item.go Co-authored-by: Chris O'Haver <cohaver@infoblox.com> * Code review; fix comment for isDNSSEC Signed-off-by: Miek Gieben <miek@miek.nl> * Update doc and set AD to false Set Authenticated Data to false when DNSSEC was not wanted. Also update the readme with the new behavior. Signed-off-by: Miek Gieben <miek@miek.nl> * Update plugin/cache/handler.go Co-authored-by: Chris O'Haver <cohaver@infoblox.com> Co-authored-by: Chris O'Haver <cohaver@infoblox.com>
Diffstat (limited to 'plugin/cache/cache.go')
-rw-r--r--plugin/cache/cache.go60
1 files changed, 33 insertions, 27 deletions
diff --git a/plugin/cache/cache.go b/plugin/cache/cache.go
index 9988d9c70..32185de19 100644
--- a/plugin/cache/cache.go
+++ b/plugin/cache/cache.go
@@ -65,31 +65,21 @@ func New() *Cache {
// key returns key under which we store the item, -1 will be returned if we don't store the message.
// Currently we do not cache Truncated, errors zone transfers or dynamic update messages.
// qname holds the already lowercased qname.
-func key(qname string, m *dns.Msg, t response.Type, do bool) (bool, uint64) {
+func key(qname string, m *dns.Msg, t response.Type) (bool, uint64) {
// We don't store truncated responses.
if m.Truncated {
return false, 0
}
- // Nor errors or Meta or Update
+ // Nor errors or Meta or Update.
if t == response.OtherError || t == response.Meta || t == response.Update {
return false, 0
}
- return true, hash(qname, m.Question[0].Qtype, do)
+ return true, hash(qname, m.Question[0].Qtype)
}
-var one = []byte("1")
-var zero = []byte("0")
-
-func hash(qname string, qtype uint16, do bool) uint64 {
+func hash(qname string, qtype uint16) uint64 {
h := fnv.New64()
-
- if do {
- h.Write(one)
- } else {
- h.Write(zero)
- }
-
h.Write([]byte{byte(qtype >> 8)})
h.Write([]byte{byte(qtype)})
h.Write([]byte(qname))
@@ -152,14 +142,10 @@ func (w *ResponseWriter) RemoteAddr() net.Addr {
// WriteMsg implements the dns.ResponseWriter interface.
func (w *ResponseWriter) WriteMsg(res *dns.Msg) error {
- do := false
- mt, opt := response.Typify(res, w.now().UTC())
- if opt != nil {
- do = opt.Do()
- }
+ mt, _ := response.Typify(res, w.now().UTC())
// key returns empty string for anything we don't want to cache.
- hasKey, key := key(w.state.Name(), res, mt, do)
+ hasKey, key := key(w.state.Name(), res, mt)
msgTTL := dnsutil.MinimalTTL(res, mt)
var duration time.Duration
@@ -187,18 +173,38 @@ func (w *ResponseWriter) WriteMsg(res *dns.Msg) error {
return nil
}
+ do := w.state.Do()
+
// Apply capped TTL to this reply to avoid jarring TTL experience 1799 -> 8 (e.g.)
+ // We also may need to filter out DNSSEC records, see toMsg() for similar code.
ttl := uint32(duration.Seconds())
- for i := range res.Answer {
- res.Answer[i].Header().Ttl = ttl
+ j := 0
+ for _, r := range res.Answer {
+ if !do && isDNSSEC(r) {
+ continue
+ }
+ res.Answer[j].Header().Ttl = ttl
+ j++
}
- for i := range res.Ns {
- res.Ns[i].Header().Ttl = ttl
+ res.Answer = res.Answer[:j]
+ j = 0
+ for _, r := range res.Ns {
+ if !do && isDNSSEC(r) {
+ continue
+ }
+ res.Ns[j].Header().Ttl = ttl
+ j++
}
- for i := range res.Extra {
- if res.Extra[i].Header().Rrtype != dns.TypeOPT {
- res.Extra[i].Header().Ttl = ttl
+ res.Ns = res.Ns[:j]
+ j = 0
+ for _, r := range res.Extra {
+ if !do && isDNSSEC(r) {
+ continue
+ }
+ if res.Extra[j].Header().Rrtype != dns.TypeOPT {
+ res.Extra[j].Header().Ttl = ttl
}
+ j++
}
return w.ResponseWriter.WriteMsg(res)
}