From: Cyril Bonté Date: Sun, 4 Jan 2015 14:17:36 +0000 (+0100) Subject: BUG/MEDIUM: backend: correctly detect the domain when use_domain_only is used X-Git-Tag: v1.6-dev1~204 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f607d81d09ab839fb1143b749ff231d6093f2038;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: backend: correctly detect the domain when use_domain_only is used balance hdr() provides on option 'use_domain_only' to match only the domain part in a header (designed for the Host header). Olivier Fredj reported that the hashes were not the same for 'subdomain.domain.tld' and 'domain.tld'. This is because the pointer was rewinded one step to far, resulting in a hash calculated against wrong values : - '.domai' for 'subdomain.domain.tld' - ' domai' for 'domain.tld' (beginning with the space in the header line) Another special case is when no dot can be found in the header : the hash will be calculated against an empty string. The patch addresses both cases : 'domain' will be used to compute the hash for 'subdomain.domain.tld', 'domain.tld' and 'domain' (using the whole header value for the last case). The fix must be backported to haproxy 1.5 and 1.4. --- diff --git a/src/backend.c b/src/backend.c index 32e19f9156..35edf75041 100644 --- a/src/backend.c +++ b/src/backend.c @@ -409,29 +409,33 @@ struct server *get_server_hh(struct session *s) hash = gen_hash(px, p, len); } else { int dohash = 0; - p += len - 1; - start = end = p; + p += len; /* special computation, use only main domain name, not tld/host * going back from the end of string, start hashing at first * dot stop at next. * This is designed to work with the 'Host' header, and requires * a special option to activate this. */ + end = p; while (len) { - if (*p == '.') { - if (!dohash) { - dohash = 1; - start = end = p - 1; - } - else + if (dohash) { + /* Rewind the pointer until the previous char + * is a dot, this will allow to set the start + * position of the domain. */ + if (*(p - 1) == '.') break; - } else { - if (dohash) - start--; } - len--; + else if (*p == '.') { + /* The pointer is rewinded to the dot before the + * tld, we memorize the end of the domain and + * can enter the domain processing. */ + end = p; + dohash = 1; + } p--; + len--; } + start = p; hash = gen_hash(px, start, (end - start)); } if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)