diff options
author | 2018-06-19 20:50:08 +0200 | |
---|---|---|
committer | 2018-06-19 19:50:08 +0100 | |
commit | 9c2dc7a1564a4cfc5c197d99c828364fc02bfbae (patch) | |
tree | c664c38be016ee3ab8eafceab02031e22a74d5ea /plugin/cache/handler.go | |
parent | f78f30231df90da6184d5f811ecf9c06b0160c2b (diff) | |
download | coredns-9c2dc7a1564a4cfc5c197d99c828364fc02bfbae.tar.gz coredns-9c2dc7a1564a4cfc5c197d99c828364fc02bfbae.tar.zst coredns-9c2dc7a1564a4cfc5c197d99c828364fc02bfbae.zip |
Ensure cache.ResponseWriter can be used asynchronously during prefetch (#1884)
The default dns.Response implementation of a dns.ResponseWriter will
panic if RemoteAddr() is called after the connection to the client has
been closed already. The current cache implementation doesn't create a
new request+responsewriter during an asynchronous prefetch, but
piggybacks on the request triggering the prefetch.
This change copies the RemoteAddr first, so that it's safe to use it
later during the actual prefetch request.
A better implementation would be to completely decouple the prefetch
request from the client triggering a request.
Diffstat (limited to 'plugin/cache/handler.go')
-rw-r--r-- | plugin/cache/handler.go | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/plugin/cache/handler.go b/plugin/cache/handler.go index 598640568..bb5898934 100644 --- a/plugin/cache/handler.go +++ b/plugin/cache/handler.go @@ -40,20 +40,18 @@ func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) threshold := int(math.Ceil(float64(c.percentage) / 100 * float64(i.origTTL))) if i.Freq.Hits() >= c.prefetch && ttl <= threshold { - go func() { + cw := newPrefetchResponseWriter(server, state, c) + go func(w dns.ResponseWriter) { cachePrefetches.WithLabelValues(server).Inc() + plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r) + // When prefetching we loose the item i, and with it the frequency // that we've gathered sofar. See we copy the frequencies info back // into the new item that was stored in the cache. - prr := &ResponseWriter{ResponseWriter: w, Cache: c, - prefetch: true, state: state, - server: server} - plugin.NextOrFailure(c.Name(), c.Next, ctx, prr, r) - if i1 := c.exists(state); i1 != nil { i1.Freq.Reset(now, i.Freq.Hits()) } - }() + }(cw) } } return dns.RcodeSuccess, nil |