commit 2c109646ee0be071d39acc68f8cda66157d37582 from: Oliver Lowe date: Fri Dec 17 07:40:58 2021 UTC recursor: reject more invalid messages commit - 7e5b66014d8e51608b3c909ab643e1f91f12b8db commit + 2c109646ee0be071d39acc68f8cda66157d37582 blob - ca9087535c873b2e3b6c49b86ed6a39ac8dd432b blob + 90337d381fc684d9d17c40a0cea994840f60d762 --- cmd/recursor/recursor.go +++ cmd/recursor/recursor.go @@ -9,32 +9,32 @@ import ( "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 @@ -82,6 +82,8 @@ import ( 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()))