@@ -19,6 +19,10 @@ type Alternate struct {
19
19
handlers []HandlerWithCallbacks
20
20
}
21
21
22
+ // Use RCode that is out-of-range for any DNS response
23
+ // RCodes can be any of 4 to 16 bits long
24
+ const RcodeNoData int = - 1
25
+
22
26
type rule struct {
23
27
original bool
24
28
handler HandlerWithCallbacks
@@ -55,6 +59,11 @@ func (f Alternate) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Ms
55
59
rulesIndex = nw .Msg .Rcode
56
60
}
57
61
62
+ // if rcode is SUCCESS, and no answer is given, use RcodeNoData as hint for negative response.
63
+ if rulesIndex == dns .RcodeSuccess && isEmpty (r ) {
64
+ rulesIndex = RcodeNoData
65
+ }
66
+
58
67
if u , ok := f .rules [rulesIndex ]; ok {
59
68
if u .original && originalRequest != nil {
60
69
return u .handler .ServeDNS (ctx , w , originalRequest )
@@ -69,3 +78,16 @@ func (f Alternate) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Ms
69
78
70
79
// Name implements the Handler interface.
71
80
func (f Alternate ) Name () string { return "alternate" }
81
+
82
+ func isEmpty (r * dns.Msg ) bool {
83
+ if len (r .Answer ) == 0 {
84
+ return true
85
+ }
86
+
87
+ for _ , r := range r .Answer {
88
+ if r != nil {
89
+ return false
90
+ }
91
+ }
92
+ return true
93
+ }
0 commit comments