aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2016-11-07 16:27:50 +0000
committerGravatar GitHub <noreply@github.com> 2016-11-07 16:27:50 +0000
commite89c4b5c2863cdc889ac756185a15d1e959ddcdc (patch)
treec11d805316fdc54c1de4c8ee009180da9035a601
parent4318dfbf02ca4248dab29fc4fb730e2515a05754 (diff)
downloadcoredns-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.go10
-rw-r--r--middleware/pkg/response/typify.go32
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
}