]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
5 years agoBUILD: tools: rely on __ELF__ not USE_DL to enable use of dladdr()
Willy Tarreau [Wed, 4 Mar 2020 09:31:58 +0000 (10:31 +0100)] 
BUILD: tools: rely on __ELF__ not USE_DL to enable use of dladdr()

The approach was wrong. USE_DL is for the makefile to know if it's required
to append -ldl at link time. Some platforms do not need it (and in fact do
not have it) yet they have a working dladdr(). The real condition is related
to ELF. Given that due to Lua, all platforms that require -ldl already have
USE_DL set, let's replace USE_DL with __ELF__ here and consider that dladdr
is always needed on ELF, which basically is already the case.

5 years agoBUILD: tools: unbreak resolve_sym_name() on non-GNU platforms
Willy Tarreau [Wed, 4 Mar 2020 09:19:36 +0000 (10:19 +0100)] 
BUILD: tools: unbreak resolve_sym_name() on non-GNU platforms

resolve_sym_name() doesn't build when USE_DL is set on non-GNU platforms
because "Elf(W)" isn't defined. Since it's only used for dladdr1(), let's
refactor all this so that we can completely ifdef out that part on other
platforms. Now we have a separate function to perform the call depending
on the platform and it only returns the size when available.

5 years agoMINOR: debug: dump the whole trace if we can't spot the starting point
Willy Tarreau [Wed, 4 Mar 2020 06:39:32 +0000 (07:39 +0100)] 
MINOR: debug: dump the whole trace if we can't spot the starting point

Instead of special-casing the use of the symbol resolving to decide
whether to dump a partial or complete trace, let's simply start over
and dump everything when we reach the end after having found nothing.
It will be more robust against dirty traces as well.

5 years agoMINOR: debug: use our own backtrace function on clang+x86_64
Willy Tarreau [Wed, 4 Mar 2020 10:54:16 +0000 (11:54 +0100)] 
MINOR: debug: use our own backtrace function on clang+x86_64

A test on FreeBSD with clang 4 to 8 produces this on a call to a
spinning loop on the CLI:

  call trace(5):
  |       0x53e2bc [eb 16 48 63 c3 48 c1 e0]: wdt_handler+0x10c
  |    0x800e02cfe [e8 5d 83 00 00 8b 18 8b]: libthr:pthread_sigmask+0x53e

with our own function it correctly produces this:

  call trace(20):
  |       0x53e2dc [eb 16 48 63 c3 48 c1 e0]: wdt_handler+0x10c
  |    0x800e02cfe [e8 5d 83 00 00 8b 18 8b]: libthr:pthread_sigmask+0x53e
  |    0x800e022bf [48 83 c4 38 5b 41 5c 41]: libthr:pthread_getspecific+0xdef
  | 0x7ffffffff003 [48 8d 7c 24 10 6a 00 48]: main+0x7fffffb416f3
  |    0x801373809 [85 c0 0f 84 6f ff ff ff]: libc:__sys_gettimeofday+0x199
  |    0x801373709 [89 c3 85 c0 75 a6 48 8b]: libc:__sys_gettimeofday+0x99
  |    0x801371c62 [83 f8 4e 75 0f 48 89 df]: libc:gettimeofday+0x12
  |       0x51fa0a [48 89 df 4c 89 f6 e8 6b]: ha_thread_dump_all_to_trash+0x49a
  |       0x4b723b [85 c0 75 09 49 8b 04 24]: mworker_cli_sockpair_new+0xd9b
  |       0x4b6c68 [85 c0 75 08 4c 89 ef e8]: mworker_cli_sockpair_new+0x7c8
  |       0x532f81 [4c 89 e7 48 83 ef 80 41]: task_run_applet+0xe1

So let's add clang+x86_64 to the list of platforms that will use our
simplified version. As a bonus it will not require to link with
-lexecinfo on FreeBSD and will work out of the box when passing
USE_BACKTRACE=1.

5 years agoMINOR: debug: improve backtrace() on aarch64 and possibly other systems
Willy Tarreau [Wed, 4 Mar 2020 06:44:06 +0000 (07:44 +0100)] 
MINOR: debug: improve backtrace() on aarch64 and possibly other systems

It happens that on aarch64 backtrace() only returns one entry (tested
with gcc 4.7.4, 5.5.0 and 7.4.1). Probably that it refrains from unwinding
the stack due to the risk of hitting a bad pointer. Here we can use
may_access() to know when it's safe, so we can actually unwind the stack
without taking risks. It happens that the faulting function (the one
just after the signal handler) is not listed here, very likely because
the signal handler uses a special stack and did not create a new frame.

So this patch creates a new my_backtrace() function in standard.h that
either calls backtrace() or does its own unrolling. The choice depends
on HA_HAVE_WORKING_BACKTRACE which is set in compat.h based on the build
target.

5 years agoMINOR: debug: report the number of entries in the backtrace
Willy Tarreau [Wed, 4 Mar 2020 06:38:23 +0000 (07:38 +0100)] 
MINOR: debug: report the number of entries in the backtrace

It's useful to get an indication of unresolved stuff or memory
corruption to have the apparent depth of the stack trace in the
output, especially if we dump nothing.

5 years agoMINOR: wdt: do not depend on USE_THREAD
Willy Tarreau [Wed, 4 Mar 2020 09:53:07 +0000 (10:53 +0100)] 
MINOR: wdt: do not depend on USE_THREAD

There is no reason for restricting the use of the watchdog to threads
anymore, as it works perfectly without threads as well.

5 years agoMEDIUM: wdt: fall back to CLOCK_REALTIME if CLOCK_THREAD_CPUTIME is not available
Willy Tarreau [Wed, 4 Mar 2020 09:48:18 +0000 (10:48 +0100)] 
MEDIUM: wdt: fall back to CLOCK_REALTIME if CLOCK_THREAD_CPUTIME is not available

At least FreeBSD has a fully functional CLOCK_THREAD_CPUTIME but it
cannot create a timer on it. This is not a problem since our timer is
only used to measure each thread's usage using now_cpu_time_thread().
So by just replacing this clock with CLOCK_REALTIME we allow such
platforms to periodically call the wdt and check the thread's CPU usage.
The consequence is that even on a totally idle system there will still
be a few extra periodic wakeups, but the watchdog becomes usable there
as well.

5 years agoBUILD: Makefile: include librt before libpthread
Willy Tarreau [Wed, 4 Mar 2020 07:31:47 +0000 (08:31 +0100)] 
BUILD: Makefile: include librt before libpthread

Statically building on for i386/x86_64 on linux+glibc 2.18 fails in rt with
undefined references to pthread_attr_init and a few others. Let's just swap
the two libs in order to fix this.

5 years agoBUG/MINOR: wdt: do not return an error when the watchdog couldn't be enabled
Willy Tarreau [Wed, 4 Mar 2020 09:46:13 +0000 (10:46 +0100)] 
BUG/MINOR: wdt: do not return an error when the watchdog couldn't be enabled

On operating systems not supporting to create a timer on
POSIX_THREAD_CPUTIME we emit a warning but we return an error so the
process fails to start, which is absurd. Let's return a success once
the warning is emitted instead.

This may be backported to 2.1 and 2.0.

5 years agoMINOR: ssl: add "ca-verify-file" directive
Emmanuel Hocdet [Mon, 16 Dec 2019 15:39:17 +0000 (16:39 +0100)] 
MINOR: ssl: add "ca-verify-file" directive

It's only available for bind line. "ca-verify-file" allows to separate
CA certificates from "ca-file". CA names sent in server hello message is
only compute from "ca-file". Typically, "ca-file" must be defined with
intermediate certificates and "ca-verify-file" with certificates to
ending the chain, like root CA.

Fix issue #404.

5 years agoMINOR: debug: call backtrace() once upon startup
Willy Tarreau [Wed, 4 Mar 2020 05:01:40 +0000 (06:01 +0100)] 
MINOR: debug: call backtrace() once upon startup

Calling backtrace() will access libgcc at runtime. We don't want to do
it after the chroot, so let's perform a first call to have it ready in
memory for later use.

5 years agoMEDIUM: debug: add support for dumping backtraces of stuck threads
Willy Tarreau [Tue, 3 Mar 2020 14:40:23 +0000 (15:40 +0100)] 
MEDIUM: debug: add support for dumping backtraces of stuck threads

When a panic() occurs due to a stuck thread, we'll try to dump a
backtrace of this thread if the config directive USE_BACKTRACE is
set (which is the case on linux+glibc). For this we use the
backtrace() call provided by glibc and iterate the pointers through
resolve_sym_name(). In order to minimize the output (which is limited
to one buffer), we only do this for stuck threads, and we start the
dump above ha_panic()/ha_thread_dump_all_to_trash(), and stop when
meeting known points such as main/run_tasks_from_list/run_poll_loop.

If enabled without USE_DL, the dump will be complete with no details
except that pointers will all be given relative to main, which is
still better than nothing.

The new USE_BACKTRACE config option is enabled by default on glibc since
it has been present for ages. When it is set, the export-dynamic linker
option is enabled so that all non-static symbols are properly resolved.

5 years agoMINOR: cli: make "show fd" rely on resolve_sym_name()
Willy Tarreau [Tue, 3 Mar 2020 16:29:58 +0000 (17:29 +0100)] 
MINOR: cli: make "show fd" rely on resolve_sym_name()

This way we can drop all hard-coded iocb matching.

5 years agoMINOR: debug: use resolve_sym_name() to dump task handlers
Willy Tarreau [Tue, 3 Mar 2020 16:13:02 +0000 (17:13 +0100)] 
MINOR: debug: use resolve_sym_name() to dump task handlers

Now in "show threads", the task/tasklet handler will be resolved
using this function, which will provide more detailed results and
will still support offsets to main for unresolved symbols.

5 years agoMINOR: tools: add resolve_sym_name() to resolve function pointers
Willy Tarreau [Tue, 3 Mar 2020 16:09:08 +0000 (17:09 +0100)] 
MINOR: tools: add resolve_sym_name() to resolve function pointers

We use various hacks at a few places to try to identify known function
pointers in debugging outputs (show threads & show fd). Let's centralize
this into a new function dedicated to this. It already knows about the
functions matched by "show threads" and "show fd", and when built with
USE_DL, it can rely on dladdr1() to resolve other functions. There are
some limitations, as static functions are not resolved, linking with
-rdynamic is mandatory, and even then some functions will not necessarily
appear. It's possible to do a better job by rebuilding the whole symbol
table from the ELF headers in memory but it's less portable and the gains
are still limited, so this solution remains a reasonable tradeoff.

5 years agoMINOR: tools: add new function dump_addr_and_bytes()
Willy Tarreau [Tue, 3 Mar 2020 14:57:10 +0000 (15:57 +0100)] 
MINOR: tools: add new function dump_addr_and_bytes()

This function dumps <n> bytes from <addr> in hex form into buffer <buf>
enclosed in brackets after the address itself, formatted on 14 chars
including the "0x" prefix. This is meant to be used as a prefix for code
areas. For example: "0x7f10b6557690 [48 c7 c0 0f 00 00 00 0f]: "
It relies on may_access() to know if the bytes are dumpable, otherwise "--"
is emitted. An optional prefix is supported.

5 years agoBUILD: tools: remove obsolete and conflicting trace() from standard.c
Willy Tarreau [Tue, 3 Mar 2020 16:06:52 +0000 (17:06 +0100)] 
BUILD: tools: remove obsolete and conflicting trace() from standard.c

Since commit 4c2ae48375 ("MINOR: trace: implement a very basic trace()
function") merged in 2.1, trace() is an inline function. It must not
appear in standard.c anymore and may break build depending on includes.

This can be backported to 2.1.

5 years agoMINOR: task: export run_tasks_from_list
Willy Tarreau [Tue, 3 Mar 2020 13:59:28 +0000 (14:59 +0100)] 
MINOR: task: export run_tasks_from_list

This will help refine debug traces.

5 years agoMINOR: haproxy: export run_poll_loop
Willy Tarreau [Tue, 3 Mar 2020 13:59:56 +0000 (14:59 +0100)] 
MINOR: haproxy: export run_poll_loop

This will help refine debug traces.

5 years agoMINOR: haproxy: export main to ease access from debugger
Willy Tarreau [Tue, 3 Mar 2020 14:25:10 +0000 (15:25 +0100)] 
MINOR: haproxy: export main to ease access from debugger

Better just export main instead of declaring it as extern, it's cleaner
and may be usable elsewhere.

5 years agoBUG/MEDIUM: debug: make the debug_handler check for the thread in threads_to_dump
Willy Tarreau [Tue, 3 Mar 2020 07:31:34 +0000 (08:31 +0100)] 
BUG/MEDIUM: debug: make the debug_handler check for the thread in threads_to_dump

It happens that just sending the debug signal to the process makes on
thread wait for its turn while nobody wants to dump. We need to at
least verify that a dump was really requested for this thread.

This can be backported to 2.1 and 2.0.

5 years agoMINOR: debug: report the task handler's pointer relative to main
Willy Tarreau [Tue, 3 Mar 2020 06:04:42 +0000 (07:04 +0100)] 
MINOR: debug: report the task handler's pointer relative to main

Often in crash dumps we see unknown function pointers. Let's display
them relative to main, that helps quite a lot figure the function
from an executable, for example:

  (gdb) x/a main+645360
  0x4c56a0 <h1_timeout_task>:     0x2e6666666666feeb

This could be backported to 2.0.

5 years agoMINOR: tools: make sure to correctly check the returned 'ms' in date2std_log
Willy Tarreau [Sat, 29 Feb 2020 08:08:02 +0000 (09:08 +0100)] 
MINOR: tools: make sure to correctly check the returned 'ms' in date2std_log

In commit 4eee38a ("BUILD/MINOR: tools: fix build warning in the date
conversion functions") we added some return checks to shut build
warnings but the last test is useless since the tested pointer is not
updated by the last call to utoa_pad() used to convert the milliseconds.
It turns out the original code from 2012 already skipped this part,
probably in order to avoid the risk of seeing a millisecond field not
belonging to the 0-999 range. Better keep the check and put the code
into stricter shape.

No backport is needed. This fixes issue #526.

5 years agoBUG/MINOR: arg: don't reject missing optional args
Willy Tarreau [Fri, 28 Feb 2020 15:41:29 +0000 (16:41 +0100)] 
BUG/MINOR: arg: don't reject missing optional args

Commit 80b53ffb1c ("MEDIUM: arg: make make_arg_list() stop after its
own arguments") changed the way we detect the empty list because we
cannot stop by looking up the closing parenthesis anymore, thus for
the first missing arg we have to enter the parsing loop again. And
there, finding an empty arg means we go to the empty_err label, where
it was not initially planned to handle this condition. This results
in %[date()] to fail while %[date] works. Let's simply check if we've
reached the minimally supported args there (it used to be done during
the function entry).

Thanks to Jérôme for reporting this issue. No backport is needed,
this is 2.2-dev2+ only.

5 years agoMEDIUM: mux-h1: do not blindly wake up the tasklet at end of request anymore
Willy Tarreau [Fri, 28 Feb 2020 14:21:42 +0000 (15:21 +0100)] 
MEDIUM: mux-h1: do not blindly wake up the tasklet at end of request anymore

Since commit "MEDIUM: connection: make the subscribe() call able to wakeup
if ready" we have the guarantee that the tasklet will be woken up if
subscribing to a connection for an even that's ready. Since we have too
many tasklet_wakeup() calls in mux-h1, let's now use this property to
improve the situation a bit.

With this change, no syscall count changed, however the number of useless
calls to some functions significantly went down. Here are the differences
for the test below (100k req), in number of calls per request :

  $ ./h1load -n 100000 -t 4 -c 1000 -T 20 -F 127.0.0.1:8001/?s=1k/t=20

                           before   after  change   note
  tasklet_wakeup:           3        1      -66%
  h1_io_cb:                 4        3      -25%
  h1_send:                  6.7      5.4    -19%
  h1_wake:                  0.73     0.44   -39%
  h1_process:               4.7      3.4    -27%
  h1_wake_stream_for_send:  6.7      5.5    -18%
  si_cs_process             3.7      3.4     -7.8%
  conn_fd_handler           2.7      2.4    -10%
  raw_sock_to_buf:          4        2      -50%
  pool_free:                4        2      -50%    from failed rx calls

Note that the situation could be further improved by having muxes lazily
subscribe to Rx events in case the FD is already being polled. However
this requires deeper changes to implement a LAZY_RECV subscribe mode,
and to replace the FD's active bit by 3 states representing the desired
action to perform on the FD during the update, among NONE (no need to
change), POLL (can't proceed without), and STOP (buffer full). This
would only impact Rx since on Tx we know what we have to send. The
savings to expect from this might be more visible with splicing and/or
when dealing with many connections having long think times.

5 years agoMEDIUM: connection: don't stop receiving events in the FD handler
Willy Tarreau [Fri, 28 Feb 2020 13:42:26 +0000 (14:42 +0100)] 
MEDIUM: connection: don't stop receiving events in the FD handler

The remaining epoll_ctl() calls are exclusively caused by the disagreement
between conn_fd_handler() and the mux receiving the data: the fd handler
wants to stop after having woken up the tasklet, then the mux after
receiving data wants to receive again. Given that they don't happen in
the same poll loop when there are many FDs, this causes a lot of state
changes.

As suggested by Olivier, if the task is already scheduled for running,
we don't need to disable the event because it's in the run queue, poll()
cannot stop, and reporting it again will be harmless. What *might*
happen however is that a sampling-based poller like epoll() would report
many times the same event and has trouble getting others behind. But if
it would happen, it would still indicate the run queue has plenty of
pending operations, so it would in fact only displace the problem from
the poller to the run queue, which doesn't seem to be worse (and in
fact we do support priorities while the poller does not).

By doing this change, the keep-alive test with 1k conns and 100k reqs
completely gets rid of the per-request epoll_ctl changes, while still
not causing extra recvfrom() :

  $ ./h1load -n 100000 -t 4 -c 1000 -T 20 -F 127.0.0.1:8001/?s=1k/t=20

  200000 sendto 1
  200000 recvfrom 1
   10762 epoll_wait 1
    3664 epoll_ctl 1
    1999 recvfrom -1

In close mode, it didn't change anything, we're still in the optimal
case (2 epoll per connection) :

  $ ./h1load -n 100000 -r 1 -t 4 -c 1000 -T 20 -F 127.0.0.1:8001/?s=1k/t=20

  203764 epoll_ctl 1
  200000 sendto 1
  200000 recvfrom 1
    6091 epoll_wait 1
    2994 recvfrom -1

5 years agoMEDIUM: connection: make the subscribe() call able to wakeup if ready
Willy Tarreau [Fri, 28 Feb 2020 13:24:49 +0000 (14:24 +0100)] 
MEDIUM: connection: make the subscribe() call able to wakeup if ready

There's currently an internal API limitation at the connection layer
regarding conn_subscribe(). We must not subscribe if we haven't yet
met EAGAIN or such a condition, so we sometimes force ourselves to read
in order to meet this condition and being allowed to call subscribe.
But reading cannot always be done (e.g. at the end of a loop where we
cannot afford to retrieve new data and start again) so we instead
perform a tasklet_wakeup() of the requester's io_cb. This is what is
done in mux_h1 for example. The problem with this is that it forces
a new receive when we're not necessarily certain we need one. And if
the FD is not ready and was already being polled, it's a useless
wakeup.

The current patch improves the connection-level subscribe() so that
it really manipulates the polling if the FD is marked not-ready, but
instead schedules the argument tasklet for a wakeup if the FD is
ready. This guarantees we'll wake this tasklet up in any case once the
FD is ready, either immediately or after polling.

By doing so, a test on pure close mode shows we cut in half the number
of epoll_ctl() calls and almost eliminate failed recvfrom():

  $ ./h1load -n 100000 -r 1 -t 4 -c 1000 -T 20 -F 127.0.0.1:8001/?s=1k/t=20

  before:
   399464 epoll_ctl 1
   200007 recvfrom 1
   200000 sendto 1
   100000 recvfrom -1
     7508 epoll_wait 1

  after:
   205739 epoll_ctl 1
   200000 sendto 1
   200000 recvfrom 1
     6084 epoll_wait 1
     2651 recvfrom -1

On keep-alive there is no change however.

5 years agoMINOR: rawsock: always mark the FD not ready when we're certain it happens
Willy Tarreau [Fri, 28 Feb 2020 13:09:12 +0000 (14:09 +0100)] 
MINOR: rawsock: always mark the FD not ready when we're certain it happens

This partially reverts commit 1113116b4a ("MEDIUM: raw-sock: remove
obsolete calls to fd_{cant,cond,done}_{send,recv}") so that we can mark
the FD not ready as required since commit 19bc201c9f ("MEDIUM: connection:
remove the intermediary polling state from the connection"). Indeed, with
the removal of the latter we don't have any other reliable indication that
the FD is blocked, which explains why there are so many EAGAIN in traces.

It's worth noting that a short read or a short write are also reliable
indicators of exhausted buffers and are even documented as such in the
epoll man page in case of edge-triggered mode. That's why we also report
the FD as blocked in such a case.

With this change we completely got rid of EAGAIN in keep-alive tests, but
they were expectedly transferred to epoll_ctl:

  $ ./h1load -n 100000 -t 4 -c 1000 -T 20 -F 127.0.0.1:8001/?s=1k/t=20

  before:
   266331 epoll_ctl 1
   200000 sendto 1
   200000 recvfrom 1
   135757 recvfrom -1
     8626 epoll_wait 1

  after:
   394865 epoll_ctl 1
   200000 sendto 1
   200000 recvfrom 1
    10748 epoll_wait 1
     1999 recvfrom -1

5 years agoMINOR: mux-h1: Remove useless case-insensitive comparisons
Christopher Faulet [Fri, 28 Feb 2020 09:42:20 +0000 (10:42 +0100)] 
MINOR: mux-h1: Remove useless case-insensitive comparisons

Header names from an HTX message are always in lower-case, so the comparison may
be case-sensitive.

5 years agoBUG/MINOR: http-htx: Do case-insensive comparisons on Host header name
Christopher Faulet [Fri, 28 Feb 2020 08:47:07 +0000 (09:47 +0100)] 
BUG/MINOR: http-htx: Do case-insensive comparisons on Host header name

When a header is added or modified, in http_add_header() or
http_replace_header(), a comparison is performed on its name to know if it is
the Host header and if the authority part of the uri must be updated or
not. This comparision must be case-insensive.

This patch should fix the issue #522. It must be backported to 2.1.

5 years agoMINOR: contrib/prometheus-exporter: Add the last heathcheck duration metric
Christopher Faulet [Thu, 27 Feb 2020 15:12:07 +0000 (16:12 +0100)] 
MINOR: contrib/prometheus-exporter: Add the last heathcheck duration metric

ST_F_CHECK_DURATION is now part of exported server metrics, named
haproxy_server_check_duration_seconds and expressed in seconds. For a given
server, this value is exported only if the healthcheck is finished (the status
is greater or equal to HCHK_STATUS_CHECKED).

This patch fixes the issue #519. It may be backported as fat as 2.0.

5 years agoBUG/MINOR: dns: ignore trailing dot
Lukas Tribus [Thu, 27 Feb 2020 14:47:24 +0000 (15:47 +0100)] 
BUG/MINOR: dns: ignore trailing dot

As per issue #435 a hostname with a trailing dot confuses our DNS code,
as for a zero length DNS label we emit a null-byte. This change makes us
ignore the zero length label instead.

Must be backported to 1.8.

5 years agoMINOR: fd: merge the read and write error bits into RW error
Willy Tarreau [Wed, 26 Feb 2020 15:12:45 +0000 (16:12 +0100)] 
MINOR: fd: merge the read and write error bits into RW error

We always set them both, which makes sense since errors at the FD level
indicate a terminal condition for the socket that cannot be recovered.
Usually this is detected via a write error, but sometimes such an error
may asynchronously be reported on the read side. Let's simplify this
using only the write bit and calling it RW since it's used like this
everywhere, and leave the R bit spare for future use.

5 years agoCLEANUP: fd: remove some unneeded definitions of FD_EV_* flags
Willy Tarreau [Fri, 21 Feb 2020 15:26:19 +0000 (16:26 +0100)] 
CLEANUP: fd: remove some unneeded definitions of FD_EV_* flags

There's no point in trying to be too generic for these flags as the
read and write sides will soon differ a bit. Better explicitly define
the flags for each direction without trying to be direction-agnostic.
this clarifies the code and removes some defines.

5 years agoCLEANUP: fd: remove the FD_EV_STATUS aggregate
Willy Tarreau [Fri, 21 Feb 2020 13:25:34 +0000 (14:25 +0100)] 
CLEANUP: fd: remove the FD_EV_STATUS aggregate

This was used only by fd_recv_state() and fd_send_state(), both of
which are unused. This will not work anymore once recv and send flags
start to differ, so let's remove this.

5 years agoBUG/MINOR: http_ana: make sure redirect flags don't have overlapping bits
Jerome Magnin [Thu, 27 Feb 2020 22:36:56 +0000 (23:36 +0100)] 
BUG/MINOR: http_ana: make sure redirect flags don't have overlapping bits

commit c87e46881 ("MINOR: http-rules: Add a flag on redirect rules to know the
rule direction") introduced a new flag for redirect rules, but its value has
bits in common with REDIRECT_FLAG_DROP_QS, which makes us enter this code path
in http_apply_redirect_rule(), which will then drop the query string.
To fix this, just give REDIRECT_FLAG_FROM_REQ its own unique value.

This must be backported where c87e46881687b8ddb9b3f459e60edb1e8d7c5d7c is backported.

This should fix issue 521.

5 years agoBUILD: cirrus-ci: suppress OS version check when installing packages
Ilya Shipitsin [Wed, 26 Feb 2020 14:29:36 +0000 (19:29 +0500)] 
BUILD: cirrus-ci: suppress OS version check when installing packages

since we run "snapshot" images of FreeBSD, it is possible that kernel
ABI version might change from time to time. It might differ from
prebuilt packages (installed via "pkg"). We do not test kernel modules,
so for us is safe to ignore ABI mismatch.

5 years agoBUG/MEDIUM: ssl: chain must be initialized with sk_X509_new_null()
William Lallemand [Thu, 27 Feb 2020 13:48:35 +0000 (14:48 +0100)] 
BUG/MEDIUM: ssl: chain must be initialized with sk_X509_new_null()

Even when there isn't a chain, it must be initialized to a empty X509
structure with sk_X509_new_null().

This patch fixes a segfault which appears with older versions of the SSL
libs (openssl 0.9.8, libressl 2.8.3...) because X509_chain_up_ref() does
not check the pointer.

This bug was introduced by b90d2cb ("MINOR: ssl: resolve issuers chain
later").

Should fix issue #516.

5 years agoBUG/MINOR: sample: Make sure to return stable IDs in the unique-id fetch
Tim Duesterhus [Wed, 26 Feb 2020 15:20:49 +0000 (16:20 +0100)] 
BUG/MINOR: sample: Make sure to return stable IDs in the unique-id fetch

Previously when the `unique-id-format` contained non-deterministic parts,
such as the `uuid` fetch each use of the `unique-id` fetch would generate
a new unique ID, replacing the old one. The following configuration shows
the error:

  global
        log stdout format short daemon

  listen test
        log global
        log-format "%ID"
        unique-id-format %{+X}o\ TEST-%[uuid]

        mode http
        bind *:8080
        http-response set-header A %[unique-id]
        http-response set-header B %[unique-id]
        server example example.com:80

Without the patch the contents of the `A` and `B` response header would
differ.

This bug was introduced in commit f4011ddcf5b41284d2b137e84c25f2d1264ce458,
which was first released with HAProxy 1.7-dev3.

This fix should be backported to HAProxy 1.7+.

5 years agoMINOR: epoll: always initialize all of epoll_event to please valgrind
Willy Tarreau [Wed, 26 Feb 2020 13:32:53 +0000 (14:32 +0100)] 
MINOR: epoll: always initialize all of epoll_event to please valgrind

valgrind complains that epoll_ctl() uses an epoll_event in which we
have only set the part we use from the data field (i.e. the fd). Tests
show that pre-initializing the struct in the stack doesn't have a
measurable impact so let's do it.

5 years agoMINOR: wdt: always clear sigev_value to make valgrind happy
Willy Tarreau [Wed, 26 Feb 2020 13:03:05 +0000 (14:03 +0100)] 
MINOR: wdt: always clear sigev_value to make valgrind happy

In issue #471 it was reported that valgrind sometimes complains about
timer_create() being called with uninitialized bytes. These are in fact
the bits from sigev_value.sival_ptr that are not part of sival_int that
are tagged as such, as valgrind has no way to know we're using the int
instead of the ptr in the union. It's cheap to initialize the field so
let's do it.

5 years agoBUG/MINOR: h2: reject again empty :path pseudo-headers
Willy Tarreau [Wed, 26 Feb 2020 12:51:38 +0000 (13:51 +0100)] 
BUG/MINOR: h2: reject again empty :path pseudo-headers

Since commit 92919f7fd5 ("MEDIUM: h2: make the request parser rebuild
a complete URI") we make sure to rebuild a complete URI. Unfortunately
the test for an empty :path pseudo-header that is mandated by #8.1.2.3
appened to be performed on the URI before this patch, which is never
empty anymore after being rebuilt, causing h2spec to complain :

  8. HTTP Message Exchanges
    8.1. HTTP Request/Response Exchange
      8.1.2. HTTP Header Fields
        8.1.2.3. Request Pseudo-Header Fields
          - 1: Sends a HEADERS frame with empty ":path" pseudo-header field
            -> The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
               Expected: GOAWAY Frame (Error Code: PROTOCOL_ERROR)
                         RST_STREAM Frame (Error Code: PROTOCOL_ERROR)
                         Connection closed
                 Actual: DATA Frame (length:0, flags:0x01, stream_id:1)

It's worth noting that this error doesn't trigger when calling h2spec
with a timeout as some scripts do, which explains why it wasn't detected
after the patch above.

This fixes one half of issue #471 and should be backported to 2.1.

5 years agoMINOR: ssl/cli: "show ssl cert" command should print the "Chain Filename:"
Emmanuel Hocdet [Tue, 18 Feb 2020 15:06:14 +0000 (16:06 +0100)] 
MINOR: ssl/cli: "show ssl cert" command should print the "Chain Filename:"

When the issuers chain of a certificate is picked from
the "issuers-chain-path" tree, "ssl show cert" prints it.

5 years agoMINOR: ssl: resolve ocsp_issuer later
Emmanuel Hocdet [Tue, 18 Feb 2020 14:56:39 +0000 (15:56 +0100)] 
MINOR: ssl: resolve ocsp_issuer later

The goal is to use the ckch to store data from PEM files or <payload> and
only for that. This patch adresses the ckch->ocsp_issuer case. It finds
issuers chain if no chain is present in the ckch in ssl_sock_put_ckch_into_ctx(),
filling the ocsp_issuer from the chain must be done after.
It changes the way '.issuer' is managed: it tries to load '.issuer' in
ckch->ocsp_issuer first and then look for the issuer in the chain later
(in ssl_sock_load_ocsp() ). "ssl-load-extra-files" without the "issuer"
parameter can negate extra '.issuer' file check.

5 years agoMINOR: ssl: resolve issuers chain later
Emmanuel Hocdet [Tue, 18 Feb 2020 14:27:32 +0000 (15:27 +0100)] 
MINOR: ssl: resolve issuers chain later

The goal is to use the ckch to store data from a loaded PEM file or a
<payload> and only for that. This patch addresses the ckch->chain case.
Looking for the issuers chain, if no chain is present in the ckch, can
be done in ssl_sock_put_ckch_into_ctx(). This way it is possible to know
the origin of the certificate chain without an extra state.

5 years agoMINOR: ssl: move find certificate chain code to its own function
Emmanuel Hocdet [Tue, 18 Feb 2020 14:19:24 +0000 (15:19 +0100)] 
MINOR: ssl: move find certificate chain code to its own function

New function ssl_get_issuer_chain(cert) to find an issuer_chain entry
from "issers-chain-path" tree.

5 years agoMEDIUM: buffer: remove the buffer_wq lock
Willy Tarreau [Wed, 26 Feb 2020 09:39:36 +0000 (10:39 +0100)] 
MEDIUM: buffer: remove the buffer_wq lock

This lock was only needed to protect the buffer_wq list, but now we have
the mt_list for this. This patch simply turns the buffer_wq list to an
mt_list and gets rid of the lock.

It's worth noting that the whole buffer_wait thing still looks totally
wrong especially in a threaded context: the wakeup_cb() callback is
called synchronously from any thread and may end up calling some
connection code that was not expected to run on a given thread. The
whole thing should probably be reworked to use tasklets instead and be
a bit more centralized.

5 years ago[RELEASE] Released version 2.2-dev3 v2.2-dev3
Willy Tarreau [Tue, 25 Feb 2020 17:14:02 +0000 (18:14 +0100)] 
[RELEASE] Released version 2.2-dev3

Released version 2.2-dev3 with the following main changes :
    - SCRIPTS: announce-release: place the send command in the mail's header
    - SCRIPTS: announce-release: allow the user to force to overwrite old files
    - SCRIPTS: backport: fix the master branch detection
    - BUG/MINOR: http-act: Set stream error flag before returning an error
    - BUG/MINOR: http-act: Fix bugs on error path during parsing of return actions
    - BUG/MEDIUM: ssl/cli: 'commit ssl cert' wrong SSL_CTX init
    - BUG/MEDIUM: tcp-rules: Fix track-sc* actions for L4/L5 TCP rules
    - DOC: schematic of the SSL certificates architecture
    - BUG/MAJOR: mux-h2: don't wake streams after connection was destroyed
    - BUG/MINOR: unix: better catch situations where the unix socket path length is close to the limit
    - BUILD: cirrus-ci: switch to "snap" images to unify openssl naming
    - BUILD: cirrus-ci: workaround "pkg install" bug
    - BUILD: cirrus-ci: add ERR=1 to freebsd builds
    - BUG/MINOR: connection: correctly retry I/O on signals
    - CLEANUP: mini-clist: simplify nested do { while(1) {} } while (0)
    - BUILD: http_act: cast file sizes when reporting file size error
    - BUG/MEDIUM: listener: only consider running threads when resuming listeners
    - BUG/MINOR: listener: enforce all_threads_mask on bind_thread on init
    - BUG/MINOR: tcp: avoid closing fd when socket failed in tcp_bind_listener
    - MINOR: build: add aix72-gcc build TARGET and power{8,9} CPUs
    - BUILD: travis-ci: no more allowed failures for openssl-1.0.2
    - BUILD: travis-ci: harden builds, add ERR=1 (warning ought to be errors)
    - BUILD: scripts/build-ssl.sh: use "uname" instead of ${TRAVIS_OS_NAME}
    - BUG/MINOR: tcp: don't try to set defaultmss when value is negative
    - SCRIPTS: make announce-release executable again
    - BUG/MINOR: namespace: avoid closing fd when socket failed in my_socketat
    - BUG/MEDIUM: muxes: Use the right argument when calling the destroy method.
    - BUG/MINOR: mux-fcgi: Forbid special characters when matching PATH_INFO param
    - CLEANUP: ssl: remove unused functions in openssl-compat.h
    - MINOR: mux-fcgi: Make the capture of the path-info optional in pathinfo regex
    - MINOR: tools: add is_idchar() to tell if a char may belong to an identifier
    - MINOR: chunk: implement chunk_strncpy() to copy partial strings
    - MINOR: sample/acl: use is_idchar() to locate the fetch/conv name
    - MEDIUM: arg: make make_arg_list() stop after its own arguments
    - MEDIUM: arg: copy parsed arguments into the trash instead of allocating them
    - MEDIUM: arg: make make_arg_list() support quotes in arguments
    - MINOR: sample: make sample_parse_expr() able to return an end pointer
    - MEDIUM: log-format: make the LF parser aware of sample expressions' end
    - BUG/MINOR: arg: report an error if an argument is larger than bufsize
    - SCRIPTS: announce-release: use mutt -H instead of -i to include the draft
    - BUILD: enable ERR=1 in github cygwin builds
    - BUG/MINOR: arg: fix again incorrect argument length check
    - MINOR: sample: regsub now supports backreferences
    - BUG/MINOR: tools: also accept '+' as a valid character in an identifier
    - MINOR: http-htx: Add a function to retrieve the headers size of an HTX message
    - MINOR: filters: Forward data only if the last filter forwards something
    - BUG/MINOR: filters: Count HTTP headers as filtered data but don't forward them
    - BUG/MINOR: http-htx: Don't return error if authority is updated without changes
    - BUG/MINOR: stream: Don't incr frontend cum_req counter when stream is closed
    - BUG/MINOR: sample: exit regsub() in case of trash allocation error
    - MINOR: ssl: add "issuers-chain-path" directive.
    - REGTESTS: use "command -v" instead of "which"
    - BUG/MINOR: http-ana: Matching on monitor-uri should be case-sensitive
    - MINOR: http-ana: Match on the path if the monitor-uri starts by a /
    - BUG/MINOR: ssl: Stop passing dynamic strings as format arguments
    - BUG/MAJOR: http-ana: Always abort the request when a tarpit is triggered
    - BUG/MINOR: mux: do not call conn_xprt_stop_recv() on buffer shortage
    - MINOR: checks: do not call conn_xprt_stop_send() anymore
    - CLEANUP: epoll: place the struct epoll_event in the stack
    - MEDIUM: connection: remove the intermediary polling state from the connection
    - MINOR: raw_sock: directly call fd_stop_send() and not conn_xprt_stop_send()
    - MINOR: tcp/uxst/sockpair: use fd_want_send() instead of conn_xprt_want_send()
    - MINOR: connection: remove the last calls to conn_xprt_{want,stop}_*
    - CLEANUP: connection: remove the definitions of conn_xprt_{stop,want}_{send,recv}
    - MINOR: connection: introduce a new receive flag: CO_RFL_READ_ONCE
    - MINOR: mux-h1: pass CO_RFL_READ_ONCE to the lower layers when relevant
    - MINOR: ist: add an iststop() function
    - BUG/MINOR: http: http-request replace-path duplicates the query string
    - CLEANUP: sample: use iststop instead of a for loop
    - BUG/MEDIUM: shctx: make sure to keep all blocks aligned
    - MINOR: compiler: move CPU capabilities definition from config.h and complete them
    - BUG/MEDIUM: ebtree: don't set attribute packed without unaligned access support
    - CLEANUP: http/h1: rely on HA_UNALIGNED_LE instead of checking for CPU families
    - BUILD: fix recent build failure on unaligned archs
    - MINOR: ssl: load the key from a dedicated file
    - BUG/MINOR: ssl: load .key in a directory only after PEM
    - MINOR: compiler: drop special cases of likely/unlikely for older compilers
    - CLEANUP: conn: Do not pass a pointer to likely
    - CLEANUP: net_helper: Do not negate the result of unlikely
    - BUILD: remove obsolete support for -mregparm / USE_REGPARM
    - CLEANUP: cfgparse: Fix type of second calloc() parameter
    - BUILD: ssl: only pass unsigned chars to isspace()
    - BUILD: general: always pass unsigned chars to is* functions
    - BUG/MINOR: sample: fix the json converter's endian-sensitivity
    - BUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions
    - CLEANUP: fd: use a union in fd_rm_from_fd_list() to shut aliasing warnings
    - CLEANUP: cache: use read_u32/write_u32 to access the cache entry's hash
    - CLEANUP: stick-tables: use read_u32() to display a node's key
    - CLEANUP: sample: use read_u64() in ipmask() to apply an IPv6 mask
    - MINOR: pattern: fix all remaining strict aliasing issues
    - CLEANUP: lua: fix aliasing issues in the address matching code
    - CLEANUP: connection: use read_u32() instead of a cast in the netscaler parser
    - BUILD: makefile: re-enable strict aliasing
    - BUG/MINOR: connection: make sure to correctly tag local PROXY connections
    - MINOR: compiler: add new alignment macros
    - BUILD: ebtree: improve architecture-specific alignment
    - MINOR: config: mark global.debug as deprecated
    - BUILD: travis-ci: enable s390x builds
    - MINOR: ssl/cli: 'show ssl cert' displays the chain
    - MINOR: ssl/cli: 'show ssl cert'displays the issuer in the chain
    - MINOR: ssl/cli: reorder 'show ssl cert' output
    - CLEANUP: ssl: move issuer_chain tree and definition
    - DOC: proxy-protocol: clarify IPv6 address representation in the spec

5 years agoDOC: proxy-protocol: clarify IPv6 address representation in the spec
Willy Tarreau [Tue, 25 Feb 2020 17:04:39 +0000 (18:04 +0100)] 
DOC: proxy-protocol: clarify IPv6 address representation in the spec

Daniel Barclay reported that the wording around "IPv6 addresses must be
indicated as series of 4 hex digits" is confusing and can be interpreted
two ways (only 4 digits or series of sets of 4 digits), so let's adjust
the wording to resolve this ambiguity.

5 years agoCLEANUP: ssl: move issuer_chain tree and definition
William Lallemand [Tue, 25 Feb 2020 13:53:06 +0000 (14:53 +0100)] 
CLEANUP: ssl: move issuer_chain tree and definition

Move the cert_issuer_tree outside the global_ssl structure since it's
not a configuration variable. And move the declaration of the
issuer_chain structure in types/ssl_sock.h

5 years agoMINOR: ssl/cli: reorder 'show ssl cert' output
William Lallemand [Tue, 25 Feb 2020 13:07:58 +0000 (14:07 +0100)] 
MINOR: ssl/cli: reorder 'show ssl cert' output

Reorder the 'show ssl cert' output so it's easier to see if the whole
chain is correct.

For a chain to be correct, an "Issuer" line must have the same
content as the next "Subject" line.

Example:

  Subject: /C=FR/ST=Paris/O=HAProxy Test Certificate/CN=test.haproxy.local
  Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Root CA/CN=root.haproxy.local

5 years agoMINOR: ssl/cli: 'show ssl cert'displays the issuer in the chain
William Lallemand [Tue, 25 Feb 2020 13:04:33 +0000 (14:04 +0100)] 
MINOR: ssl/cli: 'show ssl cert'displays the issuer in the chain

For each certificate in the chain, displays the issuer, so it's easy to
know if the chain is right.

Also rename "Chain" to "Chain Subject".

Example:

  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Root CA/CN=root.haproxy.local

5 years agoMINOR: ssl/cli: 'show ssl cert' displays the chain
William Lallemand [Tue, 25 Feb 2020 10:56:32 +0000 (11:56 +0100)] 
MINOR: ssl/cli: 'show ssl cert' displays the chain

Display the subject of each certificate contained in the chain in the
output of "show ssl cert <filename>".
Each subjects are on a unique line prefixed by "Chain: "

Example:

Chain: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
Chain: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local

5 years agoBUILD: travis-ci: enable s390x builds
Ilya Shipitsin [Wed, 19 Feb 2020 18:47:56 +0000 (23:47 +0500)] 
BUILD: travis-ci: enable s390x builds

reg-tests/seamless-reload/abns_socket.vtc is skipped due to #504

5 years agoMINOR: config: mark global.debug as deprecated
Willy Tarreau [Tue, 25 Feb 2020 10:27:22 +0000 (11:27 +0100)] 
MINOR: config: mark global.debug as deprecated

This directive has never made any sense and has already caused trouble
by forcing the process to stay in foreground during the boot process.
Let's emit a warning mentioning it's deprecated and will be removed in
2.3.

5 years agoBUILD: ebtree: improve architecture-specific alignment
Willy Tarreau [Sat, 22 Feb 2020 14:55:33 +0000 (15:55 +0100)] 
BUILD: ebtree: improve architecture-specific alignment

Commit 2c315ee75e ("BUG/MEDIUM: ebtree: don't set attribute packed
without unaligned access support") addressed alignment issues in
ebtrees in a way that is not really optimal since it will leave holes
in eb32trees for example.

This fix is better in that it restores the packed attribute on ebnode
but enforces proper alignment on the carrying nodes where necessary.
This also has the benefit of closing holes wherever possible and to
align data to the minimally required size.

The only thing it cannot close is the 32-bit hole at the end of ebmbnode
due to the required 64-bit on certain archs but at least it guarantees
that the key correctly points to the end of the node and that there is
never a hole after it.

This is a better fix than the one above and should be backported to
branches where the one above will be backported.

5 years agoMINOR: compiler: add new alignment macros
Willy Tarreau [Sat, 22 Feb 2020 14:51:39 +0000 (15:51 +0100)] 
MINOR: compiler: add new alignment macros

This commit adds ALWAYS_ALIGN(), MAYBE_ALIGN() and ATOMIC_ALIGN() to
be placed as delimitors inside structures to force alignment to a
given size. These depend on the architecture's capabilities so that
it is possible to always align, align only on archs not supporting
unaligned accesses at all, or only on those not supporting them for
atomic accesses (e.g. before a lock).

5 years agoBUG/MINOR: connection: make sure to correctly tag local PROXY connections
Willy Tarreau [Wed, 19 Feb 2020 14:10:00 +0000 (15:10 +0100)] 
BUG/MINOR: connection: make sure to correctly tag local PROXY connections

As reported in issue #511, when sending an outgoing local connection
(e.g. health check) we must set the "local" tag and not a "proxy" tag.
The issue comes from historic support on v1 which required to steal the
address on the outgoing connection for such ones, creating confusion in
the v2 code which believes it sees the incoming connection.

In order not to risk to break existing setups which might rely on seeing
the LB's address in the connection's source field, let's just change the
connection type from proxy to local and keep the addresses. The protocol
spec states that for local, the addresses must be ignored anyway.

This problem has always existed, this can be backported as far as 1.5,
though it's probably not a good idea to change such setups, thus maybe
2.0 would be more reasonable.

5 years agoBUILD: makefile: re-enable strict aliasing
Willy Tarreau [Tue, 25 Feb 2020 09:10:47 +0000 (10:10 +0100)] 
BUILD: makefile: re-enable strict aliasing

For a very long time we've used to build without strict aliasing due to
very few places in the stick-tables code mostly, that initially we didn't
know how to deal with. The problem of doing this is that it encourages
to write possibly incorrect code such as the few SSL sample fetch functions
that were recently fixed.

All places causing aliasing errors on x86_64, i586, armv8, armv7 and
mips were fixed so it's about time to re-enable the warning hoping to
catch such errors early in the development cycle. As a bonus, this
removed about 5kB of code.

5 years agoCLEANUP: connection: use read_u32() instead of a cast in the netscaler parser
Willy Tarreau [Tue, 25 Feb 2020 09:06:49 +0000 (10:06 +0100)] 
CLEANUP: connection: use read_u32() instead of a cast in the netscaler parser

The netscaler protocol parser used to involve a few casts from char to
(uint32_t*), let's properly use u32 for this instead.

5 years agoCLEANUP: lua: fix aliasing issues in the address matching code
Willy Tarreau [Tue, 25 Feb 2020 09:02:51 +0000 (10:02 +0100)] 
CLEANUP: lua: fix aliasing issues in the address matching code

Just use read_u32() instead of casting IPv6 addresses to uint32_t*.

5 years agoMINOR: pattern: fix all remaining strict aliasing issues
Willy Tarreau [Tue, 25 Feb 2020 08:58:41 +0000 (09:58 +0100)] 
MINOR: pattern: fix all remaining strict aliasing issues

There were still a number of struct casts from various sizes. All of
them were now replaced with read_u32(), read_u16(), read_u64() or
memcpy().

5 years agoCLEANUP: sample: use read_u64() in ipmask() to apply an IPv6 mask
Willy Tarreau [Tue, 25 Feb 2020 08:43:22 +0000 (09:43 +0100)] 
CLEANUP: sample: use read_u64() in ipmask() to apply an IPv6 mask

There were 8 strict aliasing warnings there due to the dereferences
casting to uint32_t of input and output. We can achieve the same using
two write_u64() and four read_u64() which do not cause this issue and
even let the compiler use 64-bit operations.

5 years agoCLEANUP: stick-tables: use read_u32() to display a node's key
Willy Tarreau [Tue, 25 Feb 2020 08:41:22 +0000 (09:41 +0100)] 
CLEANUP: stick-tables: use read_u32() to display a node's key

This fixes another aliasing issue that pops up in stick_table.c
and peers.c's debug code.

5 years agoCLEANUP: cache: use read_u32/write_u32 to access the cache entry's hash
Willy Tarreau [Tue, 25 Feb 2020 08:35:07 +0000 (09:35 +0100)] 
CLEANUP: cache: use read_u32/write_u32 to access the cache entry's hash

Enabling strict aliasing fails on the cache's hash which is a series of
20 bytes cast as u32. And in practice it could even fail on some archs
if the http_txn didn't guarantee the hash was properly aligned. Let's
use read_u32() to read the value and write_u32() to set it, this makes
sure the compiler emits the correct code to access these and knows about
the intentional aliasing.

5 years agoCLEANUP: fd: use a union in fd_rm_from_fd_list() to shut aliasing warnings
Willy Tarreau [Tue, 25 Feb 2020 08:25:53 +0000 (09:25 +0100)] 
CLEANUP: fd: use a union in fd_rm_from_fd_list() to shut aliasing warnings

Enabling strict aliasing fails in fd.c when using the double-word CAS,
let's get rid of the (void**)(void*)&cur_list junk and use a union
instead. This way the compiler knows they do alias.

5 years agoBUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions
Willy Tarreau [Tue, 25 Feb 2020 07:59:23 +0000 (08:59 +0100)] 
BUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions

Sample fetch functions ssl_x_sha1(), ssl_fc_npn(), ssl_fc_alpn(),
ssl_fc_session_id(), as well as the CLI's "show cert details" handler
used to dereference the output buffer's <data> field by casting it to
"unsigned *". But while doing this could work before 1.9, it broke
starting with commit 843b7cbe9d ("MEDIUM: chunks: make the chunk struct's
fields match the buffer struct") which merged chunks and buffers, causing
the <data> field to become a size_t. The impact is only on 64-bit platform
and depends on the endianness: on little endian, there should never be any
non-zero bits in the field as it is supposed to have been zeroed before the
call, so it shouldbe harmless; on big endian, the high part of the value
only is written instead of the lower one, often making the result appear
4 billion times larger, and making such values dropped everywhere due to
being larger than a buffer.

It seems that it would be wise to try to re-enable strict-aliasing to
catch such errors.

This must be backported till 1.9.

5 years agoBUG/MINOR: sample: fix the json converter's endian-sensitivity
Willy Tarreau [Tue, 25 Feb 2020 07:37:37 +0000 (08:37 +0100)] 
BUG/MINOR: sample: fix the json converter's endian-sensitivity

About every time there's a pointer cast in the code, there's a hidden
bug, and this one was no exception, as it passes the first octet of the
native representation of an integer as a single-character string, which
obviously only works on little endian machines. On big-endian machines,
something as simple as "str(foo),json" only returns zeroes.

This bug was introduced with the JSON converter in 1.6-dev1 by commit
317e1c4f1e ("MINOR: sample: add "json" converter"), the fix may be
backported to all stable branches.

5 years agoBUILD: general: always pass unsigned chars to is* functions
Willy Tarreau [Tue, 25 Feb 2020 07:16:33 +0000 (08:16 +0100)] 
BUILD: general: always pass unsigned chars to is* functions

The isalnum(), isalpha(), isdigit() etc functions from ctype.h are
supposed to take an int in argument which must either reflect an
unsigned char or EOF. In practice on some platforms they're implemented
as macros referencing an array, and when passed a char, they either cause
a warning "array subscript has type 'char'" when lucky, or cause random
segfaults when unlucky. It's quite unconvenient by the way since none of
them may return true for negative values. The recent introduction of
cygwin to the list of regularly tested build platforms revealed a lot
of breakage there due to the same issues again.

So this patch addresses the problem all over the code at once. It adds
unsigned char casts to every valid use case, and also drops the unneeded
double cast to int that was sometimes added on top of it.

It may be backported by dropping irrelevant changes if that helps better
support uncommon platforms. It's unlikely to fix bugs on platforms which
would already not emit any warning though.

5 years agoBUILD: ssl: only pass unsigned chars to isspace()
Willy Tarreau [Tue, 25 Feb 2020 06:51:59 +0000 (07:51 +0100)] 
BUILD: ssl: only pass unsigned chars to isspace()

A build failure on cygwin was reported on github actions here:

  https://github.com/haproxy/haproxy/runs/466507874

It's caused by a signed char being passed to isspace(), and this one
being implemented as a macro instead of a function as the man page
suggests. It's the same issue that regularly pops up on Solaris. This
comes from commit 98263291cc3 which was merged in 1.8-dev1. A backport
is possible though not incredibly useful.

5 years agoCLEANUP: cfgparse: Fix type of second calloc() parameter
Tim Duesterhus [Sat, 22 Feb 2020 15:39:05 +0000 (16:39 +0100)] 
CLEANUP: cfgparse: Fix type of second calloc() parameter

`curr_idle_thr` is of type `unsigned int`, not `int`. Fix this issue by
taking the size of the dereferenced `curr_idle_thr` array.

This issue was introduced when adding the `curr_idle_thr` struct member
in commit f131481a0af79037bc6616edf450ae81d80084d7. This commit is first
tagged in 2.0-dev1 and marked for backport to 1.9.

5 years agoBUILD: remove obsolete support for -mregparm / USE_REGPARM
Willy Tarreau [Tue, 25 Feb 2020 06:38:05 +0000 (07:38 +0100)] 
BUILD: remove obsolete support for -mregparm / USE_REGPARM

This used to be a minor optimization on ix86 where registers are scarce
and the calling convention not very efficient, but this platform is not
relevant enough anymore to warrant all this dirt in the code for the sake
of saving 1 or 2% of performance. Modern platforms don't use this at all
since their calling convention already defaults to using several registers
so better get rid of this once for all.

5 years agoCLEANUP: net_helper: Do not negate the result of unlikely
Tim Duesterhus [Fri, 21 Feb 2020 12:02:04 +0000 (13:02 +0100)] 
CLEANUP: net_helper: Do not negate the result of unlikely

This patch turns the double negation of 'not unlikely' into 'likely'
and then turns the negation of 'not smaller' into 'greater or equal'
in an attempt to improve readability of the condition.

[wt: this was not a bug but purposely written like this to improve code
 generation on older compilers but not needed anymore as described here:
 https://www.mail-archive.com/haproxy@formilux.org/msg36392.html ]

5 years agoCLEANUP: conn: Do not pass a pointer to likely
Tim Duesterhus [Fri, 21 Feb 2020 12:02:03 +0000 (13:02 +0100)] 
CLEANUP: conn: Do not pass a pointer to likely

Move the `!` inside the likely and negate it to unlikely.

The previous version should not have caused issues, because it is converted
to a boolean / integral value before being passed to __builtin_expect(), but
it's certainly unusual.

[wt: this was not a bug but purposely written like this to improve code
 generation on older compilers but not needed anymore as described here:
 https://www.mail-archive.com/haproxy@formilux.org/msg36392.html ]

5 years agoMINOR: compiler: drop special cases of likely/unlikely for older compilers
Willy Tarreau [Tue, 25 Feb 2020 06:14:43 +0000 (07:14 +0100)] 
MINOR: compiler: drop special cases of likely/unlikely for older compilers

We used to special-case the likely()/unlikely() macros for a series of
early gcc 4.x compilers which used to produce very bad code when using
__builtin_expect(x,1), which basically used to build an integer (0 or 1)
from a condition then compare it to integer 1. This was already fixed in
5.x, but even now, looking at the code produced by various flavors of 4.x
this bad behavior couldn't be witnessed anymore. So let's consider it as
fixed by now, which will allow to get rid of some ugly tricks at some
specific places. A test on 4.7.4 shows that the code shrinks by about 3kB
now, thanks to some tests being inlined closer to the call place and the
unlikely case being moved to real functions. See the link below for more
background on this.

Link: https://www.mail-archive.com/haproxy@formilux.org/msg36392.html
5 years agoBUG/MINOR: ssl: load .key in a directory only after PEM
William Lallemand [Mon, 24 Feb 2020 15:30:12 +0000 (16:30 +0100)] 
BUG/MINOR: ssl: load .key in a directory only after PEM

Don't try to load a .key in a directory without loading its associated
certificate file.

This patch ignores the .key files when iterating over the files in a
directory.

Introduced by 4c5adbf ("MINOR: ssl: load the key from a dedicated
file").

5 years agoMINOR: ssl: load the key from a dedicated file
William Lallemand [Mon, 24 Feb 2020 13:23:22 +0000 (14:23 +0100)] 
MINOR: ssl: load the key from a dedicated file

For a certificate on a bind line, if the private key was not found in
the PEM file, look for a .key and load it.

This default behavior can be changed by using the ssl-load-extra-files
directive in the global section

This feature was mentionned in the issue #221.

5 years agoBUILD: fix recent build failure on unaligned archs
Willy Tarreau [Fri, 21 Feb 2020 16:40:25 +0000 (17:40 +0100)] 
BUILD: fix recent build failure on unaligned archs

Last commit 2c315ee ("BUG/MEDIUM: ebtree: don't set attribute packed
without unaligned access support") accidently enclosed the semicolon
in the ifdef so it will fail when HA_UNALIGNED is not set.

5 years agoCLEANUP: http/h1: rely on HA_UNALIGNED_LE instead of checking for CPU families
Willy Tarreau [Fri, 21 Feb 2020 15:31:22 +0000 (16:31 +0100)] 
CLEANUP: http/h1: rely on HA_UNALIGNED_LE instead of checking for CPU families

Now that we have flags indicating the CPU's capabilities, better use
them instead of missing some updates for new CPU families (ARMv8 was
missing there).

5 years agoBUG/MEDIUM: ebtree: don't set attribute packed without unaligned access support
Willy Tarreau [Fri, 21 Feb 2020 14:47:36 +0000 (15:47 +0100)] 
BUG/MEDIUM: ebtree: don't set attribute packed without unaligned access support

An alignment issue on Sparc64 with ebtrees was reported in early 2017
here https://www.mail-archive.com/haproxy@formilux.org/msg25937.html and
a similar one was finally reported in issue #512.

The problem has its roots in the fact that 64-bit keys will end up being
unaligned on such archs which do not support unaligned accesses. But on
most platforms supporting unaligned accesses, dealing with smaller nodes
results in better performance.

One of the possible problems caused by attribute packed there is that it
promotes a structure both to be unaligned and unpadded, which may come
with fun if some fields of the struct itself are accessed and such a node
is placed at an unaligned location. It's not a problem for regular unaligned
accesses but may become one for atomic operations such as the CAS on leaf_p
that's used in struct task. In practice we know that this struct is properly
aligned and is a very edge case so this patch adds comments there to remind
to be careful about it.

This patch depends on previous patch "MINOR: compiler: move CPU capabilities
definition from config.h and complete them" and could be backported to all
stable branches. It fixes issues #512 and #9.

5 years agoMINOR: compiler: move CPU capabilities definition from config.h and complete them
Willy Tarreau [Fri, 21 Feb 2020 14:40:58 +0000 (15:40 +0100)] 
MINOR: compiler: move CPU capabilities definition from config.h and complete them

These ones are irrelevant to the config but rather to the platform, and
as such are better placed in compiler.h.

Here we take the opportunity for declaring a few extra capabilities:
 - HA_UNALIGNED         : CPU supports unaligned accesses
 - HA_UNALIGNED_LE      : CPU supports unaligned accesses in little endian
 - HA_UNALIGNED_FAST    : CPU supports fast unaligned accesses
 - HA_UNALIGNED_ATOMIC  : CPU supports unaligned accesses in atomics

This will help remove a number of #ifdefs with arch-specific statements.

5 years agoBUG/MEDIUM: shctx: make sure to keep all blocks aligned
Willy Tarreau [Fri, 21 Feb 2020 12:45:58 +0000 (13:45 +0100)] 
BUG/MEDIUM: shctx: make sure to keep all blocks aligned

The blocksize and the extra field are not necessarily aligned on a
machine word. This can result in crashing an align-sensitive machine
when initializing the shctx area. Let's round both sizes up to a pointer
size to make this safe everywhere.

This fixes issue #512. This should be backported as far as 1.8.

5 years agoCLEANUP: sample: use iststop instead of a for loop
Jerome Magnin [Fri, 21 Feb 2020 09:49:12 +0000 (10:49 +0100)] 
CLEANUP: sample: use iststop instead of a for loop

In sample_fetch_path we can use iststop() instead of a for loop
to find the '?' and return the correct length. This requires commit
"MINOR: ist: add an iststop() function".

5 years agoBUG/MINOR: http: http-request replace-path duplicates the query string
Jerome Magnin [Fri, 21 Feb 2020 09:37:48 +0000 (10:37 +0100)] 
BUG/MINOR: http: http-request replace-path duplicates the query string

In http_action_replace_uri() we call http_get_path() in the case of
a replace-path rule. http_get_path() will return an ist pointing to
the start of the path, but uri.ptr + uri.len points to the end of the
uri. As as result, we are matching against a string containing the
query, which we append to the "path" later, effectively duplicating
the query string.

This patch uses the iststop() function introduced in "MINOR: ist: add
an iststop() function" to find the '?' character and update the ist
length when needed.

This fixes issue #510.

The bug was introduced by commit 262c3f1a ("MINOR: http: add a new
"replace-path" action"), which was backported to 2.1 and 2.0.

5 years agoMINOR: ist: add an iststop() function
Jerome Magnin [Fri, 21 Feb 2020 09:33:12 +0000 (10:33 +0100)] 
MINOR: ist: add an iststop() function

Add a function that finds a character in an ist and returns an
updated ist with the length of the portion of the original string
that doesn't contain the char.

Might be backported to 2.1

5 years agoMINOR: mux-h1: pass CO_RFL_READ_ONCE to the lower layers when relevant
Willy Tarreau [Thu, 20 Feb 2020 10:11:50 +0000 (11:11 +0100)] 
MINOR: mux-h1: pass CO_RFL_READ_ONCE to the lower layers when relevant

When we're in H1_MSG_RQBEFORE or H1_MSG_RPBEFORE, we know that the
first message is highly likely the only one and that it's pointless
to try to perform a second recvfrom() to complete a first partial
read. This is similar to what used to be done in the older I/O methods
with the CF_READ_DONTWAIT flag on the channel. So let's pass
CO_RFL_READ_ONCE to the transport layer during rcv_buf() in this case.

By doing so, in a test involving keep-alive connections with a non-null
client think time, we remove 20% of the recvfrom() calls, all of which
used to systematically fail. More precisely, we observe a drop from 5.0
recvfrom() per request with 60% failure to 4.0 per request with 50%
failure.

5 years agoMINOR: connection: introduce a new receive flag: CO_RFL_READ_ONCE
Willy Tarreau [Thu, 20 Feb 2020 10:04:40 +0000 (11:04 +0100)] 
MINOR: connection: introduce a new receive flag: CO_RFL_READ_ONCE

This flag is currently supported by raw_sock to perform a single recv()
attempt and avoid subscribing. Typically on the request and response
paths with keep-alive, with short messages we know that it's very likely
that the first message is enough.

5 years agoCLEANUP: connection: remove the definitions of conn_xprt_{stop,want}_{send,recv}
Willy Tarreau [Fri, 21 Feb 2020 08:58:29 +0000 (09:58 +0100)] 
CLEANUP: connection: remove the definitions of conn_xprt_{stop,want}_{send,recv}

This marks the end of the transition from the connection polling states
introduced in 1.5-dev12 and the subscriptions in that arrived in 1.9.
The socket layer can now safely use its FD while all upper layers rely
exclusively on subscriptions. These old functions were removed. Some may
deserve some renaming to improved clarty though. The single call to
conn_xprt_stop_both() was dropped in favor of conn_cond_update_polling()
which already does the same.

5 years agoMINOR: connection: remove the last calls to conn_xprt_{want,stop}_*
Willy Tarreau [Fri, 21 Feb 2020 09:34:19 +0000 (10:34 +0100)] 
MINOR: connection: remove the last calls to conn_xprt_{want,stop}_*

The last few calls to conn_xprt_{want,stop}_{recv,send} in the central
connection code were replaced with their strictly exact equivalent fd_*,
adding the call to conn_ctrl_ready() when it was missing.

5 years agoMINOR: tcp/uxst/sockpair: use fd_want_send() instead of conn_xprt_want_send()
Willy Tarreau [Fri, 21 Feb 2020 09:24:51 +0000 (10:24 +0100)] 
MINOR: tcp/uxst/sockpair: use fd_want_send() instead of conn_xprt_want_send()

Just like previous commit, we don't need to pass through the connection
layer anymore to enable polling during a connect(), we know the FD, so
let's simply call fd_want_send().

5 years agoMINOR: raw_sock: directly call fd_stop_send() and not conn_xprt_stop_send()
Willy Tarreau [Fri, 21 Feb 2020 09:21:46 +0000 (10:21 +0100)] 
MINOR: raw_sock: directly call fd_stop_send() and not conn_xprt_stop_send()

Now that we know that the connection layer is transparent for polling
changes, we have no reason for hiding behind conn_xprt_stop_send() and
can safely call fd_stop_send() on the FD once the buffer is empty.

5 years agoMEDIUM: connection: remove the intermediary polling state from the connection
Willy Tarreau [Fri, 21 Feb 2020 07:46:19 +0000 (08:46 +0100)] 
MEDIUM: connection: remove the intermediary polling state from the connection

Historically we used to require that the connections held the desired
polling states for the data layer and the socket layer. Then with muxes
these were more or less merged into the transport layer, and now it
happens that with all transport layers having their own state, the
"transport layer state" as we have it in the connection (XPRT_RD_ENA,
XPRT_WR_ENA) is only an exact copy of the undelying file descriptor
state, but with a delay. All of this is causing some difficulties at
many places in the code because there are still some locations which
use the conn_want_* API to remain clean and only rely on connection,
and count on a later collection call to conn_cond_update_polling(),
while others need an immediate action and directly use the FD updates.

Since our updates are now much cheaper, most of them being only an
atomic test-and-set operation, and since our I/O callbacks are deferred,
there's no benefit anymore in trying to "cache" the transient state
change in the connection flags hoping to cancel them before they
become an FD event. Better make such calls transparent indirections
to the FD layer instead and get rid of the deferred operations which
needlessly complicate the logic inside.

This removes flags CO_FL_XPRT_{RD,WR}_ENA and CO_FL_WILL_UPDATE.
A number of functions related to polling updates were either greatly
simplified or removed.

Two places were using CO_FL_XPRT_WR_ENA as a hint to know if more data
were expected to be sent after a PROXY protocol or SOCKSv4 header. These
ones were simply replaced with a check on the subscription which is
where we ought to get the autoritative information from.

Now the __conn_xprt_want_* and their conn_xprt_want_* counterparts
are the same. conn_stop_polling() and conn_xprt_stop_both() are the
same as well. conn_cond_update_polling() only causes errors to stop
polling. It also becomes way more obvious that muxes should not at
all employ conn_xprt_{want|stop}_{recv,send}(), and that the call
to __conn_xprt_stop_recv() in case a mux failed to allocate a buffer
is inappropriate, it ought to unsubscribe from reads instead. All of
this definitely requires a serious cleanup.

5 years agoCLEANUP: epoll: place the struct epoll_event in the stack
Willy Tarreau [Thu, 20 Feb 2020 10:23:43 +0000 (11:23 +0100)] 
CLEANUP: epoll: place the struct epoll_event in the stack

Historically we used to have a global epoll_event for various
manipulations involving epoll_ctl() and when threads were added,
this was turned to a thread_local, which is needlessly expensive
since it's just a temporary variable. Let's move it to a local
variable wherever it's called instead.

5 years agoMINOR: checks: do not call conn_xprt_stop_send() anymore
Willy Tarreau [Fri, 21 Feb 2020 09:13:03 +0000 (10:13 +0100)] 
MINOR: checks: do not call conn_xprt_stop_send() anymore

While trying to address issue #253, Commit 5909380c ("BUG/MINOR: checks:
stop polling for write when we have nothing left to send") made sure that
we stop polling for writes when the buffer is empty. This was actually
more a workaround than a bug fix because by doing so we may be stopping
polling for an intermediary transport layer without acting on the check
itself in case there's SSL or send-proxy in the chain for example, thus
the approach is wrong. In practice due to the small size of check
requests, this will not have any impact. At best, we ought to unsubscribe
for sending, but that's already the case when we arrive in this function.
But given that the root cause of the issue was addressed later in commits
cc705a6bc5940392 and ccf3f6d1, we can now safely revert this change.

It was confirmed on the faulty config that this change doesn't have any
effect anymore on the test.

5 years agoBUG/MINOR: mux: do not call conn_xprt_stop_recv() on buffer shortage
Willy Tarreau [Fri, 21 Feb 2020 08:44:39 +0000 (09:44 +0100)] 
BUG/MINOR: mux: do not call conn_xprt_stop_recv() on buffer shortage

In H1/H2/FCGI, the *_get_buf() functions try to disable receipt of data
when there's no buffer available. But they do so at the lowest possible
level, which is unrelated to the upper transport layers which may still
be trying to feed data based on subscription. The correct approach here
would theorically be to only disable subscription, though when we get
there, the subscription will already have been dropped, so we can safely
just remove that call.

It's unlikely that this could have had any practical impact, as the upper
xprt layer would call this callback which would fail an not resubscribe.
Having the lowest layer disabled would just be temporary since when
re-enabling reading, a subscribe at the end of data would re-enable it.

Backport should not harm but seems useless at this point.

5 years agoBUG/MAJOR: http-ana: Always abort the request when a tarpit is triggered
Christopher Faulet [Fri, 21 Feb 2020 09:20:46 +0000 (10:20 +0100)] 
BUG/MAJOR: http-ana: Always abort the request when a tarpit is triggered

If an client error is reported on the request channel (CF_READ_ERROR) while a
session is tarpitted, no error is returned to the client. Concretly,
http_reply_and_close() function is not called. This function is reponsible to
forward the error to the client. But not only. It is also responsible to abort
the request. Because this function is not called when a read error is reported
on the request channel, and because the tarpit analyzer is the last one, there
is nothing preventing a connection attempt on a server while it is totally
unexpected.

So, a useless connexion on a backend server may be performed because of this
bug. If an HTTP load-balancing algorithm is used on the backend side, it leads
to a crash of HAProxy because the request was already erased.

If you have tarpit rules and if you use an HTTP load-balancing algorithm on your
backends, you must apply this patch. Otherwise a simple TCP reset on a tarpitted
connexion will most likely crash your HAProxy. A safe workaround is to use a
silent-drop rule or a deny rule instead of a tarpit.

This bug also affect the legacy code. It is in fact an very old hidden bug. But
the refactoring of process_stream() in the 1.9 makes it visible. And,
unfortunately, with the HTX, it is easier to hit it because many processing has
been moved in lower layers, in the muxes.

It must be backported as far as 1.9. For the 2.0 and the 1.9, the legacy HTTP
code must also be patched the same way. For older versions, it may be backported
but the bug seems to not impact them.

Thanks to Olivier D <webmaster@ajeux.com> to have reported the bug and provided
all the infos to analyze it.

5 years agoBUG/MINOR: ssl: Stop passing dynamic strings as format arguments
Tim Duesterhus [Wed, 19 Feb 2020 10:41:13 +0000 (11:41 +0100)] 
BUG/MINOR: ssl: Stop passing dynamic strings as format arguments

gcc complains rightfully:

src/ssl_sock.c: In function ‘ssl_load_global_issuers_from_path’:
src/ssl_sock.c:9860:4: warning: format not a string literal and no format arguments [-Wformat-security]
    ha_warning(warn);
    ^

Introduced in 70df7bf19cebd5593c0abb01923e6c9f72961da6.

5 years agoMINOR: http-ana: Match on the path if the monitor-uri starts by a /
Christopher Faulet [Tue, 18 Feb 2020 14:34:58 +0000 (15:34 +0100)] 
MINOR: http-ana: Match on the path if the monitor-uri starts by a /

if the monitor-uri starts by a slash ('/'), the matching is performed against
the request's path instead of the request's uri. It is a workaround to let the
HTTP/2 requests match the monitor-uri. Indeed, in HTTP/2, clients are encouraged
to send absolute URIs only.

This patch is not tagged as a bug, because the previous behavior matched exactly
what the doc describes. But it may surprise that HTTP/2 requests don't match the
monitor-uri.

This patch may be backported to 2.1 because URIs of HTTP/2 are stored using the
absolute-form starting this version. For previous versions, this patch will only
helps explicitely absolute HTTP/1 requests (and only the HTX part because on the
legacy HTTP, all the URI is matched).

It should fix the issue #509.

5 years agoBUG/MINOR: http-ana: Matching on monitor-uri should be case-sensitive
Christopher Faulet [Tue, 18 Feb 2020 13:51:51 +0000 (14:51 +0100)] 
BUG/MINOR: http-ana: Matching on monitor-uri should be case-sensitive

The monitor-uri should be case-sensitive. In reality, the scheme and the host
part are case-insensitives and only the path is case-sensive. But concretely,
since the start, the matching on the monitor-uri is case-sensitive. And it is
probably the expected behavior of almost all users.

This patch must be backported as far as 1.9. For HAProxy 2.0 and 1.9, it must be
applied on src/proto_htx.c.