Skip to content

Commit

Permalink
Merge branch 'master' into 4898-redirect-https
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Nov 1, 2022
2 parents 815e299 + ac7634d commit bc41b6c
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 294 deletions.
26 changes: 14 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ require (
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.5
github.com/digineo/go-ipset/v2 v2.2.1
github.com/dimfeld/httptreemux/v5 v5.4.0
github.com/fsnotify/fsnotify v1.5.4
github.com/dimfeld/httptreemux/v5 v5.5.0
github.com/fsnotify/fsnotify v1.6.0
github.com/go-ping/ping v1.1.0
github.com/google/go-cmp v0.5.8
github.com/google/go-cmp v0.5.9
github.com/google/gopacket v1.1.19
github.com/google/renameio v1.0.1
github.com/google/uuid v1.3.0
github.com/insomniacslk/dhcp v0.0.0-20220822114210-de18a9d48e84
github.com/kardianos/service v1.2.1
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c
github.com/kardianos/service v1.2.2
github.com/lucas-clemente/quic-go v0.29.2
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118
github.com/mdlayher/netlink v1.6.0
github.com/mdlayher/netlink v1.6.2
// TODO(a.garipov): This package is deprecated; find a new one or use
// our own code for that. Perhaps, use gopacket.
github.com/mdlayher/raw v0.1.0
github.com/miekg/dns v1.1.50
github.com/stretchr/testify v1.8.0
github.com/ti-mo/netfilter v0.4.0
go.etcd.io/bbolt v1.3.6
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
golang.org/x/exp v0.0.0-20221019170559-20944726eadf
golang.org/x/crypto v0.1.0
golang.org/x/exp v0.0.0-20221026153819-32f3d567a233
golang.org/x/net v0.1.0
golang.org/x/sys v0.1.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
Expand All @@ -48,20 +48,22 @@ require (
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/josharian/native v1.0.0 // indirect
github.com/marten-seemann/qpack v0.2.1 // indirect
github.com/marten-seemann/qpack v0.3.0 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
github.com/mdlayher/packet v1.0.0 // indirect
github.com/mdlayher/socket v0.2.3 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/ginkgo/v2 v2.4.0 // indirect
github.com/onsi/gomega v1.22.1 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4 // indirect
golang.org/x/mod v0.6.0-dev.0.20220922195421-2adab6b8c60e // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.org/x/tools v0.2.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
72 changes: 36 additions & 36 deletions go.sum

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions internal/aghos/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ func isReconfigureSignal(sig os.Signal) (ok bool) {

func isShutdownSignal(sig os.Signal) (ok bool) {
switch sig {
case
os.Interrupt,
syscall.SIGTERM:
case os.Interrupt, syscall.SIGTERM:
return true
default:
return false
Expand Down
152 changes: 98 additions & 54 deletions internal/aghtest/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import (
"encoding/hex"
"fmt"
"net"
"net/netip"
"strings"
"testing"

"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/errors"
"github.com/miekg/dns"
"github.com/stretchr/testify/require"
)

// Additional Upstream Testing Utilities
Expand All @@ -26,51 +25,10 @@ type Upstream struct {
IPv4 map[string][]net.IP
// IPv6 is a map of hostname to IPv6.
IPv6 map[string][]net.IP
// Reverse is a map of address to domain name.
Reverse map[string][]string
// Addr is the address for Address method.
Addr string
}

var _ upstream.Upstream = (*Upstream)(nil)

// RespondTo returns a response with answer if req has class cl, question type
// qt, and target targ.
func RespondTo(t testing.TB, req *dns.Msg, cl, qt uint16, targ, answer string) (resp *dns.Msg) {
t.Helper()

require.NotNil(t, req)
require.Len(t, req.Question, 1)

q := req.Question[0]
targ = dns.Fqdn(targ)
if q.Qclass != cl || q.Qtype != qt || q.Name != targ {
return nil
}

respHdr := dns.RR_Header{
Name: targ,
Rrtype: qt,
Class: cl,
Ttl: 60,
}

resp = new(dns.Msg).SetReply(req)
switch qt {
case dns.TypePTR:
resp.Answer = []dns.RR{
&dns.PTR{
Hdr: respHdr,
Ptr: answer,
},
}
default:
t.Fatalf("unsupported question type: %s", dns.Type(qt))
}

return resp
}

// Exchange implements the [upstream.Upstream] interface for *Upstream.
//
// TODO(a.garipov): Split further into handlers.
Expand Down Expand Up @@ -105,10 +63,6 @@ func (u *Upstream) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {
for _, ip := range u.IPv6[name] {
resp.Answer = append(resp.Answer, &dns.AAAA{Hdr: hdr, AAAA: ip})
}
case dns.TypePTR:
for _, name := range u.Reverse[name] {
resp.Answer = append(resp.Answer, &dns.PTR{Hdr: hdr, Ptr: name})
}
}
if len(resp.Answer) == 0 {
resp.SetRcode(m, dns.RcodeNameError)
Expand All @@ -119,14 +73,106 @@ func (u *Upstream) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {

// Address implements [upstream.Upstream] interface for *Upstream.
func (u *Upstream) Address() string {
return u.Addr
return "todo.upstream.example"
}

// Close implements [upstream.Upstream] interface for *Upstream.
func (u *Upstream) Close() (err error) {
return nil
}

// MatchedResponse is a test helper that returns a response with answer if req
// has question type qt, and target targ. Otherwise, it returns nil.
//
// req must not be nil and req.Question must have a length of 1. Answer is
// interpreted in the following ways:
//
// - For A and AAAA queries, answer must be an IP address of the corresponding
// protocol version.
//
// - For PTR queries, answer should be a domain name in the response.
//
// If the answer does not correspond to the question type, MatchedResponse panics.
// Panics are used instead of [testing.TB], because the helper is intended to
// use in [UpstreamMock.OnExchange] callbacks, which are usually called in a
// separate goroutine.
//
// TODO(a.garipov): Consider adding version with DNS class as well.
func MatchedResponse(req *dns.Msg, qt uint16, targ, answer string) (resp *dns.Msg) {
if req == nil || len(req.Question) != 1 {
panic(fmt.Errorf("bad req: %+v", req))
}

q := req.Question[0]
targ = dns.Fqdn(targ)
if q.Qclass != dns.ClassINET || q.Qtype != qt || q.Name != targ {
return nil
}

respHdr := dns.RR_Header{
Name: targ,
Rrtype: qt,
Class: dns.ClassINET,
Ttl: 60,
}

resp = new(dns.Msg).SetReply(req)
switch qt {
case dns.TypeA:
resp.Answer = mustAnsA(respHdr, answer)
case dns.TypeAAAA:
resp.Answer = mustAnsAAAA(respHdr, answer)
case dns.TypePTR:
resp.Answer = []dns.RR{&dns.PTR{
Hdr: respHdr,
Ptr: answer,
}}
default:
panic(fmt.Errorf("aghtest: bad question type: %s", dns.Type(qt)))
}

return resp
}

// mustAnsA returns valid answer records if s is a valid IPv4 address.
// Otherwise, mustAnsA panics.
func mustAnsA(respHdr dns.RR_Header, s string) (ans []dns.RR) {
ip, err := netip.ParseAddr(s)
if err != nil || !ip.Is4() {
panic(fmt.Errorf("aghtest: bad A answer: %+v", s))
}

return []dns.RR{&dns.A{
Hdr: respHdr,
A: ip.AsSlice(),
}}
}

// mustAnsAAAA returns valid answer records if s is a valid IPv6 address.
// Otherwise, mustAnsAAAA panics.
func mustAnsAAAA(respHdr dns.RR_Header, s string) (ans []dns.RR) {
ip, err := netip.ParseAddr(s)
if err != nil || !ip.Is6() {
panic(fmt.Errorf("aghtest: bad AAAA answer: %+v", s))
}

return []dns.RR{&dns.AAAA{
Hdr: respHdr,
AAAA: ip.AsSlice(),
}}
}

// NewUpstreamMock returns an [*UpstreamMock], fields OnAddress and OnClose of
// which are set to stubs that return "upstream.example" and nil respectively.
// The field OnExchange is set to onExc.
func NewUpstreamMock(onExc func(req *dns.Msg) (resp *dns.Msg, err error)) (u *UpstreamMock) {
return &UpstreamMock{
OnAddress: func() (addr string) { return "upstream.example" },
OnExchange: onExc,
OnClose: func() (err error) { return nil },
}
}

// NewBlockUpstream returns an [*UpstreamMock] that works like an upstream that
// supports hash-based safe-browsing/adult-blocking feature. If shouldBlock is
// true, hostname's actual hash is returned, blocking it. Otherwise, it returns
Expand All @@ -152,16 +198,15 @@ func NewBlockUpstream(hostname string, shouldBlock bool) (u *UpstreamMock) {
}

return &UpstreamMock{
OnAddress: func() (addr string) {
return "sbpc.upstream.example"
},
OnAddress: func() (addr string) { return "sbpc.upstream.example" },
OnExchange: func(req *dns.Msg) (resp *dns.Msg, err error) {
resp = respTmpl.Copy()
resp.SetReply(req)
resp.Answer[0].(*dns.TXT).Hdr.Name = req.Question[0].Name

return resp, nil
},
OnClose: func() (err error) { return nil },
}
}

Expand All @@ -173,11 +218,10 @@ const ErrUpstream errors.Error = "test upstream error"
// its Exchange method.
func NewErrorUpstream() (u *UpstreamMock) {
return &UpstreamMock{
OnAddress: func() (addr string) {
return "error.upstream.example"
},
OnAddress: func() (addr string) { return "error.upstream.example" },
OnExchange: func(_ *dns.Msg) (resp *dns.Msg, err error) {
return nil, errors.Error("test upstream error")
},
OnClose: func() (err error) { return nil },
}
}
38 changes: 13 additions & 25 deletions internal/dnsforward/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,19 +457,13 @@ func TestServer_ProcessRestrictLocal(t *testing.T) {
intPTRAnswer = "some.local-client."
)

ups := &aghtest.UpstreamMock{
OnAddress: func() (addr string) { return "upstream.example" },
OnExchange: func(req *dns.Msg) (resp *dns.Msg, err error) {
resp = aghalg.Coalesce(
aghtest.RespondTo(t, req, dns.ClassINET, dns.TypePTR, extPTRQuestion, extPTRAnswer),
aghtest.RespondTo(t, req, dns.ClassINET, dns.TypePTR, intPTRQuestion, intPTRAnswer),
new(dns.Msg).SetRcode(req, dns.RcodeNameError),
)

return resp, nil
},
OnClose: func() (err error) { return nil },
}
ups := aghtest.NewUpstreamMock(func(req *dns.Msg) (resp *dns.Msg, err error) {
return aghalg.Coalesce(
aghtest.MatchedResponse(req, dns.TypePTR, extPTRQuestion, extPTRAnswer),
aghtest.MatchedResponse(req, dns.TypePTR, intPTRQuestion, intPTRAnswer),
new(dns.Msg).SetRcode(req, dns.RcodeNameError),
), nil
})

s := createTestServer(t, &filtering.Config{}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
Expand Down Expand Up @@ -547,18 +541,12 @@ func TestServer_ProcessLocalPTR_usingResolvers(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
},
&aghtest.UpstreamMock{
OnAddress: func() (addr string) { return "upstream.example" },
OnExchange: func(req *dns.Msg) (resp *dns.Msg, err error) {
resp = aghalg.Coalesce(
aghtest.RespondTo(t, req, dns.ClassINET, dns.TypePTR, reqAddr, locDomain),
new(dns.Msg).SetRcode(req, dns.RcodeNameError),
)

return resp, nil
},
OnClose: func() (err error) { return nil },
},
aghtest.NewUpstreamMock(func(req *dns.Msg) (resp *dns.Msg, err error) {
return aghalg.Coalesce(
aghtest.MatchedResponse(req, dns.TypePTR, reqAddr, locDomain),
new(dns.Msg).SetRcode(req, dns.RcodeNameError),
), nil
}),
)

var proxyCtx *proxy.DNSContext
Expand Down
Loading

0 comments on commit bc41b6c

Please sign in to comment.