Pull request: 2843 upd dnsproxy
Merge in DNS/adguard-home from 2843-upd-dnsproxy to master Closes #2843. Squashed commit of the following: commit c3ffddcbf85cbd2542c5bb111984a8f422113a24 Author: Eugene Burkov <e.burkov@adguard.com> Date: Tue Apr 20 19:39:11 2021 +0300 all: fix docs commit 4b596e4776bfc05e4171bc53e8f9c55c88e1e6a5 Author: Eugene Burkov <e.burkov@adguard.com> Date: Tue Apr 20 19:25:24 2021 +0300 all: imp code, docs commit 8e3655f4f888ccc2c0902373cf8dd2aa4e113857 Author: Eugene Burkov <e.burkov@adguard.com> Date: Tue Apr 20 18:41:14 2021 +0300 all: upd dnsproxy
This commit is contained in:
@@ -142,7 +142,7 @@ func processClientID(dctx *dnsContext) (rc resultCode) {
|
||||
return resultCodeError
|
||||
}
|
||||
|
||||
cliSrvName = qs.ConnectionState().ServerName
|
||||
cliSrvName = qs.ConnectionState().TLS.ServerName
|
||||
}
|
||||
|
||||
clientID, err := clientIDFromClientServerName(hostSrvName, cliSrvName, srvConf.StrictSNICheck)
|
||||
|
||||
@@ -40,7 +40,7 @@ type testQUICSession struct {
|
||||
|
||||
// ConnectionState implements the quicSession interface for testQUICSession.
|
||||
func (c testQUICSession) ConnectionState() (cs quic.ConnectionState) {
|
||||
cs.ServerName = c.serverName
|
||||
cs.TLS.ServerName = c.serverName
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ func TestDoTServer(t *testing.T) {
|
||||
|
||||
func TestDoQServer(t *testing.T) {
|
||||
s, _ := createTestTLS(t, TLSConfig{
|
||||
QUICListenAddrs: []*net.UDPAddr{{}},
|
||||
QUICListenAddrs: []*net.UDPAddr{{IP: net.IP{127, 0, 0, 1}}},
|
||||
})
|
||||
s.conf.UpstreamConfig.Upstreams = []upstream.Upstream{
|
||||
&aghtest.TestUpstream{
|
||||
|
||||
@@ -2,11 +2,15 @@ package home
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/google/renameio/maybe"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -14,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
// currentSchemaVersion is the current schema version.
|
||||
const currentSchemaVersion = 9
|
||||
const currentSchemaVersion = 10
|
||||
|
||||
// These aliases are provided for convenience.
|
||||
type (
|
||||
@@ -75,6 +79,7 @@ func upgradeConfigSchema(oldVersion int, diskConf yobj) (err error) {
|
||||
upgradeSchema6to7,
|
||||
upgradeSchema7to8,
|
||||
upgradeSchema8to9,
|
||||
upgradeSchema9to10,
|
||||
}
|
||||
|
||||
n := 0
|
||||
@@ -456,7 +461,7 @@ func upgradeSchema7to8(diskConf yobj) (err error) {
|
||||
bindHostVal := dns["bind_host"]
|
||||
bindHost, ok := bindHostVal.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("undexpected type of dns.bind_host: %T", bindHostVal)
|
||||
return fmt.Errorf("unexpected type of dns.bind_host: %T", bindHostVal)
|
||||
}
|
||||
|
||||
delete(dns, "bind_host")
|
||||
@@ -502,7 +507,7 @@ func upgradeSchema8to9(diskConf yobj) (err error) {
|
||||
|
||||
autohostTLD, ok := autohostTLDVal.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("undexpected type of dns.autohost_tld: %T", autohostTLDVal)
|
||||
return fmt.Errorf("unexpected type of dns.autohost_tld: %T", autohostTLDVal)
|
||||
}
|
||||
|
||||
delete(dns, "autohost_tld")
|
||||
@@ -511,6 +516,102 @@ func upgradeSchema8to9(diskConf yobj) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// addQUICPort inserts a port into QUIC upstream's hostname if it is missing.
|
||||
func addQUICPort(ups string, port int) (withPort string) {
|
||||
if ups == "" || ups[0] == '#' {
|
||||
return ups
|
||||
}
|
||||
|
||||
var doms string
|
||||
withPort = ups
|
||||
if strings.HasPrefix(ups, "[/") {
|
||||
domsAndUps := strings.Split(strings.TrimPrefix(ups, "[/"), "/]")
|
||||
if len(domsAndUps) != 2 {
|
||||
return ups
|
||||
}
|
||||
|
||||
doms, withPort = "[/"+domsAndUps[0]+"/]", domsAndUps[1]
|
||||
}
|
||||
|
||||
if !strings.Contains(withPort, "://") {
|
||||
return ups
|
||||
}
|
||||
|
||||
upsURL, err := url.Parse(withPort)
|
||||
if err != nil || upsURL.Scheme != "quic" {
|
||||
return ups
|
||||
}
|
||||
|
||||
var host string
|
||||
host, err = aghnet.SplitHost(upsURL.Host)
|
||||
if err != nil || host != upsURL.Host {
|
||||
return ups
|
||||
}
|
||||
|
||||
upsURL.Host = strings.Join([]string{host, strconv.Itoa(port)}, ":")
|
||||
|
||||
return doms + upsURL.String()
|
||||
}
|
||||
|
||||
// upgradeSchema9to10 performs the following changes:
|
||||
//
|
||||
// # BEFORE:
|
||||
// 'dns':
|
||||
// 'upstream_dns':
|
||||
// - 'quic://some-upstream.com'
|
||||
//
|
||||
// # AFTER:
|
||||
// 'dns':
|
||||
// 'upstream_dns':
|
||||
// - 'quic://some-upstream.com:784'
|
||||
//
|
||||
func upgradeSchema9to10(diskConf yobj) (err error) {
|
||||
log.Printf("Upgrade yaml: 9 to 10")
|
||||
|
||||
diskConf["schema_version"] = 10
|
||||
|
||||
dnsVal, ok := diskConf["dns"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
var dns yobj
|
||||
dns, ok = dnsVal.(yobj)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type of dns: %T", dnsVal)
|
||||
}
|
||||
|
||||
const quicPort = 784
|
||||
for _, upsField := range []string{
|
||||
"upstream_dns",
|
||||
"local_ptr_upstreams",
|
||||
} {
|
||||
var upsVal any
|
||||
upsVal, ok = dns[upsField]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
var ups yarr
|
||||
ups, ok = upsVal.(yarr)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type of dns.%s: %T", upsField, upsVal)
|
||||
}
|
||||
|
||||
var u string
|
||||
for i, uVal := range ups {
|
||||
u, ok = uVal.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type of upstream field: %T", uVal)
|
||||
}
|
||||
|
||||
ups[i] = addQUICPort(u, quicPort)
|
||||
}
|
||||
dns[upsField] = ups
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(a.garipov): Replace with log.Output when we port it to our logging
|
||||
// package.
|
||||
func funcName() string {
|
||||
|
||||
@@ -214,3 +214,157 @@ func testDNSConf(schemaVersion int) (dnsConf yobj) {
|
||||
|
||||
return dnsConf
|
||||
}
|
||||
|
||||
func TestAddQUICPort(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ups string
|
||||
want string
|
||||
}{{
|
||||
name: "simple_ip",
|
||||
ups: "8.8.8.8",
|
||||
want: "8.8.8.8",
|
||||
}, {
|
||||
name: "url_ipv4",
|
||||
ups: "quic://8.8.8.8",
|
||||
want: "quic://8.8.8.8:784",
|
||||
}, {
|
||||
name: "url_ipv4_with_port",
|
||||
ups: "quic://8.8.8.8:25565",
|
||||
want: "quic://8.8.8.8:25565",
|
||||
}, {
|
||||
name: "url_ipv6",
|
||||
ups: "quic://[::1]",
|
||||
want: "quic://[::1]:784",
|
||||
}, {
|
||||
name: "url_ipv6_invalid",
|
||||
ups: "quic://::1",
|
||||
want: "quic://::1",
|
||||
}, {
|
||||
name: "url_ipv6_with_port",
|
||||
ups: "quic://[::1]:25565",
|
||||
want: "quic://[::1]:25565",
|
||||
}, {
|
||||
name: "url_hostname",
|
||||
ups: "quic://example.com",
|
||||
want: "quic://example.com:784",
|
||||
}, {
|
||||
name: "url_hostname_with_port",
|
||||
ups: "quic://example.com:25565",
|
||||
want: "quic://example.com:25565",
|
||||
}, {
|
||||
name: "url_hostname_with_endpoint",
|
||||
ups: "quic://example.com/some-endpoint",
|
||||
want: "quic://example.com:784/some-endpoint",
|
||||
}, {
|
||||
name: "url_hostname_with_port_endpoint",
|
||||
ups: "quic://example.com:25565/some-endpoint",
|
||||
want: "quic://example.com:25565/some-endpoint",
|
||||
}, {
|
||||
name: "non-quic_proto",
|
||||
ups: "tls://example.com",
|
||||
want: "tls://example.com",
|
||||
}, {
|
||||
name: "comment",
|
||||
ups: "# comment",
|
||||
want: "# comment",
|
||||
}, {
|
||||
name: "blank",
|
||||
ups: "",
|
||||
want: "",
|
||||
}, {
|
||||
name: "with_domain_ip",
|
||||
ups: "[/example.domain/]8.8.8.8",
|
||||
want: "[/example.domain/]8.8.8.8",
|
||||
}, {
|
||||
name: "with_domain_url",
|
||||
ups: "[/example.domain/]quic://example.com",
|
||||
want: "[/example.domain/]quic://example.com:784",
|
||||
}, {
|
||||
name: "invalid_domain",
|
||||
ups: "[/exmaple.domain]quic://example.com",
|
||||
want: "[/exmaple.domain]quic://example.com",
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
withPort := addQUICPort(tc.ups, 784)
|
||||
|
||||
assert.Equal(t, tc.want, withPort)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpgradeSchema9to10(t *testing.T) {
|
||||
const ultimateAns = 42
|
||||
|
||||
testCases := []struct {
|
||||
ups any
|
||||
want any
|
||||
wantErr string
|
||||
name string
|
||||
}{{
|
||||
ups: yarr{"quic://8.8.8.8"},
|
||||
want: yarr{"quic://8.8.8.8:784"},
|
||||
wantErr: "",
|
||||
name: "success",
|
||||
}, {
|
||||
ups: ultimateAns,
|
||||
want: nil,
|
||||
wantErr: "unexpected type of dns.upstream_dns: int",
|
||||
name: "bad_yarr_type",
|
||||
}, {
|
||||
ups: yarr{ultimateAns},
|
||||
want: nil,
|
||||
wantErr: "unexpected type of upstream field: int",
|
||||
name: "bad_upstream_type",
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
conf := yobj{
|
||||
"dns": yobj{
|
||||
"upstream_dns": tc.ups,
|
||||
},
|
||||
"schema_version": 9,
|
||||
}
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := upgradeSchema9to10(conf)
|
||||
|
||||
if tc.wantErr != "" {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, tc.wantErr, err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, conf["schema_version"], 10)
|
||||
|
||||
dnsVal, ok := conf["dns"]
|
||||
require.True(t, ok)
|
||||
|
||||
newDNSConf, ok := dnsVal.(yobj)
|
||||
require.True(t, ok)
|
||||
|
||||
fixedUps, ok := newDNSConf["upstream_dns"].(yarr)
|
||||
require.True(t, ok)
|
||||
|
||||
assert.Equal(t, tc.want, fixedUps)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("no_dns", func(t *testing.T) {
|
||||
err := upgradeSchema9to10(yobj{})
|
||||
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("bad_dns", func(t *testing.T) {
|
||||
err := upgradeSchema9to10(yobj{
|
||||
"dns": ultimateAns,
|
||||
})
|
||||
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, "unexpected type of dns: int", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user