commit 7c6a6149a91d2e240a5a63f981c5d07d681df725 Author: Willy Tarreau Date: Mon Jan 14 17:07:39 2019 +0100 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. (cherry picked from commit 6c30be52da3d949a8dd6fb5e2de7319c031e656e) Signed-off-by: Willy Tarreau (cherry picked from commit 48147c424680b7e887fb176662d58d87baa16098) Signed-off-by: William Lallemand diff --git a/src/backend.c b/src/backend.c index 4c4044a6..0cf14cfd 100644 --- a/src/backend.c +++ b/src/backend.c @@ -183,7 +183,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); @@ -236,7 +236,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); @@ -293,7 +293,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); @@ -367,7 +367,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); @@ -463,7 +463,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); @@ -507,7 +507,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); @@ -615,7 +615,7 @@ int assign_server(struct stream *s) case BE_LB_LKUP_CHTREE: case BE_LB_LKUP_MAP: if ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR) { - 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); @@ -691,7 +691,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);