all: conf upstream mode

This commit is contained in:
Dimitry Kolyshev 2023-12-18 15:10:01 +02:00
parent d32832735c
commit 58b53ccd97
15 changed files with 212 additions and 37 deletions

View File

@ -2,4 +2,4 @@
package configmigrate
// LastSchemaVersion is the most recent schema version.
const LastSchemaVersion uint = 27
const LastSchemaVersion uint = 28

View File

@ -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"
@ -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.UpstreamModeTypeLoadBalance,
},
"schema_version": newSchemaVer,
},
}, {
name: "parallel",
in: yobj{
"dns": yobj{
"all_servers": true,
"fastest_addr": false,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeTypeParallel,
},
"schema_version": newSchemaVer,
},
}, {
name: "parallel_fastest",
in: yobj{
"dns": yobj{
"all_servers": true,
"fastest_addr": true,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeTypeParallel,
},
"schema_version": newSchemaVer,
},
}, {
name: "load_balance",
in: yobj{
"dns": yobj{
"all_servers": false,
"fastest_addr": true,
},
},
want: yobj{
"dns": yobj{
"upstream_mode": dnsforward.UpstreamModeTypeFastestAddr,
},
"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)
})
}
}

View File

@ -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 string
if allServers {
upstreamModeType = dnsforward.UpstreamModeTypeParallel
} else if fastestAddr {
upstreamModeType = dnsforward.UpstreamModeTypeFastestAddr
} else {
upstreamModeType = dnsforward.UpstreamModeTypeLoadBalance
}
dns["upstream_mode"] = upstreamModeType
delete(dns, "all_servers")
delete(dns, "fastest_addr")
return nil
}

View File

@ -89,12 +89,9 @@ 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.
// See UpstreamModeType* constants.
UpstreamMode string `yaml:"upstream_mode"`
// FastestTimeout replaces the default timeout for dialing IP addresses
// when FastestAddr is true.
@ -294,6 +291,13 @@ type ServerConfig struct {
ServePlainDNS bool
}
// UpstreamMode types representation. See [proxy.UpstreamModeType].
const (
UpstreamModeTypeLoadBalance = "load_balance"
UpstreamModeTypeParallel = "parallel"
UpstreamModeTypeFastestAddr = "fastest_addr"
)
// newProxyConfig creates and validates configuration for the main proxy.
func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
srvConf := s.conf
@ -328,12 +332,10 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
conf.CacheSizeBytes = int(srvConf.CacheSize)
}
setProxyUpstreamMode(
conf,
srvConf.AllServers,
srvConf.FastestAddr,
srvConf.FastestTimeout.Duration,
)
err = setProxyUpstreamMode(conf, srvConf.UpstreamMode, srvConf.FastestTimeout.Duration)
if err != nil {
return nil, fmt.Errorf("upstream mode: %w", err)
}
conf.BogusNXDomain, err = parseBogusNXDOMAIN(srvConf.BogusNXDomain)
if err != nil {

View File

@ -290,6 +290,7 @@ func TestServer_HandleDNSRequest_dns64(t *testing.T) {
TCPListenAddrs: []*net.TCPAddr{{}},
UseDNS64: true,
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,

View File

@ -703,12 +703,10 @@ func (s *Server) prepareInternalProxy() (err error) {
MaxGoroutines: int(s.conf.MaxGoroutines),
}
setProxyUpstreamMode(
conf,
srvConf.AllServers,
srvConf.FastestAddr,
srvConf.FastestTimeout.Duration,
)
err = setProxyUpstreamMode(conf, srvConf.UpstreamMode, srvConf.FastestTimeout.Duration)
if err != nil {
return fmt.Errorf("invalid upstream mode: %w", err)
}
// TODO(a.garipov): Make a proper constructor for proxy.Proxy.
p := &proxy.Proxy{

View File

@ -177,6 +177,7 @@ func createTestTLS(t *testing.T, tlsConf TLSConfig) (s *Server, certPem []byte)
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -305,6 +306,7 @@ func TestServer(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -344,6 +346,7 @@ func TestServer_timeout(t *testing.T) {
srvConf := &ServerConfig{
UpstreamTimeout: testTimeout,
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -362,6 +365,7 @@ func TestServer_timeout(t *testing.T) {
s, err := NewServer(DNSCreateParams{DNSFilter: createTestDNSFilter(t)})
require.NoError(t, err)
s.conf.Config.UpstreamMode = UpstreamModeTypeLoadBalance
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{
Enabled: false,
}
@ -379,6 +383,7 @@ func TestServer_Prepare_fallbacks(t *testing.T) {
"#tls://1.1.1.1",
"8.8.8.8",
},
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -401,6 +406,7 @@ func TestServerWithProtectionDisabled(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -478,7 +484,8 @@ func TestServerRace(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
UpstreamMode: UpstreamModeTypeLoadBalance,
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
},
ConfigModified: func() {},
ServePlainDNS: true,
@ -531,6 +538,7 @@ func TestSafeSearch(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -614,6 +622,7 @@ func TestInvalidRequest(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -643,6 +652,7 @@ func TestBlockedRequest(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -678,7 +688,8 @@ func TestServerCustomClientUpstream(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
CacheSize: defaultCacheSize,
CacheSize: defaultCacheSize,
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -756,6 +767,7 @@ func TestBlockCNAMEProtectionEnabled(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -789,6 +801,7 @@ func TestBlockCNAME(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -864,6 +877,7 @@ func TestClientRulesForCNAMEMatching(t *testing.T) {
FilterHandler: func(_ netip.Addr, _ string, settings *filtering.Settings) {
settings.FilteringEnabled = false
},
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -909,6 +923,7 @@ func TestNullBlockedRequest(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -974,7 +989,8 @@ func TestBlockedCustomIP(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -1027,6 +1043,7 @@ func TestBlockedByHosts(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -1078,6 +1095,7 @@ func TestBlockedBySafeBrowsing(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -1136,7 +1154,8 @@ func TestRewrite(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53"},
UpstreamDNS: []string{"8.8.8.8:53"},
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},
@ -1265,6 +1284,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.UpstreamMode = UpstreamModeTypeLoadBalance
err = s.Prepare(&s.conf)
require.NoError(t, err)
@ -1347,6 +1367,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.UpstreamMode = UpstreamModeTypeLoadBalance
err = s.Prepare(&s.conf)
require.NoError(t, err)

View File

@ -38,6 +38,7 @@ func TestServer_FilterDNSRewrite(t *testing.T) {
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,

View File

@ -31,6 +31,7 @@ func TestHandleDNSRequest_handleDNSRequest(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},

View File

@ -146,10 +146,12 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
localPTRUpstreams := stringutil.CloneSliceOrEmpty(s.conf.LocalPTRResolvers)
var upstreamMode string
if s.conf.FastestAddr {
upstreamMode = "fastest_addr"
} else if s.conf.AllServers {
// TODO(d.kolyshev): Set 'load_balance' type string instead of nil.
switch s.conf.UpstreamMode {
case UpstreamModeTypeParallel:
upstreamMode = "parallel"
case UpstreamModeTypeFastestAddr:
upstreamMode = "fastest_addr"
}
defPTRUps, err := s.defaultLocalPTRUpstreams()
@ -446,8 +448,16 @@ func (s *Server) setConfig(dc *jsonDNSConfig) (shouldRestart bool) {
}
if dc.UpstreamMode != nil {
s.conf.AllServers = *dc.UpstreamMode == "parallel"
s.conf.FastestAddr = *dc.UpstreamMode == "fastest_addr"
switch *dc.UpstreamMode {
case "parallel":
s.conf.UpstreamMode = UpstreamModeTypeParallel
case "fastest_addr":
s.conf.UpstreamMode = UpstreamModeTypeFastestAddr
default:
s.conf.UpstreamMode = UpstreamModeTypeLoadBalance
}
} else {
s.conf.UpstreamMode = UpstreamModeTypeLoadBalance
}
if dc.EDNSCSUseCustom != nil && *dc.EDNSCSUseCustom {

View File

@ -77,6 +77,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
FallbackDNS: []string{"9.9.9.10"},
RatelimitSubnetLenIPv4: 24,
RatelimitSubnetLenIPv6: 56,
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ConfigModified: func() {},
@ -103,7 +104,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
}, {
conf: func() ServerConfig {
conf := defaultConf
conf.FastestAddr = true
conf.UpstreamMode = UpstreamModeTypeFastestAddr
return conf
},
@ -111,7 +112,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
}, {
conf: func() ServerConfig {
conf := defaultConf
conf.AllServers = true
conf.UpstreamMode = UpstreamModeTypeParallel
return conf
},
@ -157,6 +158,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
RatelimitSubnetLenIPv4: 24,
RatelimitSubnetLenIPv6: 56,
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ConfigModified: func() {},
@ -523,6 +525,7 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
TCPListenAddrs: []*net.TCPAddr{{}},
UpstreamTimeout: upsTimeout,
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,

View File

@ -79,6 +79,7 @@ func TestServer_ProcessInitial(t *testing.T) {
c := ServerConfig{
Config: Config{
AAAADisabled: tc.aaaaDisabled,
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -179,6 +180,7 @@ func TestServer_ProcessFilteringAfterResponse(t *testing.T) {
c := ServerConfig{
Config: Config{
AAAADisabled: tc.aaaaDisabled,
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -694,6 +696,7 @@ func TestServer_ProcessRestrictLocal(t *testing.T) {
// TODO(s.chzhen): Add tests where EDNSClientSubnet.Enabled is true.
// Improve Config declaration for tests.
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,
@ -770,6 +773,7 @@ func TestServer_ProcessLocalPTR_usingResolvers(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,

View File

@ -17,6 +17,7 @@ func TestGenAnswerHTTPS_andSVCB(t *testing.T) {
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
Config: Config{
UpstreamMode: UpstreamModeTypeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
ServePlainDNS: true,

View File

@ -136,18 +136,22 @@ func UpstreamHTTPVersions(http3 bool) (v []upstream.HTTPVersion) {
// based on provided parameters.
func setProxyUpstreamMode(
conf *proxy.Config,
allServers bool,
fastestAddr bool,
upstreamMode string,
fastestTimeout time.Duration,
) {
if allServers {
) (err error) {
switch upstreamMode {
case UpstreamModeTypeParallel:
conf.UpstreamMode = proxy.UModeParallel
} else if fastestAddr {
case UpstreamModeTypeFastestAddr:
conf.UpstreamMode = proxy.UModeFastestAddr
conf.FastestPingTimeout = fastestTimeout
} else {
case UpstreamModeTypeLoadBalance:
conf.UpstreamMode = proxy.UModeLoadBalance
default:
return fmt.Errorf("unexpected value %q", upstreamMode)
}
return nil
}
// createBootstrap returns a bootstrap resolver based on the configuration of s.

View File

@ -315,7 +315,7 @@ var config = &configuration{
RatelimitSubnetLenIPv4: 24,
RatelimitSubnetLenIPv6: 56,
RefuseAny: true,
AllServers: false,
UpstreamMode: dnsforward.UpstreamModeTypeLoadBalance,
HandleDDR: true,
FastestTimeout: timeutil.Duration{
Duration: fastip.DefaultPingWaitTimeout,