+ dnsforward: match CNAME with filtering rules
+ GET /control/querylog: add "cname_match" field * querylog: Add() now receives an object with parameters
This commit is contained in:
@@ -2,7 +2,6 @@ package querylog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -96,52 +95,60 @@ type logEntry struct {
|
||||
QType string `json:"QT"`
|
||||
QClass string `json:"QC"`
|
||||
|
||||
Answer []byte `json:",omitempty"` // sometimes empty answers happen like binerdunt.top or rev2.globalrootservers.net
|
||||
Answer []byte `json:",omitempty"` // sometimes empty answers happen like binerdunt.top or rev2.globalrootservers.net
|
||||
OrigAnswer []byte `json:",omitempty"`
|
||||
|
||||
Result dnsfilter.Result
|
||||
Elapsed time.Duration
|
||||
Upstream string `json:",omitempty"` // if empty, means it was cached
|
||||
}
|
||||
|
||||
func (l *queryLog) Add(question *dns.Msg, answer *dns.Msg, result *dnsfilter.Result, elapsed time.Duration, ip net.IP, upstream string) {
|
||||
func (l *queryLog) Add(params AddParams) {
|
||||
if !l.conf.Enabled {
|
||||
return
|
||||
}
|
||||
|
||||
if question == nil || len(question.Question) != 1 || len(question.Question[0].Name) == 0 ||
|
||||
ip == nil {
|
||||
if params.Question == nil || len(params.Question.Question) != 1 || len(params.Question.Question[0].Name) == 0 ||
|
||||
params.ClientIP == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var a []byte
|
||||
var err error
|
||||
|
||||
if answer != nil {
|
||||
a, err = answer.Pack()
|
||||
if err != nil {
|
||||
log.Printf("failed to pack answer for querylog: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
result = &dnsfilter.Result{}
|
||||
if params.Result == nil {
|
||||
params.Result = &dnsfilter.Result{}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
entry := logEntry{
|
||||
IP: ip.String(),
|
||||
IP: params.ClientIP.String(),
|
||||
Time: now,
|
||||
|
||||
Answer: a,
|
||||
Result: *result,
|
||||
Elapsed: elapsed,
|
||||
Upstream: upstream,
|
||||
Result: *params.Result,
|
||||
Elapsed: params.Elapsed,
|
||||
Upstream: params.Upstream,
|
||||
}
|
||||
q := question.Question[0]
|
||||
q := params.Question.Question[0]
|
||||
entry.QHost = strings.ToLower(q.Name[:len(q.Name)-1]) // remove the last dot
|
||||
entry.QType = dns.Type(q.Qtype).String()
|
||||
entry.QClass = dns.Class(q.Qclass).String()
|
||||
|
||||
if params.Answer != nil {
|
||||
a, err := params.Answer.Pack()
|
||||
if err != nil {
|
||||
log.Info("Querylog: Answer.Pack(): %s", err)
|
||||
return
|
||||
}
|
||||
entry.Answer = a
|
||||
}
|
||||
|
||||
if params.OrigAnswer != nil {
|
||||
a, err := params.OrigAnswer.Pack()
|
||||
if err != nil {
|
||||
log.Info("Querylog: OrigAnswer.Pack(): %s", err)
|
||||
return
|
||||
}
|
||||
entry.OrigAnswer = a
|
||||
}
|
||||
|
||||
l.bufferLock.Lock()
|
||||
l.buffer = append(l.buffer, &entry)
|
||||
needFlush := false
|
||||
@@ -335,6 +342,19 @@ func (l *queryLog) getData(params getDataParams) map[string]interface{} {
|
||||
jsonEntry["answer"] = answers
|
||||
}
|
||||
|
||||
if len(entry.OrigAnswer) != 0 {
|
||||
a := new(dns.Msg)
|
||||
err := a.Unpack(entry.OrigAnswer)
|
||||
if err == nil {
|
||||
answers = answerToMap(a)
|
||||
if answers != nil {
|
||||
jsonEntry["original_answer"] = answers
|
||||
}
|
||||
} else {
|
||||
log.Debug("Querylog: a.Unpack(entry.OrigAnswer): %s: %s", err, string(entry.OrigAnswer))
|
||||
}
|
||||
}
|
||||
|
||||
data = append(data, jsonEntry)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ type QueryLog interface {
|
||||
Close()
|
||||
|
||||
// Add a log entry
|
||||
Add(question *dns.Msg, answer *dns.Msg, result *dnsfilter.Result, elapsed time.Duration, ip net.IP, upstream string)
|
||||
Add(params AddParams)
|
||||
|
||||
// WriteDiskConfig - write configuration
|
||||
WriteDiskConfig(dc *DiskConfig)
|
||||
@@ -42,6 +42,17 @@ type Config struct {
|
||||
HTTPRegister func(string, string, func(http.ResponseWriter, *http.Request))
|
||||
}
|
||||
|
||||
// AddParams - parameters for Add()
|
||||
type AddParams struct {
|
||||
Question *dns.Msg
|
||||
Answer *dns.Msg // The response we sent to the client (optional)
|
||||
OrigAnswer *dns.Msg // The response from an upstream server (optional)
|
||||
Result *dnsfilter.Result // Filtering result (optional)
|
||||
Elapsed time.Duration // Time spent for processing the request
|
||||
ClientIP net.IP
|
||||
Upstream string
|
||||
}
|
||||
|
||||
// New - create a new instance of the query log
|
||||
func New(conf Config) QueryLog {
|
||||
return newQueryLog(conf)
|
||||
|
||||
@@ -574,6 +574,8 @@ func decode(ent *logEntry, str string) {
|
||||
|
||||
case "Answer":
|
||||
ent.Answer, err = base64.StdEncoding.DecodeString(v)
|
||||
case "OrigAnswer":
|
||||
ent.OrigAnswer, err = base64.StdEncoding.DecodeString(v)
|
||||
|
||||
case "IsFiltered":
|
||||
b, err = strconv.ParseBool(v)
|
||||
|
||||
@@ -115,7 +115,14 @@ func addEntry(l *queryLog, host, answerStr, client string) {
|
||||
answer.A = net.ParseIP(answerStr)
|
||||
a.Answer = append(a.Answer, answer)
|
||||
res := dnsfilter.Result{}
|
||||
l.Add(&q, &a, &res, 0, net.ParseIP(client), "upstream")
|
||||
params := AddParams{
|
||||
Question: &q,
|
||||
Answer: &a,
|
||||
Result: &res,
|
||||
ClientIP: net.ParseIP(client),
|
||||
Upstream: "upstream",
|
||||
}
|
||||
l.Add(params)
|
||||
}
|
||||
|
||||
func checkEntry(t *testing.T, m map[string]interface{}, host, answer, client string) bool {
|
||||
|
||||
Reference in New Issue
Block a user