Pull request: 4238 response filtering

Merge in DNS/adguard-home from 4238-response-filtering to master

Closes #4238.

Squashed commit of the following:

commit 2113f83c617a396a39f910bb8df939364fedf391
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Feb 3 21:04:25 2022 +0300

    dnsforward: restore a bit

commit f78607ed97892557c6bd6f3c3332f0bae01c1987
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Feb 3 20:52:45 2022 +0300

    all: imp code, docs

commit 646074ce141e8ac12a972f46d071389a2ce124e4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Feb 3 20:37:05 2022 +0300

    all: log changes

commit 94556d810549370fc455bcf14537fa1d2783eed1
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Feb 3 20:30:57 2022 +0300

    all: imp test upstream, cover resp filtering

commit 63e7721822a049734a390c7d7ea6d8416a43c8b5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Feb 1 21:58:08 2022 +0300

    all: filter response by rrtype
This commit is contained in:
Eugene Burkov
2022-02-03 21:19:32 +03:00
parent 0ee34534c6
commit e783564084
10 changed files with 257 additions and 128 deletions

View File

@@ -20,17 +20,19 @@ func DiscardLogOutput(m *testing.M) {
// ReplaceLogWriter moves logger output to w and uses Cleanup method of t to
// revert changes.
func ReplaceLogWriter(t *testing.T, w io.Writer) {
stdWriter := log.Writer()
t.Cleanup(func() {
log.SetOutput(stdWriter)
})
func ReplaceLogWriter(t testing.TB, w io.Writer) {
t.Helper()
prev := log.Writer()
t.Cleanup(func() { log.SetOutput(prev) })
log.SetOutput(w)
}
// ReplaceLogLevel sets logging level to l and uses Cleanup method of t to
// revert changes.
func ReplaceLogLevel(t *testing.T, l log.Level) {
func ReplaceLogLevel(t testing.TB, l log.Level) {
t.Helper()
switch l {
case log.INFO, log.DEBUG, log.ERROR:
// Go on.
@@ -38,9 +40,7 @@ func ReplaceLogLevel(t *testing.T, l log.Level) {
t.Fatalf("wrong l value (must be one of %v, %v, %v)", log.INFO, log.DEBUG, log.ERROR)
}
stdLevel := log.GetLevel()
t.Cleanup(func() {
log.SetLevel(stdLevel)
})
prev := log.GetLevel()
t.Cleanup(func() { log.SetLevel(prev) })
log.SetLevel(l)
}

View File

@@ -11,10 +11,10 @@ import (
"github.com/miekg/dns"
)
// TestUpstream is a mock of real upstream.
type TestUpstream struct {
// Upstream is a mock implementation of upstream.Upstream.
type Upstream struct {
// CName is a map of hostname to canonical name.
CName map[string]string
CName map[string][]string
// IPv4 is a map of hostname to IPv4.
IPv4 map[string][]net.IP
// IPv6 is a map of hostname to IPv6.
@@ -25,78 +25,45 @@ type TestUpstream struct {
Addr string
}
// Exchange implements upstream.Upstream interface for *TestUpstream.
// Exchange implements the upstream.Upstream interface for *Upstream.
//
// TODO(a.garipov): Split further into handlers.
func (u *TestUpstream) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {
resp = &dns.Msg{}
resp.SetReply(m)
func (u *Upstream) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {
resp = new(dns.Msg).SetReply(m)
if len(m.Question) == 0 {
return nil, fmt.Errorf("question should not be empty")
}
name := m.Question[0].Name
if cname, ok := u.CName[name]; ok {
ans := &dns.CNAME{
Hdr: dns.RR_Header{
Name: name,
Rrtype: dns.TypeCNAME,
},
q := m.Question[0]
name := q.Name
for _, cname := range u.CName[name] {
resp.Answer = append(resp.Answer, &dns.CNAME{
Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME},
Target: cname,
}
resp.Answer = append(resp.Answer, ans)
})
}
rrType := m.Question[0].Qtype
qtype := q.Qtype
hdr := dns.RR_Header{
Name: name,
Rrtype: rrType,
Rrtype: qtype,
}
var names []string
var ips []net.IP
switch m.Question[0].Qtype {
switch qtype {
case dns.TypeA:
ips = u.IPv4[name]
for _, ip := range u.IPv4[name] {
resp.Answer = append(resp.Answer, &dns.A{Hdr: hdr, A: ip})
}
case dns.TypeAAAA:
ips = u.IPv6[name]
for _, ip := range u.IPv6[name] {
resp.Answer = append(resp.Answer, &dns.AAAA{Hdr: hdr, AAAA: ip})
}
case dns.TypePTR:
names = u.Reverse[name]
}
for _, ip := range ips {
var ans dns.RR
if rrType == dns.TypeA {
ans = &dns.A{
Hdr: hdr,
A: ip,
}
resp.Answer = append(resp.Answer, ans)
continue
for _, name := range u.Reverse[name] {
resp.Answer = append(resp.Answer, &dns.PTR{Hdr: hdr, Ptr: name})
}
ans = &dns.AAAA{
Hdr: hdr,
AAAA: ip,
}
resp.Answer = append(resp.Answer, ans)
}
for _, n := range names {
ans := &dns.PTR{
Hdr: hdr,
Ptr: n,
}
resp.Answer = append(resp.Answer, ans)
}
if len(resp.Answer) == 0 {
resp.SetRcode(m, dns.RcodeNameError)
}
@@ -104,8 +71,8 @@ func (u *TestUpstream) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {
return resp, nil
}
// Address implements upstream.Upstream interface for *TestUpstream.
func (u *TestUpstream) Address() string {
// Address implements upstream.Upstream interface for *Upstream.
func (u *Upstream) Address() string {
return u.Addr
}