Skip to content

Commit

Permalink
Merge branch 'master' into 1660-refactor-dns
Browse files Browse the repository at this point in the history
  • Loading branch information
ainar-g committed Nov 17, 2023
2 parents 85e8252 + 388583c commit ed49233
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 28 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ NOTE: Add new changes BELOW THIS COMMENT.
#### Configuration changes

- The property `dns.bogus_nxdomain` is now validated more strictly.
- Added new properties `clients.persistent.*.upstreams_cache_enabled` and
`clients.persistent.*.upstreams_cache_size` that describe cache configuration
for each client's custom upstream configuration.

### Fixed

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
go 1.20

require (
github.com/AdguardTeam/dnsproxy v0.58.0
github.com/AdguardTeam/dnsproxy v0.59.0
github.com/AdguardTeam/golibs v0.17.2
github.com/AdguardTeam/urlfilter v0.17.3
github.com/NYTimes/gziphandler v1.1.1
Expand Down Expand Up @@ -48,6 +48,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
github.com/jessevdk/go-flags v1.5.0 // indirect
github.com/mdlayher/socket v0.5.0 // indirect
github.com/onsi/ginkgo/v2 v2.13.1 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
github.com/AdguardTeam/dnsproxy v0.58.0 h1:1zPmDYWIc60D5Mn2idt3TcH+CQzKBvkWzJ5/u49wraw=
github.com/AdguardTeam/dnsproxy v0.58.0/go.mod h1:ZvkbM71HwpilgkCnTubDiR4Ba6x5Qvnhy2iasMWaTDM=
github.com/AdguardTeam/dnsproxy v0.58.1-0.20231114082217-26ee425d7cb9 h1:8JLgm92qlmd9LHh9maxo1Ao+vGLvLRSOClYH2/IvJ2g=
github.com/AdguardTeam/dnsproxy v0.58.1-0.20231114082217-26ee425d7cb9/go.mod h1:ZvkbM71HwpilgkCnTubDiR4Ba6x5Qvnhy2iasMWaTDM=
github.com/AdguardTeam/dnsproxy v0.59.0 h1:J0Iw4+GZ7U44scgkrNCM5W2G+tNS0r9nfQOuSLBqapE=
github.com/AdguardTeam/dnsproxy v0.59.0/go.mod h1:ZvkbM71HwpilgkCnTubDiR4Ba6x5Qvnhy2iasMWaTDM=
github.com/AdguardTeam/golibs v0.17.2 h1:vg6wHMjUKscnyPGRvxS5kAt7Uw4YxcJiITZliZ476W8=
github.com/AdguardTeam/golibs v0.17.2/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
Expand Down Expand Up @@ -52,6 +56,8 @@ github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c h1:PgxFEySCI41sH0mB7/2XswdXbUykQsRUGod8Rn+NubM=
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
Expand Down Expand Up @@ -100,6 +106,7 @@ github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
Expand Down Expand Up @@ -145,6 +152,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
4 changes: 2 additions & 2 deletions internal/aghtest/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ type ClientsContainer struct {
OnUpstreamConfigByID func(
id string,
boot upstream.Resolver,
) (conf *proxy.UpstreamConfig, err error)
) (conf *proxy.CustomUpstreamConfig, err error)
}

// UpstreamConfigByID implements the [dnsforward.ClientsContainer] interface
// for *ClientsContainer.
func (c *ClientsContainer) UpstreamConfigByID(
id string,
boot upstream.Resolver,
) (conf *proxy.UpstreamConfig, err error) {
) (conf *proxy.CustomUpstreamConfig, err error) {
return c.OnUpstreamConfigByID(id, boot)
}

Expand Down
5 changes: 4 additions & 1 deletion internal/dnsforward/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ type ClientsContainer interface {
// 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.UpstreamConfig, err error)
UpstreamConfigByID(
id string,
boot upstream.Resolver,
) (conf *proxy.CustomUpstreamConfig, err error)
}

// Config represents the DNS filtering configuration of AdGuard Home. The zero
Expand Down
36 changes: 29 additions & 7 deletions internal/dnsforward/dnsforward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -644,10 +644,15 @@ func TestBlockedRequest(t *testing.T) {
}

func TestServerCustomClientUpstream(t *testing.T) {
const defaultCacheSize = 1024 * 1024

var upsCalledCounter uint32

forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
CacheSize: defaultCacheSize,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
Expand All @@ -658,34 +663,51 @@ func TestServerCustomClientUpstream(t *testing.T) {
}, forwardConf, nil)

ups := aghtest.NewUpstreamMock(func(req *dns.Msg) (resp *dns.Msg, err error) {
atomic.AddUint32(&upsCalledCounter, 1)

return aghalg.Coalesce(
aghtest.MatchedResponse(req, dns.TypeA, "host", "192.168.0.1"),
new(dns.Msg).SetRcode(req, dns.RcodeNameError),
), nil
})

customUpsConf := proxy.NewCustomUpstreamConfig(
&proxy.UpstreamConfig{
Upstreams: []upstream.Upstream{ups},
},
true,
defaultCacheSize,
forwardConf.EDNSClientSubnet.Enabled,
)

s.conf.ClientsContainer = &aghtest.ClientsContainer{
OnUpstreamConfigByID: func(
_ string,
_ upstream.Resolver,
) (conf *proxy.UpstreamConfig, err error) {
return &proxy.UpstreamConfig{Upstreams: []upstream.Upstream{ups}}, nil
) (conf *proxy.CustomUpstreamConfig, err error) {
return customUpsConf, nil
},
}

startDeferStop(t, s)

addr := s.dnsProxy.Addr(proxy.ProtoUDP)
addr := s.dnsProxy.Addr(proxy.ProtoUDP).String()

// Send test request.
req := createTestMessage("host.")

reply, err := dns.Exchange(req, addr.String())
reply, err := dns.Exchange(req, addr)
require.NoError(t, err)

assert.Equal(t, dns.RcodeSuccess, reply.Rcode)
require.NotEmpty(t, reply.Answer)

require.Len(t, reply.Answer, 1)

assert.Equal(t, dns.RcodeSuccess, reply.Rcode)
assert.Equal(t, net.IP{192, 168, 0, 1}, reply.Answer[0].(*dns.A).A)
assert.Equal(t, uint32(1), atomic.LoadUint32(&upsCalledCounter))

_, err = dns.Exchange(req, addr)
require.NoError(t, err)
assert.Equal(t, uint32(1), atomic.LoadUint32(&upsCalledCounter))
}

// testCNAMEs is a map of names and CNAMEs necessary for the TestUpstream work.
Expand Down
16 changes: 9 additions & 7 deletions internal/home/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import (

// Client contains information about persistent clients.
type Client struct {
// upstreamConfig is the custom upstream config for this client. If
// it's nil, it has not been initialized yet. If it's non-nil and
// empty, there are no valid upstreams. If it's non-nil and non-empty,
// these upstream must be used.
upstreamConfig *proxy.UpstreamConfig
// upstreamConfig is the custom upstream configuration for this client. If
// it's nil, it has not been initialized yet. If it's non-nil and empty,
// there are no valid upstreams. If it's non-nil and non-empty, these
// upstream must be used.
upstreamConfig *proxy.CustomUpstreamConfig

safeSearchConf filtering.SafeSearchConfig
SafeSearch filtering.SafeSearch
Expand All @@ -32,6 +32,9 @@ type Client struct {
Tags []string
Upstreams []string

UpstreamsCacheSize uint32
UpstreamsCacheEnabled bool

UseOwnSettings bool
FilteringEnabled bool
SafeBrowsingEnabled bool
Expand All @@ -57,8 +60,7 @@ func (c *Client) ShallowClone() (sh *Client) {
// closeUpstreams closes the client-specific upstream config of c if any.
func (c *Client) closeUpstreams() (err error) {
if c.upstreamConfig != nil {
err = c.upstreamConfig.Close()
if err != nil {
if err = c.upstreamConfig.Close(); err != nil {
return fmt.Errorf("closing upstreams of client %q: %w", c.Name, err)
}
}
Expand Down
25 changes: 21 additions & 4 deletions internal/home/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ type clientObject struct {
Tags []string `yaml:"tags"`
Upstreams []string `yaml:"upstreams"`

// UpstreamsCacheSize is the DNS cache size (in bytes).
//
// TODO(d.kolyshev): Use [datasize.Bytesize].
UpstreamsCacheSize uint32 `yaml:"upstreams_cache_size"`

// UpstreamsCacheEnabled indicates if the DNS cache is enabled.
UpstreamsCacheEnabled bool `yaml:"upstreams_cache_enabled"`

UseGlobalSettings bool `yaml:"use_global_settings"`
FilteringEnabled bool `yaml:"filtering_enabled"`
ParentalEnabled bool `yaml:"parental_enabled"`
Expand Down Expand Up @@ -216,6 +224,8 @@ func (clients *clientsContainer) addFromConfig(
UseOwnBlockedServices: !o.UseGlobalBlockedServices,
IgnoreQueryLog: o.IgnoreQueryLog,
IgnoreStatistics: o.IgnoreStatistics,
UpstreamsCacheEnabled: o.UpstreamsCacheEnabled,
UpstreamsCacheSize: o.UpstreamsCacheSize,
}

if o.SafeSearchConf.Enabled {
Expand Down Expand Up @@ -429,11 +439,12 @@ func (clients *clientsContainer) shouldCountClient(ids []string) (y bool) {
var _ dnsforward.ClientsContainer = (*clientsContainer)(nil)

// UpstreamConfigByID implements the [dnsforward.ClientsContainer] interface for
// *clientsContainer.
// *clientsContainer. upsConf is nil if the client isn't found or if the client
// has no custom upstreams.
func (clients *clientsContainer) UpstreamConfigByID(
id string,
bootstrap upstream.Resolver,
) (upsConf *proxy.UpstreamConfig, err error) {
) (conf *proxy.CustomUpstreamConfig, err error) {
clients.lock.Lock()
defer clients.lock.Unlock()

Expand All @@ -449,8 +460,8 @@ func (clients *clientsContainer) UpstreamConfigByID(
return nil, nil
}

var conf *proxy.UpstreamConfig
conf, err = proxy.ParseUpstreamsConfig(
var upsConf *proxy.UpstreamConfig
upsConf, err = proxy.ParseUpstreamsConfig(
upstreams,
&upstream.Options{
Bootstrap: bootstrap,
Expand All @@ -464,6 +475,12 @@ func (clients *clientsContainer) UpstreamConfigByID(
return nil, err
}

conf = proxy.NewCustomUpstreamConfig(
upsConf,
c.UpstreamsCacheEnabled,
int(c.UpstreamsCacheSize),
config.DNS.EDNSClientSubnet.Enabled,
)
c.upstreamConfig = conf

return conf, nil
Expand Down
10 changes: 4 additions & 6 deletions internal/home/clients_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,11 @@ func TestClientsCustomUpstream(t *testing.T) {
require.NoError(t, err)
assert.True(t, ok)

config, err := clients.UpstreamConfigByID("1.2.3.4", net.DefaultResolver)
assert.Nil(t, config)
upsConf, err := clients.UpstreamConfigByID("1.2.3.4", net.DefaultResolver)
assert.Nil(t, upsConf)
assert.NoError(t, err)

config, err = clients.UpstreamConfigByID("1.1.1.1", net.DefaultResolver)
require.NotNil(t, config)
upsConf, err = clients.UpstreamConfigByID("1.1.1.1", net.DefaultResolver)
require.NotNil(t, upsConf)
assert.NoError(t, err)
assert.Len(t, config.Upstreams, 1)
assert.Len(t, config.DomainReservedUpstreams, 1)
}

0 comments on commit ed49233

Please sign in to comment.