diff options
Diffstat (limited to 'middleware/pkg/response/classify.go')
-rw-r--r-- | middleware/pkg/response/classify.go | 52 |
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 +} |