diff options
author | Simão Gomes Viana <simao.gomes@toowoxx.de> | 2021-04-29 18:52:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-29 10:52:22 -0600 |
commit | 90175571698d7cb0e4184d257a425f0bd11c713d (patch) | |
tree | cfa7d28aa0491fc38547e640ff458a21c1c5f3cd | |
parent | 3a1e81dbf6587d2e886529d55e7a02eabeaa7c47 (diff) |
reverseproxy: fix hash selection policy (#4137)
* caddyhttp: reverseproxy: fix hash selection policy
Fixes: #4135
Test: go test './...' -count=1
* caddyhttp: reverseproxy: add test to catch #4135
If you revert the last commit, the test will fail.
-rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies.go | 3 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies_test.go | 29 |
2 files changed, 30 insertions, 2 deletions
diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index 357ee33..001f7f8 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -523,8 +523,7 @@ func hostByHashing(pool []*Upstream, s string) *Upstream { } index := hash(s) % poolLen for i := uint32(0); i < poolLen; i++ { - index += i - upstream := pool[index%poolLen] + upstream := pool[(index+i)%poolLen] if upstream.Available() { return upstream } diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go index 70d05ac..60a2702 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go @@ -198,6 +198,35 @@ func TestIPHashPolicy(t *testing.T) { if h != nil { t.Error("Expected ip hash policy host to be nil.") } + + // Reproduce #4135 + pool = UpstreamPool{ + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + } + pool[0].SetHealthy(false) + pool[1].SetHealthy(false) + pool[2].SetHealthy(false) + pool[3].SetHealthy(false) + pool[4].SetHealthy(false) + pool[5].SetHealthy(false) + pool[6].SetHealthy(false) + pool[7].SetHealthy(false) + pool[8].SetHealthy(true) + + // We should get a result back when there is one healthy host left. + h = ipHash.Select(pool, req, nil) + if h == nil { + // If it is nil, it means we missed a host even though one is available + t.Error("Expected ip hash policy host to not be nil, but it is nil.") + } } func TestFirstPolicy(t *testing.T) { |