all: sync with master; upd chlog
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user