Skip to content

Commit

Permalink
Pull request: all: support more $dnsrewrite rr types
Browse files Browse the repository at this point in the history
Merge in DNS/adguard-home from 2102-dnsrewrite-2 to master

Updates AdguardTeam#2102.
Updates AdguardTeam#2452.

Squashed commit of the following:

commit b41e577
Author: Ainar Garipov <[email protected]>
Date:   Tue Dec 22 20:40:56 2020 +0300

    dnsforward: improve naming

commit 70b832c
Author: Ainar Garipov <[email protected]>
Date:   Tue Dec 22 19:36:21 2020 +0300

    all: support more $dnsrewrite rr types
  • Loading branch information
ainar-g authored and heyxkhoa committed Mar 17, 2023
1 parent 286d35b commit e4dbce7
Show file tree
Hide file tree
Showing 10 changed files with 409 additions and 52 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.14
require (
github.com/AdguardTeam/dnsproxy v0.33.7
github.com/AdguardTeam/golibs v0.4.4
github.com/AdguardTeam/urlfilter v0.14.0
github.com/AdguardTeam/urlfilter v0.14.1
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.0.1
github.com/fsnotify/fsnotify v1.4.9
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKU
github.com/AdguardTeam/golibs v0.4.4 h1:cM9UySQiYFW79zo5XRwnaIWVzfW4eNXmZktMrWbthpw=
github.com/AdguardTeam/golibs v0.4.4/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.14.0 h1:+aAhOvZDVGzl5gTERB4pOJCL1zxMyw7vLecJJ6TQTCw=
github.com/AdguardTeam/urlfilter v0.14.0/go.mod h1:klx4JbOfc4EaNb5lWLqOwfg+pVcyRukmoJRvO55lL5U=
github.com/AdguardTeam/urlfilter v0.14.1 h1:imYls0fit9ojA6pP1hWFUEIjyoXbDF85ZM+G67bI48c=
github.com/AdguardTeam/urlfilter v0.14.1/go.mod h1:klx4JbOfc4EaNb5lWLqOwfg+pVcyRukmoJRvO55lL5U=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
Expand Down
2 changes: 1 addition & 1 deletion internal/dnsfilter/dnsrewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

// DNSRewriteResult is the result of application of $dnsrewrite rules.
type DNSRewriteResult struct {
RCode rules.RCode `json:",omitempty"`
Response DNSRewriteResultResponse `json:",omitempty"`
RCode rules.RCode `json:",omitempty"`
}

// DNSRewriteResultResponse is the collection of DNS response records
Expand Down
2 changes: 1 addition & 1 deletion internal/dnsforward/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func processFilteringAfterResponse(ctx *dnsContext) int {

if len(d.Res.Answer) != 0 {
answer := []dns.RR{}
answer = append(answer, s.genCNAMEAnswer(d.Req, res.CanonName))
answer = append(answer, s.genAnswerCNAME(d.Req, res.CanonName))
answer = append(answer, d.Res.Answer...)
d.Res.Answer = answer
}
Expand Down
42 changes: 35 additions & 7 deletions internal/dnsforward/dnsrewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,55 @@ import (
)

// filterDNSRewriteResponse handles a single DNS rewrite response entry.
// It returns the constructed answer resource record.
// It returns the properly constructed answer resource record.
func (s *Server) filterDNSRewriteResponse(req *dns.Msg, rr rules.RRType, v rules.RRValue) (ans dns.RR, err error) {
// TODO(a.garipov): As more types are added, we will probably want to
// use a handler-oriented approach here. So, think of a way to decouple
// the answer generation logic from the Server.

switch rr {
case dns.TypeA, dns.TypeAAAA:
ip, ok := v.(net.IP)
if !ok {
return nil, fmt.Errorf("value has type %T, not net.IP", v)
return nil, fmt.Errorf("value for rr type %d has type %T, not net.IP", rr, v)
}

if rr == dns.TypeA {
return s.genAAnswer(req, ip.To4()), nil
return s.genAnswerA(req, ip.To4()), nil
}

return s.genAAAAAnswer(req, ip), nil
case dns.TypeTXT:
return s.genAnswerAAAA(req, ip), nil
case dns.TypePTR,
dns.TypeTXT:
str, ok := v.(string)
if !ok {
return nil, fmt.Errorf("value has type %T, not string", v)
return nil, fmt.Errorf("value for rr type %d has type %T, not string", rr, v)
}

if rr == dns.TypeTXT {
return s.genAnswerTXT(req, []string{str}), nil
}

return s.genAnswerPTR(req, str), nil
case dns.TypeMX:
mx, ok := v.(*rules.DNSMX)
if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not *rules.DNSMX", rr, v)
}

return s.genAnswerMX(req, mx), nil
case dns.TypeHTTPS,
dns.TypeSVCB:
svcb, ok := v.(*rules.DNSSVCB)
if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not *rules.DNSSVCB", rr, v)
}

if rr == dns.TypeHTTPS {
return s.genAnswerHTTPS(req, svcb), nil
}

return s.genTXTAnswer(req, []string{str}), nil
return s.genAnswerSVCB(req, svcb), nil
default:
log.Debug("don't know how to handle dns rr type %d, skipping", rr)

Expand Down
6 changes: 3 additions & 3 deletions internal/dnsforward/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,17 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {

name := host
if len(res.CanonName) != 0 {
resp.Answer = append(resp.Answer, s.genCNAMEAnswer(req, res.CanonName))
resp.Answer = append(resp.Answer, s.genAnswerCNAME(req, res.CanonName))
name = res.CanonName
}

for _, ip := range res.IPList {
if req.Question[0].Qtype == dns.TypeA {
a := s.genAAnswer(req, ip.To4())
a := s.genAnswerA(req, ip.To4())
a.Hdr.Name = dns.Fqdn(name)
resp.Answer = append(resp.Answer, a)
} else if req.Question[0].Qtype == dns.TypeAAAA {
a := s.genAAAAAnswer(req, ip)
a := s.genAnswerAAAA(req, ip)
a.Hdr.Name = dns.Fqdn(name)
resp.Answer = append(resp.Answer, a)
}
Expand Down
78 changes: 41 additions & 37 deletions internal/dnsforward/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns"
)

Expand Down Expand Up @@ -92,48 +93,64 @@ func (s *Server) genServerFailure(request *dns.Msg) *dns.Msg {

func (s *Server) genARecord(request *dns.Msg, ip net.IP) *dns.Msg {
resp := s.makeResponse(request)
resp.Answer = append(resp.Answer, s.genAAnswer(request, ip))
resp.Answer = append(resp.Answer, s.genAnswerA(request, ip))
return resp
}

func (s *Server) genAAAARecord(request *dns.Msg, ip net.IP) *dns.Msg {
resp := s.makeResponse(request)
resp.Answer = append(resp.Answer, s.genAAAAAnswer(request, ip))
resp.Answer = append(resp.Answer, s.genAnswerAAAA(request, ip))
return resp
}

func (s *Server) genAAnswer(req *dns.Msg, ip net.IP) *dns.A {
answer := new(dns.A)
answer.Hdr = dns.RR_Header{
func (s *Server) hdr(req *dns.Msg, rrType rules.RRType) (h dns.RR_Header) {
return dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypeA,
Rrtype: rrType,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
}
answer.A = ip
return answer
}

func (s *Server) genAAAAAnswer(req *dns.Msg, ip net.IP) *dns.AAAA {
answer := new(dns.AAAA)
answer.Hdr = dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypeAAAA,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
func (s *Server) genAnswerA(req *dns.Msg, ip net.IP) (ans *dns.A) {
return &dns.A{
Hdr: s.hdr(req, dns.TypeA),
A: ip,
}
answer.AAAA = ip
return answer
}

func (s *Server) genTXTAnswer(req *dns.Msg, strs []string) (answer *dns.TXT) {
func (s *Server) genAnswerAAAA(req *dns.Msg, ip net.IP) (ans *dns.AAAA) {
return &dns.AAAA{
Hdr: s.hdr(req, dns.TypeAAAA),
AAAA: ip,
}
}

func (s *Server) genAnswerCNAME(req *dns.Msg, cname string) (ans *dns.CNAME) {
return &dns.CNAME{
Hdr: s.hdr(req, dns.TypeCNAME),
Target: dns.Fqdn(cname),
}
}

func (s *Server) genAnswerMX(req *dns.Msg, mx *rules.DNSMX) (ans *dns.MX) {
return &dns.MX{
Hdr: s.hdr(req, dns.TypePTR),
Preference: mx.Preference,
Mx: mx.Exchange,
}
}

func (s *Server) genAnswerPTR(req *dns.Msg, ptr string) (ans *dns.PTR) {
return &dns.PTR{
Hdr: s.hdr(req, dns.TypePTR),
Ptr: ptr,
}
}

func (s *Server) genAnswerTXT(req *dns.Msg, strs []string) (ans *dns.TXT) {
return &dns.TXT{
Hdr: dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypeTXT,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
},
Hdr: s.hdr(req, dns.TypeTXT),
Txt: strs,
}
}
Expand Down Expand Up @@ -198,19 +215,6 @@ func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSCo
return resp
}

// Make a CNAME response
func (s *Server) genCNAMEAnswer(req *dns.Msg, cname string) *dns.CNAME {
answer := new(dns.CNAME)
answer.Hdr = dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypeCNAME,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
}
answer.Target = dns.Fqdn(cname)
return answer
}

// Create REFUSED DNS response
func (s *Server) makeResponseREFUSED(request *dns.Msg) *dns.Msg {
resp := dns.Msg{}
Expand Down
Loading

0 comments on commit e4dbce7

Please sign in to comment.