AdGuardHome/internal/dnsforward/dnsrewrite_test.go
Dimitry Kolyshev 2c2c0d445b Pull request #1473: svcb dohpath support
Merge in DNS/adguard-home from 4463-ddr-support to master

Squashed commit of the following:

commit 99a149e9024354ad0341739c3c9b08cefbd74468
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Apr 12 14:13:17 2022 +0200

    imp docs

commit 26150be8df8b35e47c108f6e3319c57b39fb8e38
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Apr 11 20:36:18 2022 +0200

    imp code docs

commit 5a4607f71abba83a9ac8753abd74c9fb97e4a545
Merge: 00f0abf5 9f0fdc5e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Apr 11 16:14:49 2022 +0200

    Merge remote-tracking branch 'origin/master' into 4463-ddr-support

    # Conflicts:
    #	internal/dnsforward/svcbmsg.go

commit 00f0abf5eea07aeeebc2a856a958215021a51ab7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Apr 11 16:06:42 2022 +0200

    svcb dohpath support

commit ace81ce1ea2fb96c4434c6c1fded4a79427cf17e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Apr 7 14:31:32 2022 +0200

    svcb dohpath support

commit a1b5df4fb2e87dab265d6ca55928610a6acc1c00
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Apr 6 16:53:17 2022 +0200

    svcb dohpath support
2022-04-12 15:45:18 +03:00

235 lines
5.9 KiB
Go

package dnsforward
import (
"net"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy"
"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 := net.IP{127, 0, 0, 1}
ip6 := net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
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 := &Server{}
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, ip4, 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, ip6, 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)
})
}