Improved return codes

This commit is contained in:
Frank Denis 2018-06-04 23:18:28 +02:00
parent 3bbdf93095
commit 977dcad826
6 changed files with 59 additions and 24 deletions

View File

@ -121,7 +121,7 @@ func (plugin *PluginBlockIP) Eval(pluginsState *PluginsState, msg *dns.Msg) erro
}
if reject {
pluginsState.action = PluginsActionReject
pluginsState.rcode = dns.RcodeRefused
pluginsState.returnCode = PluginsReturnCodeReject
if plugin.logger != nil {
questions := msg.Question
if len(questions) != 1 {

View File

@ -66,6 +66,6 @@ func (plugin *PluginBlockIPv6) Eval(pluginsState *PluginsState, msg *dns.Msg) er
synth.Ns = []dns.RR{soa}
pluginsState.synthResponse = synth
pluginsState.action = PluginsActionSynth
pluginsState.rcode = dns.RcodeNotImplemented
pluginsState.returnCode = PluginsReturnCodeSynth
return nil
}

View File

@ -103,7 +103,7 @@ func (plugin *PluginBlockName) Eval(pluginsState *PluginsState, msg *dns.Msg) er
}
if reject {
pluginsState.action = PluginsActionReject
pluginsState.rcode = dns.RcodeRefused
pluginsState.returnCode = PluginsReturnCodeReject
if plugin.logger != nil {
var clientIPStr string
if pluginsState.clientProto == "udp" {

View File

@ -66,6 +66,10 @@ func (plugin *PluginQueryLog) Eval(pluginsState *PluginsState, msg *dns.Msg) err
clientIPStr = (*pluginsState.clientAddr).(*net.TCPAddr).IP.String()
}
qName := StripTrailingDot(question.Name)
returnCode, ok := PluginsReturnCodeToString[pluginsState.returnCode]
if !ok {
returnCode = string(returnCode)
}
var line string
if plugin.format == "tsv" {
@ -73,14 +77,10 @@ func (plugin *PluginQueryLog) Eval(pluginsState *PluginsState, msg *dns.Msg) err
year, month, day := now.Date()
hour, minute, second := now.Clock()
tsStr := fmt.Sprintf("[%d-%02d-%02d %02d:%02d:%02d]", year, int(month), day, hour, minute, second)
line = fmt.Sprintf("%s\t%s\t%s\t%s\n", tsStr, clientIPStr, StringQuote(qName), qType)
line = fmt.Sprintf("%s\t%s\t%s\t%s\t%s\n", tsStr, clientIPStr, StringQuote(qName), qType, returnCode)
} else if plugin.format == "ltsv" {
rcode, ok := dns.RcodeToString[int(pluginsState.rcode)]
if !ok {
rcode = string(rcode)
}
line = fmt.Sprintf("time:%d\thost:%s\tmessage:%s\ttype:%s\trcode:%s\n",
time.Now().Unix(), clientIPStr, StringQuote(qName), qType, rcode)
line = fmt.Sprintf("time:%d\thost:%s\tmessage:%s\ttype:%s\treturn:%s\n",
time.Now().Unix(), clientIPStr, StringQuote(qName), qType, returnCode)
} else {
dlog.Fatalf("Unexpected log format: [%s]", plugin.format)
}

View File

@ -26,6 +26,32 @@ type PluginsGlobals struct {
loggingPlugins *[]Plugin
}
type PluginsReturnCode int
const (
PluginsReturnCodePass = iota
PluginsReturnCodeForward
PluginsReturnCodeDrop
PluginsReturnCodeReject
PluginsReturnCodeSynth
PluginsReturnCodeParseError
PluginsReturnCodeNXDomain
PluginsReturnCodeResponseError
PluginsReturnCodeServerError
)
var PluginsReturnCodeToString = map[PluginsReturnCode]string{
PluginsReturnCodePass: "PASS",
PluginsReturnCodeForward: "FORWARD",
PluginsReturnCodeDrop: "DROP",
PluginsReturnCodeReject: "REJECT",
PluginsReturnCodeSynth: "SYNTH",
PluginsReturnCodeParseError: "PARSE_ERROR",
PluginsReturnCodeNXDomain: "NXDOMAIN",
PluginsReturnCodeResponseError: "RESPONSE_ERROR",
PluginsReturnCodeServerError: "SERVER_ERROR",
}
type PluginsState struct {
sessionData map[string]interface{}
action PluginsAction
@ -41,7 +67,7 @@ type PluginsState struct {
cacheMinTTL uint32
cacheMaxTTL uint32
questionMsg *dns.Msg
rcode uint8
returnCode PluginsReturnCode
}
func InitPluginsGlobals(pluginsGlobals *PluginsGlobals, proxy *Proxy) error {
@ -179,7 +205,16 @@ func (pluginsState *PluginsState) ApplyResponsePlugins(pluginsGlobals *PluginsGl
}
return packet, err
}
pluginsState.rcode = Rcode(packet)
switch Rcode(packet) {
case dns.RcodeSuccess:
pluginsState.returnCode = PluginsReturnCodePass
case dns.RcodeNameError:
pluginsState.returnCode = PluginsReturnCodeNXDomain
case dns.RcodeServerFailure:
pluginsState.returnCode = PluginsReturnCodeServerError
default:
pluginsState.returnCode = PluginsReturnCodeResponseError
}
pluginsGlobals.RLock()
for _, plugin := range *pluginsGlobals.responsePlugins {
if ret := plugin.Eval(pluginsState, &msg); ret != nil {

View File

@ -8,8 +8,6 @@ import (
"sync/atomic"
"time"
"github.com/miekg/dns"
"github.com/jedisct1/dlog"
clocksmith "github.com/jedisct1/go-clocksmith"
stamps "github.com/jedisct1/go-dnsstamps"
@ -268,23 +266,25 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
if pluginsState.synthResponse != nil {
response, err = pluginsState.synthResponse.PackBuffer(response)
if err != nil {
pluginsState.rcode = dns.RcodeFormatError
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
return
}
}
if pluginsState.action == PluginsActionDrop {
pluginsState.rcode = dns.RcodeRefused
pluginsState.returnCode = PluginsReturnCodeDrop
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
return
}
} else {
pluginsState.returnCode = PluginsReturnCodeForward
}
if len(response) == 0 {
var ttl *uint32
if serverInfo.Proto == stamps.StampProtoTypeDNSCrypt {
sharedKey, encryptedQuery, clientNonce, err := proxy.Encrypt(serverInfo, query, serverProto)
if err != nil {
pluginsState.rcode = dns.RcodeFormatError
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
return
}
@ -295,7 +295,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
response, err = proxy.exchangeWithTCPServer(serverInfo, sharedKey, encryptedQuery, clientNonce)
}
if err != nil {
pluginsState.rcode = dns.RcodeServerFailure
pluginsState.returnCode = PluginsReturnCodeServerError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return
@ -307,14 +307,14 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
resp, _, err := proxy.xTransport.DoHQuery(serverInfo.useGet, serverInfo.URL, query, proxy.timeout)
SetTransactionID(query, tid)
if err != nil {
pluginsState.rcode = dns.RcodeServerFailure
pluginsState.returnCode = PluginsReturnCodeServerError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return
}
response, err = ioutil.ReadAll(io.LimitReader(resp.Body, int64(MaxDNSPacketSize)))
if err != nil {
pluginsState.rcode = dns.RcodeServerFailure
pluginsState.returnCode = PluginsReturnCodeServerError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return
@ -326,14 +326,14 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
dlog.Fatal("Unsupported protocol")
}
if len(response) < MinDNSPacketSize || len(response) > MaxDNSPacketSize {
pluginsState.rcode = dns.RcodeFormatError
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return
}
response, err = pluginsState.ApplyResponsePlugins(&proxy.pluginsGlobals, response, ttl)
if err != nil {
pluginsState.rcode = dns.RcodeServerFailure
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return
@ -349,7 +349,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
if len(response) > MaxDNSUDPPacketSize {
response, err = TruncatedResponse(response)
if err != nil {
pluginsState.rcode = dns.RcodeSuccess
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
return
}
@ -363,7 +363,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
} else {
response, err = PrefixWithSize(response)
if err != nil {
pluginsState.rcode = dns.RcodeFormatError
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
return