Pull request #886: all: allow multiple rules in dns filter results

Merge in DNS/adguard-home from 2102-rules-result to master

Updates #2102.

Squashed commit of the following:

commit 47b2aa94c56b37be492c3c01e8111054612d9722
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Dec 17 13:12:27 2020 +0300

    querylog: remove pre-v0.99.3 compatibility code

commit 2af0ee43c2444a7d842fcff057f2ba02f300244b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Dec 17 13:00:27 2020 +0300

    all: improve documentation

commit 3add300a42f0aa67bb315a448e294636c85d0b3b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 16 18:30:01 2020 +0300

    all: improve changelog

commit e04ef701fc2de7f4453729e617641c47e0883679
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 16 17:56:53 2020 +0300

    all: improve code and documentation

commit 4f04845ae275ae4291869e00c62e4ff81b01eaa3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 16 17:01:08 2020 +0300

    all: document changes, improve api

commit bc59b7656a402d0c65f13bd74a71d8dda6a8a65d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Dec 15 18:22:01 2020 +0300

    all: allow multiple rules in dns filter results
This commit is contained in:
Ainar Garipov
2020-12-17 13:32:46 +03:00
parent 2c56a68597
commit 2e8352d31c
28 changed files with 610 additions and 356 deletions

View File

@@ -6,10 +6,13 @@ import (
"strconv"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"
)
// TODO(a.garipov): Use a proper structured approach here.
// Get Client IP address
func (l *queryLog) getClientIP(clientIP string) string {
if l.conf.AnonymizeClientIP {
@@ -29,10 +32,12 @@ func (l *queryLog) getClientIP(clientIP string) string {
return clientIP
}
// entriesToJSON - converts log entries to JSON
func (l *queryLog) entriesToJSON(entries []*logEntry, oldest time.Time) map[string]interface{} {
// init the response object
data := []map[string]interface{}{}
// jobject is a JSON object alias.
type jobject = map[string]interface{}
// entriesToJSON converts query log entries to JSON.
func (l *queryLog) entriesToJSON(entries []*logEntry, oldest time.Time) (res jobject) {
data := []jobject{}
// the elements order is already reversed (from newer to older)
for i := 0; i < len(entries); i++ {
@@ -41,17 +46,18 @@ func (l *queryLog) entriesToJSON(entries []*logEntry, oldest time.Time) map[stri
data = append(data, jsonEntry)
}
result := map[string]interface{}{}
result["oldest"] = ""
if !oldest.IsZero() {
result["oldest"] = oldest.Format(time.RFC3339Nano)
res = jobject{
"data": data,
"oldest": "",
}
if !oldest.IsZero() {
res["oldest"] = oldest.Format(time.RFC3339Nano)
}
result["data"] = data
return result
return res
}
func (l *queryLog) logEntryToJSONEntry(entry *logEntry) map[string]interface{} {
func (l *queryLog) logEntryToJSONEntry(entry *logEntry) (jsonEntry jobject) {
var msg *dns.Msg
if len(entry.Answer) > 0 {
@@ -62,17 +68,18 @@ func (l *queryLog) logEntryToJSONEntry(entry *logEntry) map[string]interface{} {
}
}
jsonEntry := map[string]interface{}{
jsonEntry = jobject{
"reason": entry.Result.Reason.String(),
"elapsedMs": strconv.FormatFloat(entry.Elapsed.Seconds()*1000, 'f', -1, 64),
"time": entry.Time.Format(time.RFC3339Nano),
"client": l.getClientIP(entry.IP),
"client_proto": entry.ClientProto,
}
jsonEntry["question"] = map[string]interface{}{
"host": entry.QHost,
"type": entry.QType,
"class": entry.QClass,
"upstream": entry.Upstream,
"question": jobject{
"host": entry.QHost,
"type": entry.QType,
"class": entry.QClass,
},
}
if msg != nil {
@@ -83,12 +90,15 @@ func (l *queryLog) logEntryToJSONEntry(entry *logEntry) map[string]interface{} {
if opt != nil {
dnssecOk = opt.Do()
}
jsonEntry["answer_dnssec"] = dnssecOk
}
if len(entry.Result.Rule) > 0 {
jsonEntry["rule"] = entry.Result.Rule
jsonEntry["filterId"] = entry.Result.FilterID
jsonEntry["rules"] = resultRulesToJSONRules(entry.Result.Rules)
if len(entry.Result.Rules) > 0 && len(entry.Result.Rules[0].Text) > 0 {
jsonEntry["rule"] = entry.Result.Rules[0].Text
jsonEntry["filterId"] = entry.Result.Rules[0].FilterListID
}
if len(entry.Result.ServiceName) != 0 {
@@ -113,20 +123,30 @@ func (l *queryLog) logEntryToJSONEntry(entry *logEntry) map[string]interface{} {
}
}
jsonEntry["upstream"] = entry.Upstream
return jsonEntry
}
func answerToMap(a *dns.Msg) []map[string]interface{} {
func resultRulesToJSONRules(rules []*dnsfilter.ResultRule) (jsonRules []jobject) {
jsonRules = make([]jobject, len(rules))
for i, r := range rules {
jsonRules[i] = jobject{
"filter_list_id": r.FilterListID,
"text": r.Text,
}
}
return jsonRules
}
func answerToMap(a *dns.Msg) (answers []jobject) {
if a == nil || len(a.Answer) == 0 {
return nil
}
answers := []map[string]interface{}{}
answers = []jobject{}
for _, k := range a.Answer {
header := k.Header()
answer := map[string]interface{}{
answer := jobject{
"type": dns.TypeToString[header.Rrtype],
"ttl": header.Ttl,
}