diff --git a/doc/configuration.txt b/doc/configuration.txt index 65dafcb5d..c430a4796 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -8260,7 +8260,10 @@ hash-type none don't hash the key, the key will be used as a hash, this can be useful to manually hash the key using a converter for that purpose - and let haproxy use the result directly. + and let haproxy use the result directly. The operation will + convert the key to a string if it is not already, and parse it as + an integer whose value will be used as the key. Some input key + types might not be relevant here (e.g. IP addresses). indicates an optional method applied after hashing the key : diff --git a/src/backend.c b/src/backend.c index f460b261c..97085be25 100644 --- a/src/backend.c +++ b/src/backend.c @@ -87,7 +87,7 @@ unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len hash = hash_crc32(key, len); break; case BE_LB_HFCN_NONE: - /* use key as a hash */ + /* use key as a hash. It MUST be in string format */ { const char *_key = key; @@ -545,7 +545,14 @@ struct server *get_server_expr(struct stream *s, const struct server *avoid) if (px->lbprm.tot_used == 1) goto hash_done; - smp = sample_fetch_as_type(px, s->sess, s, SMP_OPT_DIR_REQ | SMP_OPT_FINAL, px->lbprm.expr, SMP_T_BIN); + /* Note that if the hash-type doesn't hash the key, we must provide it + * as a string representing a number as it will be parsed by read_int64(). + * Otherwise it's binary. The difference happens on samples returing + * ints (e.g. rand()) as well as IP addresses, which, when turned to + * binary, are just binary-encoded and cannot be parsed. + */ + smp = sample_fetch_as_type(px, s->sess, s, SMP_OPT_DIR_REQ | SMP_OPT_FINAL, px->lbprm.expr, + ((px->lbprm.algo & BE_LB_HASH_FUNC) == BE_LB_HFCN_NONE) ? SMP_T_STR : SMP_T_BIN); if (!smp) return NULL;