BUG/MINOR: backend: BE_LB_LKUP_CHTREE is a value, not a bit

There are a few instances where the lookup algo is tested against
BE_LB_LKUP_CHTREE using a binary "AND" operation while this macro
is a value among a set, and not a bit. The test happens to work
because the value is exactly 4 and no bit overlaps with the other
possible values but this is a latent bug waiting for a new LB algo
to appear to strike. At the moment the only other algo sharing a bit
with it is the "first" algo which is never supported in the same code
places.

This fix should be backported to maintained versions for safety if it
passes easily, otherwise it's not important as it will not fix any
visible issue.
This commit is contained in:
Willy Tarreau 2019-01-14 17:07:39 +01:00
parent 602a499da5
commit 6c30be52da

View File

@ -185,7 +185,7 @@ static struct server *get_server_sh(struct proxy *px, const char *addr, int len,
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
h = full_hash(h);
hash_done:
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, h, avoid);
else
return map_get_server_hash(px, h);
@ -238,7 +238,7 @@ static struct server *get_server_uh(struct proxy *px, char *uri, int uri_len, co
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
hash = full_hash(hash);
hash_done:
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, hash, avoid);
else
return map_get_server_hash(px, hash);
@ -295,7 +295,7 @@ static struct server *get_server_ph(struct proxy *px, const char *uri, int uri_l
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
hash = full_hash(hash);
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, hash, avoid);
else
return map_get_server_hash(px, hash);
@ -369,7 +369,7 @@ static struct server *get_server_ph_post(struct stream *s, const struct server *
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
hash = full_hash(hash);
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, hash, avoid);
else
return map_get_server_hash(px, hash);
@ -465,7 +465,7 @@ static struct server *get_server_hh(struct stream *s, const struct server *avoid
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
hash = full_hash(hash);
hash_done:
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, hash, avoid);
else
return map_get_server_hash(px, hash);
@ -510,7 +510,7 @@ static struct server *get_server_rch(struct stream *s, const struct server *avoi
if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
hash = full_hash(hash);
hash_done:
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
return chash_get_server_hash(px, hash, avoid);
else
return map_get_server_hash(px, hash);
@ -640,7 +640,7 @@ int assign_server(struct stream *s)
if ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR) {
if ((s->be->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM)
srv = get_server_rnd(s, prev_srv);
else if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
else if ((s->be->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
srv = chash_get_next_server(s->be, prev_srv);
else
srv = map_get_server_rr(s->be, prev_srv);
@ -716,7 +716,7 @@ int assign_server(struct stream *s)
* back to round robin on the map.
*/
if (!srv) {
if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
if ((s->be->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
srv = chash_get_next_server(s->be, prev_srv);
else
srv = map_get_server_rr(s->be, prev_srv);