all: sync with master; upd chlog

This commit is contained in:
Ainar Garipov
2023-02-15 16:53:29 +03:00
parent 80eb339896
commit 66b831072c
55 changed files with 24817 additions and 798 deletions

View File

@@ -10,6 +10,8 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/stringutil"
@@ -17,6 +19,9 @@ import (
)
// To transfer information between modules
//
// TODO(s.chzhen): Add lowercased, non-FQDN version of the hostname from the
// question of the request.
type dnsContext struct {
proxyCtx *proxy.DNSContext
@@ -419,7 +424,7 @@ func (s *Server) processDHCPHosts(dctx *dnsContext) (rc resultCode) {
}
resp.Answer = append(resp.Answer, a)
case dns.TypeAAAA:
if len(s.dns64Prefs) > 0 {
if s.dns64Pref != (netip.Prefix{}) {
// Respond with DNS64-mapped address for IPv4 host if DNS64 is
// enabled.
aaaa := &dns.AAAA{
@@ -468,15 +473,6 @@ func (s *Server) processRestrictLocal(dctx *dnsContext) (rc resultCode) {
return resultCodeSuccess
}
if s.shouldStripDNS64(ip) {
// Strip the prefix from the address to get the original IPv4.
ip = ip[nat64PrefixLen:]
// Treat a DNS64-prefixed address as a locally served one since those
// queries should never be sent to the global DNS.
dctx.unreversedReqIP = ip
}
// Restrict an access to local addresses for external clients. We also
// assume that all the DHCP leases we give are locally served or at least
// shouldn't be accessible externally.
@@ -655,13 +651,7 @@ func (s *Server) processUpstream(dctx *dnsContext) (rc resultCode) {
s.setCustomUpstream(pctx, dctx.clientID)
origReqAD := false
if s.conf.EnableDNSSEC {
origReqAD = req.AuthenticatedData
if !req.AuthenticatedData {
req.AuthenticatedData = true
}
}
reqWantsDNSSEC := s.setReqAD(req)
// Process the request further since it wasn't filtered.
prx := s.proxy()
@@ -671,23 +661,73 @@ func (s *Server) processUpstream(dctx *dnsContext) (rc resultCode) {
return resultCodeError
}
if dctx.err = prx.Resolve(pctx); dctx.err != nil {
return resultCodeError
}
if err := prx.Resolve(pctx); err != nil {
if errors.Is(err, upstream.ErrNoUpstreams) {
// Do not even put into querylog. Currently this happens either
// when the private resolvers enabled and the request is DNS64 PTR,
// or when the client isn't considered local by prx.
//
// TODO(e.burkov): Make proxy detect local client the same way as
// AGH does.
pctx.Res = s.genNXDomain(req)
return resultCodeFinish
}
dctx.err = err
if s.performDNS64(prx, dctx) == resultCodeError {
return resultCodeError
}
dctx.responseFromUpstream = true
dctx.responseAD = pctx.Res.AuthenticatedData
if s.conf.EnableDNSSEC && !origReqAD {
s.setRespAD(pctx, reqWantsDNSSEC)
return resultCodeSuccess
}
// setReqAD changes the request based on the server settings. wantsDNSSEC is
// false if the response should be cleared of the AD bit.
//
// TODO(a.garipov, e.burkov): This should probably be done in module dnsproxy.
func (s *Server) setReqAD(req *dns.Msg) (wantsDNSSEC bool) {
if !s.conf.EnableDNSSEC {
return false
}
origReqAD := req.AuthenticatedData
req.AuthenticatedData = true
// Per [RFC 6840] says, validating resolvers should only set the AD bit when
// the response has the AD bit set and the request contained either a set DO
// bit or a set AD bit. So, if neither of these is true, clear the AD bits
// in [Server.setRespAD].
//
// [RFC 6840]: https://datatracker.ietf.org/doc/html/rfc6840#section-5.8
return origReqAD || hasDO(req)
}
// hasDO returns true if msg has EDNS(0) options and the DNSSEC OK flag is set
// in there.
//
// TODO(a.garipov): Move to golibs/dnsmsg when it's there.
func hasDO(msg *dns.Msg) (do bool) {
o := msg.IsEdns0()
if o == nil {
return false
}
return o.Do()
}
// setRespAD changes the request and response based on the server settings and
// the original request data.
func (s *Server) setRespAD(pctx *proxy.DNSContext, reqWantsDNSSEC bool) {
if s.conf.EnableDNSSEC && !reqWantsDNSSEC {
pctx.Req.AuthenticatedData = false
pctx.Res.AuthenticatedData = false
}
return resultCodeSuccess
}
// isDHCPClientHostQ returns true if q is from a request for a DHCP client