Le 13/06/2017 à 14:16, Christopher Faulet a écrit :
Le 13/06/2017 à 10:31, siclesang a écrit :
haproxy balances by host,but often captures a part of request header
host or null, and requests balance to default server.
how to debug it ,
Hi,
I'll try to help you. Can you share your configuration please ? It could
help to find a potential bug.
Could you also provide the tcpdump of a buggy request ?
And finally, could you upgrade your HAProxy to the last 1.6 version
(1.6.12) to be sure ?
Hi,
Just for the record. After some exchanges in private with siclesang, we
found the bug in the configuration parser, because of a too high value
for tune.http.maxhdr. Here is the explanation:
Well, I think I found the problem. This is not a bug (not really). There
is something I missed in your configuration. You set tune.http.maxhdr to
64000. I guess you keep this parameter during all your tests. This is an
invalid value. It needs to be in the range [0, 32767]. This is mandatory
to avoid integer overflow. the size of the array where headers offsets
are stored is a signed short.
To be fair, there is no check on this value during the configuration
parsing. And the documentation does not specify any range for this
parameter. I will post a fix very quickly to avoid errors.
BTW, this is a really huge value. The default one is 101. You can
legitimately increase this value. But there is no reason to have 64000
headers in an HTTP message. IMHO, 1000/2000 is already an very huge limit.
I attached a patch to improve the configuration parsing and to update
the documentation. It can be backported in 1.7, 1.6 and 1.5. I finally
marked this patch as a bug fix.
Thanks siclesang for your help,
--
Christopher Faulet
>From 5b00b9eeda0838a2ab86835c9e3b28b503889b24 Mon Sep 17 00:00:00 2001
From: Christopher Faulet <[email protected]>
Date: Wed, 21 Jun 2017 16:31:35 +0200
Subject: [PATCH] BUG/MINOR: cfgparse: Check if tune.http.maxhdr is in the
range 1..32767
We cannot store more than 32K headers in the structure hdr_idx, because
internaly we use signed short integers. To avoid any bugs (due to an integers
overflow), a check has been added on tune.http.maxhdr to be sure to not set a
value greater than 32767 and lower than 1 (because this is a nonsense to set
this parameter to a value <= 0).
The documentation has been updated accordingly.
This patch can be backported in 1.7, 1.6 and 1.5.
---
doc/configuration.txt | 6 +++---
src/cfgparse.c | 8 +++++++-
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 49bfd85..082b857 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1374,9 +1374,9 @@ tune.http.maxhdr <number>
are blocked with "502 Bad Gateway". The default value is 101, which is enough
for all usages, considering that the widely deployed Apache server uses the
same limit. It can be useful to push this limit further to temporarily allow
- a buggy application to work by the time it gets fixed. Keep in mind that each
- new header consumes 32bits of memory for each session, so don't push this
- limit too high.
+ a buggy application to work by the time it gets fixed. The accepted range is
+ 1..32767. Keep in mind that each new header consumes 32bits of memory for
+ each session, so don't push this limit too high.
tune.idletimer <timeout>
Sets the duration after which haproxy will consider that an empty buffer is
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 261a0eb..3706bca 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -916,7 +916,13 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
- global.tune.max_http_hdr = atol(args[1]);
+ global.tune.max_http_hdr = atoi(args[1]);
+ if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
+ Alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
+ file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
}
else if (!strcmp(args[0], "tune.comp.maxlevel")) {
if (alertif_too_many_args(1, file, linenum, args, &err_code))
--
2.9.4