Skip to content

Commit

Permalink
Merge branch 'master' into 6409-cache-ttl-override
Browse files Browse the repository at this point in the history
  • Loading branch information
schzhn committed Dec 26, 2023
2 parents 959b618 + ad147ac commit 7dea2a3
Show file tree
Hide file tree
Showing 23 changed files with 370 additions and 75 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Expand Up @@ -31,10 +31,36 @@ NOTE: Add new changes BELOW THIS COMMENT.
- Ability to disable plain-DNS serving via UI if an encrypted protocol is
already used ([#1660]).

### Changed

- The field `"upstream_mode"` in `POST /control/dns_config` and
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
`openapi/CHANGELOG.md` for more details.

#### Configuration changes

- The properties `dns.'all_servers` and `dns.fastest_addr` were removed, their
values migrated to newly added field `dns.upstream_mode` that describes the
logic through which upstreams will be used.

```yaml
# BEFORE:
'dns':
#
'all_servers': true
'fastest_addr': true

# AFTER:
'dns':
#
'upstream_mode': 'parallel'
```

### Fixed

- Maximum cache TTL requirement when editing minimum cache TTL in the Web UI
([#6409]).
- Load balancing algorithm stuck on a single server ([#6480]).
- Statistics for 7 days displayed as 168 hours on the dashboard.
- Pre-filling the Edit static lease window with data ([#6534]).
- Names defined in the `/etc/hosts` for a single address family wrongly
Expand All @@ -44,6 +70,7 @@ NOTE: Add new changes BELOW THIS COMMENT.

[#6352]: https://github.com/AdguardTeam/AdGuardHome/issues/6352
[#6409]: https://github.com/AdguardTeam/AdGuardHome/issues/6409
[#6480]: https://github.com/AdguardTeam/AdGuardHome/issues/6480
[#6534]: https://github.com/AdguardTeam/AdGuardHome/issues/6534
[#6541]: https://github.com/AdguardTeam/AdGuardHome/issues/6541
[#6545]: https://github.com/AdguardTeam/AdGuardHome/issues/6545
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Expand Up @@ -3,8 +3,8 @@ module github.com/AdguardTeam/AdGuardHome
go 1.20

require (
github.com/AdguardTeam/dnsproxy v0.60.1
github.com/AdguardTeam/golibs v0.18.0
github.com/AdguardTeam/dnsproxy v0.61.0
github.com/AdguardTeam/golibs v0.18.1
github.com/AdguardTeam/urlfilter v0.17.3
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.7
Expand Down Expand Up @@ -64,4 +64,6 @@ require (
golang.org/x/sync v0.5.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
gonum.org/v1/gonum v0.14.0 // indirect
)

10 changes: 6 additions & 4 deletions go.sum
@@ -1,7 +1,7 @@
github.com/AdguardTeam/dnsproxy v0.60.1 h1:YveGe7UZLaAiePkaV3orkc0IIfPX9vi/qQDIFdeO//A=
github.com/AdguardTeam/dnsproxy v0.60.1/go.mod h1:B7FvvTFQZBfey1cJXQo732EyCLX6xj4JqrciCawATzg=
github.com/AdguardTeam/golibs v0.18.0 h1:ckS2YK7t2Ub6UkXl0fnreVaM15Zb07Hh1gmFqttjpWg=
github.com/AdguardTeam/golibs v0.18.0/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
github.com/AdguardTeam/dnsproxy v0.61.0 h1:A5tmOpPw9c1kw5L4RKrOPzscRZuzpLaikwXLDsibQnY=
github.com/AdguardTeam/dnsproxy v0.61.0/go.mod h1:IdmXdkpc+m+S2EajJkVZDZm//yQ4mQm2FCOugQpc/N8=
github.com/AdguardTeam/golibs v0.18.1 h1:6u0fvrIj2qjUsRdbIGJ9AR0g5QRSWdKIo/DYl3tp5aM=
github.com/AdguardTeam/golibs v0.18.1/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
github.com/AdguardTeam/urlfilter v0.17.3/go.mod h1:Jru7jFfeH2CoDf150uDs+rRYcZBzHHBz05r9REyDKyE=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
Expand Down Expand Up @@ -164,6 +164,8 @@ golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
Expand Down
2 changes: 1 addition & 1 deletion internal/configmigrate/configmigrate.go
Expand Up @@ -2,4 +2,4 @@
package configmigrate

// LastSchemaVersion is the most recent schema version.
const LastSchemaVersion uint = 27
const LastSchemaVersion uint = 28
82 changes: 82 additions & 0 deletions internal/configmigrate/migrations_internal_test.go
Expand Up @@ -4,6 +4,7 @@ import (
"testing"
"time"

"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/golibs/timeutil"
Expand Down Expand Up @@ -1646,3 +1647,84 @@ func TestUpgradeSchema26to27(t *testing.T) {
})
}
}

func TestUpgradeSchema27to28(t *testing.T) {
const newSchemaVer = 28

testCases := []struct {
in yobj
want yobj
name string
}{{
name: "empty",
in: yobj{},
want: yobj{
"schema_version": newSchemaVer,
},
}, {
name: "load_balance",
in: yobj{
"dns": yobj{
"all_servers": false,
"fastest_addr": false,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeLoadBalance,
},
"schema_version": newSchemaVer,
},
}, {
name: "parallel",
in: yobj{
"dns": yobj{
"all_servers": true,
"fastest_addr": false,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeParallel,
},
"schema_version": newSchemaVer,
},
}, {
name: "parallel_fastest",
in: yobj{
"dns": yobj{
"all_servers": true,
"fastest_addr": true,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeParallel,
},
"schema_version": newSchemaVer,
},
}, {
name: "load_balance",
in: yobj{
"dns": yobj{
"all_servers": false,
"fastest_addr": true,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeFastestAddr,
},
"schema_version": newSchemaVer,
},
}}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := migrateTo28(tc.in)
require.NoError(t, err)

assert.Equal(t, tc.want, tc.in)
})
}
}
1 change: 1 addition & 0 deletions internal/configmigrate/migrator.go
Expand Up @@ -119,6 +119,7 @@ func (m *Migrator) upgradeConfigSchema(current, target uint, diskConf yobj) (err
24: migrateTo25,
25: migrateTo26,
26: migrateTo27,
27: migrateTo28,
}

for i, migrate := range upgrades[current:target] {
Expand Down
47 changes: 47 additions & 0 deletions internal/configmigrate/v28.go
@@ -0,0 +1,47 @@
package configmigrate

import (
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
)

// migrateTo28 performs the following changes:
//
// # BEFORE:
// 'dns':
// 'all_servers': true
// 'fastest_addr': true
// # …
// # …
//
// # AFTER:
// 'dns':
// 'upstream_mode': 'parallel'
// # …
// # …
func migrateTo28(diskConf yobj) (err error) {
diskConf["schema_version"] = 28

dns, ok, err := fieldVal[yobj](diskConf, "dns")
if !ok {
return err
}

allServers, _, _ := fieldVal[bool](dns, "all_servers")
fastestAddr, _, _ := fieldVal[bool](dns, "fastest_addr")

var upstreamModeType dnsforward.UpstreamMode
if allServers {
upstreamModeType = dnsforward.UpstreamModeParallel
} else if fastestAddr {
upstreamModeType = dnsforward.UpstreamModeFastestAddr
} else {
upstreamModeType = dnsforward.UpstreamModeLoadBalance
}

dns["upstream_mode"] = upstreamModeType

delete(dns, "all_servers")
delete(dns, "fastest_addr")

return nil
}
63 changes: 44 additions & 19 deletions internal/dnsforward/config.go
Expand Up @@ -89,12 +89,8 @@ type Config struct {
// servers are not responding.
FallbackDNS []string `yaml:"fallback_dns"`

// AllServers, if true, parallel queries to all configured upstream servers
// are enabled.
AllServers bool `yaml:"all_servers"`

// FastestAddr, if true, use Fastest Address algorithm.
FastestAddr bool `yaml:"fastest_addr"`
// UpstreamMode determines the logic through which upstreams will be used.
UpstreamMode UpstreamMode `yaml:"upstream_mode"`

// FastestTimeout replaces the default timeout for dialing IP addresses
// when FastestAddr is true.
Expand Down Expand Up @@ -154,7 +150,7 @@ type Config struct {

// MaxGoroutines is the max number of parallel goroutines for processing
// incoming requests.
MaxGoroutines uint32 `yaml:"max_goroutines"`
MaxGoroutines uint `yaml:"max_goroutines"`

// HandleDDR, if true, handle DDR requests
HandleDDR bool `yaml:"handle_ddr"`
Expand Down Expand Up @@ -294,6 +290,16 @@ type ServerConfig struct {
ServePlainDNS bool
}

// UpstreamMode is a enumeration of upstream mode representations. See
// [proxy.UpstreamModeType].
type UpstreamMode string

const (
UpstreamModeLoadBalance UpstreamMode = "load_balance"
UpstreamModeParallel UpstreamMode = "parallel"
UpstreamModeFastestAddr UpstreamMode = "fastest_addr"
)

// newProxyConfig creates and validates configuration for the main proxy.
func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
srvConf := s.conf
Expand All @@ -313,7 +319,7 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
RequestHandler: s.handleDNSRequest,
HTTPSServerName: aghhttp.UserAgent(),
EnableEDNSClientSubnet: srvConf.EDNSClientSubnet.Enabled,
MaxGoroutines: int(srvConf.MaxGoroutines),
MaxGoroutines: srvConf.MaxGoroutines,
UseDNS64: srvConf.UseDNS64,
DNS64Prefs: srvConf.DNS64Prefixes,
}
Expand All @@ -323,18 +329,11 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
conf.EDNSAddr = net.IP(srvConf.EDNSClientSubnet.CustomIP.AsSlice())
}

if srvConf.CacheSize != 0 {
conf.CacheEnabled = true
conf.CacheSizeBytes = int(srvConf.CacheSize)
err = setProxyUpstreamMode(conf, srvConf.UpstreamMode, srvConf.FastestTimeout.Duration)
if err != nil {
return nil, fmt.Errorf("upstream mode: %w", err)
}

setProxyUpstreamMode(
conf,
srvConf.AllServers,
srvConf.FastestAddr,
srvConf.FastestTimeout.Duration,
)

conf.BogusNXDomain, err = parseBogusNXDOMAIN(srvConf.BogusNXDomain)
if err != nil {
return nil, fmt.Errorf("bogus_nxdomain: %w", err)
Expand All @@ -361,7 +360,33 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
return nil, errors.Error("no default upstream servers configured")
}

err = validateCacheTTL(srvConf.CacheMinTTL, srvConf.CacheMaxTTL)
conf, err = prepareCacheConfig(conf,
srvConf.CacheSize,
srvConf.CacheMinTTL,
srvConf.CacheMaxTTL,
)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}

return conf, nil
}

// prepareCacheConfig prepares the cache configuration and returns an error if
// there is one.
func prepareCacheConfig(
conf *proxy.Config,
size uint32,
minTTL uint32,
maxTTL uint32,
) (prepared *proxy.Config, err error) {
if size != 0 {
conf.CacheEnabled = true
conf.CacheSizeBytes = int(size)
}

err = validateCacheTTL(minTTL, maxTTL)
if err != nil {
return nil, fmt.Errorf("validating cache ttl: %w", err)
}
Expand Down
1 change: 1 addition & 0 deletions internal/dnsforward/dns64_test.go
Expand Up @@ -290,6 +290,7 @@ func TestServer_HandleDNSRequest_dns64(t *testing.T) {
TCPListenAddrs: []*net.TCPAddr{{}},
UseDNS64: true,
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
Expand Down

0 comments on commit 7dea2a3

Please sign in to comment.