@@ -46,6 +46,7 @@ type PluginForward struct {
4646 bootstrapResolvers []string
4747 dhcpdns []* dhcpdns.Detector
4848 proxyDialer netproxy.Dialer
49+ forceTCP bool
4950
5051 // Hot-reloading support
5152 rwLock sync.RWMutex
@@ -66,6 +67,7 @@ func (plugin *PluginForward) Init(proxy *Proxy) error {
6667 plugin .configFile = proxy .forwardFile
6768 dlog .Noticef ("Loading the set of forwarding rules from [%s]" , plugin .configFile )
6869
70+ plugin .forceTCP = proxy .forceTCP
6971 if proxy .xTransport != nil {
7072 plugin .bootstrapResolvers = proxy .xTransport .bootstrapResolvers
7173 if proxy .xTransport .proxyDialer != nil {
@@ -423,8 +425,12 @@ func (plugin *PluginForward) Eval(pluginsState *PluginsState, msg *dns.Msg) erro
423425 dlog .Debugf ("Forwarding [%s] to [%s] using DNS-over-TCP through the configured proxy" , qName , server )
424426 respMsg , err = plugin .exchangeViaProxy (forwardMsg , server , pluginsState .timeout )
425427 } else {
428+ proto := "udp"
429+ if sequence [i ].typ == Bootstrap && plugin .forceTCP {
430+ proto = "tcp"
431+ }
426432 dlog .Debugf ("Forwarding [%s] to [%s]" , qName , server )
427- respMsg , err = plugin .exchangeDirect (forwardMsg , pluginsState . serverProto , server , pluginsState .timeout )
433+ respMsg , err = plugin .exchangeDirect (forwardMsg , proto , server , pluginsState .timeout )
428434 }
429435 if err != nil {
430436 continue
@@ -450,17 +456,17 @@ func (plugin *PluginForward) Eval(pluginsState *PluginsState, msg *dns.Msg) erro
450456 return err
451457}
452458
453- // exchangeDirect sends a query to the selected upstream server using the current
454- // protocol, retrying a truncated UDP response over TCP.
459+ // exchangeDirect sends a query to the selected upstream server, starting with
460+ // the given protocol and retrying a truncated UDP response over TCP.
455461func (plugin * PluginForward ) exchangeDirect (
456462 forwardMsg * dns.Msg ,
457- serverProto string ,
463+ proto string ,
458464 server string ,
459465 timeout time.Duration ,
460466) (* dns.Msg , error ) {
461467 client := dns.Client {}
462468 ctx , cancel := context .WithTimeout (context .Background (), timeout )
463- respMsg , _ , err := client .Exchange (ctx , forwardMsg , serverProto , server )
469+ respMsg , _ , err := client .Exchange (ctx , forwardMsg , proto , server )
464470 cancel ()
465471 if err != nil && (respMsg == nil || ! respMsg .Truncated ) {
466472 return nil , err
0 commit comments