commit - 7e5b66014d8e51608b3c909ab643e1f91f12b8db
commit + 2c109646ee0be071d39acc68f8cda66157d37582
blob - ca9087535c873b2e3b6c49b86ed6a39ac8dd432b
blob + 90337d381fc684d9d17c40a0cea994840f60d762
--- cmd/recursor/recursor.go
+++ cmd/recursor/recursor.go
"olowe.co/dns"
)
+func shouldReject(m *dnsmessage.Message) (bool, dnsmessage.RCode) {
+ if !m.Header.RecursionDesired {
+ return true, dnsmessage.RCodeRefused
+ } else if m.Header.OpCode != dns.OpCodeQUERY {
+ return true, dnsmessage.RCodeRefused
+ } else if len(m.Questions) != 1 {
+ return true, dnsmessage.RCodeFormatError
+ } else if m.Questions[0].Type == dnsmessage.TypeALL {
+ return true, dnsmessage.RCodeNotImplemented
+ }
+ return false, dnsmessage.RCodeSuccess
+}
+
func handler(w dns.ResponseWriter, qmsg *dnsmessage.Message) {
var rmsg dnsmessage.Message
rmsg.Header.ID = qmsg.Header.ID
rmsg.Header.Response = true
rmsg.Questions = qmsg.Questions
- if !qmsg.Header.RecursionDesired {
- rmsg.Header.RCode = dnsmessage.RCodeRefused
+ if reject, rc := shouldReject(qmsg); reject {
+ rmsg.Header.RCode = rc
w.WriteMsg(rmsg)
return
}
- // Reject multiple questions; not even BIND supports it.
- if len(qmsg.Questions) > 1 {
- rmsg.Header.RCode = dnsmessage.RCodeFormatError
- w.WriteMsg(rmsg)
- return
- }
q := qmsg.Questions[0]
- // CloudFlare rejects these queries too. See RFC 8482
- if q.Type == dnsmessage.TypeALL {
- rmsg.Header.RCode = dnsmessage.RCodeNotImplemented
- w.WriteMsg(rmsg)
- return
- }
-
cache.RLock()
if answers, ok := cache.m[q]; ok {
rmsg.Answers = answers
blob - dd7b5f2f459e6e76827e5b097efb0938d67b0156
blob + dc38d3fcf077993bf8f3c91ae6db467d16f841ac
--- dns.go
+++ dns.go
const MediaType string = "application/dns-message"
const MaxMsgSize int = 65535 // max size of a message in bytes
+const OpCodeQUERY dnsmessage.OpCode = 0
+
var errMismatchedID = errors.New("mismatched message id")
var randomsrc *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))