plugin/cache: allow cache TTLs above default 3600s (#8134)

* plugin/cache: allow cache TTLs above default 3600s

This change allows the cache plugin to honor configured maximum TTL values above the default 3600s limit. Default behavior remains unchanged
This PR fixes 7846

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Keep MinimalTTL

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

---------

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang
2026-06-05 21:48:26 -07:00
committed by GitHub
parent b49fe2d469
commit 3342b414e3
5 changed files with 32 additions and 4 deletions

View File

@@ -221,14 +221,15 @@ func (w *ResponseWriter) WriteMsg(res *dns.Msg) error {
// key returns empty string for anything we don't want to cache.
hasKey, key := key(w.state.Name(), res, mt, w.do, w.cd)
msgTTL := dnsutil.MinimalTTL(res, mt)
var duration time.Duration
switch mt {
case response.NameError, response.NoData:
msgTTL := dnsutil.MinimalTTLWithMaximum(res, mt, w.nttl)
duration = computeTTL(msgTTL, w.minnttl, w.nttl)
case response.ServerError:
duration = w.failttl
default:
msgTTL := dnsutil.MinimalTTLWithMaximum(res, mt, w.pttl)
duration = computeTTL(msgTTL, w.minpttl, w.pttl)
}

View File

@@ -362,6 +362,27 @@ func TestCacheZeroTTL(t *testing.T) {
}
}
func TestCacheHonorsConfiguredPositiveMaxTTLAboveDefault(t *testing.T) {
c := New()
c.pttl = 2 * time.Hour
c.minpttl = 0
c.Next = ttlBackend(24 * 60 * 60)
req := new(dns.Msg)
req.SetQuestion("example.org.", dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
c.ServeDNS(context.TODO(), rec, req)
if rec.Msg == nil || len(rec.Msg.Answer) == 0 {
t.Fatalf("expected answer, got %+v", rec.Msg)
}
if got, want := rec.Msg.Answer[0].Header().Ttl, uint32(7200); got != want {
t.Fatalf("expected TTL %d, got %d", want, got)
}
}
func TestCacheServfailTTL0(t *testing.T) {
c := New()
c.minpttl = minTTL

View File

@@ -10,6 +10,12 @@ import (
// MinimalTTL scans the message returns the lowest TTL found taking into the response.Type of the message.
func MinimalTTL(m *dns.Msg, mt response.Type) time.Duration {
return MinimalTTLWithMaximum(m, mt, MaximumDefaultTTL)
}
// MinimalTTLWithMaximum scans the DNS message and returns the lowest TTL found,
// constrained by maximumTTL and the response type.
func MinimalTTLWithMaximum(m *dns.Msg, mt response.Type, maximumTTL time.Duration) time.Duration {
if mt != response.NoError && mt != response.NameError && mt != response.NoData {
return MinimalDefaultTTL
}
@@ -20,7 +26,7 @@ func MinimalTTL(m *dns.Msg, mt response.Type) time.Duration {
return MinimalDefaultTTL
}
minTTL := MaximumDefaulTTL
minTTL := maximumTTL
for _, r := range m.Answer {
if r.Header().Ttl < uint32(minTTL.Seconds()) {
minTTL = time.Duration(r.Header().Ttl) * time.Second