aboutsummaryrefslogtreecommitdiff
path: root/plugin/cache/cache.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/cache/cache.go')
-rw-r--r--plugin/cache/cache.go31
1 files changed, 30 insertions, 1 deletions
diff --git a/plugin/cache/cache.go b/plugin/cache/cache.go
index 59439653f..58a73e72c 100644
--- a/plugin/cache/cache.go
+++ b/plugin/cache/cache.go
@@ -38,7 +38,9 @@ type Cache struct {
duration time.Duration
percentage int
- staleUpTo time.Duration
+ // Stale serve
+ staleUpTo time.Duration
+ verifyStale bool
// Testing.
now func() time.Time
@@ -227,6 +229,33 @@ func (w *ResponseWriter) Write(buf []byte) (int, error) {
return n, err
}
+// verifyStaleResponseWriter is a response writer that only writes messages if they should replace a
+// stale cache entry, and otherwise discards them.
+type verifyStaleResponseWriter struct {
+ *ResponseWriter
+ refreshed bool // set to true if the last WriteMsg wrote to ResponseWriter, false otherwise.
+}
+
+// newVerifyStaleResponseWriter returns a ResponseWriter to be used when verifying stale cache
+// entries. It only forward writes if an entry was successfully refreshed according to RFC8767,
+// section 4 (response is NoError or NXDomain), and ignores any other response.
+func newVerifyStaleResponseWriter(w *ResponseWriter) *verifyStaleResponseWriter {
+ return &verifyStaleResponseWriter{
+ w,
+ false,
+ }
+}
+
+// WriteMsg implements the dns.ResponseWriter interface.
+func (w *verifyStaleResponseWriter) WriteMsg(res *dns.Msg) error {
+ w.refreshed = false
+ if res.Rcode == dns.RcodeSuccess || res.Rcode == dns.RcodeNameError {
+ w.refreshed = true
+ return w.ResponseWriter.WriteMsg(res) // stores to the cache and send to client
+ }
+ return nil // else discard
+}
+
const (
maxTTL = dnsutil.MaximumDefaulTTL
minTTL = dnsutil.MinimalDefaultTTL