@ -76,8 +76,6 @@ const (
wellKnownHostBackupDelay = 200 * time . Millisecond
wellKnownHostBackupDelay = 200 * time . Millisecond
)
)
var errNoUpstreams = errors . New ( "upstream nameservers not set" )
// txid identifies a DNS transaction.
// txid identifies a DNS transaction.
//
//
// As the standard DNS Request ID is only 16 bits, we extend it:
// As the standard DNS Request ID is only 16 bits, we extend it:
@ -205,7 +203,7 @@ type forwarder struct {
//
//
// That is, if we're running on GCP or AWS where there's always a well-known
// That is, if we're running on GCP or AWS where there's always a well-known
// IP of a recursive resolver, return that rather than having callers return
// IP of a recursive resolver, return that rather than having callers return
// errNoUpstreams . This fixes both normal 100.100.100.100 resolution when
// SERVFAIL . This fixes both normal 100.100.100.100 resolution when
// /etc/resolv.conf is missing/corrupt, and the peerapi ExitDNS stub
// /etc/resolv.conf is missing/corrupt, and the peerapi ExitDNS stub
// resolver lookup.
// resolver lookup.
cloudHostFallback [ ] resolverAndDelay
cloudHostFallback [ ] resolverAndDelay
@ -698,7 +696,18 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
resolvers = f . resolvers ( domain )
resolvers = f . resolvers ( domain )
if len ( resolvers ) == 0 {
if len ( resolvers ) == 0 {
metricDNSFwdErrorNoUpstream . Add ( 1 )
metricDNSFwdErrorNoUpstream . Add ( 1 )
return errNoUpstreams
f . logf ( "no upstream resolvers set, returning SERVFAIL" )
res , err := servfailResponse ( query )
if err != nil {
f . logf ( "building servfail response: %v" , err )
return nil
}
select {
case <- ctx . Done ( ) :
return ctx . Err ( )
case responseChan <- res :
return nil
}
}
}
}
}