mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
Fix incorrect empty answer handling per RFC4074
This commit is contained in:
parent
4c5461a788
commit
ccefcd6b3b
2 changed files with 15 additions and 12 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/safing/portbase/log"
|
||||
|
@ -73,10 +74,8 @@ func ZeroIP(msgs ...string) ResponderFunc {
|
|||
}
|
||||
|
||||
switch {
|
||||
case hasErr && len(reply.Answer) == 0:
|
||||
case hasErr || len(reply.Answer) == 0:
|
||||
reply.SetRcode(request, dns.RcodeServerFailure)
|
||||
case len(reply.Answer) == 0:
|
||||
reply.SetRcode(request, dns.RcodeNameError)
|
||||
default:
|
||||
reply.SetRcode(request, dns.RcodeSuccess)
|
||||
}
|
||||
|
@ -115,10 +114,8 @@ func Localhost(msgs ...string) ResponderFunc {
|
|||
}
|
||||
|
||||
switch {
|
||||
case hasErr && len(reply.Answer) == 0:
|
||||
case hasErr || len(reply.Answer) == 0:
|
||||
reply.SetRcode(request, dns.RcodeServerFailure)
|
||||
case len(reply.Answer) == 0:
|
||||
reply.SetRcode(request, dns.RcodeNameError)
|
||||
default:
|
||||
reply.SetRcode(request, dns.RcodeSuccess)
|
||||
}
|
||||
|
@ -134,6 +131,15 @@ func NxDomain(msgs ...string) ResponderFunc {
|
|||
return func(ctx context.Context, request *dns.Msg) *dns.Msg {
|
||||
reply := new(dns.Msg).SetRcode(request, dns.RcodeNameError)
|
||||
AddMessagesToReply(ctx, reply, log.InfoLevel, msgs...)
|
||||
|
||||
// According to RFC4074 (https://tools.ietf.org/html/rfc4074), there are
|
||||
// nameservers that incorrectly respond with NXDomain instead of an empty
|
||||
// SUCCESS response when there are other RRs for the queried domain name.
|
||||
// This can lead to the software thinking that no RRs exist for that
|
||||
// domain. In order to mitigate this a bit, we slightly delay NXDomain
|
||||
// responses.
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
return reply
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,12 +82,6 @@ func (rrCache *RRCache) Clean(minExpires uint32) {
|
|||
lowestTTL = maxTTL
|
||||
}
|
||||
|
||||
// Adjust return code if there are no answers
|
||||
if rrCache.RCode == dns.RcodeSuccess &&
|
||||
len(rrCache.Answer) == 0 {
|
||||
rrCache.RCode = dns.RcodeNameError
|
||||
}
|
||||
|
||||
// shorten caching
|
||||
switch {
|
||||
case rrCache.RCode != dns.RcodeSuccess:
|
||||
|
@ -96,6 +90,9 @@ func (rrCache *RRCache) Clean(minExpires uint32) {
|
|||
case netenv.IsConnectivityDomain(rrCache.Domain):
|
||||
// Responses from these domains might change very quickly depending on the environment.
|
||||
lowestTTL = 3
|
||||
case len(rrCache.Answer) == 0:
|
||||
// Empty answer section: Domain exists, but not the queried RR.
|
||||
lowestTTL = 60
|
||||
case !netenv.Online():
|
||||
// Not being fully online could mean that we get funny responses.
|
||||
lowestTTL = 60
|
||||
|
|
Loading…
Add table
Reference in a new issue