MCPcopy
hub / github.com/coredns/coredns / ServeDNS

Method ServeDNS

plugin/cache/handler.go:17–89  ·  view source on GitHub ↗

ServeDNS implements the plugin.Handler interface.

(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)

Source from the content-addressed store, hash-verified

15
16// ServeDNS implements the plugin.Handler interface.
17func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
18 rc := r.Copy() // We potentially modify r, to prevent other plugins from seeing this (r is a pointer), copy r into rc.
19 state := request.Request{W: w, Req: rc}
20 do := state.Do()
21 cd := r.CheckingDisabled
22 ad := r.AuthenticatedData
23
24 zone := plugin.Zones(c.Zones).Matches(state.Name())
25 if zone == "" {
26 return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, rc)
27 }
28
29 now := c.now().UTC()
30 server := metrics.WithServer(ctx)
31
32 // On cache refresh, we will just use the DO bit from the incoming query for the refresh since we key our cache
33 // with the query DO bit. That means two separate cache items for the query DO bit true or false. In the situation
34 // in which upstream doesn't support DNSSEC, the two cache items will effectively be the same. Regardless, any
35 // DNSSEC RRs in the response are written to cache with the response.
36
37 i := c.getIfNotStale(now, state, server)
38 if i == nil {
39 crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: state, server: server, do: do, ad: ad, cd: cd,
40 nexcept: c.nexcept, pexcept: c.pexcept, wildcardFunc: wildcardFunc(ctx)}
41 return c.doRefresh(ctx, state, crr)
42 }
43 ttl := i.ttl(now)
44 if ttl < 0 {
45 // serve stale behavior
46 if c.verifyStale {
47 crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: state, server: server, do: do, cd: cd}
48 if c.verifyStaleTimeout > 0 {
49 // Background verify: cache the response but do not write to the wire.
50 // On timeout, we serve the stale entry below and let the goroutine continue.
51 crr.prefetch = true
52 }
53 cw := newVerifyStaleResponseWriter(crr)
54 if c.verifyStaleTimeout == 0 {
55 ret, err := c.doRefresh(ctx, state, cw)
56 if cw.refreshed {
57 return ret, err
58 }
59 } else if served, ret, err := c.verifyWithTimeout(ctx, state, w, cw, r, do, ad); served {
60 return ret, err
61 }
62 }
63
64 // Adjust the time to get a 0 TTL in the reply built from a stale item.
65 now = now.Add(time.Duration(ttl) * time.Second)
66 if !c.verifyStale {
67 c.tryPrefetch(ctx, i, server, rc, do, cd, now)
68 }
69 servedStale.WithLabelValues(server, c.zonesMetricLabel, c.viewMetricLabel).Inc()
70 } else if c.shouldPrefetch(i, now) {
71 c.tryPrefetch(ctx, i, server, rc, do, cd, now)
72 }
73
74 if i.wildcard != "" {

Callers

nothing calls this directly

Calls 15

DoMethod · 0.95
NameMethod · 0.95
NameMethod · 0.95
getIfNotStaleMethod · 0.95
doRefreshMethod · 0.95
verifyWithTimeoutMethod · 0.95
tryPrefetchMethod · 0.95
shouldPrefetchMethod · 0.95
ZonesTypeAlias · 0.92
NextOrFailureFunction · 0.92
WithServerFunction · 0.92
SetValueFuncFunction · 0.92

Tested by

no test coverage detected