From 6c30be52da3d949a8dd6fb5e2de7319c031e656e Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 14 Jan 2019 17:07:39 +0100 Subject: [PATCH] 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. --- src/backend.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/backend.c b/src/backend.c index 00537f094..13543c90e 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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);