forked from pool/haproxy
1 OBS-URL: https://build.opensuse.org/request/show/280162 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/haproxy?expand=0&rev=22
84 lines
2.5 KiB
Diff
84 lines
2.5 KiB
Diff
From 7ccea2642c54f9a07f4fbd29d3b005008cd457a3 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
|
|
Date: Sun, 4 Jan 2015 15:17:36 +0100
|
|
Subject: [PATCH] BUG/MEDIUM: backend: correctly detect the domain when
|
|
use_domain_only is used
|
|
|
|
balance hdr(<name>) 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.
|
|
(cherry picked from commit f607d81d09ab839fb1143b749ff231d6093f2038)
|
|
---
|
|
src/backend.c | 28 ++++++++++++++++------------
|
|
1 file changed, 16 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/src/backend.c b/src/backend.c
|
|
index ada8370..9980cf8 100644
|
|
--- a/src/backend.c
|
|
+++ b/src/backend.c
|
|
@@ -408,29 +408,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)
|
|
--
|
|
2.1.2
|
|
|