diff options
author | 2020-09-17 16:28:43 +0200 | |
---|---|---|
committer | 2020-09-17 07:28:43 -0700 | |
commit | acf9a0fa19928e605ac8ac3314890c9fef73e16b (patch) | |
tree | a442ad2a7894d86b462eade46c44db4572016333 /plugin/cache/cache.go | |
parent | 22b68466262219284a47063e7f7bf9a833d21b61 (diff) | |
download | coredns-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.go | 60 |
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) } |