@@ -2,6 +2,7 @@ package dns
2
2
3
3
import (
4
4
"fmt"
5
+ "math/rand"
5
6
"net"
6
7
"strings"
7
8
@@ -84,9 +85,53 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
84
85
return
85
86
}
86
87
88
+ // Query fallback servers
89
+ fallbackResp , err := queryFallbackServer (r )
90
+ if err != nil {
91
+ // Send failure response
92
+ m .SetRcode (r , dns .RcodeServerFailure )
93
+ if err := w .WriteMsg (m ); err != nil {
94
+ logger .Errorf ("failed to write response: %s" , err )
95
+ }
96
+ logger .Errorf ("failed to query fallback server: %s" , err )
97
+ return
98
+ } else {
99
+ // Copy relevant data from fallback response into our response
100
+ m .SetRcode (r , fallbackResp .MsgHdr .Rcode )
101
+ m .RecursionDesired = r .RecursionDesired
102
+ m .RecursionAvailable = fallbackResp .RecursionAvailable
103
+ if fallbackResp .Ns != nil {
104
+ m .Ns = append (m .Ns , fallbackResp .Ns ... )
105
+ }
106
+ if fallbackResp .Answer != nil {
107
+ m .Answer = append (m .Answer , fallbackResp .Answer ... )
108
+ }
109
+ if fallbackResp .Extra != nil {
110
+ m .Extra = append (m .Extra , fallbackResp .Extra ... )
111
+ }
112
+ // Send response
113
+ if err := w .WriteMsg (m ); err != nil {
114
+ logger .Errorf ("failed to write response: %s" , err )
115
+ }
116
+ return
117
+ }
118
+
87
119
// Return NXDOMAIN if we have no information about the requested domain or any of its parents
88
120
m .SetRcode (r , dns .RcodeNameError )
89
121
if err := w .WriteMsg (m ); err != nil {
90
122
logger .Errorf ("failed to write response: %s" , err )
91
123
}
92
124
}
125
+
126
+ func queryFallbackServer (req * dns.Msg ) (* dns.Msg , error ) {
127
+ // Pick random fallback server
128
+ cfg := config .GetConfig ()
129
+ fallbackServer := cfg .Dns .FallbackServers [rand .Intn (len (cfg .Dns .FallbackServers ))]
130
+ // Query chosen server
131
+ m := new (dns.Msg )
132
+ m .Id = dns .Id ()
133
+ m .RecursionDesired = req .RecursionDesired
134
+ m .Question = append (m .Question , req .Question ... )
135
+ in , err := dns .Exchange (m , fmt .Sprintf ("%s:53" , fallbackServer ))
136
+ return in , err
137
+ }
0 commit comments