mirror of
https://github.com/coredns/coredns.git
synced 2026-08-20 23:08:28 -04:00
plugin/cache: add prefer_positive stale policy (#8378)
* plugin/cache: add prefer_positive stale policy Add an opt-in serve_stale_policy that prefers an eligible success-cache answer over denial-cache entries while serve_stale is enabled. Preserve the existing ncache-first behavior when the policy is absent. Also classify SOA-backed CNAME NODATA responses in the cache so incomplete answers cannot be selected as positive stale responses. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25da81ab-92dd-4663-b480-efd6262090c6 Signed-off-by: Nitin Nizhawan <nnizhawan@microsoft.com> * plugin/cache: retain last-known-good positive answers Keep an answering success-cache item reachable when a later NOERROR or referral response overwrites the visible cache key without answering the question. This lets prefer_positive survive empty responses, referrals, and additional-only data while leaving policy-off lookup behavior unchanged. Return the exact accepted verify refresh item instead of re-reading an ambiguous cache key, avoiding expired TTL wraparound for uncacheable replies. Add regression coverage for non-answer refreshes, NODATA, SERVFAIL, NOTIMP, stale-window expiry, and bounded verify reply shaping. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25da81ab-92dd-4663-b480-efd6262090c6 Signed-off-by: Nitin Nizhawan <nnizhawan@microsoft.com> * plugin/cache: validate preferred stale answers Reject truncated, DNSSEC-expired, mismatched-class, unrelated ANY, and ambiguous CNAME refreshes before replacing a stale last-known-good answer. Precompute answer eligibility when cache items are created so prefer_positive hits avoid repeated CNAME walks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25da81ab-92dd-4663-b480-efd6262090c6 Signed-off-by: Nitin Nizhawan <nnizhawan@microsoft.com> --------- Signed-off-by: Nitin Nizhawan <nnizhawan@microsoft.com> Co-authored-by: Nitin Nizhawan <nnizhawan@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25da81ab-92dd-4663-b480-efd6262090c6
This commit is contained in:
21
plugin/cache/setup.go
vendored
21
plugin/cache/setup.go
vendored
@@ -63,6 +63,8 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
}
|
||||
}
|
||||
origins := plugin.OriginsFromArgsOrServerBlock(args, c.ServerBlockKeys)
|
||||
serveStaleConfigured := false
|
||||
serveStalePolicyConfigured := false
|
||||
|
||||
// Refinements? In an extra block.
|
||||
for c.NextBlock() {
|
||||
@@ -171,6 +173,7 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
}
|
||||
|
||||
case "serve_stale":
|
||||
serveStaleConfigured = true
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 5 {
|
||||
return nil, c.ArgErr()
|
||||
@@ -236,6 +239,21 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
case "serve_stale_policy":
|
||||
if serveStalePolicyConfigured {
|
||||
return nil, errors.New("serve_stale_policy can only be specified once")
|
||||
}
|
||||
serveStalePolicyConfigured = true
|
||||
args := c.RemainingArgs()
|
||||
if len(args) != 1 {
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
switch strings.ToLower(args[0]) {
|
||||
case "prefer_positive":
|
||||
ca.preferPositive = true
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid serve_stale_policy: %s", args[0])
|
||||
}
|
||||
case "servfail":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) != 1 {
|
||||
@@ -292,6 +310,9 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
}
|
||||
if serveStalePolicyConfigured && !serveStaleConfigured {
|
||||
return nil, errors.New("serve_stale_policy requires serve_stale")
|
||||
}
|
||||
|
||||
ca.Zones = origins
|
||||
ca.zonesMetricLabel = strings.Join(origins, ",")
|
||||
|
||||
Reference in New Issue
Block a user