aboutsummaryrefslogtreecommitdiff
path: root/middleware/pkg/response/classify.go
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/pkg/response/classify.go')
-rw-r--r--middleware/pkg/response/classify.go113
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
}