Pull request 2346: AGDNS-2686-client-upstream-manager
Merge in DNS/adguard-home from AGDNS-2686-client-upstream-manager to master Squashed commit of the following: commit 563cb583f01c26434fa04d0e37dcbe2ba15c0912 Merge: f4b0caf5c61fe269cbAuthor: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Mar 3 19:07:35 2025 +0300 Merge branch 'master' into AGDNS-2686-client-upstream-manager commit f4b0caf5c8bc48ee8be97f031cd1aa1399eb461c Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Feb 27 21:52:51 2025 +0300 client: imp docs commit e7d74931b1cc9b62eeadbe1168ae5781d57d6c73 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Feb 26 21:44:04 2025 +0300 client: imp code commit 1cba38c1bc3b6b5afb7829c230c4e831f789647e Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Feb 26 18:06:17 2025 +0300 client: fix typo commit 65b6b1e8c0fde47f367c428a78fefc4c63bc45f9 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Feb 26 17:52:02 2025 +0300 all: imp code, docs commit ed158ef09fc26bc9c57c91dbfa04d89fede583d0 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Feb 26 14:34:50 2025 +0300 client: imp code commit ab897f64c8751ea158408521116d5b689e6d39a9 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Feb 25 18:26:16 2025 +0300 all: upd chlog commit a2c30e3ede6fb61f6d23fd392cc3035dc96f77af Merge: bdb08ee0ed8ce5b453Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Feb 25 17:40:32 2025 +0300 Merge branch 'master' into AGDNS-2686-client-upstream-manager commit bdb08ee0e6122de727f2749a44f5df7e29d0eee2 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Feb 25 17:16:31 2025 +0300 all: imp tests commit 00f0eb60474a2297567acf5a3a27e8b5c2d99229 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Feb 20 21:37:58 2025 +0300 all: imp code, docs commit 13934176636dd70a17e53bc1956d6cf51602760a Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Feb 19 15:58:11 2025 +0300 all: client upstream manager
This commit is contained in:
@@ -15,7 +15,7 @@ import (
|
||||
var _ proxy.BeforeRequestHandler = (*Server)(nil)
|
||||
|
||||
// HandleBefore is the handler that is called before any other processing,
|
||||
// including logs. It performs access checks and puts the client ID, if there
|
||||
// including logs. It performs access checks and puts the ClientID, if there
|
||||
// is one, into the server's cache.
|
||||
//
|
||||
// TODO(d.kolyshev): Extract to separate package.
|
||||
|
||||
@@ -266,6 +266,7 @@ func TestServer_HandleBefore_udp(t *testing.T) {
|
||||
UpstreamDNS: []string{localUpsAddr},
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
|
||||
@@ -62,7 +62,7 @@ func clientIDFromClientServerName(
|
||||
return strings.ToLower(clientID), nil
|
||||
}
|
||||
|
||||
// clientIDFromDNSContextHTTPS extracts the client's ID from the path of the
|
||||
// clientIDFromDNSContextHTTPS extracts the ClientID from the path of the
|
||||
// client's DNS-over-HTTPS request.
|
||||
func clientIDFromDNSContextHTTPS(pctx *proxy.DNSContext) (clientID string, err error) {
|
||||
r := pctx.HTTPRequest
|
||||
|
||||
46
internal/dnsforward/clientscontainer.go
Normal file
46
internal/dnsforward/clientscontainer.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package dnsforward
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/client"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
)
|
||||
|
||||
// ClientsContainer provides information about preconfigured DNS clients.
|
||||
type ClientsContainer interface {
|
||||
// CustomUpstreamConfig returns the custom client upstream configuration, if
|
||||
// any. It prioritizes ClientID over client IP address to identify the
|
||||
// client.
|
||||
CustomUpstreamConfig(clientID string, cliAddr netip.Addr) (conf *proxy.CustomUpstreamConfig)
|
||||
|
||||
// UpdateCommonUpstreamConfig updates the common upstream configuration.
|
||||
UpdateCommonUpstreamConfig(conf *client.CommonUpstreamConfig)
|
||||
|
||||
// ClearUpstreamCache clears the upstream cache for each stored custom
|
||||
// client upstream configuration.
|
||||
ClearUpstreamCache()
|
||||
}
|
||||
|
||||
// EmptyClientsContainer is an [ClientsContainer] implementation that does nothing.
|
||||
type EmptyClientsContainer struct{}
|
||||
|
||||
// type check
|
||||
var _ ClientsContainer = EmptyClientsContainer{}
|
||||
|
||||
// CustomUpstreamConfig implements the [ClientsContainer] interface for
|
||||
// EmptyClientsContainer.
|
||||
func (EmptyClientsContainer) CustomUpstreamConfig(
|
||||
clientID string,
|
||||
cliAddr netip.Addr,
|
||||
) (conf *proxy.CustomUpstreamConfig) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCommonUpstreamConfig implements the [ClientsContainer] interface for
|
||||
// EmptyClientsContainer.
|
||||
func (EmptyClientsContainer) UpdateCommonUpstreamConfig(conf *client.CommonUpstreamConfig) {}
|
||||
|
||||
// ClearUpstreamCache implements the [ClientsContainer] interface for
|
||||
// EmptyClientsContainer.
|
||||
func (EmptyClientsContainer) ClearUpstreamCache() {}
|
||||
@@ -29,19 +29,6 @@ import (
|
||||
"github.com/ameshkov/dnscrypt/v2"
|
||||
)
|
||||
|
||||
// ClientsContainer provides information about preconfigured DNS clients.
|
||||
type ClientsContainer interface {
|
||||
// UpstreamConfigByID returns the custom upstream configuration for the
|
||||
// client having id, using boot to initialize the one if necessary. It
|
||||
// returns nil if there is no custom upstream configuration for the client.
|
||||
// The id is expected to be either a string representation of an IP address
|
||||
// or the ClientID.
|
||||
UpstreamConfigByID(
|
||||
id string,
|
||||
boot upstream.Resolver,
|
||||
) (conf *proxy.CustomUpstreamConfig, err error)
|
||||
}
|
||||
|
||||
// Config represents the DNS filtering configuration of AdGuard Home. The zero
|
||||
// Config is empty and ready for use.
|
||||
type Config struct {
|
||||
@@ -467,7 +454,7 @@ func (s *Server) prepareIpsetListSettings() (ipsets []string, err error) {
|
||||
}
|
||||
|
||||
ipsets = stringutil.SplitTrimmed(string(data), "\n")
|
||||
ipsets = slices.DeleteFunc(ipsets, IsCommentOrEmpty)
|
||||
ipsets = slices.DeleteFunc(ipsets, aghnet.IsCommentOrEmpty)
|
||||
|
||||
log.Debug("dns: using %d ipset rules from file %q", len(ipsets), fn)
|
||||
|
||||
@@ -478,7 +465,7 @@ func (s *Server) prepareIpsetListSettings() (ipsets []string, err error) {
|
||||
// the configuration itself.
|
||||
func (conf *ServerConfig) loadUpstreams() (upstreams []string, err error) {
|
||||
if conf.UpstreamDNSFileName == "" {
|
||||
return stringutil.FilterOut(conf.UpstreamDNS, IsCommentOrEmpty), nil
|
||||
return stringutil.FilterOut(conf.UpstreamDNS, aghnet.IsCommentOrEmpty), nil
|
||||
}
|
||||
|
||||
var data []byte
|
||||
@@ -491,7 +478,7 @@ func (conf *ServerConfig) loadUpstreams() (upstreams []string, err error) {
|
||||
|
||||
log.Debug("dnsforward: got %d upstreams in %q", len(upstreams), conf.UpstreamDNSFileName)
|
||||
|
||||
return stringutil.FilterOut(upstreams, IsCommentOrEmpty), nil
|
||||
return stringutil.FilterOut(upstreams, aghnet.IsCommentOrEmpty), nil
|
||||
}
|
||||
|
||||
// collectListenAddr adds addrPort to addrs. It also adds its port to
|
||||
|
||||
@@ -299,6 +299,7 @@ func TestServer_HandleDNSRequest_dns64(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
UpstreamDNS: []string{upsAddr},
|
||||
},
|
||||
UsePrivateRDNS: true,
|
||||
@@ -337,6 +338,7 @@ func TestServer_dns64WithDisabledRDNS(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
UpstreamDNS: []string{upsAddr},
|
||||
},
|
||||
UsePrivateRDNS: false,
|
||||
|
||||
@@ -540,7 +540,7 @@ func (s *Server) prepareUpstreamSettings(boot upstream.Resolver) (err error) {
|
||||
uc, err := newUpstreamConfig(upstreams, defaultDNS, &upstream.Options{
|
||||
Bootstrap: boot,
|
||||
Timeout: s.conf.UpstreamTimeout,
|
||||
HTTPVersions: UpstreamHTTPVersions(s.conf.UseHTTP3Upstreams),
|
||||
HTTPVersions: aghnet.UpstreamHTTPVersions(s.conf.UseHTTP3Upstreams),
|
||||
PreferIPv6: s.conf.BootstrapPreferIPv6,
|
||||
// Use a customized set of RootCAs, because Go's default mechanism of
|
||||
// loading TLS roots does not always work properly on some routers so we're
|
||||
@@ -557,6 +557,13 @@ func (s *Server) prepareUpstreamSettings(boot upstream.Resolver) (err error) {
|
||||
}
|
||||
|
||||
s.conf.UpstreamConfig = uc
|
||||
s.conf.ClientsContainer.UpdateCommonUpstreamConfig(&client.CommonUpstreamConfig{
|
||||
Bootstrap: boot,
|
||||
UpstreamTimeout: s.conf.UpstreamTimeout,
|
||||
BootstrapPreferIPv6: s.conf.BootstrapPreferIPv6,
|
||||
EDNSClientSubnetEnabled: s.conf.EDNSClientSubnet.Enabled,
|
||||
UseHTTP3Upstreams: s.conf.UseHTTP3Upstreams,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -630,7 +637,7 @@ func (s *Server) prepareInternalDNS() (err error) {
|
||||
|
||||
bootOpts := &upstream.Options{
|
||||
Timeout: DefaultTimeout,
|
||||
HTTPVersions: UpstreamHTTPVersions(s.conf.UseHTTP3Upstreams),
|
||||
HTTPVersions: aghnet.UpstreamHTTPVersions(s.conf.UseHTTP3Upstreams),
|
||||
}
|
||||
|
||||
s.bootstrap, s.bootResolvers, err = newBootstrap(s.conf.BootstrapDNS, s.etcHosts, bootOpts)
|
||||
@@ -661,7 +668,7 @@ func (s *Server) prepareInternalDNS() (err error) {
|
||||
// setupFallbackDNS initializes the fallback DNS servers.
|
||||
func (s *Server) setupFallbackDNS() (uc *proxy.UpstreamConfig, err error) {
|
||||
fallbacks := s.conf.FallbackDNS
|
||||
fallbacks = stringutil.FilterOut(fallbacks, IsCommentOrEmpty)
|
||||
fallbacks = stringutil.FilterOut(fallbacks, aghnet.IsCommentOrEmpty)
|
||||
if len(fallbacks) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/client"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering/hashprefix"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering/safesearch"
|
||||
@@ -61,6 +62,42 @@ const (
|
||||
// TODO(a.garipov): Use more.
|
||||
var testClientAddrPort = netip.MustParseAddrPort("1.2.3.4:12345")
|
||||
|
||||
// type check
|
||||
var _ ClientsContainer = (*clientsContainer)(nil)
|
||||
|
||||
// clientsContainer is a mock [ClientsContainer] implementation for tests.
|
||||
type clientsContainer struct {
|
||||
OnCustomUpstreamConfig func(
|
||||
clientID string,
|
||||
cliAddr netip.Addr,
|
||||
) (conf *proxy.CustomUpstreamConfig)
|
||||
|
||||
OnUpdateCommonUpstreamConfig func(conf *client.CommonUpstreamConfig)
|
||||
|
||||
OnClearUpstreamCache func()
|
||||
}
|
||||
|
||||
// CustomUpstreamConfig implements the [ClientsContainer] interface for
|
||||
// *clientsContainer.
|
||||
func (c *clientsContainer) CustomUpstreamConfig(
|
||||
clientID string,
|
||||
cliAddr netip.Addr,
|
||||
) (conf *proxy.CustomUpstreamConfig) {
|
||||
return c.OnCustomUpstreamConfig(clientID, cliAddr)
|
||||
}
|
||||
|
||||
// UpdateCommonUpstreamConfig implements the [ClientsContainer] interface for
|
||||
// *clientsContainer.
|
||||
func (c *clientsContainer) UpdateCommonUpstreamConfig(conf *client.CommonUpstreamConfig) {
|
||||
c.OnUpdateCommonUpstreamConfig(conf)
|
||||
}
|
||||
|
||||
// ClearUpstreamCache implements the [ClientsContainer] interface for
|
||||
// *clientsContainer.
|
||||
func (c *clientsContainer) ClearUpstreamCache() {
|
||||
c.OnClearUpstreamCache()
|
||||
}
|
||||
|
||||
func startDeferStop(t *testing.T, s *Server) {
|
||||
t.Helper()
|
||||
|
||||
@@ -168,6 +205,7 @@ func createTestTLS(t *testing.T, tlsConf TLSConfig) (s *Server, certPem []byte)
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
@@ -297,6 +335,7 @@ func TestServer(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
@@ -337,6 +376,7 @@ func TestServer_timeout(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -364,6 +404,7 @@ func TestServer_timeout(t *testing.T) {
|
||||
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
}
|
||||
s.conf.Config.ClientsContainer = EmptyClientsContainer{}
|
||||
err = s.Prepare(&s.conf)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -380,6 +421,7 @@ func TestServer_Prepare_fallbacks(t *testing.T) {
|
||||
},
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -405,6 +447,7 @@ func TestServerWithProtectionDisabled(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
@@ -536,6 +579,7 @@ func TestSafeSearch(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -629,6 +673,7 @@ func TestInvalidRequest(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
@@ -659,6 +704,7 @@ func TestBlockedRequest(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -696,6 +742,7 @@ func TestServerCustomClientUpstream(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -721,12 +768,12 @@ func TestServerCustomClientUpstream(t *testing.T) {
|
||||
forwardConf.EDNSClientSubnet.Enabled,
|
||||
)
|
||||
|
||||
s.conf.ClientsContainer = &aghtest.ClientsContainer{
|
||||
OnUpstreamConfigByID: func(
|
||||
s.conf.ClientsContainer = &clientsContainer{
|
||||
OnCustomUpstreamConfig: func(
|
||||
_ string,
|
||||
_ upstream.Resolver,
|
||||
) (conf *proxy.CustomUpstreamConfig, err error) {
|
||||
return customUpsConf, nil
|
||||
_ netip.Addr,
|
||||
) (conf *proxy.CustomUpstreamConfig) {
|
||||
return customUpsConf
|
||||
},
|
||||
}
|
||||
|
||||
@@ -774,6 +821,7 @@ func TestBlockCNAMEProtectionEnabled(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
@@ -808,6 +856,7 @@ func TestBlockCNAME(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -884,6 +933,7 @@ func TestClientRulesForCNAMEMatching(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -930,6 +980,7 @@ func TestNullBlockedRequest(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -998,6 +1049,7 @@ func TestBlockedCustomIP(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -1051,6 +1103,7 @@ func TestBlockedByHosts(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -1103,6 +1156,7 @@ func TestBlockedBySafeBrowsing(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -1164,6 +1218,7 @@ func TestRewrite(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}))
|
||||
@@ -1290,6 +1345,7 @@ func TestPTRResponseFromDHCPLeases(t *testing.T) {
|
||||
s.conf.TCPListenAddrs = []*net.TCPAddr{{}}
|
||||
s.conf.UpstreamDNS = []string{"127.0.0.1:53"}
|
||||
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{Enabled: false}
|
||||
s.conf.Config.ClientsContainer = EmptyClientsContainer{}
|
||||
s.conf.Config.UpstreamMode = UpstreamModeLoadBalance
|
||||
|
||||
err = s.Prepare(&s.conf)
|
||||
@@ -1375,6 +1431,7 @@ func TestPTRResponseFromHosts(t *testing.T) {
|
||||
s.conf.TCPListenAddrs = []*net.TCPAddr{{}}
|
||||
s.conf.UpstreamDNS = []string{"127.0.0.1:53"}
|
||||
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{Enabled: false}
|
||||
s.conf.Config.ClientsContainer = EmptyClientsContainer{}
|
||||
s.conf.Config.UpstreamMode = UpstreamModeLoadBalance
|
||||
|
||||
err = s.Prepare(&s.conf)
|
||||
@@ -1643,6 +1700,7 @@ func TestServer_Exchange(t *testing.T) {
|
||||
UpstreamDNS: []string{upsAddr},
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
LocalPTRResolvers: []string{localUpsAddr},
|
||||
UsePrivateRDNS: true,
|
||||
@@ -1665,6 +1723,7 @@ func TestServer_Exchange(t *testing.T) {
|
||||
UpstreamDNS: []string{upsAddr},
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
LocalPTRResolvers: []string{},
|
||||
ServePlainDNS: true,
|
||||
|
||||
@@ -40,6 +40,7 @@ func TestServer_FilterDNSRewrite(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
|
||||
@@ -36,6 +36,7 @@ func TestHandleDNSRequest_handleDNSRequest(t *testing.T) {
|
||||
EDNSClientSubnet: &EDNSClientSubnet{
|
||||
Enabled: false,
|
||||
},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
@@ -647,7 +648,7 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
req.BootstrapDNS = stringutil.FilterOut(req.BootstrapDNS, IsCommentOrEmpty)
|
||||
req.BootstrapDNS = stringutil.FilterOut(req.BootstrapDNS, aghnet.IsCommentOrEmpty)
|
||||
|
||||
opts := &upstream.Options{
|
||||
Timeout: s.conf.UpstreamTimeout,
|
||||
@@ -673,6 +674,8 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
|
||||
// handleCacheClear is the handler for the POST /control/cache_clear HTTP API.
|
||||
func (s *Server) handleCacheClear(w http.ResponseWriter, _ *http.Request) {
|
||||
s.dnsProxy.ClearCache()
|
||||
s.conf.ClientsContainer.ClearUpstreamCache()
|
||||
|
||||
_, _ = io.WriteString(w, "OK")
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
|
||||
RatelimitSubnetLenIPv6: 56,
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ConfigModified: func() {},
|
||||
ServePlainDNS: true,
|
||||
@@ -164,6 +165,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
|
||||
RatelimitSubnetLenIPv6: 56,
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ConfigModified: func() {},
|
||||
ServePlainDNS: true,
|
||||
@@ -299,24 +301,6 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCommentOrEmpty(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
want assert.BoolAssertionFunc
|
||||
str string
|
||||
}{{
|
||||
want: assert.True,
|
||||
str: "",
|
||||
}, {
|
||||
want: assert.True,
|
||||
str: "# comment",
|
||||
}, {
|
||||
want: assert.False,
|
||||
str: "1.2.3.4",
|
||||
}} {
|
||||
tc.want(t, IsCommentOrEmpty(tc.str))
|
||||
}
|
||||
}
|
||||
|
||||
func newLocalUpstreamListener(t *testing.T, port uint16, handler dns.Handler) (real netip.AddrPort) {
|
||||
t.Helper()
|
||||
|
||||
@@ -388,6 +372,7 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dnsforward
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
@@ -577,17 +576,14 @@ func (s *Server) setCustomUpstream(pctx *proxy.DNSContext, clientID string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Use the ClientID first, since it has a higher priority.
|
||||
id := cmp.Or(clientID, pctx.Addr.Addr().String())
|
||||
upsConf, err := s.conf.ClientsContainer.UpstreamConfigByID(id, s.bootstrap)
|
||||
if err != nil {
|
||||
log.Error("dnsforward: getting custom upstreams for client %s: %s", id, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
cliAddr := pctx.Addr.Addr()
|
||||
upsConf := s.conf.ClientsContainer.CustomUpstreamConfig(clientID, cliAddr)
|
||||
if upsConf != nil {
|
||||
log.Debug("dnsforward: using custom upstreams for client %s", id)
|
||||
log.Debug(
|
||||
"dnsforward: using custom upstreams for client with ip %s and clientid %q",
|
||||
cliAddr,
|
||||
clientID,
|
||||
)
|
||||
|
||||
pctx.CustomUpstreamConfig = upsConf
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ func TestServer_ProcessInitial(t *testing.T) {
|
||||
AAAADisabled: tc.aaaaDisabled,
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -180,6 +181,7 @@ func TestServer_ProcessFilteringAfterResponse(t *testing.T) {
|
||||
AAAADisabled: tc.aaaaDisabled,
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
}
|
||||
@@ -324,6 +326,7 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
||||
HandleDDR: tc.ddrEnabled,
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
TLSConfig: TLSConfig{
|
||||
ServerName: ddrTestDomainName,
|
||||
@@ -660,6 +663,7 @@ func TestServer_HandleDNSRequest_restrictLocal(t *testing.T) {
|
||||
UpstreamDNS: []string{localUpsAddr},
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
UsePrivateRDNS: true,
|
||||
LocalPTRResolvers: []string{localUpsAddr},
|
||||
@@ -788,6 +792,7 @@ func TestServer_ProcessUpstream_localPTR(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
UsePrivateRDNS: true,
|
||||
LocalPTRResolvers: []string{localUpsAddr},
|
||||
@@ -816,6 +821,7 @@ func TestServer_ProcessUpstream_localPTR(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
UsePrivateRDNS: false,
|
||||
LocalPTRResolvers: []string{localUpsAddr},
|
||||
|
||||
@@ -19,6 +19,7 @@ func TestGenAnswerHTTPS_andSVCB(t *testing.T) {
|
||||
Config: Config{
|
||||
UpstreamMode: UpstreamModeLoadBalance,
|
||||
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
|
||||
ClientsContainer: EmptyClientsContainer{},
|
||||
},
|
||||
ServePlainDNS: true,
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ func newPrivateConfig(
|
||||
) (uc *proxy.UpstreamConfig, err error) {
|
||||
confNeedsFiltering := len(addrs) > 0
|
||||
if confNeedsFiltering {
|
||||
addrs = stringutil.FilterOut(addrs, IsCommentOrEmpty)
|
||||
addrs = stringutil.FilterOut(addrs, aghnet.IsCommentOrEmpty)
|
||||
} else {
|
||||
sysResolvers := slices.DeleteFunc(slices.Clone(sysResolvers.Addrs()), unwanted.Has)
|
||||
addrs = make([]string, 0, len(sysResolvers))
|
||||
@@ -127,20 +127,6 @@ func newPrivateConfig(
|
||||
return uc, nil
|
||||
}
|
||||
|
||||
// UpstreamHTTPVersions returns the HTTP versions for upstream configuration
|
||||
// depending on configuration.
|
||||
func UpstreamHTTPVersions(http3 bool) (v []upstream.HTTPVersion) {
|
||||
if !http3 {
|
||||
return upstream.DefaultHTTPVersions
|
||||
}
|
||||
|
||||
return []upstream.HTTPVersion{
|
||||
upstream.HTTPVersion3,
|
||||
upstream.HTTPVersion2,
|
||||
upstream.HTTPVersion11,
|
||||
}
|
||||
}
|
||||
|
||||
// setProxyUpstreamMode sets the upstream mode and related settings in conf
|
||||
// based on provided parameters.
|
||||
func setProxyUpstreamMode(
|
||||
@@ -162,10 +148,3 @@ func setProxyUpstreamMode(
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsCommentOrEmpty returns true if s starts with a "#" character or is empty.
|
||||
// This function is useful for filtering out non-upstream lines from upstream
|
||||
// configs.
|
||||
func IsCommentOrEmpty(s string) (ok bool) {
|
||||
return len(s) == 0 || s[0] == '#'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user