diff --git a/internal/cmd/args.go b/internal/cmd/args.go index 40b3761f7..be0d8c6da 100644 --- a/internal/cmd/args.go +++ b/internal/cmd/args.go @@ -131,7 +131,7 @@ var commandLineOptions = []*commandLineOption{ valueType: "address", }, upstreamModeIdx: { - description: "Defines the upstreams logic mode, possible values: load_balance, parallel, " + + description: "Defines the upstreams logic mode, possible values: load_balance, parallel, random, " + "fastest_addr (default: load_balance).", long: "upstream-mode", short: "", diff --git a/proxy/config.go b/proxy/config.go index 65065c868..6dbfe1935 100644 --- a/proxy/config.go +++ b/proxy/config.go @@ -296,6 +296,7 @@ func (p *Proxy) validateConfig() (err error) { "", UpstreamModeFastestAddr, UpstreamModeLoadBalance, + UpstreamModeRandom, UpstreamModeParallel: // Go on. default: diff --git a/proxy/exchange.go b/proxy/exchange.go index a34eaf63d..f6e53e8c4 100644 --- a/proxy/exchange.go +++ b/proxy/exchange.go @@ -21,6 +21,12 @@ func (p *Proxy) exchangeUpstreams( switch p.UpstreamMode { case UpstreamModeParallel: return upstream.ExchangeParallel(ups, req) + case UpstreamModeRandom: + // Simply set ups to a random entry in ups + // Falls back to default behaviour as if ups <= 1 it will run UpstreamModeLoadBalance as intended + if len(ups) > 1 { + ups = []upstream.Upstream{ups[p.randSrc.Intn(len(ups))]} + } case UpstreamModeFastestAddr: switch req.Question[0].Qtype { case dns.TypeA, dns.TypeAAAA: diff --git a/proxy/upstreammode.go b/proxy/upstreammode.go index 6b5b995d2..c7a4cc8c0 100644 --- a/proxy/upstreammode.go +++ b/proxy/upstreammode.go @@ -23,6 +23,9 @@ const ( // or AAAA requests only with the fastest IP address detected by ICMP // response time or TCP connection time. UpstreamModeFastestAddr UpstreamMode = "fastest_addr" + + // UpstreamModeRandom makes server to a random upstream + UpstreamModeRandom UpstreamMode = "random" ) // type check @@ -35,6 +38,7 @@ func (m *UpstreamMode) UnmarshalText(b []byte) (err error) { case UpstreamModeLoadBalance, UpstreamModeParallel, + UpstreamModeRandom, UpstreamModeFastestAddr: *m = um default: @@ -43,6 +47,7 @@ func (m *UpstreamMode) UnmarshalText(b []byte) (err error) { b, UpstreamModeLoadBalance, UpstreamModeParallel, + UpstreamModeRandom, UpstreamModeFastestAddr, ) }