From 9631eff60862d88667eaa853ebfa3bce1e1cdd8e Mon Sep 17 00:00:00 2001
From: Ainar Garipov <a.garipov@adguard.com>
Date: Fri, 26 Mar 2021 13:03:36 +0300
Subject: [PATCH] Pull request: dnsfilter: imp code, decr cyclo

Updates #2646.

Squashed commit of the following:

commit c153f08bcf5ade4d0fb9b59d2a0e6a21598c4127
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Mar 25 21:03:51 2021 +0300

    dnsfilter: imp code, decr cyclo
---
 internal/dnsfilter/dnsfilter.go | 113 ++++++++++++++++++--------------
 scripts/make/go-lint.sh         |  13 +++-
 2 files changed, 72 insertions(+), 54 deletions(-)

diff --git a/internal/dnsfilter/dnsfilter.go b/internal/dnsfilter/dnsfilter.go
index 73ea3695..0660f7ae 100644
--- a/internal/dnsfilter/dnsfilter.go
+++ b/internal/dnsfilter/dnsfilter.go
@@ -659,6 +659,55 @@ func (d *DNSFilter) matchHostProcessAllowList(host string, dnsres urlfilter.DNSR
 	return makeResult(rule, NotFilteredAllowList), nil
 }
 
+// matchHostProcessDNSResult processes the matched DNS filtering result.
+func (d *DNSFilter) matchHostProcessDNSResult(
+	qtype uint16,
+	dnsres urlfilter.DNSResult,
+) (res Result) {
+	if dnsres.NetworkRule != nil {
+		reason := FilteredBlockList
+		if dnsres.NetworkRule.Whitelist {
+			reason = NotFilteredAllowList
+		}
+
+		return makeResult(dnsres.NetworkRule, reason)
+	}
+
+	if qtype == dns.TypeA && dnsres.HostRulesV4 != nil {
+		rule := dnsres.HostRulesV4[0]
+		res = makeResult(rule, FilteredBlockList)
+		res.Rules[0].IP = rule.IP.To4()
+
+		return res
+	}
+
+	if qtype == dns.TypeAAAA && dnsres.HostRulesV6 != nil {
+		rule := dnsres.HostRulesV6[0]
+		res = makeResult(rule, FilteredBlockList)
+		res.Rules[0].IP = rule.IP.To16()
+
+		return res
+	}
+
+	if dnsres.HostRulesV4 != nil || dnsres.HostRulesV6 != nil {
+		// Question type doesn't match the host rules.  Return the first
+		// matched host rule, but without an IP address.
+		var rule rules.Rule
+		if dnsres.HostRulesV4 != nil {
+			rule = dnsres.HostRulesV4[0]
+		} else if dnsres.HostRulesV6 != nil {
+			rule = dnsres.HostRulesV6[0]
+		}
+
+		res = makeResult(rule, FilteredBlockList)
+		res.Rules[0].IP = net.IP{}
+
+		return res
+	}
+
+	return Result{}
+}
+
 // 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(
@@ -697,13 +746,12 @@ func (d *DNSFilter) matchHost(
 
 	dnsres, ok := d.filteringEngine.MatchRequest(ureq)
 
-	// Check DNS rewrites first, because the API there is a bit
-	// awkward.
+	// Check DNS rewrites first, because the API there is a bit awkward.
 	if dnsr := dnsres.DNSRewrites(); len(dnsr) > 0 {
 		res = d.processDNSRewrites(dnsr)
 		if res.Reason == RewrittenRule && res.CanonName == host {
-			// A rewrite of a host to itself.  Go on and
-			// try matching other things.
+			// A rewrite of a host to itself.  Go on and try
+			// matching other things.
 		} else {
 			return res, nil
 		}
@@ -711,55 +759,18 @@ func (d *DNSFilter) matchHost(
 		return Result{}, nil
 	}
 
-	if dnsres.NetworkRule != nil {
-		log.Debug("Filtering: found rule for host %q: %q  list_id: %d",
-			host, dnsres.NetworkRule.Text(), dnsres.NetworkRule.GetFilterListID())
-		reason := FilteredBlockList
-		if dnsres.NetworkRule.Whitelist {
-			reason = NotFilteredAllowList
-		}
-
-		return makeResult(dnsres.NetworkRule, reason), nil
+	res = d.matchHostProcessDNSResult(qtype, dnsres)
+	if len(res.Rules) > 0 {
+		r := res.Rules[0]
+		log.Debug(
+			"filtering: found rule %q for host %q, filter list id: %d",
+			r.Text,
+			host,
+			r.FilterListID,
+		)
 	}
 
-	if qtype == dns.TypeA && dnsres.HostRulesV4 != nil {
-		rule := dnsres.HostRulesV4[0] // note that we process only 1 matched rule
-		log.Debug("Filtering: found rule for host %q: %q  list_id: %d",
-			host, rule.Text(), rule.GetFilterListID())
-		res = makeResult(rule, FilteredBlockList)
-		res.Rules[0].IP = rule.IP.To4()
-
-		return res, nil
-	}
-
-	if qtype == dns.TypeAAAA && dnsres.HostRulesV6 != nil {
-		rule := dnsres.HostRulesV6[0] // note that we process only 1 matched rule
-		log.Debug("Filtering: found rule for host %q: %q  list_id: %d",
-			host, rule.Text(), rule.GetFilterListID())
-		res = makeResult(rule, FilteredBlockList)
-		res.Rules[0].IP = rule.IP
-
-		return res, nil
-	}
-
-	if dnsres.HostRulesV4 != nil || dnsres.HostRulesV6 != nil {
-		// Question Type doesn't match the host rules
-		// Return the first matched host rule, but without an IP address
-		var rule rules.Rule
-		if dnsres.HostRulesV4 != nil {
-			rule = dnsres.HostRulesV4[0]
-		} else if dnsres.HostRulesV6 != nil {
-			rule = dnsres.HostRulesV6[0]
-		}
-		log.Debug("Filtering: found rule for host %q: %q  list_id: %d",
-			host, rule.Text(), rule.GetFilterListID())
-		res = makeResult(rule, FilteredBlockList)
-		res.Rules[0].IP = net.IP{}
-
-		return res, nil
-	}
-
-	return Result{}, nil
+	return res, nil
 }
 
 // makeResult returns a properly constructed Result.
diff --git a/scripts/make/go-lint.sh b/scripts/make/go-lint.sh
index ccd21486..95decef7 100644
--- a/scripts/make/go-lint.sh
+++ b/scripts/make/go-lint.sh
@@ -128,6 +128,12 @@ exit_on_output() (
 
 
 
+# Constants
+
+readonly go_files='./main.go ./tools.go ./internal/'
+
+
+
 # Checks
 
 exit_on_output blocklist_imports
@@ -142,11 +148,12 @@ golint --set_exit_status ./...
 
 "$GO" vet ./...
 
-gocyclo --over 19 .
+# Here and below, don't use quotes to get word splitting.
+gocyclo --over 18 $go_files
 
-gosec --quiet .
+gosec --quiet $go_files
 
-ineffassign .
+ineffassign ./...
 
 unparam ./...