diff options
Diffstat (limited to 'middleware/pkg/response/classify.go')
-rw-r--r-- | middleware/pkg/response/classify.go | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/middleware/pkg/response/classify.go b/middleware/pkg/response/classify.go index e22c2e0ad..0251623a0 100644 --- a/middleware/pkg/response/classify.go +++ b/middleware/pkg/response/classify.go @@ -1,74 +1,73 @@ package response -import "github.com/miekg/dns" +import ( + "fmt" -// Type is the type of the message -type Type int + "github.com/miekg/dns" +) + +// Class holds sets of Types +type Class int const ( - // Success indicates a positive reply - Success 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 + // All is a meta class encompassing all the classes. + All Class = iota + // Success is a class for a successful response. + Success + // Denial is a class for denying existence (NXDOMAIN, or a nodata: type does not exist) + Denial + // Error is a class for errors, right now defined as not Success and not Denial + Error ) -func (t Type) String() string { - switch t { +func (c Class) String() string { + switch c { + case All: + return "all" case Success: - return "NOERROR" - case NameError: - return "NXDOMAIN" - case NoData: - return "NODATA" - case Delegation: - return "DELEGATION" - case OtherError: - return "OTHERERROR" + return "success" + case Denial: + return "denial" + case Error: + return "error" } return "" } -// Classify classifies a message, it returns the Type. -func Classify(m *dns.Msg) (Type, *dns.OPT) { - opt := m.IsEdns0() - - if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess { - return Success, 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 +// ClassFromString returns the class from the string s. If not class matches +// the All class and an error are returned +func ClassFromString(s string) (Class, error) { + switch s { + case "all": + return All, nil + case "success": + return Success, nil + case "denial": + return Denial, nil + case "error": + return Error, nil } + return All, fmt.Errorf("invalid Class: %s", s) +} - if ns > 0 && ns == len(m.Ns) && m.Rcode == dns.RcodeSuccess { - return Delegation, opt - } +// Classify classifies a dns message: it returns its Class. +func Classify(m *dns.Msg) (Class, *dns.OPT) { + t, o := Typify(m) + return classify(t), o +} - if m.Rcode == dns.RcodeSuccess { - return Success, opt +// Does need to be exported? +func classify(t Type) Class { + switch t { + case NoError, Delegation: + return Success + case NameError, NoData: + return Denial + case OtherError: + fallthrough + default: + return Error } - - return OtherError, opt + // never reached + return All } |