Skip to content

Commit 8a3dde1

Browse files
committed
Forwarding: only use TCP with bootstrap resolvers
Everything else is just sent to local devices, so UDP is fine. Fixes #3295
1 parent 5d01beb commit 8a3dde1

3 files changed

Lines changed: 13 additions & 5 deletions

File tree

dnscrypt-proxy/config_loader.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func configureServerParams(proxy *Proxy, config *Config) {
181181
dlog.Warnf("timeout_load_reduction must be between 0.0 and 1.0, using default 0.75")
182182
proxy.timeoutLoadReduction = 0.75
183183
}
184+
proxy.forceTCP = config.ForceTCP
184185
proxy.xTransport.mainProto = "udp"
185186
if config.ForceTCP {
186187
proxy.xTransport.mainProto = "tcp"

dnscrypt-proxy/plugin_forward.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
455461
func (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

dnscrypt-proxy/proxy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type Proxy struct {
9999
showCerts bool
100100
pqDNSCrypt bool
101101
certIgnoreTimestamp bool
102+
forceTCP bool
102103
skipAnonIncompatibleResolvers bool
103104
anonDirectCertFallback bool
104105
pluginBlockUndelegated bool

0 commit comments

Comments
 (0)