Skip to content

Commit e65b029

Browse files
committed
dnsx/cacher: m refactor
1 parent ae30df2 commit e65b029

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

intra/dnsx/cacher.go

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ func (c *cres) copy() *cres {
126126
anscopy = c.ans.Copy()
127127
}
128128
return &cres{
129-
ans: anscopy,
129+
ans: anscopy, // may be nil
130130
s: copySummary(c.s),
131-
expiry: c.expiry,
131+
expiry: c.expiry, // may be zero
132132
bumps: c.bumps,
133133
}
134134
}
@@ -290,7 +290,7 @@ func asResponse(q *dns.Msg, v *cres, fresh bool) (a *dns.Msg, s *x.DNSSummary, e
290290
// github.com/jedisct1/edgedns#correct-support-for-the-dns0x20-extension
291291
a.Question = q.Question
292292
if !fresh { // if the v is not fresh, set the ttl to the minimum
293-
xdns.WithTtl(a, stalettl)
293+
xdns.WithTtl(a, stalettl) // only set for Answer records
294294
}
295295
return
296296
}
@@ -312,12 +312,13 @@ func (t *ctransport) hangoverCheckpoint() {
312312
}
313313
}
314314

315-
func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb *cache, key string) (r *dns.Msg, err error) {
315+
func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb *cache, key string) (*dns.Msg, error) {
316316
sendRequest := func(fsmm *x.DNSSummary) (*dns.Msg, error) {
317317
fsmm.ID = t.Transport.ID()
318318
fsmm.Type = t.Transport.Type()
319319

320320
v, _ := t.reqbarrier.Do(key, func() (*cres, error) {
321+
// ans may be nil
321322
ans, qerr := Req(t.Transport, network, q, fsmm)
322323
t.hangoverCheckpoint()
323324
// cb.put no-ops when ans is nil or xdns.Len(ans) is 0
@@ -326,32 +327,38 @@ func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb
326327
return &cres{ans: ans, s: copySummary(fsmm)}, qerr
327328
})
328329

330+
err := v.Err
331+
329332
cachedres, fresh := cb.freshCopy(key) // always prefer value from cache
330-
if cachedres == nil { // use barrier response
331-
cachedres = v.Val.copy() // never nil, even on errs; but cres.ans may be nil
333+
if cachedres == nil { // v.Val may be uncacheable (ex: rcode != 0)
334+
cachedres = v.Val.copy() // v.Val (cres) never nil; but cres.ans may be nil
332335
log.D("cache: barrier: empty(k: %s); barrier: %s", key, v.String())
333336
} else if !fresh { // expect fresh values, except on verrs
334337
log.W("cache: barrier: stale(k: %s); barrier: %s (cache: %s)", key, v.String(), cachedres.String())
335338
}
336339

340+
// nil ans when Transport returns err (no servfail) and cache is empty
341+
hasans := cachedres.ans != nil
337342
// if there's no network connectivity (in hangover for 10s) don't
338343
// return cached/barriered response, instead return an error
339-
if !t.hangover.Within(ttl10s) {
340-
log.D("cache: barrier: hangover(k: %s); discard ans", key)
341-
err := errors.Join(v.Err, errHangover)
344+
inhangover := t.hangover.Exceeds(ttl10s)
345+
if inhangover {
346+
err = errors.Join(err, errHangover)
347+
log.D("cache: barrier: hangover(k: %s); discard ans (has? %t)", key, hasans)
342348
fillSummary(cachedres.s, fsmm)
343349
// mimic send fail
344350
fsmm.Msg = err.Error()
345351
fsmm.RCode = dns.RcodeServerFailure
346352
fsmm.Status = SendFailed
353+
// do not return any response (stall / drop silently)
347354
return nil, err
348355
}
349356

350-
fres, cachedsmm, ferr := asResponse(q, cachedres, true)
357+
fres, cachedsmm, ferr := asResponse(q, cachedres, fresh)
351358
// fill summary regardless of errors
352359
fillSummary(cachedsmm, fsmm) // cachedsmm may itself be fsmm
353360

354-
return fres, errors.Join(v.Err, ferr)
361+
return fres, errors.Join(err, ferr)
355362
}
356363

357364
// check if underlying transport can connect fine, if not treat cache
@@ -364,9 +371,10 @@ func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb
364371

365372
if v, isfresh := cb.freshCopy(key); trok && v != nil {
366373
var cachedsummary *x.DNSSummary
374+
hasans := v.ans != nil
367375

368-
log.D("cache: hit(k: %s / stale? %t): %s", key, !isfresh, v.str())
369-
r, cachedsummary, err = asResponse(q, v, isfresh) // return cached response, may be stale
376+
log.D("cache: hit(k: %s / stale? %t / ans? %t): %s", key, !isfresh, hasans, v.str())
377+
r, cachedsummary, err := asResponse(q, v, isfresh) // return cached response, may be stale
370378
if err != nil {
371379
log.W("cache: hit(k: %s) %s, but err? %v", key, v.str(), err)
372380
if err == errCacheResponseMismatch {
@@ -385,7 +393,7 @@ func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb
385393
fillSummary(cachedsummary, summary)
386394
summary.Latency = 0 // don't use cached latency
387395
t.est.Add(0) // however, update the estimator
388-
return
396+
return r, nil
389397
} // else: fallthrough to sendRequest
390398
} else {
391399
log.D("cache: miss(k: %s): cached? %t, hangover? %t, stale? %t", key, v != nil, !trok, !isfresh)

0 commit comments

Comments
 (0)