Files
AdGuardHome/internal/dnsforward/dnsrewrite_test.go
Stanislav Chzhen 318bd2901a 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: f4b0caf5c 61fe269cb
Author: 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: bdb08ee0e d8ce5b453
Author: 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
2025-03-03 19:19:46 +03:00

245 lines
6.2 KiB
Go

package dnsforward
import (
"net"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestServer_FilterDNSRewrite(t *testing.T) {
// Helper data.
const domain = "example.com"
ip4, ip6 := netutil.IPv4Localhost(), netutil.IPv6Localhost()
mxVal := &rules.DNSMX{
Exchange: "mail.example.com",
Preference: 32,
}
svcbVal := &rules.DNSSVCB{
Params: map[string]string{"alpn": "h3", "dohpath": "/dns-query"},
Target: dns.Fqdn(domain),
Priority: 32,
}
srvVal := &rules.DNSSRV{
Priority: 32,
Weight: 60,
Port: 8080,
Target: dns.Fqdn(domain),
}
// Helper functions and entities.
srv := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
ClientsContainer: EmptyClientsContainer{},
},
ServePlainDNS: true,
})
makeQ := func(qtype rules.RRType) (req *dns.Msg) {
return &dns.Msg{
Question: []dns.Question{{
Qtype: qtype,
}},
}
}
makeRes := func(rcode rules.RCode, rr rules.RRType, v rules.RRValue) (res *filtering.Result) {
resp := filtering.DNSRewriteResultResponse{
rr: []rules.RRValue{v},
}
return &filtering.Result{
DNSRewriteResult: &filtering.DNSRewriteResult{
RCode: rcode,
Response: resp,
},
}
}
// Tests.
t.Run("nxdomain", func(t *testing.T) {
req := makeQ(dns.TypeA)
res := makeRes(dns.RcodeNameError, 0, nil)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeNameError, d.Res.Rcode)
})
t.Run("noerror_empty", func(t *testing.T) {
req := makeQ(dns.TypeA)
res := makeRes(dns.RcodeSuccess, 0, nil)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
assert.Empty(t, d.Res.Answer)
})
t.Run("noerror_a", func(t *testing.T) {
req := makeQ(dns.TypeA)
res := makeRes(dns.RcodeSuccess, dns.TypeA, ip4)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
assert.Equal(t, net.IP(ip4.AsSlice()), d.Res.Answer[0].(*dns.A).A)
})
t.Run("noerror_aaaa", func(t *testing.T) {
req := makeQ(dns.TypeAAAA)
res := makeRes(dns.RcodeSuccess, dns.TypeAAAA, ip6)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
assert.Equal(t, net.IP(ip6.AsSlice()), d.Res.Answer[0].(*dns.AAAA).AAAA)
})
t.Run("noerror_ptr", func(t *testing.T) {
req := makeQ(dns.TypePTR)
res := makeRes(dns.RcodeSuccess, dns.TypePTR, domain)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
assert.Equal(t, dns.Fqdn(domain), d.Res.Answer[0].(*dns.PTR).Ptr)
})
t.Run("noerror_txt", func(t *testing.T) {
req := makeQ(dns.TypeTXT)
res := makeRes(dns.RcodeSuccess, dns.TypeTXT, domain)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
assert.Equal(t, []string{domain}, d.Res.Answer[0].(*dns.TXT).Txt)
})
t.Run("noerror_mx", func(t *testing.T) {
req := makeQ(dns.TypeMX)
res := makeRes(dns.RcodeSuccess, dns.TypeMX, mxVal)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
ans, ok := d.Res.Answer[0].(*dns.MX)
require.True(t, ok)
assert.Equal(t, dns.Fqdn(mxVal.Exchange), ans.Mx)
assert.Equal(t, mxVal.Preference, ans.Preference)
})
t.Run("noerror_svcb", func(t *testing.T) {
req := makeQ(dns.TypeSVCB)
res := makeRes(dns.RcodeSuccess, dns.TypeSVCB, svcbVal)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
ans, ok := d.Res.Answer[0].(*dns.SVCB)
require.True(t, ok)
require.Len(t, ans.Value, 2)
assert.ElementsMatch(
t,
[]dns.SVCBKey{dns.SVCB_ALPN, dns.SVCB_DOHPATH},
[]dns.SVCBKey{ans.Value[0].Key(), ans.Value[1].Key()},
)
assert.ElementsMatch(
t,
[]string{svcbVal.Params["alpn"], svcbVal.Params["dohpath"]},
[]string{ans.Value[0].String(), ans.Value[1].String()},
)
assert.Equal(t, svcbVal.Target, ans.Target)
assert.Equal(t, svcbVal.Priority, ans.Priority)
})
t.Run("noerror_https", func(t *testing.T) {
req := makeQ(dns.TypeHTTPS)
res := makeRes(dns.RcodeSuccess, dns.TypeHTTPS, svcbVal)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
ans, ok := d.Res.Answer[0].(*dns.HTTPS)
require.True(t, ok)
require.Len(t, ans.Value, 2)
assert.ElementsMatch(
t,
[]dns.SVCBKey{dns.SVCB_ALPN, dns.SVCB_DOHPATH},
[]dns.SVCBKey{ans.Value[0].Key(), ans.Value[1].Key()},
)
assert.ElementsMatch(
t,
[]string{svcbVal.Params["alpn"], svcbVal.Params["dohpath"]},
[]string{ans.Value[0].String(), ans.Value[1].String()},
)
assert.Equal(t, svcbVal.Target, ans.Target)
assert.Equal(t, svcbVal.Priority, ans.Priority)
})
t.Run("noerror_srv", func(t *testing.T) {
req := makeQ(dns.TypeSRV)
res := makeRes(dns.RcodeSuccess, dns.TypeSRV, srvVal)
d := &proxy.DNSContext{}
err := srv.filterDNSRewrite(req, res, d)
require.NoError(t, err)
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1)
ans, ok := d.Res.Answer[0].(*dns.SRV)
require.True(t, ok)
assert.Equal(t, srvVal.Priority, ans.Priority)
assert.Equal(t, srvVal.Weight, ans.Weight)
assert.Equal(t, srvVal.Port, ans.Port)
assert.Equal(t, srvVal.Target, ans.Target)
})
}