Merge pull request #101 from safing/fix/dns-resolving-resilience

Improve dns resolving resilience
This commit is contained in:
Patrick Pacher 2020-07-21 13:42:26 +02:00 committed by GitHub
commit b87ba37d4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 17 deletions

View file

@ -29,11 +29,11 @@ var (
// Cloudflare (encrypted DNS, with malware protection) // Cloudflare (encrypted DNS, with malware protection)
`dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`, `dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
`dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`, // `dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
// AdGuard (encrypted DNS, default flavor) // AdGuard (encrypted DNS, default flavor)
`dot://176.103.130.130:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`, // `dot://176.103.130.130:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`,
`dot://176.103.130.131:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`, // `dot://176.103.130.131:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`,
// Foundation for Applied Privacy (encrypted DNS) // Foundation for Applied Privacy (encrypted DNS)
// `dot://94.130.106.88:853?verify=dot1.applied-privacy.net&name=AppliedPrivacy`, // `dot://94.130.106.88:853?verify=dot1.applied-privacy.net&name=AppliedPrivacy`,

View file

@ -45,6 +45,12 @@ var (
ErrNoCompliance = fmt.Errorf("%w: no compliant resolvers for this query", ErrBlocked) ErrNoCompliance = fmt.Errorf("%w: no compliant resolvers for this query", ErrBlocked)
) )
const (
minTTL = 60 // 1 Minute
minMDnsTTL = 60 // 1 Minute
maxTTL = 24 * 60 * 60 // 24 hours
)
// BlockedUpstreamError is returned when a DNS request // BlockedUpstreamError is returned when a DNS request
// has been blocked by the upstream server. // has been blocked by the upstream server.
type BlockedUpstreamError struct { type BlockedUpstreamError struct {
@ -296,18 +302,16 @@ resolveLoop:
// we are offline and this is not an online check query // we are offline and this is not an online check query
return nil, ErrOffline return nil, ErrOffline
default: default:
// includes ErrTimeout
log.Tracer(ctx).Debugf("resolver: failed to resolve %s: %s", q.FQDN, err) log.Tracer(ctx).Debugf("resolver: failed to resolve %s: %s", q.FQDN, err)
} }
} else { }
// no error
if rrCache == nil { if rrCache == nil {
// defensive: assume NXDomain continue
return nil, ErrNotFound
} }
break resolveLoop break resolveLoop
} }
} }
}
// check for error // check for error
if err != nil { if err != nil {
@ -326,7 +330,7 @@ resolveLoop:
// cache if enabled // cache if enabled
if !q.NoCaching { if !q.NoCaching {
// persist to database // persist to database
rrCache.Clean(600) rrCache.Clean(minTTL)
err = rrCache.Save() err = rrCache.Save()
if err != nil { if err != nil {
log.Warningf("resolver: failed to cache RR for %s%s: %s", q.FQDN, q.QType.String(), err) log.Warningf("resolver: failed to cache RR for %s%s: %s", q.FQDN, q.QType.String(), err)

View file

@ -276,7 +276,7 @@ func handleMDNSMessages(ctx context.Context, messages chan *dns.Msg) error {
var questionID string var questionID string
if saveFullRequest { if saveFullRequest {
rrCache.Clean(60) rrCache.Clean(minMDnsTTL)
err := rrCache.Save() err := rrCache.Save()
if err != nil { if err != nil {
log.Warningf("resolver: failed to cache RR %s: %s", rrCache.Domain, err) log.Warningf("resolver: failed to cache RR %s: %s", rrCache.Domain, err)
@ -304,7 +304,7 @@ func handleMDNSMessages(ctx context.Context, messages chan *dns.Msg) error {
Server: mDNSResolver.Server, Server: mDNSResolver.Server,
ServerScope: mDNSResolver.ServerIPScope, ServerScope: mDNSResolver.ServerIPScope,
} }
rrCache.Clean(60) rrCache.Clean(minMDnsTTL)
err := rrCache.Save() err := rrCache.Save()
if err != nil { if err != nil {
log.Warningf("resolver: failed to cache RR %s: %s", rrCache.Domain, err) log.Warningf("resolver: failed to cache RR %s: %s", rrCache.Domain, err)

View file

@ -419,7 +419,7 @@ func (mgr *tcpResolverConnMgr) handleQueryResponse(conn *dns.Conn, msg *dns.Msg)
// persist to database // persist to database
rrCache := inFlight.MakeCacheRecord(msg) rrCache := inFlight.MakeCacheRecord(msg)
rrCache.Clean(600) rrCache.Clean(minTTL)
err := rrCache.Save() err := rrCache.Save()
if err != nil { if err != nil {
log.Warningf( log.Warningf(

View file

@ -28,7 +28,7 @@ const (
var ( var (
// FailThreshold is amount of errors a resolvers must experience in order to be regarded as failed. // FailThreshold is amount of errors a resolvers must experience in order to be regarded as failed.
FailThreshold = 5 FailThreshold = 20
) )
// Resolver holds information about an active resolver. // Resolver holds information about an active resolver.

View file

@ -72,9 +72,12 @@ func (rrCache *RRCache) Clean(minExpires uint32) {
header.Ttl = 17 header.Ttl = 17
} }
// TTL must be at least minExpires // TTL range limits
if lowestTTL < minExpires { switch {
case lowestTTL < minExpires:
lowestTTL = minExpires lowestTTL = minExpires
case lowestTTL > maxTTL:
lowestTTL = maxTTL
} }
// shorten caching // shorten caching