From a1a42b2c46779b5951f7914e9d2812efd14129d5 Mon Sep 17 00:00:00 2001 From: Chris O'Haver Date: Wed, 23 Feb 2022 09:40:12 -0500 Subject: [PATCH] servfail if result is nil or missing question Signed-off-by: Chris O'Haver --- unbound.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/unbound.go b/unbound.go index 2107f2a..aa68049 100644 --- a/unbound.go +++ b/unbound.go @@ -2,6 +2,7 @@ package unbound import ( "context" + "errors" "fmt" "strconv" @@ -14,7 +15,12 @@ import ( "github.com/miekg/unbound" ) -var log = clog.NewWithPlugin("unbound") +var ( + log = clog.NewWithPlugin("unbound") + errNilResult = errors.New("nil result from unbound") + errNilMessage = errors.New("nil message from unbound") + errMissingQuestion = errors.New("missing question in result from unbound") +) // Unbound is a plugin that resolves requests using libunbound. type Unbound struct { @@ -116,11 +122,22 @@ func (u *Unbound) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg server := metrics.WithServer(ctx) RcodeCount.WithLabelValues(server, rc).Add(1) - RequestDuration.WithLabelValues(server).Observe(res.Rtt.Seconds()) + if res != nil { + RequestDuration.WithLabelValues(server).Observe(res.Rtt.Seconds()) + } if err != nil { return dns.RcodeServerFailure, err } + if res == nil { + return dns.RcodeServerFailure, errNilResult + } + if res.AnswerPacket == nil { + return dns.RcodeServerFailure, errNilMessage + } + if len(res.AnswerPacket.Question) == 0 { + return dns.RcodeServerFailure, errMissingQuestion + } // If the client *didn't* set the opt record, and specifically not the DO bit, // strip this from the reply (unbound default to setting DO).