@@ -19,6 +19,13 @@ const truncateSize = 512
19
19
20
20
var defaultFallbackIPs = []string {"8.8.8.8" , "1.1.1.1" }
21
21
22
+ type Network string
23
+
24
+ const (
25
+ TCP Network = "tcp"
26
+ UDP Network = "udp"
27
+ )
28
+
22
29
type HandlerOptions struct {
23
30
IPv6 bool
24
31
StaticHosts map [string ]string
@@ -57,7 +64,7 @@ func (s *Server) Shutdown() {
57
64
}
58
65
59
66
func newStaticClientConfig (ips []string ) (* dns.ClientConfig , error ) {
60
- logrus .Infof ("newStaticClientConfig creating config for the the following IPs: %v" , ips )
67
+ logrus .Debugf ("newStaticClientConfig creating config for the the following IPs: %v" , ips )
61
68
s := ``
62
69
for _ , ip := range ips {
63
70
s += fmt .Sprintf ("nameserver %s\n " , ip )
@@ -66,6 +73,23 @@ func newStaticClientConfig(ips []string) (*dns.ClientConfig, error) {
66
73
return dns .ClientConfigFromReader (r )
67
74
}
68
75
76
+ func (h * Handler ) lookupCnameToHost (cname string ) string {
77
+ seen := make (map [string ]bool )
78
+ for {
79
+ // break cyclic definition
80
+ if seen [cname ] {
81
+ break
82
+ }
83
+ if _ , ok := h .cnameToHost [cname ]; ok {
84
+ seen [cname ] = true
85
+ cname = h .cnameToHost [cname ]
86
+ continue
87
+ }
88
+ break
89
+ }
90
+ return cname
91
+ }
92
+
69
93
func NewHandler (opts HandlerOptions ) (dns.Handler , error ) {
70
94
var cc * dns.ClientConfig
71
95
var err error
@@ -89,6 +113,7 @@ func NewHandler(opts HandlerOptions) (dns.Handler, error) {
89
113
}
90
114
} else {
91
115
if cc , err = newStaticClientConfig (opts .UpstreamServers ); err != nil {
116
+ logrus .WithError (err ).Warnf ("failed to create a client config from: %v, falling back to %v" , opts .UpstreamServers , defaultFallbackIPs )
92
117
if cc , err = newStaticClientConfig (defaultFallbackIPs ); err != nil {
93
118
return nil , err
94
119
}
@@ -147,12 +172,13 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
147
172
case dns .TypeA :
148
173
var err error
149
174
var addrs []net.IP
150
- if _ , ok := h .hostToIP [q .Name ]; ok {
151
- addrs = []net.IP {h .hostToIP [q .Name ]}
175
+ cname := h .lookupCnameToHost (q .Name )
176
+ if _ , ok := h .hostToIP [cname ]; ok {
177
+ addrs = []net.IP {h .hostToIP [cname ]}
152
178
} else {
153
- addrs , err = net .LookupIP (q . Name )
179
+ addrs , err = net .LookupIP (cname )
154
180
if err != nil {
155
- logrus .Debugf ( "handleQuery lookup IP failed: %v" , err )
181
+ logrus .WithError ( err ). Debug ( "handleQuery lookup IP failed" )
156
182
continue
157
183
}
158
184
}
@@ -178,25 +204,12 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
178
204
handled = true
179
205
}
180
206
case dns .TypeCNAME :
181
- cname := q .Name
182
- seen := make (map [string ]bool )
183
- for {
184
- // break cyclic definition
185
- if seen [cname ] {
186
- break
187
- }
188
- if _ , ok := h .cnameToHost [cname ]; ok {
189
- seen [cname ] = true
190
- cname = h .cnameToHost [cname ]
191
- continue
192
- }
193
- break
194
- }
207
+ cname := h .lookupCnameToHost (q .Name )
195
208
var err error
196
209
if _ , ok := h .hostToIP [cname ]; ! ok {
197
210
cname , err = net .LookupCNAME (cname )
198
211
if err != nil {
199
- logrus .Debugf ( "handleQuery lookup CNAME failed: %v" , err )
212
+ logrus .WithError ( err ). Debug ( "handleQuery lookup CNAME failed" )
200
213
continue
201
214
}
202
215
}
@@ -212,7 +225,7 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
212
225
case dns .TypeTXT :
213
226
txt , err := net .LookupTXT (q .Name )
214
227
if err != nil {
215
- logrus .Debugf ( "handleQuery lookup TXT failed: %v" , err )
228
+ logrus .WithError ( err ). Debug ( "handleQuery lookup TXT failed" )
216
229
continue
217
230
}
218
231
for _ , s := range txt {
@@ -229,7 +242,7 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
229
242
case dns .TypeNS :
230
243
ns , err := net .LookupNS (q .Name )
231
244
if err != nil {
232
- logrus .Debugf ( "handleQuery lookup NS failed: %v" , err )
245
+ logrus .WithError ( err ). Debug ( "handleQuery lookup NS failed" )
233
246
continue
234
247
}
235
248
for _ , s := range ns {
@@ -245,7 +258,7 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
245
258
case dns .TypeMX :
246
259
mx , err := net .LookupMX (q .Name )
247
260
if err != nil {
248
- logrus .Debugf ("handleQuery lookup MX failed: %v" , err )
261
+ logrus .WithError ( err ). Debugf ("handleQuery lookup MX failed" )
249
262
continue
250
263
}
251
264
for _ , s := range mx {
@@ -262,7 +275,7 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
262
275
case dns .TypeSRV :
263
276
_ , addrs , err := net .LookupSRV ("" , "" , q .Name )
264
277
if err != nil {
265
- logrus .Debugf ( "handleQuery lookup SRV failed: %v" , err )
278
+ logrus .WithError ( err ). Debug ( "handleQuery lookup SRV failed" )
266
279
continue
267
280
}
268
281
hdr .Rrtype = dns .TypeSRV
@@ -284,7 +297,7 @@ func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
284
297
reply .Truncate (truncateSize )
285
298
}
286
299
if err := w .WriteMsg (& reply ); err != nil {
287
- logrus .Debugf ("handleQuery failed writing DNS reply: %v" , err )
300
+ logrus .WithError ( err ). Debugf ("handleQuery failed writing DNS reply" )
288
301
}
289
302
290
303
return
@@ -299,15 +312,15 @@ func (h *Handler) handleDefault(w dns.ResponseWriter, req *dns.Msg) {
299
312
addr := fmt .Sprintf ("%s:%s" , srv , h .clientConfig .Port )
300
313
reply , _ , err := client .Exchange (req , addr )
301
314
if err != nil {
302
- logrus .Debugf ("handleDefault failed to perform a synchronous query with upstream [%v]: %v " , addr , err )
315
+ logrus .WithError ( err ). Debugf ("handleDefault failed to perform a synchronous query with upstream [%v]" , addr )
303
316
continue
304
317
}
305
318
if h .truncate {
306
319
logrus .Debugf ("handleDefault truncating reply: %v" , reply )
307
320
reply .Truncate (truncateSize )
308
321
}
309
322
if err = w .WriteMsg (reply ); err != nil {
310
- logrus .Debugf ("handleDefault failed writing DNS reply to [%v]: %v " , addr , err )
323
+ logrus .WithError ( err ). Debugf ("handleDefault failed writing DNS reply to [%v]" , addr )
311
324
}
312
325
return
313
326
}
@@ -319,7 +332,7 @@ func (h *Handler) handleDefault(w dns.ResponseWriter, req *dns.Msg) {
319
332
reply .Truncate (truncateSize )
320
333
}
321
334
if err := w .WriteMsg (& reply ); err != nil {
322
- logrus .Debugf ("handleDefault failed writing DNS reply: %v" , err )
335
+ logrus .WithError ( err ). Debugf ("handleDefault failed writing DNS reply" )
323
336
}
324
337
}
325
338
@@ -335,43 +348,43 @@ func (h *Handler) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
335
348
func Start (opts ServerOptions ) (* Server , error ) {
336
349
server := & Server {}
337
350
if opts .UDPPort > 0 {
338
- udpOpts := opts
339
- // always enable reply truncate for UDP
340
- udpOpts .TruncateReply = true
341
- h , err := NewHandler (udpOpts .HandlerOptions )
351
+ udpSrv , err := listenAndServe (UDP , opts )
342
352
if err != nil {
343
353
return nil , err
344
354
}
345
- addr := fmt .Sprintf ("%s:%d" , opts .Address , opts .UDPPort )
346
- s := & dns.Server {Net : "udp" , Addr : addr , Handler : h }
347
- server .udp = s
348
- go func () {
349
- logrus .Debugf ("Start UDP server listening on: %v" , addr )
350
- if e := s .ListenAndServe (); e != nil {
351
- panic (e )
352
- }
353
- }()
355
+ server .udp = udpSrv
354
356
}
355
357
if opts .TCPPort > 0 {
356
- tcpOpts := opts
357
- tcpOpts .TruncateReply = false
358
- h , err := NewHandler (tcpOpts .HandlerOptions )
358
+ tcpSrv , err := listenAndServe (TCP , opts )
359
359
if err != nil {
360
360
return nil , err
361
361
}
362
- addr := fmt .Sprintf ("%s:%d" , opts .Address , opts .TCPPort )
363
- s := & dns.Server {Net : "tcp" , Addr : addr , Handler : h }
364
- server .tcp = s
365
- go func () {
366
- logrus .Debugf ("Start TCP server listening on: %v" , addr )
367
- if e := s .ListenAndServe (); e != nil {
368
- panic (e )
369
- }
370
- }()
362
+ server .tcp = tcpSrv
371
363
}
372
364
return server , nil
373
365
}
374
366
367
+ func listenAndServe (network Network , opts ServerOptions ) (* dns.Server , error ) {
368
+ // always enable reply truncate for UDP
369
+ if network == UDP {
370
+ opts .TruncateReply = true
371
+ }
372
+ h , err := NewHandler (opts .HandlerOptions )
373
+ if err != nil {
374
+ return nil , err
375
+ }
376
+ addr := fmt .Sprintf ("%s:%d" , opts .Address , opts .UDPPort )
377
+ s := & dns.Server {Net : string (network ), Addr : addr , Handler : h }
378
+ go func () {
379
+ logrus .Debugf ("Start UDP server listening on: %v" , addr )
380
+ if e := s .ListenAndServe (); e != nil {
381
+ panic (e )
382
+ }
383
+ }()
384
+
385
+ return s , nil
386
+ }
387
+
375
388
func chunkify (buffer string , limit int ) []string {
376
389
var result []string
377
390
for len (buffer ) > 0 {
0 commit comments