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.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/middleware/pkg/response/classify.go b/middleware/pkg/response/classify.go
new file mode 100644
index 000000000..adbaa6526
--- /dev/null
+++ b/middleware/pkg/response/classify.go
@@ -0,0 +1,52 @@
+package response
+
+import "github.com/miekg/dns"
+
+type Type int
+
+const (
+ Success Type = iota
+ NameError // NXDOMAIN in header, SOA in auth.
+ NoData // NOERROR in header, SOA in auth.
+ Delegation // NOERROR in header, NS in auth, optionally fluff in additional (not checked).
+ OtherError // Don't cache these.
+)
+
+// 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
+ }
+
+ if ns > 0 && ns == len(m.Ns) && m.Rcode == dns.RcodeSuccess {
+ return Delegation, opt
+ }
+
+ if m.Rcode == dns.RcodeSuccess {
+ return Success, opt
+ }
+
+ return OtherError, opt
+}