dns

DNS client and server implementations using the Go project's dnsmessage package
Log | Files | Refs | README | LICENSE

commit 2c109646ee0be071d39acc68f8cda66157d37582
parent 7e5b66014d8e51608b3c909ab643e1f91f12b8db
Author: Oliver Lowe <o@olowe.co>
Date:   Fri, 17 Dec 2021 18:40:58 +1100

recursor: reject more invalid messages

Diffstat:
Mcmd/recursor/recursor.go | 30+++++++++++++++---------------
Mdns.go | 2++
2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/cmd/recursor/recursor.go b/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 - w.WriteMsg(rmsg) - return - } - // Reject multiple questions; not even BIND supports it. - if len(qmsg.Questions) > 1 { - rmsg.Header.RCode = dnsmessage.RCodeFormatError + if reject, rc := shouldReject(qmsg); reject { + rmsg.Header.RCode = rc 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 diff --git a/dns.go b/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()))