]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
5 years agoMINOR: tcp: Support TCP keepalive parameters customization
MIZUTA Takeshi [Thu, 9 Jul 2020 02:13:20 +0000 (11:13 +0900)] 
MINOR: tcp: Support TCP keepalive parameters customization

It is now possible to customize TCP keepalive parameters.
These correspond to the socket options TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL
and are valid for the defaults, listen, frontend and backend sections.

This patch fixes GitHub issue #670.

5 years agoBUG/MEDIUM: lists: add missing store barrier in MT_LIST_ADD/MT_LIST_ADDQ
Willy Tarreau [Thu, 9 Jul 2020 03:01:27 +0000 (05:01 +0200)] 
BUG/MEDIUM: lists: add missing store barrier in MT_LIST_ADD/MT_LIST_ADDQ

The torture test run for previous commit 787dc20 ("BUG/MEDIUM: lists: add
missing store barrier on MT_LIST_BEHEAD()") finally broke again after 34M
connections. It appeared that MT_LIST_ADD and MT_LIST_ADDQ were suffering
from the same missing barrier when restoring the original pointers before
giving up, when checking if the element was already added. This is indeed
something which seldom happens with the shared scheduler, in case two
threads simultaneously try to wake up the same tasklet.

With a store barrier there after reverting the pointers, the torture test
survived 750M connections on the NanoPI-Fire3, so it looks good this time.
Probably that MT_LIST_BEHEAD should be added to test-list.c since it seems
to be more sensitive to concurrent accesses with MT_LIST_ADDQ.

It's worth noting that there is no barrier between the last two pointers
update, while there is one in MT_LIST_POP and MT_LIST_BEHEAD, the latter
having shown to be needed, but I cannot demonstrate why we would need
one here. Given that the code seems solid here, let's stick to what is
shown to work.

This fix should be backported to 2.1, just for the sake of safety since
the issue couldn't be triggered there, but it could change with the
compiler or when backporting a fix for example.

5 years agoBUG/MEDIUM: lists: add missing store barrier on MT_LIST_BEHEAD()
Willy Tarreau [Wed, 8 Jul 2020 17:45:50 +0000 (19:45 +0200)] 
BUG/MEDIUM: lists: add missing store barrier on MT_LIST_BEHEAD()

When running multi-threaded tests on my NanoPI-Fire3 (8 A53 cores), I
managed to occasionally get either a bus error or a segfault in the
scheduler, but only when running at a high connection rate (injecting
on a tcp-request connection reject rule). The bug is rare and happens
around once per million connections. I could never reproduce it with
less than 4 threads nor on A72 cores.

Haproxy 2.1.0 would also fail there but not 2.1.7.

Every time the crash happened with the TL_URGENT task list corrupted,
though it was not immediately after the LIST_SPLICE() call, indicating
background activity survived the MT_LIST_BEHEAD() operation. This queue
is where the shared runqueue is transferred, and the shared runqueue
gets fast inter-thread tasklet wakeups from idle conn takeover and new
connections.

Comparing the MT_LIST_BEHEAD() and MT_LIST_DEL() implementations, it's
quite obvious that a few barriers are missing from the former, and these
will simply fail on weakly ordered caches.

Two store barriers were added before the break() on failure, to match
what is done on the normal path. Missing them almost always results in
a segfault which is quite rare but consistent (after ~3M connections).

The 3rd one before updating n->prev seems intuitively needed though I
coudln't make the code fail without it. It's present in MT_LIST_DEL so
better not be needlessly creative. The last one is the most important
one, and seems to be the one that helps a concurrent MT_LIST_ADDQ()
detect a late failure and try again. With this, the code survives at
least 30M connections.

Interestingly the exact same issue was addressed in 2.0-dev2 for MT_LIST_DEL
with commit 690d2ad4d ("BUG/MEDIUM: list: add missing store barriers when
updating elements and head").

This fix must be backported to 2.1 as MT_LIST_BEHEAD() is also used there.

It's only tagged as medium because it will only affect entry-level CPUs
like Cortex A53 (x86 are not affected), and requires load levels that are
very hard to achieve on such machines to trigger it. In practice it's
unlikely anyone will ever hit it.

5 years agoCLEANUP: contrib/prometheus-exporter: typo fixes for ssl reuse metric
Pierre Cheynier [Tue, 7 Jul 2020 17:14:08 +0000 (19:14 +0200)] 
CLEANUP: contrib/prometheus-exporter: typo fixes for ssl reuse metric

A typo I identified while having a look to our metric inventory.
(s/frontent/frontend)

5 years agoCLEANUP: Add static void hlua_deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:53:26 +0000 (11:53 +0200)] 
CLEANUP: Add static void hlua_deinit()

Compiling HAProxy with USE_LUA=1 and running a configuration check within
valgrind with a very simple configuration such as:

    listen foo
     bind *:8080

Will report quite a few possible leaks afterwards:

    ==24048== LEAK SUMMARY:
    ==24048==    definitely lost: 0 bytes in 0 blocks
    ==24048==    indirectly lost: 0 bytes in 0 blocks
    ==24048==      possibly lost: 95,513 bytes in 1,209 blocks
    ==24048==    still reachable: 329,960 bytes in 71 blocks
    ==24048==         suppressed: 0 bytes in 0 blocks

Printing these possible leaks shows that all of them are caused by Lua.
Luckily Lua makes it *very* easy to free all used memory, so let's do
this on shutdown.

Afterwards this patch is applied the output looks much better:

    ==24199== LEAK SUMMARY:
    ==24199==    definitely lost: 0 bytes in 0 blocks
    ==24199==    indirectly lost: 0 bytes in 0 blocks
    ==24199==      possibly lost: 0 bytes in 0 blocks
    ==24199==    still reachable: 329,960 bytes in 71 blocks
    ==24199==         suppressed: 0 bytes in 0 blocks

5 years agoCLEANUP: Add static void vars_deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:53:25 +0000 (11:53 +0200)] 
CLEANUP: Add static void vars_deinit()

vars_deinit() frees all var_names during deinit().

5 years agoCLEANUP: haproxy: Free post_server_check_list in deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:49:50 +0000 (11:49 +0200)] 
CLEANUP: haproxy: Free post_server_check_list in deinit()

This allocation is technically always reachable and cannot leak, but so are
a few others that *are* freed.

5 years agoCLEANUP: haproxy: Free server_deinit_list in deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:49:49 +0000 (11:49 +0200)] 
CLEANUP: haproxy: Free server_deinit_list in deinit()

This allocation is technically always reachable and cannot leak, but so are
a few others that *are* freed.

5 years agoCLEANUP: haproxy: Free post_deinit_list in deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:49:48 +0000 (11:49 +0200)] 
CLEANUP: haproxy: Free post_deinit_list in deinit()

This allocation is technically always reachable and cannot leak, but so are
a few others that *are* freed.

5 years agoCLEANUP: haproxy: Free proxy_deinit_list in deinit()
Tim Duesterhus [Sat, 4 Jul 2020 09:49:47 +0000 (11:49 +0200)] 
CLEANUP: haproxy: Free proxy_deinit_list in deinit()

This allocation is technically always reachable and cannot leak, but so are
a few others that *are* freed.

5 years agoBUG/MINOR: sample: Free str.area in smp_check_const_meth
Tim Duesterhus [Sat, 4 Jul 2020 09:49:46 +0000 (11:49 +0200)] 
BUG/MINOR: sample: Free str.area in smp_check_const_meth

Given the following example configuration:

    listen foo
     mode http
     bind *:8080
     http-request set-var(txn.leak) meth(GET)
     server x example.com:80

Running a configuration check with valgrind reports:

    ==25992== 4 bytes in 1 blocks are definitely lost in loss record 1 of 344
    ==25992==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==25992==    by 0x4E239D: my_strndup (tools.c:2261)
    ==25992==    by 0x581E20: make_arg_list (arg.c:253)
    ==25992==    by 0x4DE91D: sample_parse_expr (sample.c:890)
    ==25992==    by 0x58E304: parse_store (vars.c:772)
    ==25992==    by 0x566A3F: parse_http_req_cond (http_rules.c:95)
    ==25992==    by 0x4A4CE6: cfg_parse_listen (cfgparse-listen.c:1339)
    ==25992==    by 0x494C59: readcfgfile (cfgparse.c:2049)
    ==25992==    by 0x545145: init (haproxy.c:2029)
    ==25992==    by 0x421E42: main (haproxy.c:3175)

After this patch is applied the leak is gone as expected.

This is a fairly minor leak, but it can add up for many uses of the `bool()`
sample fetch. The bug most likely exists since the `bool()` sample fetch was
introduced in commit cc103299c75c530ab3637a1698306145bdc85552. The fix may
be backported to HAProxy 1.6+.

5 years agoBUG/MINOR: sample: Free str.area in smp_check_const_bool
Tim Duesterhus [Sat, 4 Jul 2020 09:49:45 +0000 (11:49 +0200)] 
BUG/MINOR: sample: Free str.area in smp_check_const_bool

Given the following example configuration:

    listen foo
     mode http
     bind *:8080
     http-request set-var(txn.leak) bool(1)
     server x example.com:80

Running a configuration check with valgrind reports:

    ==24233== 2 bytes in 1 blocks are definitely lost in loss record 1 of 345
    ==24233==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==24233==    by 0x4E238D: my_strndup (tools.c:2261)
    ==24233==    by 0x581E10: make_arg_list (arg.c:253)
    ==24233==    by 0x4DE90D: sample_parse_expr (sample.c:890)
    ==24233==    by 0x58E2F4: parse_store (vars.c:772)
    ==24233==    by 0x566A2F: parse_http_req_cond (http_rules.c:95)
    ==24233==    by 0x4A4CE6: cfg_parse_listen (cfgparse-listen.c:1339)
    ==24233==    by 0x494C59: readcfgfile (cfgparse.c:2049)
    ==24233==    by 0x545135: init (haproxy.c:2029)
    ==24233==    by 0x421E42: main (haproxy.c:3175)

After this patch is applied the leak is gone as expected.

This is a fairly minor leak, but it can add up for many uses of the `bool()`
sample fetch. The bug most likely exists since the `bool()` sample fetch was
introduced in commit cc103299c75c530ab3637a1698306145bdc85552. The fix may
be backported to HAProxy 1.6+.

5 years agoBUG/MINOR: haproxy: Free srule->expr during deinit
Tim Duesterhus [Sat, 4 Jul 2020 09:49:44 +0000 (11:49 +0200)] 
BUG/MINOR: haproxy: Free srule->expr during deinit

Given the following example configuration:

    backend foo
     mode http
     use-server %[str(x)] if { always_true }
     server x example.com:80

Running a configuration check with valgrind reports:

    ==19376== 170 (40 direct, 130 indirect) bytes in 1 blocks are definitely lost in loss record 281 of 347
    ==19376==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==19376==    by 0x5091AC: add_sample_to_logformat_list (log.c:511)
    ==19376==    by 0x50A5A6: parse_logformat_string (log.c:671)
    ==19376==    by 0x4957F2: check_config_validity (cfgparse.c:2588)
    ==19376==    by 0x54442D: init (haproxy.c:2129)
    ==19376==    by 0x421E42: main (haproxy.c:3169)

After this patch is applied the leak is gone as expected.

This is a very minor leak that can only be observed if deinit() is called,
shortly before the OS will free all memory of the process anyway. No
backport needed.

5 years agoBUG/MINOR: haproxy: Free srule->file during deinit
Tim Duesterhus [Sat, 4 Jul 2020 09:49:43 +0000 (11:49 +0200)] 
BUG/MINOR: haproxy: Free srule->file during deinit

Given the following example configuration:

    backend foo
     mode http
     use-server x if { always_true }
     server x example.com:80

Running a configuration check with valgrind reports:

    ==18650== 14 bytes in 1 blocks are definitely lost in loss record 3 of 345
    ==18650==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==18650==    by 0x649E489: strdup (strdup.c:42)
    ==18650==    by 0x4A5438: cfg_parse_listen (cfgparse-listen.c:1548)
    ==18650==    by 0x494C59: readcfgfile (cfgparse.c:2049)
    ==18650==    by 0x5450B5: init (haproxy.c:2029)
    ==18650==    by 0x421E42: main (haproxy.c:3168)

After this patch is applied the leak is gone as expected.

This is a very minor leak that can only be observed if deinit() is called,
shortly before the OS will free all memory of the process anyway. No
backport needed.

5 years agoBUG/MINOR: haproxy: Free proxy->unique_id_header during deinit
Tim Duesterhus [Sat, 4 Jul 2020 09:49:42 +0000 (11:49 +0200)] 
BUG/MINOR: haproxy: Free proxy->unique_id_header during deinit

Given the following example configuration:

    frontend foo
     mode http
     bind *:8080
     unique-id-header x

Running a configuration check with valgrind reports:

    ==17621== 2 bytes in 1 blocks are definitely lost in loss record 1 of 341
    ==17621==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17621==    by 0x649E489: strdup (strdup.c:42)
    ==17621==    by 0x4A87F1: cfg_parse_listen (cfgparse-listen.c:2747)
    ==17621==    by 0x494C59: readcfgfile (cfgparse.c:2049)
    ==17621==    by 0x545095: init (haproxy.c:2029)
    ==17621==    by 0x421E42: main (haproxy.c:3167)

After this patch is applied the leak is gone as expected.

This is a very minor leak that can only be observed if deinit() is called,
shortly before the OS will free all memory of the process anyway. No
backport needed.

5 years agoBUG/MINOR: haproxy: Add missing free of server->(hostname|resolvers_id)
Tim Duesterhus [Sat, 4 Jul 2020 09:49:41 +0000 (11:49 +0200)] 
BUG/MINOR: haproxy: Add missing free of server->(hostname|resolvers_id)

Given the following example configuration:

    resolvers test
     nameserver test 127.0.0.1:53
    listen foo
     bind *:8080
     server foo example.com resolvers test

Running a configuration check within valgrind reports:

    ==21995== 5 bytes in 1 blocks are definitely lost in loss record 1 of 30
    ==21995==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==21995==    by 0x5726489: strdup (strdup.c:42)
    ==21995==    by 0x4B2CFB: parse_server (server.c:2163)
    ==21995==    by 0x4680C1: cfg_parse_listen (cfgparse-listen.c:534)
    ==21995==    by 0x459E33: readcfgfile (cfgparse.c:2167)
    ==21995==    by 0x50778D: init (haproxy.c:2021)
    ==21995==    by 0x418262: main (haproxy.c:3133)
    ==21995==
    ==21995== 12 bytes in 1 blocks are definitely lost in loss record 3 of 30
    ==21995==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==21995==    by 0x5726489: strdup (strdup.c:42)
    ==21995==    by 0x4AC666: srv_prepare_for_resolution (server.c:1606)
    ==21995==    by 0x4B2EBD: parse_server (server.c:2081)
    ==21995==    by 0x4680C1: cfg_parse_listen (cfgparse-listen.c:534)
    ==21995==    by 0x459E33: readcfgfile (cfgparse.c:2167)
    ==21995==    by 0x50778D: init (haproxy.c:2021)
    ==21995==    by 0x418262: main (haproxy.c:3133)

with one more leak unrelated to `struct server`. After applying this
patch the leak is gone as expected.

This is a very minor leak that can only be observed if deinit() is called,
shortly before the OS will free all memory of the process anyway. No
backport needed.

5 years agoBUG/MINOR: haproxy: Free proxy->format_unique_id during deinit
Tim Duesterhus [Sat, 4 Jul 2020 09:49:40 +0000 (11:49 +0200)] 
BUG/MINOR: haproxy: Free proxy->format_unique_id during deinit

Given the following example configuration:

    frontend foo
     mode http
     bind *:8080
     unique-id-format x

Running a configuration check with valgrind reports:

    ==30712== 42 (40 direct, 2 indirect) bytes in 1 blocks are definitely lost in loss record 18 of 39
    ==30712==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==30712==    by 0x4ED7E9: add_to_logformat_list (log.c:462)
    ==30712==    by 0x4EEE28: parse_logformat_string (log.c:720)
    ==30712==    by 0x47B09A: check_config_validity (cfgparse.c:3046)
    ==30712==    by 0x52881D: init (haproxy.c:2121)
    ==30712==    by 0x41F382: main (haproxy.c:3126)

After this patch is applied the leak is gone as expected.

This is a very minor leak that can only be observed if deinit() is called,
shortly before the OS will free all memory of the process anyway. No
backport needed.

5 years agoBUG/MINOR: sample: Fix freeing of conv_exprs in release_sample_expr
Tim Duesterhus [Sat, 4 Jul 2020 09:49:39 +0000 (11:49 +0200)] 
BUG/MINOR: sample: Fix freeing of conv_exprs in release_sample_expr

Instead of just calling release_sample_arg(conv_expr->arg_p) we also must
free() the conv_expr itself (after removing it from the list).

Given the following example configuration:

    frontend foo
     bind *:8080
     mode http
     http-request set-var(txn.foo) str(bar)
     acl is_match str(foo),strcmp(txn.hash) -m bool

Running a configuration check within valgrind reports:

    ==1431== 32 bytes in 1 blocks are definitely lost in loss record 20 of 43
    ==1431==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==1431==    by 0x4C39B5: sample_parse_expr (sample.c:982)
    ==1431==    by 0x56B410: parse_acl_expr (acl.c:319)
    ==1431==    by 0x56BA7F: parse_acl (acl.c:697)
    ==1431==    by 0x48D225: cfg_parse_listen (cfgparse-listen.c:816)
    ==1431==    by 0x4797C3: readcfgfile (cfgparse.c:2167)
    ==1431==    by 0x52943D: init (haproxy.c:2021)
    ==1431==    by 0x41F382: main (haproxy.c:3133)

After this patch is applied the leak is gone as expected.

This is a fairly minor leak that can only be observed if samples need to be
freed, which is not something that should occur during normal processing and
most likely only during shut down. Thus no backport should be needed.

5 years agoBUG/MINOR: acl: Fix freeing of expr->smp in prune_acl_expr
Tim Duesterhus [Sat, 4 Jul 2020 09:49:38 +0000 (11:49 +0200)] 
BUG/MINOR: acl: Fix freeing of expr->smp in prune_acl_expr

Instead of simply calling free() in expr->smp->arg_p in certain cases
properly free the sample using release_sample_expr().

Given the following example configuration:

    frontend foo
     bind *:8080
     mode http
     http-request set-var(txn.foo) str(bar)
     acl is_match str(foo),strcmp(txn.hash) -m bool

Running a configuration check within valgrind reports:

    ==31371== 160 (48 direct, 112 indirect) bytes in 1 blocks are definitely lost in loss record 35 of 45
    ==31371==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==31371==    by 0x4C3832: sample_parse_expr (sample.c:876)
    ==31371==    by 0x56B3E0: parse_acl_expr (acl.c:319)
    ==31371==    by 0x56BA4F: parse_acl (acl.c:697)
    ==31371==    by 0x48D225: cfg_parse_listen (cfgparse-listen.c:816)
    ==31371==    by 0x4797C3: readcfgfile (cfgparse.c:2167)
    ==31371==    by 0x5293ED: init (haproxy.c:2021)
    ==31371==    by 0x41F382: main (haproxy.c:3126)

After this patch this leak is reduced. It will be fully removed in a
follow up patch:

    ==32503== 32 bytes in 1 blocks are definitely lost in loss record 20 of 43
    ==32503==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==32503==    by 0x4C39B5: sample_parse_expr (sample.c:982)
    ==32503==    by 0x56B410: parse_acl_expr (acl.c:319)
    ==32503==    by 0x56BA7F: parse_acl (acl.c:697)
    ==32503==    by 0x48D225: cfg_parse_listen (cfgparse-listen.c:816)
    ==32503==    by 0x4797C3: readcfgfile (cfgparse.c:2167)
    ==32503==    by 0x52943D: init (haproxy.c:2021)
    ==32503==    by 0x41F382: main (haproxy.c:3133)

This is a fairly minor leak that can only be observed if ACLs need to be
freed, which is not something that should occur during normal processing
and most likely only during shut down. Thus no backport should be needed.

5 years agoMINOR: config: make strict limits enabled by default
William Dauchy [Sat, 28 Mar 2020 18:29:58 +0000 (19:29 +0100)] 
MINOR: config: make strict limits enabled by default

as agreed a few months ago, enable strict-limits for v2.3
update configuration manual accordingly

Signed-off-by: William Dauchy <w.dauchy@criteo.com>
5 years ago[RELEASE] Released version 2.3-dev0 v2.3-dev0
Willy Tarreau [Tue, 7 Jul 2020 14:39:18 +0000 (16:39 +0200)] 
[RELEASE] Released version 2.3-dev0

Released version 2.3-dev0 with the following main changes :
    - [RELEASE] Released version 2.3-dev0
    - MINOR: version: back to development, update status message

5 years agoMINOR: version: back to development, update status message
Willy Tarreau [Tue, 7 Jul 2020 14:37:05 +0000 (16:37 +0200)] 
MINOR: version: back to development, update status message

Update the status message and update INSTALL again.

5 years ago[RELEASE] Released version 2.3-dev0
Willy Tarreau [Tue, 7 Jul 2020 14:35:28 +0000 (16:35 +0200)] 
[RELEASE] Released version 2.3-dev0

Released version 2.3-dev0 with the following main changes :
    - exact copy of 2.2.0

5 years ago[RELEASE] Released version 2.2.0 v2.2.0
Willy Tarreau [Tue, 7 Jul 2020 14:33:14 +0000 (16:33 +0200)] 
[RELEASE] Released version 2.2.0

Released version 2.2.0 with the following main changes :
    - BUILD: mux-h2: fix typo breaking build when using DEBUG_LOCK
    - CLEANUP: makefile: update the outdated list of DEBUG_xxx options
    - BUILD: tools: make resolve_sym_name() return a const
    - CLEANUP: auth: fix useless self-include of auth-t.h
    - BUILD: tree-wide: cast arguments to tolower/toupper to unsigned char
    - CLEANUP: assorted typo fixes in the code and comments
    - WIP/MINOR: ssl: add sample fetches for keylog in frontend
    - DOC: fix tune.ssl.keylog sample fetches array
    - BUG/MINOR: ssl: check conn in keylog sample fetch
    - DOC: configuration: various typo fixes
    - MINOR: log: Remove unused case statement during the log-format string parsing
    - BUG/MINOR: mux-h1: Fix the splicing in TUNNEL mode
    - BUG/MINOR: mux-h1: Don't read data from a pipe if the mux is unable to receive
    - BUG/MINOR: mux-h1: Disable splicing only if input data was processed
    - BUG/MEDIUM: mux-h1: Disable splicing for the conn-stream if read0 is received
    - MINOR: mux-h1: Improve traces about the splicing
    - BUG/MINOR: backend: Remove CO_FL_SESS_IDLE if a client remains on the last server
    - BUG/MEDIUM: connection: Don't consider new private connections as available
    - BUG/MINOR: connection: See new connection as available only on reuse always
    - DOC: configuration: remove obsolete mentions of H2 being converted to HTTP/1.x
    - CLEANUP: ssl: remove unrelevant comment in smp_fetch_ssl_x_keylog()
    - DOC: update INSTALL with new compiler versions
    - DOC: minor update to coding style file
    - MINOR: version: mention that it's an LTS release now

5 years agoMINOR: version: mention that it's an LTS release now
Willy Tarreau [Tue, 7 Jul 2020 14:31:52 +0000 (16:31 +0200)] 
MINOR: version: mention that it's an LTS release now

The new version is going to be LTS up to around Q2 2025.

5 years agoDOC: minor update to coding style file
Willy Tarreau [Tue, 7 Jul 2020 14:21:19 +0000 (16:21 +0200)] 
DOC: minor update to coding style file

It used to still refrence includes/{types,proto,common}/, now turned
to import/ and haproxy/.

5 years agoDOC: update INSTALL with new compiler versions
Willy Tarreau [Tue, 7 Jul 2020 14:17:00 +0000 (16:17 +0200)] 
DOC: update INSTALL with new compiler versions

gcc is known to work up to 10.1. Also update the message about the
development version.

5 years agoCLEANUP: ssl: remove unrelevant comment in smp_fetch_ssl_x_keylog()
William Lallemand [Tue, 7 Jul 2020 13:04:54 +0000 (15:04 +0200)] 
CLEANUP: ssl: remove unrelevant comment in smp_fetch_ssl_x_keylog()

Remove a comment.

5 years agoDOC: configuration: remove obsolete mentions of H2 being converted to HTTP/1.x
Willy Tarreau [Tue, 7 Jul 2020 13:55:23 +0000 (15:55 +0200)] 
DOC: configuration: remove obsolete mentions of H2 being converted to HTTP/1.x

The first H2 implementation in version 1.8 used to turn HTTP/2 requests
to HTTP/1.1, causing many limitations. This is not true anymore and we
don't suffer from the lack of server-side H2 nor are we forced to close
mode anymore, so let's remove such obsolete mentions.

This could be backported to 2.0.

5 years agoBUG/MINOR: connection: See new connection as available only on reuse always
Christopher Faulet [Wed, 1 Jul 2020 12:59:43 +0000 (14:59 +0200)] 
BUG/MINOR: connection: See new connection as available only on reuse always

When the multiplexer creation is delayed after the handshakes phase, the
connection is added in the available connection list if http-reuse never is not
configured for the backend. But it is a wrong statement. At this step, the
connection is not safe because it is a new connection. So it must be added in
the available connection list only if http-reuse always is used.

No backport needed, this is 2.2-dev.

5 years agoBUG/MEDIUM: connection: Don't consider new private connections as available
Christopher Faulet [Tue, 30 Jun 2020 12:47:46 +0000 (14:47 +0200)] 
BUG/MEDIUM: connection: Don't consider new private connections as available

When a connection is created and the multiplexer is installed, if the connection
is marked as private, don't consider it as available, regardless the number of
available streams. This test is performed when the mux is installed when the
connection is created, in connect_server(), and when the mux is installed after
the handshakes stage.

No backport needed, this is 2.2-dev.

5 years agoBUG/MINOR: backend: Remove CO_FL_SESS_IDLE if a client remains on the last server
Christopher Faulet [Wed, 1 Jul 2020 16:56:30 +0000 (18:56 +0200)] 
BUG/MINOR: backend: Remove CO_FL_SESS_IDLE if a client remains on the last server

When a connection is picked from the session server list because the proxy or
the session are marked to use the last requested server, if it is idle, we must
marked it as used removing the CO_FL_SESS_IDLE flag and decrementing the session
idle_conns counter.

This patch must be backported as far as 1.9.

5 years agoMINOR: mux-h1: Improve traces about the splicing
Christopher Faulet [Fri, 3 Jul 2020 13:08:49 +0000 (15:08 +0200)] 
MINOR: mux-h1: Improve traces about the splicing

Trace messages have been added when the CS_FL_MAY_SPLICE flag is set or unset
and when the splicing is really enabled for the H1 connection.

This patch may be backpored to 2.1 to ease debugging.

5 years agoBUG/MEDIUM: mux-h1: Disable splicing for the conn-stream if read0 is received
Christopher Faulet [Tue, 7 Jul 2020 08:56:40 +0000 (10:56 +0200)] 
BUG/MEDIUM: mux-h1: Disable splicing for the conn-stream if read0 is received

The CS_FL_MAY_SPLICE flag must be unset for the conn-stream if a read0 is
received while reading on the kernel pipe. It is mandatory when some data was
also received. Otherwise, this flag prevent the call to the h1 rcv_buf()
callback. Thus the read0 will never be handled by the h1 multiplexer leading to
a freeze of the session until a timeout is reached.

This patch must be backported to 2.1 and 2.0.

5 years agoBUG/MINOR: mux-h1: Disable splicing only if input data was processed
Christopher Faulet [Fri, 3 Jul 2020 13:12:00 +0000 (15:12 +0200)] 
BUG/MINOR: mux-h1: Disable splicing only if input data was processed

In h1_rcv_buf(), the splicing is systematically disabled if it was previously
enabled. When it happens, if the splicing is enabled it means the channel's
buffer was empty before calling h1_rcv_buf(). Thus, the only reason to disable
the splicing at this step is when some input data have just been processed.

This patch may be backported to 2.1 and 2.0.

5 years agoBUG/MINOR: mux-h1: Don't read data from a pipe if the mux is unable to receive
Christopher Faulet [Fri, 3 Jul 2020 13:02:25 +0000 (15:02 +0200)] 
BUG/MINOR: mux-h1: Don't read data from a pipe if the mux is unable to receive

In h1_rcv_pipe(), if the mux is unable to receive data, for instance because the
multiplexer is blocked on input waiting the other side (BUSY mode), no receive
must be performed.

This patch must be backported to 2.1 and 2.0.

5 years agoBUG/MINOR: mux-h1: Fix the splicing in TUNNEL mode
Christopher Faulet [Fri, 3 Jul 2020 12:51:15 +0000 (14:51 +0200)] 
BUG/MINOR: mux-h1: Fix the splicing in TUNNEL mode

In the commit 17ccd1a35 ("BUG/MEDIUM: connection: add a mux flag to indicate
splice usability"), The CS_FL_MAY_SPLICE flags was added to notify the upper
layer that the mux is able to use the splicing. But this was only done for the
payload in a message, in HTTP_MSG_DATA state. But the splicing is also possible
in TUNNEL mode, in HTTP_MSG_TUNNEL state. In addition, the splicing ability is
always disabled for chunked messages.

This patch must be backported to 2.1 and 2.0.

5 years agoMINOR: log: Remove unused case statement during the log-format string parsing
Christopher Faulet [Mon, 6 Jul 2020 17:03:25 +0000 (19:03 +0200)] 
MINOR: log: Remove unused case statement during the log-format string parsing

Since the commit cd0d2ed6e ("MEDIUM: log-format: make the LF parser aware of
sample expressions' end"), the LF_STEXPR label in the last switch-case statement
at the end of the for loop in the parse_logformat_string() function cannot be
reached anymore.

This patch should fix the issue #723.

5 years agoDOC: configuration: various typo fixes
Daniel Corbett [Tue, 7 Jul 2020 03:01:19 +0000 (23:01 -0400)] 
DOC: configuration: various typo fixes

Quick round of typo corrections for configuration.txt

5 years agoBUG/MINOR: ssl: check conn in keylog sample fetch
William Lallemand [Tue, 7 Jul 2020 08:48:13 +0000 (10:48 +0200)] 
BUG/MINOR: ssl: check conn in keylog sample fetch

Add a check on the conn pointer to avoid a NULL dereference in
smp_fetch_ssl_x_keylog().

The problem is not suppose to happen because the function is only used
for the frontend at the moment.

Introduced by 7d42ef5, 2.2 only.

Fix issue #733.

5 years agoDOC: fix tune.ssl.keylog sample fetches array
William Lallemand [Tue, 7 Jul 2020 08:14:56 +0000 (10:14 +0200)] 
DOC: fix tune.ssl.keylog sample fetches array

The labels EXPORTER_SECRET and EARLY_EXPORTER_SECRET were swapped in the
array.

5 years agoWIP/MINOR: ssl: add sample fetches for keylog in frontend
William Lallemand [Mon, 6 Jul 2020 09:41:30 +0000 (11:41 +0200)] 
WIP/MINOR: ssl: add sample fetches for keylog in frontend

OpenSSL 1.1.1 provides a callback registering function
SSL_CTX_set_keylog_callback, which allows one to receive a string
containing the keys to deciphers TLSv1.3.

Unfortunately it is not possible to store this data in binary form and
we can only get this information using the callback. Which means that we
need to store it until the connection is closed.

This patches add 2 pools, the first one, pool_head_ssl_keylog is used to
store a struct ssl_keylog which will be inserted as a ex_data in a SSL *.
The second one is pool_head_ssl_keylog_str which will be used to store
the hexadecimal strings.

To enable the capture of the keys, you need to set "tune.ssl.keylog on"
in your configuration.

The following fetches were implemented:

ssl_fc_client_early_traffic_secret,
ssl_fc_client_handshake_traffic_secret,
ssl_fc_server_handshake_traffic_secret,
ssl_fc_client_traffic_secret_0,
ssl_fc_server_traffic_secret_0,
ssl_fc_exporter_secret,
ssl_fc_early_exporter_secret

5 years agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Sun, 5 Jul 2020 11:36:08 +0000 (16:36 +0500)] 
CLEANUP: assorted typo fixes in the code and comments

This is 11th iteration of typo fixes

5 years agoBUILD: tree-wide: cast arguments to tolower/toupper to unsigned char
Willy Tarreau [Sun, 5 Jul 2020 19:46:32 +0000 (21:46 +0200)] 
BUILD: tree-wide: cast arguments to tolower/toupper to unsigned char

NetBSD apparently uses macros for tolower/toupper and complains about
the use of char for array subscripts. Let's properly cast all of them
to unsigned char where they are used.

This is needed to fix issue #729.

5 years agoCLEANUP: auth: fix useless self-include of auth-t.h
Willy Tarreau [Sun, 5 Jul 2020 19:32:47 +0000 (21:32 +0200)] 
CLEANUP: auth: fix useless self-include of auth-t.h

Since recent include cleanups auth-t.h ended up including itself.

5 years agoBUILD: tools: make resolve_sym_name() return a const
Willy Tarreau [Sun, 5 Jul 2020 18:26:04 +0000 (20:26 +0200)] 
BUILD: tools: make resolve_sym_name() return a const

Originally it was made to return a void* because some comparisons in the
code where it was used required a lot of casts. But now we don't need
that anymore. And having it non-const breaks the build on NetBSD 9 as
reported in issue #728.

So let's switch to const and adjust debug.c to accomodate this.

5 years agoCLEANUP: makefile: update the outdated list of DEBUG_xxx options
Willy Tarreau [Sat, 4 Jul 2020 10:43:46 +0000 (12:43 +0200)] 
CLEANUP: makefile: update the outdated list of DEBUG_xxx options

A few options didn't exist anymore (FSM, HASH) and quite a few ones were
added since last update (MEM_STATS, DONT_SHARE_POOLS, NO_LOCKLESS_POOLS,
NO_LOCAL_POOLS, FAIL_ALLOC, STRICT_NOCRASH, HPACK.

5 years agoBUILD: mux-h2: fix typo breaking build when using DEBUG_LOCK
Willy Tarreau [Sat, 4 Jul 2020 05:16:18 +0000 (07:16 +0200)] 
BUILD: mux-h2: fix typo breaking build when using DEBUG_LOCK

A typo was accidently introduced in commit 48ce6a3 ("BUG/MEDIUM: muxes:
Make sure nobody stole the connection before using it."), a "&" was
placed in front of "OTHER_LOCK", which breaks DEBUG_LOCK. No backport
is needed.

5 years ago[RELEASE] Released version 2.2-dev12 v2.2-dev12
Willy Tarreau [Sat, 4 Jul 2020 05:10:24 +0000 (07:10 +0200)] 
[RELEASE] Released version 2.2-dev12

Released version 2.2-dev12 with the following main changes :
    - BUG/MINOR: mux_h2: don't lose the leaving trace in h2_io_cb()
    - MINOR: cli: make "show sess" stop at the last known session
    - CLEANUP: buffers: remove unused buffer_wq_lock lock
    - BUG/MEDIUM: buffers: always allocate from the local cache first
    - MINOR: connection: align toremove_{lock,connections} and cleanup into idle_conns
    - CONTRIB: debug: add missing flags SI_FL_L7_RETRY & SI_FL_D_L7_RETRY
    - BUG/MEDIUM: connections: Don't increase curr_used_conns for shared connections.
    - BUG/MEDIUM: checks: Increment the server's curr_used_conns
    - REORG: buffer: rename buffer.c to dynbuf.c
    - REORG: includes: create tinfo.h for the thread_info struct
    - CLEANUP: pool: only include the type files from types
    - MINOR: pools: move the LRU cache heads to thread_info
    - BUG/MINOR: debug: fix "show fd" null-deref when built with DEBUG_FD
    - MINOR: stats: add 3 new output values for the per-server idle conn state
    - MINOR: activity: add per-thread statistics on FD takeover
    - BUG/MINOR: server: start cleaning idle connections from various points
    - MEDIUM: server: improve estimate of the need for idle connections
    - MINOR: stats: add the estimated need of concurrent connections per server
    - BUG/MINOR: threads: Don't forget to init each thread toremove_lock.
    - BUG/MEDIUM: lists: Lock the element while we check if it is in a list.
    - Revert "BUG/MEDIUM: lists: Lock the element while we check if it is in a list."
    - BUG/MINOR: haproxy: don't wake already stopping threads on exit
    - BUG/MINOR: server: always count one idle slot for current thread
    - MEDIUM: server: use the two thresholds for the connection release algorithm
    - BUG/MINOR: http-rules: Fix ACLs parsing for http deny rules
    - BUG/MINOR: sched: properly cover for a rare MT_LIST_ADDQ() race
    - MINOR: mux-h1: avoid taking the toremove_lock in on dying tasks
    - MINOR: mux-h2: avoid taking the toremove_lock in on dying tasks
    - MINOR: mux-fcgi: avoid taking the toremove_lock in on dying tasks
    - MINOR: pools: increase MAX_BASE_POOLS to 64
    - DOC: ssl: add "allow-0rtt" and "ciphersuites" in crt-list
    - BUG/MEDIUM: pattern: Add a trailing \0 to match strings only if possible
    - BUG/MEDIUM: log-format: fix possible endless loop in parse_logformat_string()
    - BUG/MINOR: proxy: fix dump_server_state()'s misuse of the trash
    - BUG/MINOR: proxy: always initialize the trash in show servers state
    - MINOR: cli/proxy: add a new "show servers conn" command
    - MINOR: server: skip servers with no idle conns earlier
    - BUG/MINOR: server: fix the connection release logic regarding nearly full conditions
    - MEDIUM: server: add a new pool-low-conn server setting
    - BUG/MEDIUM: backend: always search in the safe list after failing on the idle one
    - MINOR: backend: don't always takeover from the same threads
    - MINOR: sched: make sched->task_list_size atomic
    - MEDIUM: sched: create a new TASK_KILLED task flag
    - MEDIUM: sched: implement task_kill() to kill a task
    - MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup()
    - MEDIUM: mux-h2: use task_kill() during h2_takeover() instead of task_wakeup()
    - MEDIUM: mux-fcgi: use task_kill() during fcgi_takeover() instead of task_wakeup()
    - MINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK()
    - CLEANUP: connections: rename the toremove_lock to takeover_lock
    - MEDIUM: connections: Don't use a lock when moving connections to remove.
    - DOC: configuration: add missing index entries for tune.pool-{low,high}-fd-ratio
    - DOC: configuration: fix alphabetical ordering for tune.pool-{high,low}-fd-ratio
    - MINOR: config: add a new tune.idle-pool.shared global setting.
    - MINOR: 51d: silence a warning about null pointer dereference
    - MINOR: debug: add a new "debug dev memstats" command
    - MINOR: log-format: allow to preserve spacing in log format strings
    - BUILD: debug: avoid build warnings with DEBUG_MEM_STATS
    - BUG/MAJOR: sched: make sure task_kill() always queues the task
    - BUG/MEDIUM: muxes: Make sure nobody stole the connection before using it.
    - BUG/MEDIUM: cli/proxy: don't try to dump idle connection state if there's none
    - BUILD: haproxy: fix build error when RLIMIT_AS is not set
    - BUG/MAJOR: sched: make it work also when not building with DEBUG_STRICT
    - MINOR: log: add time second fraction field to rfc5424 log timestamp.
    - BUG/MINOR: log: missing timezone on iso dates.
    - BUG/MEDIUM: server: don't kill all idle conns when there are not enough
    - MINOR: sched: split tasklet_wakeup() into tasklet_wakeup_on()
    - BUG/MEDIUM: connections: Set the tid for the old tasklet on takeover.
    - BUG/MEDIUM: connections: Let the xprt layer know a takeover happened.
    - BUG/MINOR: http_act: don't check capture id in backend (2)
    - BUILD: makefile: disable threads by default on OpenBSD
    - BUILD: peers: fix build warning with gcc 4.2.1
    - CI: cirrus-ci: exclude slow reg-tests

5 years agoCI: cirrus-ci: exclude slow reg-tests
Ilya Shipitsin [Sat, 27 Jun 2020 06:06:10 +0000 (11:06 +0500)] 
CI: cirrus-ci: exclude slow reg-tests

slow tests are racy, we already skip them on travis-ci, let us do the
same in cirrus-ci

5 years agoBUILD: peers: fix build warning with gcc 4.2.1
Willy Tarreau [Fri, 3 Jul 2020 17:09:29 +0000 (19:09 +0200)] 
BUILD: peers: fix build warning with gcc 4.2.1

Building on OpenBSD 6.7 with gcc-4.2.1 yields the following warnings
which suggest that the initialization is not taken as expected but
that the container member is reset with each initialization:

  src/peers.c: In function 'peer_send_updatemsg':
  src/peers.c:1000: warning: initialized field overwritten
  src/peers.c:1000: warning: (near initialization for 'p.updt')
  src/peers.c:1001: warning: initialized field overwritten
  src/peers.c:1001: warning: (near initialization for 'p.updt')
  src/peers.c:1002: warning: initialized field overwritten
  src/peers.c:1002: warning: (near initialization for 'p.updt')
  src/peers.c:1003: warning: initialized field overwritten
  src/peers.c:1003: warning: (near initialization for 'p.updt')
  src/peers.c:1004: warning: initialized field overwritten
  src/peers.c:1004: warning: (near initialization for 'p.updt')

Fixing this is trivial, we just have to initialize one level at
a time.

5 years agoBUILD: makefile: disable threads by default on OpenBSD
Willy Tarreau [Fri, 3 Jul 2020 16:56:33 +0000 (18:56 +0200)] 
BUILD: makefile: disable threads by default on OpenBSD

As reported by Ilya in issue #725, building with threads on OpenBSD
is broken with gcc:

  include/haproxy/tinfo.h:30: error: thread-local storage not supported for this target

Better stay safe and disable it. Clang seems to support (or emulate)
thread-local, at least it builds. Those willing to experiment can
easily pass USE_THREAD=1.

5 years agoBUG/MINOR: http_act: don't check capture id in backend (2)
Tim Duesterhus [Fri, 3 Jul 2020 11:43:42 +0000 (13:43 +0200)] 
BUG/MINOR: http_act: don't check capture id in backend (2)

Please refer to commit 19a69b3740702ce5503a063e9dfbcea5b9187d27 for all the
details. This follow up commit fixes the `http-response capture` case, the
previous one only fixed the `http-request capture` one. The documentation was
already updated and the change to `check_http_res_capture` is identical to
the `check_http_req_capture` change.

This patch must be backported together with 19a69b3740702ce5503a063e9dfbcea5b9187d27.
Most likely this is 1.6+.

5 years agoBUG/MEDIUM: connections: Let the xprt layer know a takeover happened.
Olivier Houchard [Fri, 3 Jul 2020 12:01:21 +0000 (14:01 +0200)] 
BUG/MEDIUM: connections: Let the xprt layer know a takeover happened.

When we takeover a connection, let the xprt layer know. If it has its own
tasklet, and it is already scheduled, then it has to be destroyed, otherwise
it may run the new mux tasklet on the old thread.

Note that we only do this for the ssl xprt for now, because the only other
one that might wake the mux up is the handshake one, which is supposed to
disappear before idle connections exist.

No backport is needed, this is for 2.2.

5 years agoBUG/MEDIUM: connections: Set the tid for the old tasklet on takeover.
Olivier Houchard [Fri, 3 Jul 2020 12:04:37 +0000 (14:04 +0200)] 
BUG/MEDIUM: connections: Set the tid for the old tasklet on takeover.

In the various takeover() methods, make sure we schedule the old tasklet
on the old thread, as we don't want it to run on our own thread! This
was causing a very rare crash when building with DEBUG_STRICT, seeing
that either an FD's thread mask didn't match the thread ID in h1_io_cb(),
or that stream_int_notify() would try to queue a task with the wrong
tid_bit.

In order to reproduce this, it is necessary to maintain many connections
(typically 30k) at a high request rate flowing over H1+SSL between two
proxies, the second of which would randomly reject ~1% of the incoming
connection and randomly killing some idle ones using a very short client
timeout. The request rate must be adjusted so that the CPUs are nearly
saturated, but never reach 100%. It's easier to reproduce this by skipping
local connections and always picking from other threads. The issue
should happen in less than 20s otherwise it's necessary to restart to
reset the idle connections lists.

No backport is needed, takeover() is 2.2 only.

5 years agoMINOR: sched: split tasklet_wakeup() into tasklet_wakeup_on()
Willy Tarreau [Fri, 3 Jul 2020 15:13:05 +0000 (17:13 +0200)] 
MINOR: sched: split tasklet_wakeup() into tasklet_wakeup_on()

tasklet_wakeup() only checks tl->tid to know whether the task is
programmed to run on the current thread or on a specific thread. We'll
have to ease this selection in a subsequent patch, preferably without
modifying tl->tid, so let's have a new tasklet_wakeup_on() function
to specify the thread number to run on. That the logic has not changed
at all.

5 years agoBUG/MEDIUM: server: don't kill all idle conns when there are not enough
Willy Tarreau [Thu, 2 Jul 2020 17:05:30 +0000 (19:05 +0200)] 
BUG/MEDIUM: server: don't kill all idle conns when there are not enough

In srv_cleanup_idle_connections(), we compute how many idle connections
are in excess compared to the average need. But we may actually be missing
some, for example if a certain number were recently closed and the average
of used connections didn't change much since previous period. In this
case exceed_conn can become negative. There was no special case for this
in the code, and calculating the per-thread share of connections to kill
based on this value resulted in special value -1 to be passed to
srv_migrate_conns_to_remove(), which for this function means "kill all of
them", as used in srv_cleanup_connections() for example.

This causes large variations of idle connections counts on servers and
CPU spikes at the moment the cleanup task passes. These were quite more
visible with SSL as it costs CPU to close and re-establish these
connections, and it also takes time, reducing the reuse ratio, hence
increasing the amount of connections during reconnection.

In this patch we simply skip the killing loop when this condition is met.

No backport is needed, this is purely 2.2.

5 years agoBUG/MINOR: log: missing timezone on iso dates.
Emeric Brun [Thu, 2 Jul 2020 15:22:17 +0000 (17:22 +0200)] 
BUG/MINOR: log: missing timezone on iso dates.

The function timeofday_as_iso_us adds now the trailing local timezone offset.
Doing this the function could be use directly to generate rfc5424 logs.

It affects content of a ring if the ring's format is set to 'iso' and 'timed'.
Note: the default ring 'buf0' is of type 'timed'.

It is preferable NOT to backport this to stable releases unless bugs are
reported, because while the previous format is not correct and the new
one is correct, there is a small risk to cause inconsistencies in log
format to some users who would not expect such a change in a stable
cycle.

5 years agoMINOR: log: add time second fraction field to rfc5424 log timestamp.
Emeric Brun [Thu, 2 Jul 2020 14:16:59 +0000 (16:16 +0200)] 
MINOR: log: add time second fraction field to rfc5424 log timestamp.

This patch adds the time second fraction in microseconds
as supported by the rfc.

5 years agoBUG/MAJOR: sched: make it work also when not building with DEBUG_STRICT
Willy Tarreau [Thu, 2 Jul 2020 15:17:42 +0000 (17:17 +0200)] 
BUG/MAJOR: sched: make it work also when not building with DEBUG_STRICT

Sadly, the fix from commit 54d31170a ("BUG/MAJOR: sched: make sure
task_kill() always queues the task") broke the builds without DEBUG_STRICT
as, in order to be careful, it plcaed a BUG_ON() around the previously
failing condition to check for any new possible failure, but this BUG_ON
strips the condition when DEBUG_STRICT is not set. We don't want BUG_ON
to evaluate any condition either as some debugging code calls possibly
expensive ones (e.g. in htx_get_stline). Let's just drop the useless
BUG_ON().

No backport is needed, this is 2.2-dev.

5 years agoBUILD: haproxy: fix build error when RLIMIT_AS is not set
Willy Tarreau [Thu, 2 Jul 2020 13:38:35 +0000 (15:38 +0200)] 
BUILD: haproxy: fix build error when RLIMIT_AS is not set

As reported in issue #724, openbsd fails to build in haproxy.c
due to a faulty comma in the middle of a warning message. This code
is only compiled when RLIMIT_AS is not defined, which seems to be
rare these days.

This may be backported to older versions as the problem was likely
introduced when strict limits were added.

5 years agoBUG/MEDIUM: cli/proxy: don't try to dump idle connection state if there's none
Willy Tarreau [Thu, 2 Jul 2020 13:19:57 +0000 (15:19 +0200)] 
BUG/MEDIUM: cli/proxy: don't try to dump idle connection state if there's none

Commit 69f591e3b ("MINOR: cli/proxy: add a new "show servers conn" command")
added the ability to dump the idle connections state for a server, but we
must not do this if idle connections were not allocated, which happens if
the server is configured with pool-max-conn 0.

This is 2.2, no backport is needed.

5 years agoBUG/MEDIUM: muxes: Make sure nobody stole the connection before using it.
Olivier Houchard [Thu, 2 Jul 2020 09:58:05 +0000 (11:58 +0200)] 
BUG/MEDIUM: muxes: Make sure nobody stole the connection before using it.

In the various timeout functions, make sure nobody stole the connection from
us before attempting to doing anything with it, there's a very small race
condition between the time we access the task context, and the time we
actually check it again with the lock, where it could have been free'd.

5 years agoBUG/MAJOR: sched: make sure task_kill() always queues the task
Willy Tarreau [Thu, 2 Jul 2020 12:14:00 +0000 (14:14 +0200)] 
BUG/MAJOR: sched: make sure task_kill() always queues the task

task_kill() may fail to queue a task if this task has never ever run,
because its equivalent (tasklet->list) member has never been "emptied"
since it didn't pass through the LIST_DEL_INIT() that's performed by
run_tasks_from_lists(). This results in these tasks to never be freed.

It happens during the mux takeover since the target task usually is
the timeout task which, by definition, has never run yet.

This fixes commit eb8c2c69f ("MEDIUM: sched: implement task_kill() to
kill a task") which was introduced after 2.2-dev11 and doesn't need to
be backported.

5 years agoBUILD: debug: avoid build warnings with DEBUG_MEM_STATS
Willy Tarreau [Thu, 2 Jul 2020 08:25:01 +0000 (10:25 +0200)] 
BUILD: debug: avoid build warnings with DEBUG_MEM_STATS

Some libcs define strdup() as a macro and cause redefine warnings to
be emitted, so let's first undefine all functions we redefine.

5 years agoMINOR: log-format: allow to preserve spacing in log format strings
Dragan Dosen [Tue, 23 Jun 2020 16:16:44 +0000 (18:16 +0200)] 
MINOR: log-format: allow to preserve spacing in log format strings

Now it's possible to preserve spacing everywhere except in "log-format",
"log-format-sd" and "unique-id-format" directives, where spaces are
delimiters and are merged. That may be useful when the response payload
is specified as a log format string by "lf-file" or "lf-string", or even
for headers or anything else.

In order to merge spaces, a new option LOG_OPT_MERGE_SPACES is applied
exclusively on options passed to function parse_logformat_string().

This patch fixes an issue #701 ("http-request return log-format file
evaluation altering spacing of ASCII output/art").

5 years agoMINOR: debug: add a new "debug dev memstats" command
Willy Tarreau [Thu, 2 Jul 2020 07:14:48 +0000 (09:14 +0200)] 
MINOR: debug: add a new "debug dev memstats" command

Now when building with -DDEBUG_MEM_STATS, some malloc/calloc/strdup/realloc
stats are kept per file+line number and may be displayed and even reset on
the CLI using "debug dev memstats". This allows to easily track potential
leakers or abnormal usages.

5 years agoMINOR: 51d: silence a warning about null pointer dereference
Dragan Dosen [Wed, 1 Jul 2020 17:58:32 +0000 (19:58 +0200)] 
MINOR: 51d: silence a warning about null pointer dereference

This is due to issue #713, that reports null pointer dereference
suspected by coverity.

5 years agoMINOR: config: add a new tune.idle-pool.shared global setting.
Willy Tarreau [Wed, 1 Jul 2020 16:49:24 +0000 (18:49 +0200)] 
MINOR: config: add a new tune.idle-pool.shared global setting.

Enables ('on') or disables ('off') sharing of idle connection pools between
threads for a same server. The default is to share them between threads in
order to minimize the number of persistent connections to a server, and to
optimize the connection reuse rate. But to help with debugging or when
suspecting a bug in HAProxy around connection reuse, it can be convenient to
forcefully disable this idle pool sharing between multiple threads, and force
this option to "off". The default is on.

This could have been nice to have during the idle connections debugging,
but it's not too late to add it!

5 years agoDOC: configuration: fix alphabetical ordering for tune.pool-{high,low}-fd-ratio
Willy Tarreau [Wed, 1 Jul 2020 16:30:16 +0000 (18:30 +0200)] 
DOC: configuration: fix alphabetical ordering for tune.pool-{high,low}-fd-ratio

In addition they were in the wrong alphabetical order in the doc. They
were added in 2.0 by commit 88698d966 ("MEDIUM: connections: Add a way
to control the number of idling connections.") so this must be backported
to 2.0.

5 years agoDOC: configuration: add missing index entries for tune.pool-{low,high}-fd-ratio
Willy Tarreau [Wed, 1 Jul 2020 16:27:16 +0000 (18:27 +0200)] 
DOC: configuration: add missing index entries for tune.pool-{low,high}-fd-ratio

These two keywords didn't have an entry in the index. They were added in
2.0 by commit 88698d966 ("MEDIUM: connections: Add a way to control the
number of idling connections.") so this must be backported to 2.0.

5 years agoMEDIUM: connections: Don't use a lock when moving connections to remove.
Olivier Houchard [Mon, 29 Jun 2020 18:15:59 +0000 (20:15 +0200)] 
MEDIUM: connections: Don't use a lock when moving connections to remove.

Make it so we don't have to take a lock while moving a connection from
the idle list to the toremove_list by taking advantage of the MT_LIST.

5 years agoCLEANUP: connections: rename the toremove_lock to takeover_lock
Olivier Houchard [Mon, 29 Jun 2020 18:15:59 +0000 (20:15 +0200)] 
CLEANUP: connections: rename the toremove_lock to takeover_lock

This lock was misnamed and a bit confusing. It's only used for takeover
so let's call it takeover_lock.

5 years agoMINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK()
Olivier Houchard [Mon, 29 Jun 2020 18:14:28 +0000 (20:14 +0200)] 
MINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK()

Add two new macros, MT_LIST_DEL_SAFE_NOINIT makes sure we remove the
element from the list, without reinitializing its next and prev, and
MT_LIST_ADDQ_NOCHECK is similar to MT_LIST_ADDQ(), except it doesn't check
if the element is already in a list.
The goal is to be able to move an element from a list we're currently
parsing to another, keeping it locked in the meanwhile.

5 years agoMEDIUM: mux-fcgi: use task_kill() during fcgi_takeover() instead of task_wakeup()
Willy Tarreau [Wed, 1 Jul 2020 14:39:33 +0000 (16:39 +0200)] 
MEDIUM: mux-fcgi: use task_kill() during fcgi_takeover() instead of task_wakeup()

task_wakeup() passes the task through the global run queue under the
global RQ lock, which is expensive when dealing with large amounts of
fcgi_takeover() calls. Let's use the new task_kill() instead to kill the
task.

5 years agoMEDIUM: mux-h2: use task_kill() during h2_takeover() instead of task_wakeup()
Willy Tarreau [Wed, 1 Jul 2020 14:39:33 +0000 (16:39 +0200)] 
MEDIUM: mux-h2: use task_kill() during h2_takeover() instead of task_wakeup()

task_wakeup() passes the task through the global run queue under the
global RQ lock, which is expensive when dealing with large amounts of
h2_takeover() calls. Let's use the new task_kill() instead to kill the
task.

5 years agoMEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup()
Willy Tarreau [Wed, 1 Jul 2020 14:39:33 +0000 (16:39 +0200)] 
MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup()

task_wakeup() passes the task through the global run queue under the
global RQ lock, which is expensive when dealing with large amounts of
h1_takeover() calls. Let's use the new task_kill() instead to kill the
task.

By doing so, a scenario involving approximately 130k takeover/s running on
16 threads gained almost 3% performance from 319k req/s to 328k.

5 years agoMEDIUM: sched: implement task_kill() to kill a task
Willy Tarreau [Tue, 30 Jun 2020 09:48:48 +0000 (11:48 +0200)] 
MEDIUM: sched: implement task_kill() to kill a task

task_kill() may be used by any thread to kill any task with less overhead
than a regular wakeup. In order to achieve this, it bypasses the priority
tree and inserts the task directly into the shared tasklets list, cast as
a tasklet. The task_list_size is updated to make sure it is properly
decremented after execution of this task. The task will thus be picked by
process_runnable_tasks() after checking the tree and sent to the TL_URGENT
list, where it will be processed and killed.

If the task is bound to more than one thread, its first thread will be the
one notified.

If the task was already queued or running, nothing is done, only the flag
is added so that it gets killed before or after execution. Of course it's
the caller's responsibility to make sur any resources allocated by this
task were already cleaned up or taken over.

5 years agoMEDIUM: sched: create a new TASK_KILLED task flag
Willy Tarreau [Tue, 30 Jun 2020 09:48:48 +0000 (11:48 +0200)] 
MEDIUM: sched: create a new TASK_KILLED task flag

This flag, when set, will be used to indicate that the task must die.
At the moment this may only be placed by the task itself or by the
scheduler when placing it into the TL_NORMAL queue.

5 years agoMINOR: sched: make sched->task_list_size atomic
Willy Tarreau [Tue, 30 Jun 2020 09:48:48 +0000 (11:48 +0200)] 
MINOR: sched: make sched->task_list_size atomic

We'll need to update it from foreign threads in order to throw killed
tasks and maintain correct accounting, so let's make it atomic.

5 years agoMINOR: backend: don't always takeover from the same threads
Willy Tarreau [Wed, 1 Jul 2020 13:55:30 +0000 (15:55 +0200)] 
MINOR: backend: don't always takeover from the same threads

The next thread walking algorithm in commit 566df309c ("MEDIUM:
connections: Attempt to get idle connections from other threads.")
proved to be sufficient for most cases, but it still has some rough
edges when threads are unevenly loaded. If one thread wakes up with
10 streams to process in a burst, it will mainly take over connections
from the next one until it doesn't have anymore.

This patch implements a rotating index that is stored into the server
list and that any thread taking over a connection is responsible for
updating. This way it starts mostly random and avoids always picking
from the same place. This results in a smoother distribution overall
and a slightly lower takeover rate.

5 years agoBUG/MEDIUM: backend: always search in the safe list after failing on the idle one
Willy Tarreau [Wed, 1 Jul 2020 13:04:38 +0000 (15:04 +0200)] 
BUG/MEDIUM: backend: always search in the safe list after failing on the idle one

There's a tricky behavior that was lost when the idle connections were
made sharable between thread in commit 566df309c ("MEDIUM: connections:
Attempt to get idle connections from other threads."), it is the ability
to retry from the safe list when looking for any type of idle connection
and not finding one in the idle list.

It is already important when dealing with long-lived connections since
they ultimately all become safe, but that case is already covered by
the fact that safe conns not being used end up closing and are not
looked up anymore since connect_server() sees there are none.

But it's even more important when using server-side connections which
periodically close, because the new connections may spend half of their
time in safe state and the other half in the idle state, and failing
to grab one such connection from the right list results in establishing
a new connection.

This patch makes sure that a failure to find an idle connection results
in a new attempt at finding one from the safe list if available. In order
to avoid locking twice, connections are attempted alternatively from the
idle then safe list when picking from siblings. Tests have shown a ~2%
performance increase by avoiding to lock twice.

A typical test with 10000 connections over 16 threads with 210 servers
having a 1 millisecond response time and closing every 5 requests shows
a degrading performance starting at 120k req/s down to 60-90k and an
average reuse rate of 44%. After the fix, the reuse rate raises to 79%
and the performance becomes stable at 254k req/s. Similarly the previous
test with full keep-alive has now increased from 96% reuse rate to 99%
and from 352k to 375k req/s.

No backport is needed as this is 2.2-only.

5 years agoMEDIUM: server: add a new pool-low-conn server setting
Willy Tarreau [Wed, 1 Jul 2020 05:43:51 +0000 (07:43 +0200)] 
MEDIUM: server: add a new pool-low-conn server setting

The problem with the way idle connections currently work is that it's
easy for a thread to steal all of its siblings' connections, then release
them, then it's done by another one, etc. This happens even more easily
due to scheduling latencies, or merged events inside the same pool loop,
which, when dealing with a fast server responding in sub-millisecond
delays, can really result in one thread being fully at work at a time.

In such a case, we perform a huge amount of takeover() which consumes
CPU and requires quite some locking, sometimes resulting in lower
performance than expected.

In order to fight against this problem, this patch introduces a new server
setting "pool-low-conn", whose purpose is to dictate when it is allowed to
steal connections from a sibling. As long as the number of idle connections
remains at least as high as this value, it is permitted to take over another
connection. When the idle connection count becomes lower, a thread may only
use its own connections or create a new one. By proceeding like this even
with a low number (typically 2*nbthreads), we quickly end up in a situation
where all active threads have a few connections. It then becomes possible
to connect to a server without bothering other threads the vast majority
of the time, while still being able to use these connections when the
number of available FDs becomes low.

We also use this threshold instead of global.nbthread in the connection
release logic, allowing to keep more extra connections if needed.

A test performed with 10000 concurrent HTTP/1 connections, 16 threads
and 210 servers with 1 millisecond of server response time showed the
following numbers:

   haproxy 2.1.7:           185000 requests per second
   haproxy 2.2:             314000 requests per second
   haproxy 2.2 lowconn 32:  352000 requests per second

The takeover rate goes down from 300k/s to 13k/s. The difference is
further amplified as the response time shrinks.

5 years agoBUG/MINOR: server: fix the connection release logic regarding nearly full conditions
Willy Tarreau [Wed, 1 Jul 2020 11:57:49 +0000 (13:57 +0200)] 
BUG/MINOR: server: fix the connection release logic regarding nearly full conditions

There was a logic bug in commit ddfe0743d ("MEDIUM: server: use the two
thresholds for the connection release algorithm"): instead of keeping
only our first idle connection when FDs become scarce, the condition was
inverted resulting in enforcing this constraint unless FDs are scarce.
This results in less idle connections than permitted to be kept under
normal condition.

No backport needed.

5 years agoMINOR: server: skip servers with no idle conns earlier
Willy Tarreau [Wed, 1 Jul 2020 06:24:44 +0000 (08:24 +0200)] 
MINOR: server: skip servers with no idle conns earlier

In conn_backend_get() we can avoid locking other servers when trying
to steal their connections when we know for sure they will not have
one, so let's do it to lower the contention on the lock.

5 years agoMINOR: cli/proxy: add a new "show servers conn" command
Willy Tarreau [Wed, 1 Jul 2020 05:00:59 +0000 (07:00 +0200)] 
MINOR: cli/proxy: add a new "show servers conn" command

This command reuses the existing "show servers state" to also dump the
state of active and idle connections. The main use is to serve as a
debugging tool to troubleshot connection reuse issues.

5 years agoBUG/MINOR: proxy: always initialize the trash in show servers state
Willy Tarreau [Wed, 1 Jul 2020 05:09:39 +0000 (07:09 +0200)] 
BUG/MINOR: proxy: always initialize the trash in show servers state

Actually the cleanup in commit 6ff8143f7 ("BUG/MINOR: proxy: fix
dump_server_state()'s misuse of the trash") allowed to spot that the
trash is never reset when dumping a servers state. I couldn't manage
to make it dump garbage even with large setups but didn't find either
where it's cleared between successive calls while other handlers do
explicitly invoke chunk_reset(), so it seems to happen a bit by luck.

Let's use chunk_printf() here for each turn, it makes things clearer.

This could be backported along with previous patch, especially if any
user reports occasional garbage appearing in the show servers output.

5 years agoBUG/MINOR: proxy: fix dump_server_state()'s misuse of the trash
Willy Tarreau [Wed, 1 Jul 2020 05:02:42 +0000 (07:02 +0200)] 
BUG/MINOR: proxy: fix dump_server_state()'s misuse of the trash

dump_server_state() claims to dump into a buffer but instead it writes
into a buffer then dumps the trash into the channel, so it only supports
being called with buf=&trash and doesn't need this buffer. There doesn't
seem to be any current impact of this mistake since the function is called
from one location only.

A backport may be performed if it helps fixing other bugs but it will not
fix an existing bug by itself.

5 years agoBUG/MEDIUM: log-format: fix possible endless loop in parse_logformat_string()
Dragan Dosen [Tue, 30 Jun 2020 19:16:43 +0000 (21:16 +0200)] 
BUG/MEDIUM: log-format: fix possible endless loop in parse_logformat_string()

This patch adds a missing break to end the loop in case when '%[' is not
properly closed with ']'.

The issue has been introduced with commit cd0d2ed ("MEDIUM: log-format:
make the LF parser aware of sample expressions' end").

5 years agoBUG/MEDIUM: pattern: Add a trailing \0 to match strings only if possible
Christopher Faulet [Tue, 30 Jun 2020 16:52:32 +0000 (18:52 +0200)] 
BUG/MEDIUM: pattern: Add a trailing \0 to match strings only if possible

In pat_match_str() and pat_math_beg() functions, a trailing zero is
systematically added at the end of the string, even if the buffer is not large
enough to accommodate it. It is a possible buffer overflow. For instance, when
the alpn is matched against a list of strings, the sample fetch is filled with a
non-null terminated string returned by the SSL library. No trailing zero must be
added at the end of this string, because it is outside the buffer.

So, to fix the bug, a trailing zero is added only if the buffer is large enough
to accommodate it. Otherwise, the sample fetch is duplicated. smp_dup() function
adds a trailing zero to the duplicated string, truncating it if it is too long.

This patch should fix the issue #718. It must be backported to all supported
versions.

5 years agoDOC: ssl: add "allow-0rtt" and "ciphersuites" in crt-list
William Lallemand [Tue, 30 Jun 2020 14:11:36 +0000 (16:11 +0200)] 
DOC: ssl: add "allow-0rtt" and "ciphersuites" in crt-list

Support for "allow-0rtt" and "ciphersuites" exists for crt-list.

Fix issue #721.

Should be backported as far as 1.8.

5 years agoMINOR: pools: increase MAX_BASE_POOLS to 64
Willy Tarreau [Tue, 30 Jun 2020 12:29:02 +0000 (14:29 +0200)] 
MINOR: pools: increase MAX_BASE_POOLS to 64

When not sharing pools (i.e. when building with -DDEBUG_DONT_SHARE_POOLS)
we have about 47 pools right now, while MAX_BASE_POOLS is only 32, meaning
that only the first 32 ones will benefit from a per-thread cache entry.
This totally kills performance when pools are not shared (roughly -20%).

Let's double the limit to gain some margin, and make it possible to set
it as a build option.

It might be useful to backport this to stable versions as they're likely
to be affected as well.

5 years agoMINOR: mux-fcgi: avoid taking the toremove_lock in on dying tasks
Willy Tarreau [Tue, 30 Jun 2020 09:19:23 +0000 (11:19 +0200)] 
MINOR: mux-fcgi: avoid taking the toremove_lock in on dying tasks

If the owning task is already dying (context was destroyed by fcgi_takeover)
there's no point taking the lock then removing it later since all the code
in between is conditionned by a non-null context. Let's simplify this.

5 years agoMINOR: mux-h2: avoid taking the toremove_lock in on dying tasks
Willy Tarreau [Tue, 30 Jun 2020 09:19:23 +0000 (11:19 +0200)] 
MINOR: mux-h2: avoid taking the toremove_lock in on dying tasks

If the owning task is already dying (context was destroyed by h2_takeover)
there's no point taking the lock then removing it later since all the code
in between is conditionned by a non-null context. Let's simplify this.

5 years agoMINOR: mux-h1: avoid taking the toremove_lock in on dying tasks
Willy Tarreau [Tue, 30 Jun 2020 09:19:23 +0000 (11:19 +0200)] 
MINOR: mux-h1: avoid taking the toremove_lock in on dying tasks

If the owning task is already dying (context was destroyed by h1_takeover)
there's no point taking the lock then removing it later since all the code
in between is conditionned by a non-null context. Let's simplify this.

5 years agoBUG/MINOR: sched: properly cover for a rare MT_LIST_ADDQ() race
Willy Tarreau [Tue, 30 Jun 2020 11:46:21 +0000 (13:46 +0200)] 
BUG/MINOR: sched: properly cover for a rare MT_LIST_ADDQ() race

In commit 3ef7a190b ("MEDIUM: tasks: apply a fair CPU distribution
between tasklet classes") we compute a total weight to be used to
split the CPU time between queues. There is a mention that the
total cannot be null, wihch is based on the fact that we only get
there if thread_has_task() returns non-zero. But there is a very
small race which can break this assumption: if two threads conflict
on MT_LIST_ADDQ() on an empty shared list and both roll back before
trying again, there is the possibility that a first call to
MT_LIST_ISEMPTY() sees the first thread install itself, then the
second call will see the list empty when both roll back. Thus we
could proceed with the queue while it's temporarily empty and
compute max lengths using a divide by zero. This case is very
hard to trigger, it seldom happens on 16 threads at 400k req/s.

Let's simply test for max_total and leave the loop when we've not
found any work.

No backport is needed, that's 2.2-only.

5 years agoBUG/MINOR: http-rules: Fix ACLs parsing for http deny rules
Christopher Faulet [Tue, 30 Jun 2020 07:32:01 +0000 (09:32 +0200)] 
BUG/MINOR: http-rules: Fix ACLs parsing for http deny rules

The parsing of http deny rules with no argument or only the deny_status argument
is buggy if followed by an ACLs expression (starting with "if" or "unless"
keyword). Instead of using the proxy errorfiles, a dummy error is used. To fix
the bug, the parsing function must also check for "if" or "unless" keyword in
such cases.

This patch should fix the issue #720. No backport is needed.

5 years agoMEDIUM: server: use the two thresholds for the connection release algorithm
Willy Tarreau [Mon, 29 Jun 2020 18:55:53 +0000 (20:55 +0200)] 
MEDIUM: server: use the two thresholds for the connection release algorithm

The algorithm improvement in bdb86bd ("MEDIUM: server: improve estimate
of the need for idle connections") is still not enough because there's
a hard limit between below and above the FD count, so it continues to
end up with many killed connections.

Here we're proceeding differently. Given that there are two configured
limits, a low and a high one, what we do is that we drop connections
when the high limit is reached (what's already done by the killing task
anyway), when we're between the low and the high threshold, we only keep
the connection if our idle entries are empty (with a preference for safe
ones), and below the low threshold, we keep any connection so as to give
them a chance of being reused or taken over by another thread.

Proceeding like this results in much less dropped connections, we
typically see a 99.3% reuse rate (76k conns for 10M requests over 200
servers and 4 threads, with 335k takeovers or 3%), and much less CPU
usage variations because there are no more bursts to try to kill extra
connections.

It should be possible to further improve this by counting the number
of threads exploiting a server and trying to optimize the amount of
per-thread idle connections so that it is approximately balanced among
the threads.

5 years agoBUG/MINOR: server: always count one idle slot for current thread
Willy Tarreau [Mon, 29 Jun 2020 18:37:29 +0000 (20:37 +0200)] 
BUG/MINOR: server: always count one idle slot for current thread

The idle server connection estimates brought in commit bdb86bd ("MEDIUM:
server: improve estimate of the need for idle connections") were committed
without the minimum of 1 idle conn needed for the current thread. The net
effect is that there are bursts of dropped connections when the load varies
because there's no provision for the last connection.

No backport needed, this is 2.2-dev.

5 years agoBUG/MINOR: haproxy: don't wake already stopping threads on exit
Willy Tarreau [Mon, 29 Jun 2020 17:23:19 +0000 (19:23 +0200)] 
BUG/MINOR: haproxy: don't wake already stopping threads on exit

Commit d645574 ("MINOR: soft-stop: let the first stopper only signal
other threads") introduced a minor mistake which is that when a stopping
thread signals all other threads, it also signals itself. When
single-threaded, the process constantly wakes up while waiting for
last connections to exit. Let's reintroduce the lost mask to avoid
this.

No backport is needed, this is 2.2-dev only.