From 56cb8a4dde9a7690d336d84a5c249debf5625ef4 Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Thu, 14 Jan 2021 15:30:39 +0300 Subject: [PATCH] Pull request: dnsforward: add dnsrewrite tests Merge in DNS/adguard-home from 2102-dnsrewrite-tests to master Updates #2102. Squashed commit of the following: commit 894ff4baf8378d6e3386e09c416d55241a01f79e Author: Ainar Garipov Date: Thu Jan 14 14:49:28 2021 +0300 dnsforward: add dnsrewrite tests --- internal/dnsfilter/dnsrewrite.go | 4 +- internal/dnsfilter/safebrowsing.go | 4 +- internal/dnsforward/dnsrewrite_test.go | 172 +++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 internal/dnsforward/dnsrewrite_test.go diff --git a/internal/dnsfilter/dnsrewrite.go b/internal/dnsfilter/dnsrewrite.go index 15e4e211..757f742c 100644 --- a/internal/dnsfilter/dnsrewrite.go +++ b/internal/dnsfilter/dnsrewrite.go @@ -33,7 +33,7 @@ func (d *DNSFilter) processDNSRewrites(dnsr []*rules.NetworkRule) (res Result) { if dr.NewCNAME != "" { // NewCNAME rules have a higher priority than // the other rules. - rules := []*ResultRule{{ + rules = []*ResultRule{{ FilterListID: int64(nr.GetFilterListID()), Text: nr.RuleText, }} @@ -56,7 +56,7 @@ func (d *DNSFilter) processDNSRewrites(dnsr []*rules.NetworkRule) (res Result) { default: // RcodeRefused and other such codes have higher // priority. Return immediately. - rules := []*ResultRule{{ + rules = []*ResultRule{{ FilterListID: int64(nr.GetFilterListID()), Text: nr.RuleText, }} diff --git a/internal/dnsfilter/safebrowsing.go b/internal/dnsfilter/safebrowsing.go index 8f4c8f30..87cd2607 100644 --- a/internal/dnsfilter/safebrowsing.go +++ b/internal/dnsfilter/safebrowsing.go @@ -46,12 +46,12 @@ func (d *DNSFilter) initSecurityServices() error { d.parentalUpstream, err = upstream.AddressToUpstream(d.parentalServer, opts) if err != nil { - return err + return fmt.Errorf("converting parental server: %w", err) } d.safeBrowsingUpstream, err = upstream.AddressToUpstream(d.safeBrowsingServer, opts) if err != nil { - return err + return fmt.Errorf("converting safe browsing server: %w", err) } return nil diff --git a/internal/dnsforward/dnsrewrite_test.go b/internal/dnsforward/dnsrewrite_test.go new file mode 100644 index 00000000..b3f5ecf3 --- /dev/null +++ b/internal/dnsforward/dnsrewrite_test.go @@ -0,0 +1,172 @@ +package dnsforward + +import ( + "net" + "testing" + + "github.com/AdguardTeam/AdGuardHome/internal/dnsfilter" + "github.com/AdguardTeam/dnsproxy/proxy" + "github.com/AdguardTeam/urlfilter/rules" + "github.com/miekg/dns" + "github.com/stretchr/testify/assert" +) + +func TestServer_FilterDNSRewrite(t *testing.T) { + // Helper data. + 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} + mx := &rules.DNSMX{ + Exchange: "mail.example.com", + Preference: 32, + } + svcb := &rules.DNSSVCB{ + Params: map[string]string{"alpn": "h3"}, + Target: "example.com", + Priority: 32, + } + const domain = "example.com" + + // 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 dnsfilter.Result) { + resp := dnsfilter.DNSRewriteResultResponse{ + rr: []rules.RRValue{v}, + } + return dnsfilter.Result{ + DNSRewriteResult: &dnsfilter.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) + assert.Nil(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) + assert.Nil(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) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.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) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.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) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.Len(t, d.Res.Answer, 1) { + assert.Equal(t, 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) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.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, mx) + d := &proxy.DNSContext{} + + err := srv.filterDNSRewrite(req, res, d) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.Len(t, d.Res.Answer, 1) { + ans := d.Res.Answer[0].(*dns.MX) + assert.Equal(t, mx.Exchange, ans.Mx) + assert.Equal(t, mx.Preference, ans.Preference) + } + }) + + t.Run("noerror_svcb", func(t *testing.T) { + req := makeQ(dns.TypeSVCB) + res := makeRes(dns.RcodeSuccess, dns.TypeSVCB, svcb) + d := &proxy.DNSContext{} + + err := srv.filterDNSRewrite(req, res, d) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.Len(t, d.Res.Answer, 1) { + ans := d.Res.Answer[0].(*dns.SVCB) + assert.Equal(t, dns.SVCB_ALPN, ans.Value[0].Key()) + assert.Equal(t, svcb.Params["alpn"], ans.Value[0].String()) + assert.Equal(t, svcb.Target, ans.Target) + assert.Equal(t, svcb.Priority, ans.Priority) + } + }) + + t.Run("noerror_https", func(t *testing.T) { + req := makeQ(dns.TypeHTTPS) + res := makeRes(dns.RcodeSuccess, dns.TypeHTTPS, svcb) + d := &proxy.DNSContext{} + + err := srv.filterDNSRewrite(req, res, d) + assert.Nil(t, err) + assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) + if assert.Len(t, d.Res.Answer, 1) { + ans := d.Res.Answer[0].(*dns.HTTPS) + assert.Equal(t, dns.SVCB_ALPN, ans.Value[0].Key()) + assert.Equal(t, svcb.Params["alpn"], ans.Value[0].String()) + assert.Equal(t, svcb.Target, ans.Target) + assert.Equal(t, svcb.Priority, ans.Priority) + } + }) +}