So the chain goes like this:
- In
cache.Cache.getIgnoreTTL goroutine gets a pointer to a shared object which contains previous response.
- In
cache.Cache.ServeDNS goroutine calls a toMsg method on item to transform shared object into unique response.
- And then
cache.filterRRSlice mutates shared object without synchronization.
My best guess is that:
r.Header().Ttl = ttl
if dup {
rs[j] = dns.Copy(r)
} else {
rs[j] = r
}
should be
if dup {
copied := dns.Copy(r)
copied.Header().Ttl = ttl
rs[j] = copied
} else {
r.Header().Ttl = ttl
rs[j] = r
}