Skip to content

Commit b725bad

Browse files
committed
Dynamically reduce the timeout as we get closer to the cnx limit
Similar to what pf does
1 parent 1a0e1bd commit b725bad

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

dnscrypt-proxy/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type Config struct {
8282
SourceIPv4 bool `toml:"ipv4_servers"`
8383
SourceIPv6 bool `toml:"ipv6_servers"`
8484
MaxClients uint32 `toml:"max_clients"`
85+
TimeoutLoadReduction float64 `toml:"timeout_load_reduction"`
8586
BootstrapResolversLegacy []string `toml:"fallback_resolvers"`
8687
BootstrapResolvers []string `toml:"bootstrap_resolvers"`
8788
IgnoreSystemDNS bool `toml:"ignore_system_dns"`
@@ -147,6 +148,7 @@ func newConfig() Config {
147148
SourceDoH: true,
148149
SourceODoH: false,
149150
MaxClients: 250,
151+
TimeoutLoadReduction: 0.5,
150152
BootstrapResolvers: []string{DefaultBootstrapResolver},
151153
IgnoreSystemDNS: false,
152154
LogMaxSize: 10,

dnscrypt-proxy/config_loader.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ func configureServerParams(proxy *Proxy, config *Config) {
171171
proxy.blockedQueryResponse = config.BlockedQueryResponse
172172
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond
173173
proxy.maxClients = config.MaxClients
174+
proxy.timeoutLoadReduction = config.TimeoutLoadReduction
175+
if proxy.timeoutLoadReduction < 0.0 || proxy.timeoutLoadReduction > 1.0 {
176+
dlog.Warnf("timeout_load_reduction must be between 0.0 and 1.0, using default 0.5")
177+
proxy.timeoutLoadReduction = 0.5
178+
}
174179
proxy.mainProto = "udp"
175180
if config.ForceTCP {
176181
proxy.mainProto = "tcp"

dnscrypt-proxy/proxy.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ type Proxy struct {
8686
cacheMaxTTL uint32
8787
clientsCount uint32
8888
maxClients uint32
89+
timeoutLoadReduction float64
8990
cacheMinTTL uint32
9091
cacheNegMaxTTL uint32
9192
cloakTTL uint32
@@ -474,7 +475,8 @@ func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) {
474475
go func() {
475476
defer clientPc.Close()
476477
defer proxy.clientsCountDec()
477-
if err := clientPc.SetDeadline(time.Now().Add(proxy.timeout)); err != nil {
478+
dynamicTimeout := proxy.getDynamicTimeout()
479+
if err := clientPc.SetDeadline(time.Now().Add(dynamicTimeout)); err != nil {
478480
return
479481
}
480482
start := time.Now()
@@ -686,6 +688,25 @@ func (proxy *Proxy) clientsCountDec() {
686688
}
687689
}
688690

691+
func (proxy *Proxy) getDynamicTimeout() time.Duration {
692+
if proxy.timeoutLoadReduction <= 0.0 || proxy.maxClients == 0 {
693+
return proxy.timeout
694+
}
695+
696+
currentClients := atomic.LoadUint32(&proxy.clientsCount)
697+
utilization := float64(currentClients) / float64(proxy.maxClients)
698+
699+
factor := 1.0 - (utilization * utilization * proxy.timeoutLoadReduction)
700+
if factor < 0.1 {
701+
factor = 0.1
702+
}
703+
704+
dynamicTimeout := time.Duration(float64(proxy.timeout) * factor)
705+
dlog.Debugf("Dynamic timeout: %v (utilization: %.2f%%, factor: %.2f)", dynamicTimeout, utilization*100, factor)
706+
707+
return dynamicTimeout
708+
}
709+
689710
func (proxy *Proxy) processIncomingQuery(
690711
clientProto string,
691712
serverProto string,

0 commit comments

Comments
 (0)