From 9ad4bba9aba286c88cbf26e0f57e72f6975713cf Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 22 May 2019 12:38:17 +0300 Subject: [PATCH] * dnsfilter: return the correct IP address (host rules) --- dnsfilter/dnsfilter.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/dnsfilter/dnsfilter.go b/dnsfilter/dnsfilter.go index b9292f5f..40ca57f0 100644 --- a/dnsfilter/dnsfilter.go +++ b/dnsfilter/dnsfilter.go @@ -19,6 +19,7 @@ import ( "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/urlfilter" "github.com/bluele/gcache" + "github.com/miekg/dns" "golang.org/x/net/publicsuffix" ) @@ -147,7 +148,7 @@ func (r Reason) Matched() bool { } // CheckHost tries to match host against rules, then safebrowsing and parental if they are enabled -func (d *Dnsfilter) CheckHost(host string) (Result, error) { +func (d *Dnsfilter) CheckHost(host string, qtype uint16) (Result, error) { // sometimes DNS clients will try to resolve ".", which is a request to get root servers if host == "" { return Result{Reason: NotFilteredNotFound}, nil @@ -159,7 +160,7 @@ func (d *Dnsfilter) CheckHost(host string) (Result, error) { } // try filter lists first - result, err := d.matchHost(host) + result, err := d.matchHost(host, qtype) if err != nil { return result, err } @@ -517,7 +518,7 @@ func (d *Dnsfilter) initFiltering(filters map[int]string) error { } // matchHost is a low-level way to check only if hostname is filtered by rules, skipping expensive safebrowsing and parental lookups -func (d *Dnsfilter) matchHost(host string) (Result, error) { +func (d *Dnsfilter) matchHost(host string, qtype uint16) (Result, error) { if d.filteringEngine == nil { return Result{}, nil } @@ -527,6 +528,8 @@ func (d *Dnsfilter) matchHost(host string) (Result, error) { return Result{}, nil } + log.Tracef("%d rules matched for host '%s'", len(rules), host) + for _, rule := range rules { log.Tracef("Found rule for host '%s': '%s' list_id: %d", @@ -548,8 +551,15 @@ func (d *Dnsfilter) matchHost(host string) (Result, error) { } else if hostRule, ok := rule.(*urlfilter.HostRule); ok { - res.IP = hostRule.IP - return res, nil + if qtype == dns.TypeA && hostRule.IP.To4() != nil { + // either IPv4 or IPv4-mapped IPv6 address + res.IP = hostRule.IP.To4() + return res, nil + } else if qtype == dns.TypeAAAA && hostRule.IP.To4() == nil { + res.IP = hostRule.IP + return res, nil + } + continue } else { log.Tracef("Rule type is unsupported: '%s' list_id: %d",