Add max_clients to cap the maximum number of client queries
This commit is contained in:
parent
e272dd84f7
commit
732c451dd4
|
@ -40,6 +40,7 @@ type Config struct {
|
|||
SourceRequireNoLog bool `toml:"require_nolog"`
|
||||
SourceIPv4 bool `toml:"ipv4_servers"`
|
||||
SourceIPv6 bool `toml:"ipv6_servers"`
|
||||
MaxClients uint32 `toml:"max_clients"`
|
||||
}
|
||||
|
||||
func newConfig() Config {
|
||||
|
@ -57,6 +58,7 @@ func newConfig() Config {
|
|||
SourceRequireNoLog: true,
|
||||
SourceIPv4: true,
|
||||
SourceIPv6: false,
|
||||
MaxClients: 100,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,6 +130,7 @@ func ConfigLoad(proxy *Proxy, svcFlag *string, config_file string) error {
|
|||
dlog.UseLogFile(*config.LogFile)
|
||||
}
|
||||
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond
|
||||
proxy.maxClients = config.MaxClients
|
||||
proxy.mainProto = "udp"
|
||||
if config.ForceTCP {
|
||||
proxy.mainProto = "tcp"
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
listen_addresses = ['127.0.0.1:53', '[::1]:53']
|
||||
|
||||
|
||||
## Maximum number of simultaneous client connections to accept
|
||||
|
||||
max_clients = 100
|
||||
|
||||
|
||||
## Require servers (from static definitions and from remote sources) to satisfy specific properties
|
||||
|
||||
# Use servers reachable over IPv4
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/jedisct1/dlog"
|
||||
|
@ -50,6 +51,8 @@ type Proxy struct {
|
|||
forwardFile string
|
||||
pluginsGlobals PluginsGlobals
|
||||
urlsToPrefetch []URLToPrefetch
|
||||
clientsCount uint32
|
||||
maxClients uint32
|
||||
}
|
||||
|
||||
type App struct {
|
||||
|
@ -218,6 +221,11 @@ func (proxy *Proxy) udpListener(clientPc *net.UDPConn) {
|
|||
}
|
||||
packet := buffer[:length]
|
||||
go func() {
|
||||
if !proxy.clientsCountInc() {
|
||||
dlog.Warnf("Too many connections (max=%d)", proxy.maxClients)
|
||||
return
|
||||
}
|
||||
defer proxy.clientsCountDec()
|
||||
proxy.processIncomingQuery(proxy.serversInfo.getOne(), "udp", proxy.mainProto, packet, &clientAddr, clientPc)
|
||||
}()
|
||||
}
|
||||
|
@ -242,6 +250,11 @@ func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) {
|
|||
}
|
||||
go func() {
|
||||
defer clientPc.Close()
|
||||
if !proxy.clientsCountInc() {
|
||||
dlog.Warnf("Too many connections (max=%d)", proxy.maxClients)
|
||||
return
|
||||
}
|
||||
defer proxy.clientsCountDec()
|
||||
clientPc.SetDeadline(time.Now().Add(proxy.timeout))
|
||||
packet, err := ReadPrefixed(clientPc.(*net.TCPConn))
|
||||
if err != nil || len(packet) < MinDNSPacketSize {
|
||||
|
@ -300,6 +313,26 @@ func (proxy *Proxy) exchangeWithTCPServer(serverInfo *ServerInfo, encryptedQuery
|
|||
return proxy.Decrypt(serverInfo, encryptedResponse, clientNonce)
|
||||
}
|
||||
|
||||
func (proxy *Proxy) clientsCountInc() bool {
|
||||
for {
|
||||
count := proxy.clientsCount
|
||||
if count >= proxy.maxClients {
|
||||
return false
|
||||
}
|
||||
if atomic.CompareAndSwapUint32(&proxy.clientsCount, count, count+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (proxy *Proxy) clientsCountDec() {
|
||||
for {
|
||||
if count := proxy.clientsCount; count == 0 || atomic.CompareAndSwapUint32(&proxy.clientsCount, count, count-1) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto string, serverProto string, query []byte, clientAddr *net.Addr, clientPc net.Conn) {
|
||||
if len(query) < MinDNSPacketSize || serverInfo == nil {
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue