diff options
author | 2016-11-07 16:27:50 +0000 | |
---|---|---|
committer | 2016-11-07 16:27:50 +0000 | |
commit | e89c4b5c2863cdc889ac756185a15d1e959ddcdc (patch) | |
tree | c11d805316fdc54c1de4c8ee009180da9035a601 | |
parent | 4318dfbf02ca4248dab29fc4fb730e2515a05754 (diff) | |
download | coredns-e89c4b5c2863cdc889ac756185a15d1e959ddcdc.tar.gz coredns-e89c4b5c2863cdc889ac756185a15d1e959ddcdc.tar.zst coredns-e89c4b5c2863cdc889ac756185a15d1e959ddcdc.zip |
middleware/cache: only cache query and responses (#397)
Extent typify to check the transfers, dynamic updates and notifies.
Extend *cache* to not put these in the cache.
Fixes #393
-rw-r--r-- | middleware/cache/cache.go | 10 | ||||
-rw-r--r-- | middleware/pkg/response/typify.go | 32 |
2 files changed, 36 insertions, 6 deletions
diff --git a/middleware/cache/cache.go b/middleware/cache/cache.go index d17253c38..a1db2039e 100644 --- a/middleware/cache/cache.go +++ b/middleware/cache/cache.go @@ -29,13 +29,16 @@ type Cache struct { pttl time.Duration } -// Return key under which we store the item. +// Return key under which we store the item. The empty string is returned +// when we don't want to cache the message. Currently we do not cache Truncated, errors +// zone transfers or dynamic update messages. func key(m *dns.Msg, t response.Type, do bool) string { + // We don't store truncated responses. if m.Truncated { - // TODO(miek): wise to store truncated responses? return "" } - if t == response.OtherError { + // Nor errors or Meta or Update + if t == response.OtherError || t == response.Meta || t == response.Update { return "" } @@ -65,6 +68,7 @@ func (c *ResponseWriter) WriteMsg(res *dns.Msg) error { do = opt.Do() } + // key returns empty string for anything we don't want to cache. key := key(res, mt, do) duration := c.pttl diff --git a/middleware/pkg/response/typify.go b/middleware/pkg/response/typify.go index f121ecccf..d2bbeb47e 100644 --- a/middleware/pkg/response/typify.go +++ b/middleware/pkg/response/typify.go @@ -14,11 +14,15 @@ const ( NoError Type = iota // NameError is a NXDOMAIN in header, SOA in auth. NameError - // NoData indicated name found, but not the type: NOERROR in header, SOA in auth. + // NoData indicates name found, but not the type: NOERROR in header, SOA in auth. NoData // Delegation is a msg with a pointer to another nameserver: NOERROR in header, NS in auth, optionally fluff in additional (not checked). Delegation - // OtherError indicated any other error: don't cache these. + // Meta indicates a meta message, NOTIFY, or a transfer: qType is IXFR or AXFR. + Meta + // Update is an dynamic update message. + Update + // OtherError indicates any other error: don't cache these. OtherError ) @@ -32,6 +36,10 @@ func (t Type) String() string { return "NODATA" case Delegation: return "DELEGATION" + case Meta: + return "META" + case Update: + return "UPDATE" case OtherError: return "OTHERERROR" } @@ -50,6 +58,10 @@ func TypeFromString(s string) (Type, error) { return NoData, nil case "DELEGATION": return Delegation, nil + case "META": + return Meta, nil + case "UPDATE": + return Update, nil case "OTHERERROR": return OtherError, nil } @@ -61,9 +73,23 @@ func Typify(m *dns.Msg) (Type, *dns.OPT) { if m == nil { return OtherError, nil } - opt := m.IsEdns0() + if m.Opcode == dns.OpcodeUpdate { + return Update, opt + } + + // Check transfer and update first + if m.Opcode == dns.OpcodeNotify { + return Meta, opt + } + + if len(m.Question) > 0 { + if m.Question[0].Qtype == dns.TypeAXFR || m.Question[0].Qtype == dns.TypeIXFR { + return Meta, opt + } + } + if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess { return NoError, opt } |