middleware/log: allows logging based on response classes (#325)
Add the ability to add a class of responses to be logged; success, denial or error. The default is to log everything (all). Fixes #258
This commit is contained in:
parent
caa3976bfe
commit
c22b7b2252
13 changed files with 348 additions and 108 deletions
96
middleware/pkg/response/typify.go
Normal file
96
middleware/pkg/response/typify.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Type is the type of the message
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Success indicates a positive reply
|
||||
NoError Type = iota
|
||||
// NameError is a NXDOMAIN in header, SOA in auth.
|
||||
NameError
|
||||
// NoData indicated name found, but not the type: NOERROR in header, SOA in auth.
|
||||
NoData
|
||||
// Delegation is a msg with a pointer to another nameserver: NOERROR in header, NS in auth, optionally fluff in additional (not checked).
|
||||
Delegation
|
||||
// OtherError indicated any other error: don't cache these.
|
||||
OtherError
|
||||
)
|
||||
|
||||
func (t Type) String() string {
|
||||
switch t {
|
||||
case NoError:
|
||||
return "NOERROR"
|
||||
case NameError:
|
||||
return "NXDOMAIN"
|
||||
case NoData:
|
||||
return "NODATA"
|
||||
case Delegation:
|
||||
return "DELEGATION"
|
||||
case OtherError:
|
||||
return "OTHERERROR"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// TypeFromString returns the type from the string s. If not type matches
|
||||
// the OtherError type and an error are returned.
|
||||
func TypeFromString(s string) (Type, error) {
|
||||
switch s {
|
||||
case "NOERROR":
|
||||
return NoError, nil
|
||||
case "NXDOMAIN":
|
||||
return NameError, nil
|
||||
case "NODATA":
|
||||
return NoData, nil
|
||||
case "DELEGATION":
|
||||
return Delegation, nil
|
||||
case "OTHERERROR":
|
||||
return OtherError, nil
|
||||
}
|
||||
return NoError, fmt.Errorf("invalid Type: %s", s)
|
||||
}
|
||||
|
||||
// Typify classifies a message, it returns the Type.
|
||||
func Typify(m *dns.Msg) (Type, *dns.OPT) {
|
||||
opt := m.IsEdns0()
|
||||
|
||||
if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess {
|
||||
return NoError, opt
|
||||
}
|
||||
|
||||
soa := false
|
||||
ns := 0
|
||||
for _, r := range m.Ns {
|
||||
if r.Header().Rrtype == dns.TypeSOA {
|
||||
soa = true
|
||||
continue
|
||||
}
|
||||
if r.Header().Rrtype == dns.TypeNS {
|
||||
ns++
|
||||
}
|
||||
}
|
||||
|
||||
// Check length of different sections, and drop stuff that is just to large? TODO(miek).
|
||||
if soa && m.Rcode == dns.RcodeSuccess {
|
||||
return NoData, opt
|
||||
}
|
||||
if soa && m.Rcode == dns.RcodeNameError {
|
||||
return NameError, opt
|
||||
}
|
||||
|
||||
if ns > 0 && ns == len(m.Ns) && m.Rcode == dns.RcodeSuccess {
|
||||
return Delegation, opt
|
||||
}
|
||||
|
||||
if m.Rcode == dns.RcodeSuccess {
|
||||
return NoError, opt
|
||||
}
|
||||
|
||||
return OtherError, opt
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue