@@ -47,6 +47,7 @@ const (
47
47
var (
48
48
errNoQuestion = errors .New ("no question" )
49
49
errNoAnswer = errors .New ("no answer" )
50
+ errHangover = errors .New ("no connectivity" )
50
51
errCacheResponseEmpty = errors .New ("empty cache response" )
51
52
errCacheResponseMismatch = errors .New ("cache response mismatch" )
52
53
)
@@ -328,7 +329,6 @@ func (t *ctransport) fetch(network string, q []byte, msg *dns.Msg, summary *x.DN
328
329
return & cres {ans : xdns .AsMsg (ans ), s : copySummary (fsmm )}, qerr
329
330
})
330
331
331
- trok := t .hangover .Within (ttl10s )
332
332
cachedres , fresh := cb .freshCopy (key ) // always prefer value from cache
333
333
if cachedres == nil { // use barrier response
334
334
cachedres = v .Val .copy () // never nil, even on errs; but cres.ans may be nil
@@ -337,17 +337,27 @@ func (t *ctransport) fetch(network string, q []byte, msg *dns.Msg, summary *x.DN
337
337
log .W ("cache: barrier: stale(k: %s); barrier: %s (cache: %s)" , key , v .String (), cachedres .String ())
338
338
}
339
339
340
- if ! trok {
340
+ // if there's no network connectivity (in hangover for 10s) don't
341
+ // return cached/barriered response, instead return an error
342
+ if ! t .hangover .Within (ttl10s ) {
341
343
log .D ("cache: barrier: hangover(k: %s); discard ans" , key )
342
- // if there's no network connectivity (in hangover) don't
343
- // return cached/barriered response; though, leave cachedres.s
344
- // intact as it is used to fill in fsmm (see: asResponse)
345
- cachedres .ans = nil
344
+ err := errors .Join (v .Err , errHangover )
345
+ // retain upstream
346
+ fsmm .Server = cachedres .s .Server
347
+ fsmm .RelayServer = cachedres .s .RelayServer
348
+ // retain query
349
+ fsmm .QName = cachedres .s .QName
350
+ fsmm .QType = cachedres .s .QType
351
+ // mimic send fail
352
+ fsmm .Msg = err .Error ()
353
+ fsmm .RCode = dns .RcodeServerFailure
354
+ fsmm .Status = SendFailed
355
+ return nil , err
346
356
}
347
357
348
358
fres , cachedsmm , ferr := asResponse (msg , cachedres , true )
349
359
// fill summary regardless of errors
350
- fillSummary (cachedsmm , fsmm ) // cachedsmm may be equal to finalsumm
360
+ fillSummary (cachedsmm , fsmm ) // cachedsmm may itself be fsmm
351
361
352
362
return fres , errors .Join (v .Err , ferr )
353
363
}
0 commit comments