middleware/cache: fix race (#757)

While adding a parallel performance benchmark I stumbled on a race
condition (another reason to add performance benchmarks!), so this
PR makes sure the msg is created in a race free manor and adds the
parallel benchmark.
This commit is contained in:
Miek Gieben
2017-06-26 07:44:25 -07:00
committed by GitHub
parent ea90702bfc
commit da5880a273
4 changed files with 67 additions and 27 deletions

View File

@@ -63,12 +63,29 @@ func (i *item) toMsg(m *dns.Msg) *dns.Msg {
m1.Rcode = i.Rcode
m1.Compress = true
m1.Answer = i.Answer
m1.Ns = i.Ns
m1.Extra = i.Extra
m1.Answer = make([]dns.RR, len(i.Answer))
m1.Ns = make([]dns.RR, len(i.Ns))
m1.Extra = make([]dns.RR, len(i.Extra))
ttl := int(i.origTTL) - int(time.Now().UTC().Sub(i.stored).Seconds())
setMsgTTL(m1, uint32(ttl))
ttl := uint32(i.ttl(time.Now()))
if ttl < minTTL {
ttl = minTTL
}
for j, r := range i.Answer {
m1.Answer[j] = dns.Copy(r)
m1.Answer[j].Header().Ttl = ttl
}
for j, r := range i.Ns {
m1.Ns[j] = dns.Copy(r)
m1.Ns[j].Header().Ttl = ttl
}
for j, r := range i.Extra {
m1.Extra[j] = dns.Copy(r)
if m1.Extra[j].Header().Rrtype != dns.TypeOPT {
m1.Extra[j].Header().Ttl = ttl
}
}
return m1
}
@@ -77,27 +94,6 @@ func (i *item) ttl(now time.Time) int {
return ttl
}
// setMsgTTL sets the ttl on all RRs in all sections. If ttl is smaller than minTTL
// that value is used.
func setMsgTTL(m *dns.Msg, ttl uint32) {
if ttl < minTTL {
ttl = minTTL
}
for _, r := range m.Answer {
r.Header().Ttl = ttl
}
for _, r := range m.Ns {
r.Header().Ttl = ttl
}
for _, r := range m.Extra {
if r.Header().Rrtype == dns.TypeOPT {
continue
}
r.Header().Ttl = ttl
}
}
func minMsgTTL(m *dns.Msg, mt response.Type) time.Duration {
if mt != response.NoError && mt != response.NameError && mt != response.NoData {
return 0