Pull request: 4939 Client update
Merge in DNS/adguard-home from 4939-client-upd to master Updates #4939. Squashed commit of the following: commit 34f35822afcc8020a674cd023a5907b5b3edcb65 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Fri Feb 10 14:01:57 2023 +0300 all: imp code, docs commit 1cd8767a38f6494c92fb5ceff26abe228fcca638 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Feb 9 17:20:56 2023 +0300 all: different ttls commit 66d951ba3dd72cb698b89b432cbbbdd65cb421a2 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Feb 9 14:24:47 2023 +0300 all: imp code commit 3fb8d08310296dad90783f13ba46a1d0ea11da2e Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Feb 8 19:35:29 2023 +0300 home: fix rdns check logic
This commit is contained in:
@@ -253,8 +253,8 @@ func (s *Server) Resolve(host string) ([]net.IPAddr, error) {
|
||||
|
||||
// RDNSExchanger is a resolver for clients' addresses.
|
||||
type RDNSExchanger interface {
|
||||
// Exchange tries to resolve the ip in a suitable way, e.g. either as
|
||||
// local or as external.
|
||||
// Exchange tries to resolve the ip in a suitable way, i.e. either as local
|
||||
// or as external.
|
||||
Exchange(ip net.IP) (host string, err error)
|
||||
|
||||
// ResolvesPrivatePTR returns true if the RDNSExchanger is able to
|
||||
@@ -263,13 +263,13 @@ type RDNSExchanger interface {
|
||||
}
|
||||
|
||||
const (
|
||||
// rDNSEmptyAnswerErr is returned by Exchange method when the answer
|
||||
// section of respond is empty.
|
||||
rDNSEmptyAnswerErr errors.Error = "the answer section is empty"
|
||||
// ErrRDNSNoData is returned by [RDNSExchanger.Exchange] when the answer
|
||||
// section of response is either NODATA or has no PTR records.
|
||||
ErrRDNSNoData errors.Error = "no ptr data in response"
|
||||
|
||||
// rDNSNotPTRErr is returned by Exchange method when the response is not
|
||||
// of PTR type.
|
||||
rDNSNotPTRErr errors.Error = "the response is not a ptr"
|
||||
// ErrRDNSFailed is returned by [RDNSExchanger.Exchange] if the received
|
||||
// response is not a NOERROR or NXDOMAIN.
|
||||
ErrRDNSFailed errors.Error = "failed to resolve ptr"
|
||||
)
|
||||
|
||||
// type check
|
||||
@@ -324,17 +324,24 @@ func (s *Server) Exchange(ip net.IP) (host string, err error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Distinguish between NODATA response and a failed request.
|
||||
resp := ctx.Res
|
||||
if len(resp.Answer) == 0 {
|
||||
return "", fmt.Errorf("lookup for %q: %w", arpa, rDNSEmptyAnswerErr)
|
||||
if resp.Rcode != dns.RcodeSuccess && resp.Rcode != dns.RcodeNameError {
|
||||
return "", fmt.Errorf(
|
||||
"received %s response: %w",
|
||||
dns.RcodeToString[resp.Rcode],
|
||||
ErrRDNSFailed,
|
||||
)
|
||||
}
|
||||
|
||||
ptr, ok := resp.Answer[0].(*dns.PTR)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("type checking: %w", rDNSNotPTRErr)
|
||||
for _, ans := range resp.Answer {
|
||||
ptr, ok := ans.(*dns.PTR)
|
||||
if ok {
|
||||
return strings.TrimSuffix(ptr.Ptr, "."), nil
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSuffix(ptr.Ptr, "."), nil
|
||||
return "", ErrRDNSNoData
|
||||
}
|
||||
|
||||
// ResolvesPrivatePTR implements the RDNSExchanger interface for *Server.
|
||||
|
||||
@@ -1221,6 +1221,9 @@ func TestServer_Exchange(t *testing.T) {
|
||||
|
||||
errUpstream := aghtest.NewErrorUpstream()
|
||||
nonPtrUpstream := aghtest.NewBlockUpstream("some-host", true)
|
||||
refusingUpstream := aghtest.NewUpstreamMock(func(req *dns.Msg) (resp *dns.Msg, err error) {
|
||||
return new(dns.Msg).SetRcode(req, dns.RcodeRefused), nil
|
||||
})
|
||||
|
||||
srv := &Server{
|
||||
recDetector: newRecursionDetector(0, 1),
|
||||
@@ -1265,15 +1268,21 @@ func TestServer_Exchange(t *testing.T) {
|
||||
}, {
|
||||
name: "empty_answer_error",
|
||||
want: "",
|
||||
wantErr: rDNSEmptyAnswerErr,
|
||||
wantErr: ErrRDNSNoData,
|
||||
locUpstream: locUpstream,
|
||||
req: net.IP{192, 168, 1, 2},
|
||||
}, {
|
||||
name: "not_ptr_error",
|
||||
name: "invalid_answer",
|
||||
want: "",
|
||||
wantErr: rDNSNotPTRErr,
|
||||
wantErr: ErrRDNSNoData,
|
||||
locUpstream: nonPtrUpstream,
|
||||
req: localIP,
|
||||
}, {
|
||||
name: "refused",
|
||||
want: "",
|
||||
wantErr: ErrRDNSFailed,
|
||||
locUpstream: refusingUpstream,
|
||||
req: localIP,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
Reference in New Issue
Block a user