]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 years agoMINOR: quic: split and rename qc_lstnr_pkt_rcv()
Amaury Denoyelle [Wed, 19 Oct 2022 13:37:44 +0000 (15:37 +0200)] 
MINOR: quic: split and rename qc_lstnr_pkt_rcv()

This change is the following of qc_lstnr_pkt_rcv() refactoring. This
function has finally been split into several ones.

The first half is renamed quic_rx_pkt_parse(). This function is
responsible to parse a QUIC packet header and calculate the packet
length.

QUIC connection retrieval has been extracted and is now called directly
by quic_lstnr_dghdlr().

The second half of qc_lstnr_pkt_rcv() is renamed to qc_rx_pkt_handle().
This function is responsible to copy a QUIC packet content to a
quic-conn receive buffer.

A third function named qc_rx_check_closing() is responsible to detect if
the connection is already in closing state. As this requires to drop the
whole datagram, it seems justified to be in a separate function.

This change has no functional impact. It is part of a refactoring series
on qc_lstnr_pkt_rcv(). The objective is to facilitate the integration of
FD-owned quic-conn socket patches.

This should be backported up to 2.6.

2 years agoMINOR: quic: extract connection retrieval
Amaury Denoyelle [Wed, 19 Oct 2022 13:28:44 +0000 (15:28 +0200)] 
MINOR: quic: extract connection retrieval

Simplify qc_lstnr_pkt_rcv() by extracting code responsible to retrieve
the quic-conn instance. This code is put in a dedicated function named
quic_rx_pkt_retrieve_conn(). This new function could be skipped if a
FD-owned quic-conn socket is used.

The first traces of qc_lstnr_pkt_rcv() have been clean up as qc instance
is always NULL here : thus qc parameter can be removed without any
change.

This change has no functional impact. It is a part of a refactoring
series on qc_lstnr_pkt_rcv(). The objective is facilitate integration of
FD-owned socket patches.

This should be backported up to 2.6.

2 years agoMINOR: quic: define first packet flag
Amaury Denoyelle [Wed, 19 Oct 2022 15:14:28 +0000 (17:14 +0200)] 
MINOR: quic: define first packet flag

Received packets treatment has some difference regarding if this is the
first one or not of the encapsulating datagram. Previously, this was set
via a function argument. Simplify this by defining a new Rx packet flag
named QUIC_FL_RX_PACKET_DGRAM_FIRST.

This change does not have functional impact. It will simplify API when
qc_lstnr_pkt_rcv() is broken into several functions : their number of
arguments will be reduced thanks to this patch.

This should be backported up to 2.6.

2 years agoMINOR: quic: extend pn_offset field from quic_rx_packet
Amaury Denoyelle [Mon, 17 Oct 2022 16:05:26 +0000 (18:05 +0200)] 
MINOR: quic: extend pn_offset field from quic_rx_packet

pn_offset field was only set if header protection cannot be removed.
Extend the usage of this field : it is now set everytime on packet
parsing in qc_lstnr_pkt_rcv().

This change helps to clean up API of Rx functions by removing
unnecessary variables and function argument.

This change has no functional impact. It is a part of a refactoring
series on qc_lstnr_pkt_rcv(). The objective is facilitate integration of
FD-owned socket patches.

This should be backported up to 2.6.

2 years agoMINOR: quic: add version field on quic_rx_packet
Amaury Denoyelle [Mon, 17 Oct 2022 16:05:18 +0000 (18:05 +0200)] 
MINOR: quic: add version field on quic_rx_packet

Add a new field version on quic_rx_packet structure. This is set on
header parsing in qc_lstnr_pkt_rcv() function.

This change has no functional impact. It is a part of a refactoring
series on qc_lstnr_pkt_rcv(). The objective is facilitate integration of
FD-owned socket patches.

This should be backported up to 2.6.

2 years agoBUG/MINOR: quic: fix buffer overflow on retry token generation
Amaury Denoyelle [Tue, 18 Oct 2022 09:05:02 +0000 (11:05 +0200)] 
BUG/MINOR: quic: fix buffer overflow on retry token generation

When generating a Retry token, client CID is used as encryption input.
The client must reuse the same CID when emitting the token in a new
Initial packet.

A memory overflow can occur on quic_generate_retry_token() depending on
the size of client CID. This is because space reserved for <aad> only
accounted for QUIC_HAP_CID_LEN (size of haproxy owned generated CID).
However, the client CID size only depends on client parameter and is
instead limited to QUIC_CID_MAXLEN as specified in RFC9000.

This was reproduced with ngtcp2 and haproxy built with ASAN. Here is the error
log :
  ==14964==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffee228cee at pc 0x7ffff785f427 bp 0x7fffee2289e0 sp 0x7fffee228188
  WRITE of size 17 at 0x7fffee228cee thread T5
      #0 0x7ffff785f426 in __interceptor_memcpy /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
      #1 0x555555906ea7 in quic_generate_retry_token_aad src/quic_conn.c:5452
      #2 0x555555907e72 in quic_retry_token_check src/quic_conn.c:5577
      #3 0x55555590d01e in qc_lstnr_pkt_rcv src/quic_conn.c:6103
      #4 0x5555559190fa in quic_lstnr_dghdlr src/quic_conn.c:7179
      #5 0x555555eb0abf in run_tasks_from_lists src/task.c:590
      #6 0x555555eb285f in process_runnable_tasks src/task.c:855
      #7 0x555555d9118f in run_poll_loop src/haproxy.c:2853
      #8 0x555555d91f88 in run_thread_poll_loop src/haproxy.c:3042
      #9 0x7ffff709f8fc  (/usr/lib/libc.so.6+0x868fc)
      #10 0x7ffff7121a5f  (/usr/lib/libc.so.6+0x108a5f)

This must be backported up to 2.6.

2 years agoBUILD: quic: Fix build for m68k cross-compilation
Frédéric Lécaille [Tue, 18 Oct 2022 09:57:01 +0000 (11:57 +0200)] 
BUILD: quic: Fix build for m68k cross-compilation

Fix several warinings as this one:

src/qmux_trace.c:80:45: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘uint64_t’ {aka ‘const long long unsigned int’} [-Werror=format=]
   80 |    chunk_appendf(&trace_buf, " qcs=%p .id=%lu .st=%s",
      |                                           ~~^
      |                                             |
      |                                             long unsigned int
      |                                           %llu
   81 |                  qcs, qcs->id,
      |                       ~~~~~~~
      |                          |
      |                          uint64_t {aka const long long unsigned int}
compilation terminated due to -Wfatal-errors.

Cast remaining uint64_t variables as ullong with %llu as printf format and size_t
others as ulong with %lu as printf format.

Thank you to Ilya for having reported this issue in GH #1899.

Must be backported to 2.6

2 years agoBUILD: ssl_sock: fix null dereference for QUIC build
Amaury Denoyelle [Mon, 17 Oct 2022 16:46:49 +0000 (18:46 +0200)] 
BUILD: ssl_sock: fix null dereference for QUIC build

A previous commit tries to fix uninitialized GCC warning on ssl code for
QUIC build. See the fix here :
  48e46f98ccf97427995eb41c6f28cc38705bdd7e
  BUILD: ssl_sock: bind_conf uninitialized in ssl_sock_bind_verifycbk()

However, this is incomplete as it still reports possible NULL
dereference on ctx variable (GCC v12.2.0). Here is the compilation
result :

  src/ssl_sock.c: In function ‘ssl_sock_bind_verifycbk’:
  src/ssl_sock.c:1739:12: error: potential null pointer dereference [-Werror=null-dereference]
   1739 |         ctx->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
        |

To fix this, remove check on qc which can also never happens and replace
it with a BUG_ON. This seems to satisfy GCC on my machine.

This must be backported up to 2.6.

2 years agoBUG/MEDIUM: httpclient: segfault when the httpclient parser fails
Thierry Fournier [Mon, 10 Oct 2022 10:46:38 +0000 (12:46 +0200)] 
BUG/MEDIUM: httpclient: segfault when the httpclient parser fails

If the uri is unexpected ("/" in place of "http://xxx/"), some parsing
function fails. The failure is not handled.

This patch handle these errors. Note: the return code is boolean, maybe
we can return more precise error for Lua reporting ?

Must be backported in 2.6.

2 years agoBUILD: scripts: disable tests build on QuicTLS build
Ilya Shipitsin [Sat, 15 Oct 2022 04:55:49 +0000 (09:55 +0500)] 
BUILD: scripts: disable tests build on QuicTLS build

during CI builds QuicTLS is not cached, let us speed it up by
disabling tests build. Doing so saves ~40s out of 3m40.

2 years agoBUILD: quic: QUIC mux build fix for 32-bit build
Frédéric Lécaille [Fri, 14 Oct 2022 20:10:50 +0000 (22:10 +0200)] 
BUILD: quic: QUIC mux build fix for 32-bit build

Thank you to Ilya for having reported this issue in GH #1897

Must be backported to 2.6.

2 years ago[RELEASE] Released version 2.7-dev8 v2.7-dev8
Willy Tarreau [Fri, 14 Oct 2022 18:45:23 +0000 (20:45 +0200)] 
[RELEASE] Released version 2.7-dev8

Released version 2.7-dev8 with the following main changes :
    - BUG/MINOR: checks: update pgsql regex on auth packet
    - DOC: config: Fix pgsql-check documentation to make user param mandatory
    - CLEANUP: mux-quic: remove usage of non-standard ull type
    - CLEANUP: quic: remove global var definition in quic_tls header
    - BUG/MINOR: quic: adjust quic_tls prototypes
    - CLEANUP: quic: fix headers
    - CLEANUP: quic: remove unused function prototype
    - CLEANUP: quic: remove duplicated varint code from xprt_quic.h
    - CLEANUP: quic: create a dedicated quic_conn module
    - BUG/MINOR: mux-quic: ignore STOP_SENDING for locally closed stream
    - BUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure
    - BUG/MEDIUM: lua: handle stick table implicit arguments right.
    - BUILD: h1: silence an initiialized warning with gcc-4.7 and -Os
    - MINOR: fd: add a new function to only raise RLIMIT_NOFILE
    - MINOR: init: do not try to shrink existing RLIMIT_NOFIlE
    - BUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth()
    - BUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os
    - BUG/MINOR: hlua: hlua_channel_insert_data() behavior conflicts with documentation
    - MINOR: quic: limit usage of ssl_sock_ctx in favor of quic_conn
    - MINOR: mux-quic: check quic-conn return code on Tx
    - CLEANUP: quic: fix indentation
    - MEDIUM: quic: retrieve frontend destination address
    - CLEANUP: Reapply ist.cocci (2)
    - CLEANUP: Reapply strcmp.cocci
    - CLEANUP: quic/receiver: remove the now unused tx_qring list
    - BUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only
    - MINOR: hlua: some luaL_checktype() calls were not guarded with MAY_LJMP
    - DOC: configuration: missing 'if' in tcp-request content example
    - MINOR: hlua: removing ambiguous lua_pushvalue with 0 index
    - BUG/MAJOR: stick-tables: do not try to index a server name for applets
    - MINOR: plock: support disabling exponential back-off
    - MINOR: freq_ctr: use the thread's local time whenever possible
    - MEDIUM: stick-table: switch the table lock to rwlock
    - MINOR: stick-table: do not take an exclusive lock when downing ref_cnt
    - MINOR: stick-table: move the write lock inside stktable_touch_with_exp()
    - MEDIUM: stick-table: only take the lock when needed in stktable_touch_with_exp()
    - MEDIUM: stick-table: make stksess_kill_if_expired() avoid the exclusive lock
    - MEDIUM: stick-table: return inserted entry in __stktable_store()
    - MEDIUM: stick-table: free newly allocated stkess if it couldn't be inserted
    - MEDIUM: stick-table: switch to rdlock in stktable_lookup() and lookup_key()
    - MEDIUM: stick-table: make stktable_get_entry() look up under a read lock
    - MEDIUM: stick-table: do not take a lock to update t->current anymore.
    - MEDIUM: stick-table: make stktable_set_entry() look up under a read lock
    - MEDIUM: stick-table: requeue the expiration task out of the exclusive lock
    - MINOR: stick-table: split stktable_store() between key and requeue
    - MEDIUM: stick-table: always use atomic ops to requeue the table's task
    - MEDIUM: stick-table: requeue the wakeup task out of the write lock
    - BUG/MINOR: stick-table: fix build with DEBUG_THREAD
    - REORG: mux-fcgi: Extract flags and enums into mux_fcgi-t.h
    - MINOR: flags/mux-fcgi: Decode FCGI connection and stream flags
    - BUG/MEDIUM: mux-h1: Add connection error handling when reading/sending on a pipe
    - BUG/MEDIUM: mux-h1: Handle abort with an incomplete message during parsing
    - BUG/MINOR: server: make sure "show servers state" hides private bits
    - MINOR: checks: use the lighter PRNG for spread checks
    - MEDIUM: checks: spread the checks load over random threads
    - CI: SSL: use proper version generating when "latest" semantic is used
    - CI: SSL: temporarily stick to LibreSSL=3.5.3
    - MINOR: quic: New quic_cstream object implementation
    - MINOR: quic: Extract CRYPTO frame parsing from qc_parse_pkt_frms()
    - MINOR: quic: Use a non-contiguous buffer for RX CRYPTO data
    - BUG/MINOR: quic: Stalled 0RTT connections with big ClientHello TLS message
    - MINOR: quic: Split the secrets key allocation in two parts
    - CLEANUP: quic: remove unused rxbufs member in receiver
    - CLEANUP: quic: improve naming for rxbuf/datagrams handling
    - MINOR: quic: implement datagram cleanup for quic_receiver_buf
    - MINOR: ring: ring_cast_from_area() cast from an allocated area
    - MINOR: buffers: split b_force_xfer() into b_cpy() and b_force_xfer()
    - MINOR: logs: startup-logs can use a shm for logging the reload
    - MINOR: mworker/cli: reload command displays the startup-logs
    - MEDIUM: quic: respect the threads assigned to a bind line
    - DOC: management: update the "reload" command of the master CLI
    - BUILD: ssl_sock: bind_conf uninitialized in ssl_sock_bind_verifycbk()
    - BUG/MEDIUM: httpclient: Don't set EOM flag on an empty HTX message
    - MINOR: httpclient/lua: Don't set req_payload callback if body is empty
    - DOC/CLEANUP: lua-api: some minor corrections
    - DOC: lua-api: updating toolbox link
    - DOC/CLEANUP: lua-api: removing duplicate core.proxies attribute
    - DOC: management: add forgotten "show startup-logs"
    - DOC: management: "show startup-logs" for master CLI
    - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in matrix.py
    - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in workflow definition

2 years agoCI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in...
Tim Duesterhus [Fri, 14 Oct 2022 17:46:07 +0000 (19:46 +0200)] 
CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in workflow definition

See "CI: Replace the deprecated `::set-output` command by writing to
$GITHUB_OUTPUT in matrix.py" for the reasoning behind this commit.

2 years agoCI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in...
Tim Duesterhus [Fri, 14 Oct 2022 17:46:06 +0000 (19:46 +0200)] 
CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in matrix.py

As announced in

https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

the `::set-output` command is deprecated, because processes during the workflow
execution might output untrusted information that might include the
`::set-output` command, thus allowing these untrusted information to hijack the
build.

The replacement is writing to the file indicated by the `$GITHUB_OUTPUT`
environment variable.

2 years agoDOC: management: "show startup-logs" for master CLI
William Lallemand [Fri, 14 Oct 2022 13:41:55 +0000 (15:41 +0200)] 
DOC: management: "show startup-logs" for master CLI

"show startup-logs" on the master CLI has a slighly different behavior.

No backport needed.

2 years agoDOC: management: add forgotten "show startup-logs"
William Lallemand [Fri, 14 Oct 2022 13:29:07 +0000 (15:29 +0200)] 
DOC: management: add forgotten "show startup-logs"

The keyword was never documented.

Must be backported in all maintained versions.

2 years agoDOC/CLEANUP: lua-api: removing duplicate core.proxies attribute
Aurelien DARRAGON [Fri, 14 Oct 2022 07:03:32 +0000 (09:03 +0200)] 
DOC/CLEANUP: lua-api: removing duplicate core.proxies attribute

core.proxies attribute was found 2 times in the core Class.
Removing the second occurrence, which is purely duplicate and
does not belong here.

2 years agoDOC: lua-api: updating toolbox link
Aurelien DARRAGON [Fri, 14 Oct 2022 06:48:57 +0000 (08:48 +0200)] 
DOC: lua-api: updating toolbox link

Link to lua toolbox was dead (project has been deprecated).
Adding a legacy link to get old toolbox source code as well as
a link to luarocks that seems to have superseded it.

2 years agoDOC/CLEANUP: lua-api: some minor corrections
Aurelien DARRAGON [Thu, 13 Oct 2022 17:49:42 +0000 (19:49 +0200)] 
DOC/CLEANUP: lua-api: some minor corrections

This is a minor cleanup before 2.7 release to correct some typos
and errors without changing the meaning.

2 years agoMINOR: httpclient/lua: Don't set req_payload callback if body is empty
Christopher Faulet [Fri, 14 Oct 2022 12:57:04 +0000 (14:57 +0200)] 
MINOR: httpclient/lua: Don't set req_payload callback if body is empty

The HTTPclient callback req_payload callback is set when a request payload
must be streamed. In the lua, this callback is set when a body is passed as
argument in one of httpclient functions (head/get/post/put/delete). However,
there is no reason to set it if body string is empty.

This patch is related to the issue #1898. It may be backported as far as
2.5.

2 years agoBUG/MEDIUM: httpclient: Don't set EOM flag on an empty HTX message
Christopher Faulet [Fri, 14 Oct 2022 13:10:24 +0000 (15:10 +0200)] 
BUG/MEDIUM: httpclient: Don't set EOM flag on an empty HTX message

In the HTTP client, when the request body is streamed, at the end of the
payload, we must be sure to not set the EOM flag on an empty message.
Otherwise, because there is no data, the buffer is reset to be released and
the flag is lost. Thus, the HTTP client is never notified of the end of
payload for the request and the applet is blocked. If the HTTP client is
instanciated from a Lua script, it is even worse because we fall into a
wakeup loop between the lua script and the HTTP client applet. At the end,
HAProxy is killed because of the watchdog.

This patch should fix the issue #1898. It must be backported to 2.6.

2 years agoBUILD: ssl_sock: bind_conf uninitialized in ssl_sock_bind_verifycbk()
Frédéric Lécaille [Fri, 14 Oct 2022 07:34:00 +0000 (09:34 +0200)] 
BUILD: ssl_sock: bind_conf uninitialized in ssl_sock_bind_verifycbk()

Even if this cannot happen, ensure <bind_conf> is initialized in this
function to please some compilers.

Takes the opportunity of this patch to replace an ABORT_NOW() by
a BUG_ON() because if the variable values they test are not initialized,
this is really because there is a bug.

Must be backported to 2.6.

2 years agoDOC: management: update the "reload" command of the master CLI
William Lallemand [Thu, 13 Oct 2022 16:14:55 +0000 (18:14 +0200)] 
DOC: management: update the "reload" command of the master CLI

Update the "reload" command with the new output format.

2 years agoMEDIUM: quic: respect the threads assigned to a bind line
Willy Tarreau [Thu, 13 Oct 2022 14:14:11 +0000 (16:14 +0200)] 
MEDIUM: quic: respect the threads assigned to a bind line

Right now the QUIC thread mapping derives the thread ID from the CID
by dividing by global.nbthread. This is a problem because this makes
QUIC work on all threads and ignores the "thread" directive on the
bind lines. In addition, only 8 bits are used, which is no more
compatible with the up to 4096 threads we may have in a configuration.

Let's modify it this way:
  - the CID now dedicates 12 bits to the thread ID
  - on output we continue to place the TID directly there.
  - on input, the value is extracted. If it corresponds to a valid
    thread number of the bind_conf, it's used as-is.
  - otherwise it's used as a rank within the current bind_conf's
    thread mask so that in the end we still get a valid thread ID
    for this bind_conf.

The extraction function now requires a bind_conf in order to get the
group and thread mask. It was better to use bind_confs now as the goal
is to make them support multiple listeners sooner or later.

2 years agoMINOR: mworker/cli: reload command displays the startup-logs
William Lallemand [Thu, 13 Oct 2022 15:49:54 +0000 (17:49 +0200)] 
MINOR: mworker/cli: reload command displays the startup-logs

Change the output of the "reload" command, it now displays "Success=0"
if the reload failed and "Success=1" if it succeed.

If the startup-logs is available (USE_SHM_OPEN=1), the command will
print a "--\n" line, followed by the content of the startup-logs.

Example:

$ echo "reload" | socat /tmp/master.sock -
Success=1
--
[NOTICE]   (482713) : haproxy version is 2.7-dev7-4827fb-69
[NOTICE]   (482713) : path to executable is ./haproxy
[WARNING]  (482713) : config : 'http-request' rules ignored for proxy 'frt1' as they require HTTP mode.
[NOTICE]   (482713) : New worker (482720) forked
[NOTICE]   (482713) : Loading success.

$ echo "reload" | socat /tmp/master.sock -
Success=0
--
[NOTICE]   (482886) : haproxy version is 2.7-dev7-4827fb-69
[NOTICE]   (482886) : path to executable is ./haproxy
[ALERT]    (482886) : config : parsing [test3.cfg:1]: unknown keyword 'Aglobal' out of section.
[ALERT]    (482886) : config : Fatal errors found in configuration.
[WARNING]  (482886) : Loading failure!

$

2 years agoMINOR: logs: startup-logs can use a shm for logging the reload
William Lallemand [Mon, 26 Sep 2022 10:54:39 +0000 (12:54 +0200)] 
MINOR: logs: startup-logs can use a shm for logging the reload

When compiled with USE_SHM_OPEN=1 the startup-logs are now able to use
an shm which is used to keep the logs when switching to mworker wait
mode. This allows to keep the failed reload logs.

When allocating the startup-logs at first start of the process, haproxy
will do a shm_open with a unique path using the PID of the process, the
file is unlink immediatly so we don't let unwelcomed files be. The fd
resulting from this shm is stored in the HAPROXY_STARTUPLOGS_FD
environment variable so it can be mmap again when switching to wait
mode.

When forking children, the process is copying the mmap to a a mallocated
ring so we never share the same memory section between the master and
the workers. When switching to wait mode, the shm is not used anymore as
it is also copied to a mallocated structure.

This allow to use the "show startup-logs" command over the master CLI,
to get the logs of the latest startup or reload. This way the logs of
the latest failed reload are also kept.

This is only activated on the linux-glibc target for now.

2 years agoMINOR: buffers: split b_force_xfer() into b_cpy() and b_force_xfer()
William Lallemand [Mon, 10 Oct 2022 15:27:47 +0000 (17:27 +0200)] 
MINOR: buffers: split b_force_xfer() into b_cpy() and b_force_xfer()

Split the b_force_xfer() into b_ncat() and b_force_xfer().

The previous b_force_xfer() implementation was basically a copy with a
b_del on the src buffer. Keep this implementation to make b_ncat(), and
just call b_ncat() + b_del() into b_force_xfer().

2 years agoMINOR: ring: ring_cast_from_area() cast from an allocated area
William Lallemand [Tue, 27 Sep 2022 13:53:53 +0000 (15:53 +0200)] 
MINOR: ring: ring_cast_from_area() cast from an allocated area

Cast an unified ring + storage area to a ring from area, without
reinitializing the data buffer. Reinitialize the waiters and the lock.

It helps retrieving a previously allocated ring, from an mmap for
example.

2 years agoMINOR: quic: implement datagram cleanup for quic_receiver_buf
Amaury Denoyelle [Thu, 6 Oct 2022 12:45:09 +0000 (14:45 +0200)] 
MINOR: quic: implement datagram cleanup for quic_receiver_buf

Each time data is read on QUIC receiver socket, we try to reuse the
first datagram of the currently used quic_receiver_buf instead of
allocating a new one. This algorithm is suboptimal if there is several
unused datagrams as only the first one is tested and its buffer removed
from quic_receiver_buf.

If QUIC traffic is quite substential, this can lead to an important
number of quic_dgram occurences allocated from pool_head_quic_dgram and
a lack of free space in allocated quic_receiver_buf buffers.

To improve this, each time we want to reuse a datagram, we pop elements
until a non-yet released datagram is found or the list is empty. All
intermediary elements are freed and the last found datagram can be
reused. This operation has been extracted in a dedicated function named
quic_rxbuf_purge_dgrams().

This should improve memory consumption incured by quic_dgram instances under heavy
QUIC traffic. Note that there is still room for improvement as if the
first datagram is still in use, it may block several unused datagram
after him. However this requires to support removal of datagrams out of
order which is currently not possible.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: improve naming for rxbuf/datagrams handling
Amaury Denoyelle [Thu, 6 Oct 2022 13:16:22 +0000 (15:16 +0200)] 
CLEANUP: quic: improve naming for rxbuf/datagrams handling

QUIC datagrams are read from a random thread. They are then redispatch
to the connection thread according to the first packet DCID. These
operations are implemented through a special buffer designed to avoid
locking.

Refactor this code with the following changes :
* <rxbuf> type is renamed <quic_receiver_buf>. Its list element is also
  renamed to highligh its attach point to a receiver.
* <quic_dgram> and <quic_receiver_buf> definition are moved to
  quic_sock-t.h. This helps to reduce the size of quic_conn-t.h.
* <quic_dgram> list elements are renamed to highlight their attach point
  into a <quic_receiver_buf> and a <quic_dghdlr>.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: remove unused rxbufs member in receiver
Amaury Denoyelle [Thu, 13 Oct 2022 08:11:36 +0000 (10:11 +0200)] 
CLEANUP: quic: remove unused rxbufs member in receiver

rxbuf is the structure used to store QUIC datagrams and redispatch them
to the connection thread.

Each receiver manages a list of rxbuf. This was stored both as an array
and a mt_list. Currently, only mt_list is needed so removed <rxbufs>
member from receiver structure.

This should be backported up to 2.6.

2 years agoMINOR: quic: Split the secrets key allocation in two parts
Frédéric Lécaille [Fri, 16 Sep 2022 14:24:47 +0000 (16:24 +0200)] 
MINOR: quic: Split the secrets key allocation in two parts

Implement quic_tls_secrets_keys_alloc()/quic_tls_secrets_keys_free() to allocate
the memory for only one direction (RX or TX).
Modify ha_quic_set_encryption_secrets() to call these functions for one of this
direction (or both). So, for now on we can rely on the value of the secret keys
to know if it was derived.
Remove QUIC_FL_TLS_SECRETS_SET flag which is no more useful.
Consequently, the secrets are dumped by the traces only if derived.

Must be backported to 2.6.

2 years agoBUG/MINOR: quic: Stalled 0RTT connections with big ClientHello TLS message
Frédéric Lécaille [Fri, 16 Sep 2022 08:15:58 +0000 (10:15 +0200)] 
BUG/MINOR: quic: Stalled 0RTT connections with big ClientHello TLS message

This issue was reproduced with -Q picoquic client option to split a big ClientHello
message into two Initial packets and haproxy as server without any knowledged of
any previous ORTT session (restarted after a firt 0RTT session). The ORTT received
packets were removed from their queue when the second Initial packet was parsed,
and the QUIC handshake state never progressed and remained at Initial state.

To avoid such situations, after having treated some Initial packets we always
check if there are ORTT packets to parse and we never remove them from their
queue. This will be done after the hanshake is completed or upon idle timeout
expiration.

Also add more traces to be able to analize the handshake progression.

Tested with ngtcp2 and picoquic

Must be backported to 2.6.

2 years agoMINOR: quic: Use a non-contiguous buffer for RX CRYPTO data
Frédéric Lécaille [Tue, 13 Sep 2022 12:36:44 +0000 (14:36 +0200)] 
MINOR: quic: Use a non-contiguous buffer for RX CRYPTO data

Implement quic_get_ncbuf() to dynamically allocate a new ncbuf to be attached to
any quic_cstream struct which needs such a buffer. Note that there is no quic_cstream
for 0RTT encryption level. quic_free_ncbuf() is added to release the memory
allocated for a non-contiguous buffer.

Modify qc_handle_crypto_frm() to call this function and allocate an ncbuf for
crypto data which are not received in order. The crypto data which are received in
order are not buffered but provide to the TLS stack (calling qc_provide_cdata()).

Modify qc_treat_rx_crypto_frms() which is called after having provided the
in order received crypto data to the TLS stack to provide again the remaining
crypto data which has been buffered, if possible (if they are in order). Each time
buffered CRYPTO data were consumed, we try to release the memory allocated for
the non-contiguous buffer (ncbuf).
Also move rx.crypto.offset quic_enc_level struct member to rx.offset quic_cstream
struct member.

Must be backported to 2.6.

2 years agoMINOR: quic: Extract CRYPTO frame parsing from qc_parse_pkt_frms()
Frédéric Lécaille [Mon, 12 Sep 2022 12:54:45 +0000 (14:54 +0200)] 
MINOR: quic: Extract CRYPTO frame parsing from qc_parse_pkt_frms()

Implement qc_handle_crypto_frm() to parse a CRYPTO frame.

Must be backported to 2.6.

2 years agoMINOR: quic: New quic_cstream object implementation
Frédéric Lécaille [Fri, 9 Sep 2022 16:05:45 +0000 (18:05 +0200)] 
MINOR: quic: New quic_cstream object implementation

Add new quic_cstream struct definition to implement the CRYPTO data stream.
This is a simplication of the qcs object (QUIC streams) for the CRYPTO data
without any information about the flow control. They are not attached to any
tree, but to a QUIC encryption level, one by encryption level except for
the early data encryption level (for 0RTT). A stream descriptor is also allocated
for each CRYPTO data stream.

Must be backported to 2.6

2 years agoCI: SSL: temporarily stick to LibreSSL=3.5.3
Ilya Shipitsin [Tue, 11 Oct 2022 07:11:55 +0000 (12:11 +0500)] 
CI: SSL: temporarily stick to LibreSSL=3.5.3

recently released 3.6.0 introduced some regression which must be
resolved first, let us use 3.5.3 notation instead of "latest"

2 years agoCI: SSL: use proper version generating when "latest" semantic is used
Ilya Shipitsin [Tue, 11 Oct 2022 07:10:57 +0000 (12:10 +0500)] 
CI: SSL: use proper version generating when "latest" semantic is used

both "OPENSSL_VERSION=latest" and "LIBRESSL_VERSION=latest" processing
introduced errors when build-ssl.sh script was invoked. that error
in turn led to skipping custom openssl build and haproxy was linked against
stock openssl, i.e. openssl-1.1.1

2 years agoMEDIUM: checks: spread the checks load over random threads
Willy Tarreau [Wed, 12 Oct 2022 18:58:18 +0000 (20:58 +0200)] 
MEDIUM: checks: spread the checks load over random threads

The CPU usage pattern was found to be high (5%) on a machine with
48 threads and only 100 servers checked every second That was
supposed to be only 100 connections per second, which should be very
cheap. It was figured that due to the check tasks unbinding from any
thread when going back to sleep, they're queued into the shared queue.

Not only this requires to manipulate the global queue lock, but in
addition it means that all threads have to check the global queue
before going to sleep (hence take a lock again) to figure how long
to sleep, and that they would all sleep only for the shortest amount
of time to the next check, one would pick it and all other ones would
go down to sleep waiting for the next check.

That's perfectly visible in time-to-first-byte measurements. A quick
test consisting in retrieving the stats page in CSV over a 48-thread
process checking 200 servers every 2 seconds shows the following tail:

  percentile   ttfb(ms)
  99.98        2.43
  99.985       5.72
  99.99       32.96
  99.995     82.176
  99.996     82.944
  99.9965    83.328
  99.997      83.84
  99.9975    84.288
  99.998      85.12
  99.9985    86.592
  99.999         88
  99.9995    89.728
  99.9999   100.352

One solution could consist in forcefully binding checks to threads at
boot time, but that's annoying, will cause trouble for dynamic servers
and may cause some skew in the load depending on some server patterns.

Instead here we take a different approach. A check remains bound to its
thread for as long as possible, but upon every wakeup, the thread's load
is compared with another random thread's load. If it's found that that
other thread's load is less than half of the current one's, the task is
bounced to that thread. In order to prevent that new thread from doing
the same, we set a flag "CHK_ST_SLEEPING" that indicates that it just
woke up and we're bouncing the task only on this condition.

Tests have shown that the initial load was very unfair before, with a few
checks threads having a load of 15-20 and the vast majority having zero.
With this modification, after two "inter" delays, the load is either zero
or one everywhere when checks start. The same test shows a CPU usage that
significantly drops, between 0.5 and 1%. The same latency tail measurement
is much better, roughly 10 times smaller:

  percentile   ttfb(ms)
  99.98        1.647
  99.985       1.773
  99.99        4.912
  99.995        8.76
  99.996        8.88
  99.9965      8.944
  99.997       9.016
  99.9975      9.104
  99.998       9.224
  99.9985      9.416
  99.999         9.8
  99.9995      10.04
  99.9999     10.432

In fact one difference here is that many threads work while in the past
they were waking up and going down to sleep after having perturbated the
shared lock. Thus it is anticipated that this will scale way smoother
than before. Under strace it's clearly visible that all threads are
sleeping for the time it takes to relaunch a check, there's no more
thundering herd wakeups.

However it is also possible that in some rare cases such as very short
check intervals smaller than a scheduler's timeslice (such as 4ms),
some users might have benefited from the work being concentrated on
less threads and would instead observe a small increase of apparent
CPU usage due to more total threads waking up even if that's for less
work each and less total work. That's visible with 200 servers at 4ms
where show activity shows that a few threads were overloaded and others
doing nothing. It's not a problem, though as in practice checks are not
supposed to eat much CPU and to wake up fast enough to represent a
significant load anyway, and the main issue they could have been
causing (aside the global lock) is an increase last-percentile latency.

2 years agoMINOR: checks: use the lighter PRNG for spread checks
Willy Tarreau [Wed, 12 Oct 2022 19:48:17 +0000 (21:48 +0200)] 
MINOR: checks: use the lighter PRNG for spread checks

There's no point using ha_random32() which is heavy and uses shared
variables to calculate a random timer when we have statistical_prng()
which does the same and was made exactly for this.

2 years agoBUG/MINOR: server: make sure "show servers state" hides private bits
Willy Tarreau [Wed, 12 Oct 2022 19:40:31 +0000 (21:40 +0200)] 
BUG/MINOR: server: make sure "show servers state" hides private bits

In the past we've seen "show servers state" dump some internal bits for
the check states, that were causing regtests to fail. The relevant bits
have been added to the doc to fix the public API and make sure they do
not change by accident, but the output doesn't take care of masking the
undesired ones, causing regtests (and possibly user programs) to fail
when new bits are added. Let's add the mask for the only documented ones
(0x0F for check and 0x1F for agent respectively).

This could be backported wherever the server state is present, though
there's a tiny risk that some undocumented bits might have already
leaked to some user scripts, so it might be wise to wait a bit before
doing that or even not to backport too far.

2 years agoBUG/MEDIUM: mux-h1: Handle abort with an incomplete message during parsing
Christopher Faulet [Mon, 10 Oct 2022 16:05:25 +0000 (18:05 +0200)] 
BUG/MEDIUM: mux-h1: Handle abort with an incomplete message during parsing

In h1_process_demux(), aborts for incomplete messages were not properly
handled. It was not an issue because the abort was detected later in
h1_process(). But it will be an issue to perform the aborts refoctoring.

First, when a read0 was detected, the SE_FL_EOI flag was set for messages in
DONE or TUNNEL state or for messages without known length (so responses in
close mode). The last statement is not accurate. The message must also be in
DATA state. Otherwise, SE_FL_EOI flag may be set on incomplete message.

Then, an error was reported, via SE_FL_ERROR flag, only when an incomplete
message was detected on the payload parsing. It must also be reported if
headers are incomplete. Here again, the error is detected later for now. But
it could be an issue later.

There is no reason to backport this patch.

2 years agoBUG/MEDIUM: mux-h1: Add connection error handling when reading/sending on a pipe
Christopher Faulet [Wed, 5 Oct 2022 10:04:56 +0000 (12:04 +0200)] 
BUG/MEDIUM: mux-h1: Add connection error handling when reading/sending on a pipe

There is no error handling when we read or write on a pipe. There error is
caught later, in the mux I/O handler. But there is no reason to not do so
here.

There is no reason to backport it because no issue was reported for now
because of this "bug". In all cases, it must be evaluated first.

2 years agoMINOR: flags/mux-fcgi: Decode FCGI connection and stream flags
Christopher Faulet [Wed, 12 Oct 2022 15:00:13 +0000 (17:00 +0200)] 
MINOR: flags/mux-fcgi: Decode FCGI connection and stream flags

The new functions fconn_show_flags() and fstrm_show_flags() decode the flags
state into a string, and are used by dev/flags:

$ /dev/flags/flags fconn 0x3100
fconn->flags = FCGI_CF_GET_VALUES | FCGI_CF_KEEP_CONN | FCGI_CF_MPXS_CONNS

./dev/flags/flags fstrm  0x3300
fstrm->flags = FCGI_SF_WANT_SHUTW | FCGI_SF_WANT_SHUTR | FCGI_SF_OUTGOING_DATA | FCGI_SF_BEGIN_SENT

2 years agoREORG: mux-fcgi: Extract flags and enums into mux_fcgi-t.h
Christopher Faulet [Wed, 12 Oct 2022 14:57:19 +0000 (16:57 +0200)] 
REORG: mux-fcgi: Extract flags and enums into mux_fcgi-t.h

The same was performed for the H2 and H1 multiplexers. FCGI connection and
stream flags are moved in a dedicated header file. It will be mainly used to
be able to decode mux-fcgi flags from the flags utility.

In this patch, we move the flags and enums to mux_fcgi-t.h, as well as the
two state decoding inline functions.

2 years agoBUG/MINOR: stick-table: fix build with DEBUG_THREAD
Amaury Denoyelle [Wed, 12 Oct 2022 14:47:59 +0000 (16:47 +0200)] 
BUG/MINOR: stick-table: fix build with DEBUG_THREAD

Compilation is broken with DEBUG_THREAD since the following patch
  76642223f014f89cd1f374291798499f4fba7dde
  MEDIUM: stick-table: switch the table lock to rwlock

Fix this by updating a legacy HA_SPIN_INIT() to HA_RWLOCK_INIT().

No backport needed unless the mentionned patch is backported.

2 years agoMEDIUM: stick-table: requeue the wakeup task out of the write lock
Willy Tarreau [Wed, 12 Oct 2022 10:04:01 +0000 (10:04 +0000)] 
MEDIUM: stick-table: requeue the wakeup task out of the write lock

We don't need to call stktable_requeue_exp() with the table's lock
held anymore, so let's move it out. It should slightly reduce the
contention on the write lock, though it is now already quite low.

2 years agoMEDIUM: stick-table: always use atomic ops to requeue the table's task
Willy Tarreau [Wed, 12 Oct 2022 10:00:50 +0000 (10:00 +0000)] 
MEDIUM: stick-table: always use atomic ops to requeue the table's task

We're generalizing the change performed in previous commit "MEDIUM:
stick-table: requeue the expiration task out of the exclusive lock"
to stktable_requeue_exp() so that it can also be used by callers of
__stktable_store(). At the moment there's still no visible change
since it's still called under the write lock. However, the previous
code in stitable_touch_with_exp() was updated to use this function.

2 years agoMINOR: stick-table: split stktable_store() between key and requeue
Willy Tarreau [Wed, 12 Oct 2022 09:56:08 +0000 (09:56 +0000)] 
MINOR: stick-table: split stktable_store() between key and requeue

__staktable_store() performs two distinct things, one is to insert a key
and the other one is to requeue the task's expiration date. Since the
latter might be done without a lock, let's first split the function in
two halves. For now this has no impact.

2 years agoMEDIUM: stick-table: requeue the expiration task out of the exclusive lock
Willy Tarreau [Wed, 12 Oct 2022 09:45:36 +0000 (09:45 +0000)] 
MEDIUM: stick-table: requeue the expiration task out of the exclusive lock

With 48 threads, a heavily loaded table with plenty of trackers and
rules and a short expiration timer of 10ms saturates the CPU at 232k
rps. By carefully using atomic ops we can make sure that t->exp_next
and t->task->expire converge to the earliest next expiration date and
that all of this can be performed under atomic ops without any lock.
That's what this patch is doing in stktable_touch_with_exp(). This is
sufficient to double the performance and reach 470k rps.

It's worth noting that __stktable_store() uses a mix of eb32_insert()
and task_queue, and that the second part of it could possibly benefit
from this, even though sometimes it's called under a lock that was
already held.

2 years agoMEDIUM: stick-table: make stktable_set_entry() look up under a read lock
Willy Tarreau [Wed, 12 Oct 2022 09:13:14 +0000 (09:13 +0000)] 
MEDIUM: stick-table: make stktable_set_entry() look up under a read lock

On a 24-core machine having some "stick-store response" rules, a lot of
time is spent in the write lock in stktable_set_entry(). Let's apply the
same mechanism as for the stktable_get_entry() consisting in looking up
the value under the read lock and upgrading it to a write lock only to
perform modifications. Here we even have the luxury of upgrading the
lock since there are no alloc/free in the path. All this increases the
performance by 40% (from 363k to 510k rps).

2 years agoMEDIUM: stick-table: do not take a lock to update t->current anymore.
Willy Tarreau [Tue, 11 Oct 2022 14:19:35 +0000 (16:19 +0200)] 
MEDIUM: stick-table: do not take a lock to update t->current anymore.

We don't need to be protected by the table's lock when touching t->current
if we do it using atomics, and that's great because it allows us to have
a cleaner stksess_new() that doesn't require a lock either, and to avoid
manipulating pools under a lock.

That's another 1% performance gain from 2.07 to 2.10M req/s under 48
threads.

2 years agoMEDIUM: stick-table: make stktable_get_entry() look up under a read lock
Willy Tarreau [Tue, 11 Oct 2022 13:22:42 +0000 (15:22 +0200)] 
MEDIUM: stick-table: make stktable_get_entry() look up under a read lock

On a 24-core machine doing lots of track-sc, it was found that the lock
in stktable_get_entry() was responsible for 25% of the CPU alone. It's
sad because most of its job is to protect the table during the lookup.

Here we're taking a slightly different approach: the lock is first taken
for reads during the lookup, and only in case of failure we switch it for
a write lock. We don't even perform an upgrade here since an allocation
is needed between the two, it would be wasted to do it under the lock,
and is generally not a good idea, so better release the read lock and
try again.

Here the performance under 48 threads with 3 trackers on the same table
jumped from 455k to 2.07M, or 4.55x! Note that the same approach should
be possible for stktable_set_entry().

2 years agoMEDIUM: stick-table: switch to rdlock in stktable_lookup() and lookup_key()
Willy Tarreau [Tue, 11 Oct 2022 13:42:54 +0000 (15:42 +0200)] 
MEDIUM: stick-table: switch to rdlock in stktable_lookup() and lookup_key()

These functions do not modify anything in the the table except the refcount
on success. Let's just lock the table for shared accesses and make use of
atomic ops to update the refcount. This brings a nice gain from 425k to
455k under 48 threads (7%), but some contention remains on the exclusive
locks in other parts.

Note that the refcount continues to be updated under the lock because it's
not yet certain whether there are races between it and some of the exclusive
lock on the table. The difference is marginal and we prefer to stay on the
safe side for now.

2 years agoMEDIUM: stick-table: free newly allocated stkess if it couldn't be inserted
Willy Tarreau [Tue, 11 Oct 2022 13:13:46 +0000 (15:13 +0200)] 
MEDIUM: stick-table: free newly allocated stkess if it couldn't be inserted

In __stktable_get_entry() now we're planning for the possibility that the
call to __stktable_store() doesn't add the newly allocated entry and instead
finds a previously inserted one. At the moment this doesn't exist because
the lookup + insert passes are made under the same lock. But it will soon
change.

2 years agoMEDIUM: stick-table: return inserted entry in __stktable_store()
Willy Tarreau [Tue, 11 Oct 2022 13:09:46 +0000 (15:09 +0200)] 
MEDIUM: stick-table: return inserted entry in __stktable_store()

This function is used to create an entry in the table. But it doesn't
consider the possibility that the entry already exists, because right
now it's only called in situations where it was verified under a lock
that it doesn't exist. Since we'll soon need to break that assumption
we need it to verify that the requested entry was added and to return
a pointer to the one in the tree so that the caller can detect any
possible conflict. At the moment this is not used.

2 years agoMEDIUM: stick-table: make stksess_kill_if_expired() avoid the exclusive lock
Willy Tarreau [Tue, 11 Oct 2022 18:50:22 +0000 (18:50 +0000)] 
MEDIUM: stick-table: make stksess_kill_if_expired() avoid the exclusive lock

stream_store_counters() calls stksess_kill_if_expired() for each active
counter. And this one takes an exclusive lock on the table before
checking if it has any work to do (hint: it almost never has since it
only wants to delete expired entries). However a lock is still neeed for
now to protect the ref_cnt, but we can do it atomically under the read
lock.

Let's change the mechanism. Now what we do is to check out of the lock
if the entry is expired. If it is, we take the write lock, expire it,
and decrement the refcount. Otherwise we just decrement the refcount
under a read lock. With this change alone, the config based on 3
trackers without the previous patches saw a 2.6x improvement, but here
it doesn't yet change anything because some heavy contention remains
on the lookup part.

2 years agoMEDIUM: stick-table: only take the lock when needed in stktable_touch_with_exp()
Willy Tarreau [Tue, 11 Oct 2022 18:31:04 +0000 (18:31 +0000)] 
MEDIUM: stick-table: only take the lock when needed in stktable_touch_with_exp()

As previously mentioned, this function currently holds an exclusive lock
on the table during all the time it take to check if the entry needs to
be updated and synchronized with peers. The reality is that many setups
do not use peers and that on highly loaded setups, the same entries are
hammered all the time so the key's expiration doesn't change between a
number of consecutive accesses.

With this patch we take a different approach. The function starts
without taking the lock, and will take it only if needed, keeping track
of it. This way we can avoid it most of the time, or even entirely.
Finally if the decrefcnt argument requires that the refcount is
decremented, we either do it using a non-atomic op if the table was
locked (since no other entry may touch it) or via an atomic under the
read lock only.

With this change alone, a 48-thread test with 3 trackers increased
from 193k req/s to 425k req/s, which is a 2.2x factor.

2 years agoMINOR: stick-table: move the write lock inside stktable_touch_with_exp()
Willy Tarreau [Tue, 11 Oct 2022 18:17:58 +0000 (18:17 +0000)] 
MINOR: stick-table: move the write lock inside stktable_touch_with_exp()

Taking the write lock prior to entering that function is a problem
because this function is full of conditions that most of the time can
lead to eliminating the lock.

This commit first moves the write lock inside the function and passes
the extra argument required to implement stktable_touch_remote() and
stktable_touch_local(). It also renames the function to remove the
underscores since there's no other variant and it's exported under
this name (probably an old rename that was not propagated). The code
was stressed under 48 threads using 3 trackers on the same table. It
already shows a tiny 3% improvement from 187k to 193k rps.

2 years agoMINOR: stick-table: do not take an exclusive lock when downing ref_cnt
Willy Tarreau [Tue, 11 Oct 2022 18:10:27 +0000 (18:10 +0000)] 
MINOR: stick-table: do not take an exclusive lock when downing ref_cnt

At plenty of places we decrement ts->ref_cnt under the write lock
because it's held. We don't technically need it to be done that way
if there's contention and an atomic could suffice. However until all
places are turned to atomic, we at least need to do that under a
read lock for now, so that we don't mix atomic and non-atomic uses.
Regardless it already brings ~1.5% req rate improvement with 3 trackers
on the same table under 48 threads at 184k->187k rps.

2 years agoMEDIUM: stick-table: switch the table lock to rwlock
Willy Tarreau [Tue, 11 Oct 2022 10:02:50 +0000 (12:02 +0200)] 
MEDIUM: stick-table: switch the table lock to rwlock

Right now a spinlock is used, but most accesses are for reads, so let's
switch the lock to an rwlock and switch all accesses to exclusive locks
for now. There should be no visible difference at this point.

2 years agoMINOR: freq_ctr: use the thread's local time whenever possible
Willy Tarreau [Tue, 11 Oct 2022 09:55:16 +0000 (11:55 +0200)] 
MINOR: freq_ctr: use the thread's local time whenever possible

Right now when dealing with freq_ctr updates, we're using the process-
wide monotinic time, and accessing it is expensive since every thread
needs to update it, so this adds some contention. However we don't need
it all the time, the thread's local time is most of the time strictly
equal to the global time, and may be off by one millisecond when the
global time is switched to the next one by another thread, and in this
case we don't want to use the local time because it would risk to cause
a rotation of the counter. But that's precisely the condition we're
already relying on for the slow path!

What this patch does is to add a check for the period against the
local time prior to anything else, and immediately return after
updating the counter if still within the period, otherwise fall back
to the existing code. Given that the function starts to inflate a bit,
it was split between s very short inline part that does the hot path,
and the slower fallback that's in a cold function. It was measured that
on a 24-CPU machine it was called ~0.003% of the time.

The resulting improvement sits between 2 and 3% at 500k req/s tracking
an http_req_rate counter.

2 years agoMINOR: plock: support disabling exponential back-off
Willy Tarreau [Tue, 11 Oct 2022 15:02:02 +0000 (17:02 +0200)] 
MINOR: plock: support disabling exponential back-off

The new macro PLOCK_DISABLE_EBO may be defined to disable exponential
backoff. This can be useful to more easily spot functions that cause
contention. In this case the CPU will be spent inside the functions
themselves instead of the pl_wait_unlock_{long,int}() functions, making
them easier to spot using "perf top" even if that causes a significant
degradation of the thread scalability.

2 years agoBUG/MAJOR: stick-tables: do not try to index a server name for applets
Willy Tarreau [Wed, 12 Oct 2022 08:35:41 +0000 (10:35 +0200)] 
BUG/MAJOR: stick-tables: do not try to index a server name for applets

Since commit 03cdf55e6 ("MINOR: stream: Stickiness server lookup by name.")
in 2.0-dev6, server names may be used instead of their IDs, in order to
perform stickiness. However the commit above may end up trying to insert
an empty server name in the dictionary when the server is an applet
instead, resulting in an immediate segfault. This is typically what
happens when a "stick-store" rule is present in a backend featuring a
"stats" directive. As there doesn't seem to be an easy way around it,
it seems to imply that "stick-store" is not much used anymore.

The solution here is to only try to insert non-null keys into the
dictionary. The patch moves the check of the key type before the
first lock so that the test on the key can be performed under the lock
instead of locking twice (the patch is more readable with diff -b).

Note that before 2.4, there's no <key> variable there as it was
introduced by commit 92149f9a8 ("MEDIUM: stick-tables: Add srvkey
option to stick-table"), but the __objt_server(s->target)->id still
needs to be tested.

This needs to be backported as far as 2.0.

2 years agoMINOR: hlua: removing ambiguous lua_pushvalue with 0 index
Aurelien DARRAGON [Fri, 7 Oct 2022 09:54:57 +0000 (11:54 +0200)] 
MINOR: hlua: removing ambiguous lua_pushvalue with 0 index

In cd341d531, I added a FIXME comment because I noticed a
lua_pushvalue with 0 index, whereas lua doc states that 0 is never
an acceptable index.

After reviewing and testing the hlua_applet_http_send_response() code,
it turns out that this pushvalue is not even needed.
So it's safer to remove it as it could lead to undefined
behavior (since it is not supported by Lua API) and it grows lua stack
by 1 for no reason.

No backport needed.

2 years agoDOC: configuration: missing 'if' in tcp-request content example
Aurelien DARRAGON [Wed, 5 Oct 2022 16:09:33 +0000 (18:09 +0200)] 
DOC: configuration: missing 'if' in tcp-request content example

An example given for tcp-request content rule with lua
was missing 'if' keyword. Using it "as is" makes haproxy unhappy.

The example was introduced with 579d83b05.
So it may be backported as far as 1.6, but it is a really minor typo.

2 years agoMINOR: hlua: some luaL_checktype() calls were not guarded with MAY_LJMP
Aurelien DARRAGON [Wed, 5 Oct 2022 09:46:45 +0000 (11:46 +0200)] 
MINOR: hlua: some luaL_checktype() calls were not guarded with MAY_LJMP

In hlua code, we mark every function that may longjump using
MAY_LJMP macro so it's easier to identify them by reading the code.

However, some luaL_checktypes() were performed without the MAY_LJMP.

According to lua doc:
Functions called luaL_check* always raise an error if
the check is not satisfied.

-> Adding the missing MAY_LJMP for those luaLchecktypes() calls.

No backport needed.

2 years agoBUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only
Amaury Denoyelle [Tue, 11 Oct 2022 14:22:18 +0000 (16:22 +0200)] 
BUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only

Move code which activates IP_PKTINFO socket option (or affiliated
options) from sock_inet_bind_receiver() to quic_bind_listener()
function. This change is useful for two reasons :

* first, and the most important one : this activates IP_PKTINFO only for
  QUIC receivers. The previous version impacted all datagram receivers,
  used for example by log-forwarder. This should reduce memory usage for
  these datagram sockets which do not need this option.

* second, USE_QUIC preprocessor statements are removed from
  src/sock_inet.c which clean up the code.

IP_PKTINFO was introduced recently by the following patch :
  97ecc7a8ea5339a753507c3d4e4cd83028c6d038 (quic-dev/qns)
  MEDIUM: quic: retrieve frontend destination address

For the moment, this does not impact any stable release. However, as
previous patch is scheduled for 2.6 backporting, the current change must
also be backported to the same versions.

2 years agoCLEANUP: quic/receiver: remove the now unused tx_qring list
Willy Tarreau [Tue, 11 Oct 2022 06:36:21 +0000 (08:36 +0200)] 
CLEANUP: quic/receiver: remove the now unused tx_qring list

The tx_qrings[] and tx_qring_list in the receiver are not used
anymore since commit f2476053f ("MINOR: quic: replace custom buf on Tx
by default struct buffer"), the only place where they're referenced
was in quic_alloc_tx_rings_listener(), which by the way implies that
these were not even freed on exit.

Let's just remove them. This should be backported to 2.6 since the
commit above also was.

2 years agoCLEANUP: Reapply strcmp.cocci
Tim Duesterhus [Sat, 8 Oct 2022 10:33:19 +0000 (12:33 +0200)] 
CLEANUP: Reapply strcmp.cocci

This reapplies strcmp.cocci across the whole src/ tree.

2 years agoCLEANUP: Reapply ist.cocci (2)
Tim Duesterhus [Sat, 8 Oct 2022 10:33:18 +0000 (12:33 +0200)] 
CLEANUP: Reapply ist.cocci (2)

This reapplies ist.cocci across the whole src/ tree.

2 years agoMEDIUM: quic: retrieve frontend destination address
Amaury Denoyelle [Fri, 23 Sep 2022 15:15:58 +0000 (17:15 +0200)] 
MEDIUM: quic: retrieve frontend destination address

Retrieve the frontend destination address for a QUIC connection. This
address is retrieve from the first received datagram and then stored in
the associated quic-conn.

This feature relies on IP_PKTINFO or affiliated flags support on the
socket. This flag is set for each QUIC listeners in
sock_inet_bind_receiver(). To retrieve the destination address,
recvfrom() has been replaced by recvmsg() syscall. This operation and
parsing of msghdr structure has been extracted in a wrapper quic_recv().

This change is useful to finalize the implementation of 'dst' sample
fetch. As such, quic_sock_get_dst() has been edited to return local
address from the quic-conn. As a best effort, if local address is not
available due to kernel non-support of IP_PKTINFO, address of the
listener is returned instead.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: fix indentation
Amaury Denoyelle [Tue, 27 Sep 2022 08:35:29 +0000 (10:35 +0200)] 
CLEANUP: quic: fix indentation

Fix some indentation in qc_lstnr_pkt_rcv().

This should be backported up to 2.6.

2 years agoMINOR: mux-quic: check quic-conn return code on Tx
Amaury Denoyelle [Mon, 26 Sep 2022 13:02:31 +0000 (15:02 +0200)] 
MINOR: mux-quic: check quic-conn return code on Tx

Inspect return code of qc_send_mux(). If quic-conn layer reports an
error, this will interrupt the current emission process.

This should be backported up to 2.6.

2 years agoMINOR: quic: limit usage of ssl_sock_ctx in favor of quic_conn
Amaury Denoyelle [Mon, 26 Sep 2022 12:53:59 +0000 (14:53 +0200)] 
MINOR: quic: limit usage of ssl_sock_ctx in favor of quic_conn

Continue on the cleanup of QUIC stack and components.

quic_conn uses internally a ssl_sock_ctx to handle mandatory TLS QUIC
integration. However, this is merely as a convenience, and it is not
equivalent to stackable ssl xprt layer in the context of HTTP1 or 2.

To better emphasize this, ssl_sock_ctx usage in quic_conn has been
removed wherever it is not necessary : namely in functions not related
to TLS. quic_conn struct now contains its own wait_event for tasklet
quic_conn_io_cb().

This should be backported up to 2.6.

2 years agoBUG/MINOR: hlua: hlua_channel_insert_data() behavior conflicts with documentation
Aurelien DARRAGON [Tue, 4 Oct 2022 10:16:05 +0000 (12:16 +0200)] 
BUG/MINOR: hlua: hlua_channel_insert_data() behavior conflicts with documentation

Channel.insert(channel, string, [,offset]):

When no offset is provided, hlua_channel_insert_data() inserts
string at the end of incoming data.

This behavior conflicts with the documentation that explicitly says
that the default behavior is to insert the string in front of incoming data.

This patch fixes hlua_channel_insert_data() behavior so that it fully
complies with the documentation.

Thanks to Smackd0wn for noticing it.

This could be backported to 2.6 and 2.5

2 years agoBUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os
Willy Tarreau [Tue, 4 Oct 2022 07:18:34 +0000 (09:18 +0200)] 
BUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os

Gcc 4.x, 5.x and 6.x report this when compiling http_fetch.c:

  src/http_fetch.c: In function 'smp_fetch_meth':
  src/http_fetch.c:357:6: warning: 'htx' may be used uninitialized in this function [-Wmaybe-uninitialized]
     sl = http_get_stline(htx);

That's quite weird since there's no such code path, but presetting the
htx variable to NULL during declaration is enough to shut it up.

This may be backported to any version that has dbbdb25f1 ("BUG/MINOR:
http-fetch: Use integer value when possible in "method" sample fetch")
as it's the one that triggered this warning (hence at least 2.0).

2 years agoBUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth()
Christopher Faulet [Tue, 4 Oct 2022 06:58:02 +0000 (08:58 +0200)] 
BUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth()

In smp_fetch_meth(), smp_prefetch_htx() function may be called to parse the
HTX message and update the HTTP transaction accordingly. In this case, in
smp_fetch_metch() and on success, we must update "meth" variable. Otherwise,
the variable is still equal to HTTP_METH_OTHER and the string version is
always used instead of the enum for known methods.

This patch must be backported as far as 2.0.

2 years agoMINOR: init: do not try to shrink existing RLIMIT_NOFIlE
Willy Tarreau [Thu, 22 Sep 2022 14:12:08 +0000 (16:12 +0200)] 
MINOR: init: do not try to shrink existing RLIMIT_NOFIlE

As seen in issue #1866, some environments will not allow to change the
current FD limit, and actually we don't need to do it, we only do it as
a byproduct of adjusting the limit to the one that fits. Here we're
replacing calls to setrlimit() with calls to raise_rlim_nofile(), which
will avoid making the setrlimit() syscall in case the desired value is
lower than the current process' one.

This depends on previous commit "MINOR: fd: add a new function to only
raise RLIMIT_NOFILE" and may need to be backported to 2.6, possibly
earlier, depending on users' experience in such environments.

2 years agoMINOR: fd: add a new function to only raise RLIMIT_NOFILE
Willy Tarreau [Thu, 22 Sep 2022 14:08:47 +0000 (16:08 +0200)] 
MINOR: fd: add a new function to only raise RLIMIT_NOFILE

In issue #1866 an issue was reported under docker, by which a user cannot
lower the number of FD needed. It looks like a restriction imposed in this
environment, but it results in an error while it ought not have to in the
case of shrinking.

This patch adds a new function raise_rlim_nofile() that takes the desired
new setting, compares it to the current one, and only calls setrlimit() if
one of the values in the new setting is larger than the older one. As such
it will continue to emit warnings and errors in case of failure to raise
the limit but will never shrink it.

This patch is only preliminary to another one, but will have to be
backported where relevant (likely only 2.6).

2 years agoBUILD: h1: silence an initiialized warning with gcc-4.7 and -Os
Willy Tarreau [Tue, 4 Oct 2022 06:02:03 +0000 (08:02 +0200)] 
BUILD: h1: silence an initiialized warning with gcc-4.7 and -Os

Building h1.c with gcc-4.7 -Os produces the following warning:

  src/h1.c: In function 'h1_headers_to_hdr_list':
  src/h1.c:1101:36: warning: 'ptr' may be used uninitialized in this function [-Wmaybe-uninitialized]

In fact ptr may be taken from sl.rq.u.ptr which is only initialized after
passing through the relevant states, but gcc doesn't know which states
are visited. Adding an ALREADY_CHECKED() statement there is sufficient to
shut it up and doesn't affect the emitted code.

This may be backported to stable versions to make sure that builds on older
distros and systems is clean.

2 years agoBUG/MEDIUM: lua: handle stick table implicit arguments right.
Olivier Houchard [Mon, 12 Sep 2022 22:35:53 +0000 (00:35 +0200)] 
BUG/MEDIUM: lua: handle stick table implicit arguments right.

In hlua_lua2arg_check(), we allow for the first argument to not be
provided, if it has a type we know, this is true for frontend, backend,
and stick table. However, the stick table code was changed. It used
to be deduced from the proxy, but it is now directly provided in struct
args. So setting the proxy there no longer work, and we have to
explicitely set the stick table.
Not doing so will lead the code do use the proxy pointer as a stick
table pointer, which will likely cause crashes.

This should be backported up to 2.0.

2 years agoBUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure
Olivier Houchard [Mon, 12 Sep 2022 22:31:17 +0000 (00:31 +0200)] 
BUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure

In hlua_lua2arg_check(), on failure, before calling free_argp(), make
sure to always mark the failed argument as ARGT_STOP. We only want to
free argument prior to that point, because we did not allocate the
strings after this one, and so we don't want to free them.

This should be backported up to 2.2.

2 years agoBUG/MINOR: mux-quic: ignore STOP_SENDING for locally closed stream
Amaury Denoyelle [Mon, 3 Oct 2022 15:20:31 +0000 (17:20 +0200)] 
BUG/MINOR: mux-quic: ignore STOP_SENDING for locally closed stream

It is possible to receive a STOP_SENDING frame for a locally closed
stream. This was not properly managed as this would result in a BUG_ON()
crash from qcs_idle_open() call under qcc_recv_stop_sending().

Now, STOP_SENDING frames are ignored when received on streams already
locally closed. This has two consequences depending on the reason of
closure :

* if a RESET_STREAM was already emitted and closed the stream, this
  patch prevents to emit a new RESET_STREAM. This behavior is thus
  better.

* if stream was closed due to all data transmitted, no RESET_STREAM will
  be built. This is contrary to the RFC 9000 which advice to transmit
  it, even on "Data Sent" state. However, this is not mandatory so the
  new behavior is acceptable, even if it could be improved.

This crash has been detected on haproxy.org. This can be artifically
reproduced by adding the following snippet at the end of qc_send_mux()
when doing a request with a small payload response :
  qcc_recv_stop_sending(qc->qcc, 0, 0);

This must be backported up to 2.6.

2 years agoCLEANUP: quic: create a dedicated quic_conn module
Amaury Denoyelle [Fri, 30 Sep 2022 16:11:13 +0000 (18:11 +0200)] 
CLEANUP: quic: create a dedicated quic_conn module

xprt_quic module was too large and did not reflect the true architecture
by contrast to the other protocols in haproxy.

Extract code related to XPRT layer and keep it under xprt_quic module.
This code should only contains a simple API to communicate between QUIC
lower layer and connection/MUX.

The vast majority of the code has been moved into a new module named
quic_conn. This module is responsible to the implementation of QUIC
lower layer. Conceptually, it overlaps with TCP kernel implementation
when comparing QUIC and HTTP1/2 stacks of haproxy.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: remove duplicated varint code from xprt_quic.h
Amaury Denoyelle [Fri, 30 Sep 2022 15:47:04 +0000 (17:47 +0200)] 
CLEANUP: quic: remove duplicated varint code from xprt_quic.h

There was some identical code between xprt_quic and quic_enc modules.
This concerns helper on QUIC varint type. Keep only the version in
quic_enc file : this should help to reduce dependency on xprt_quic
module.

Note that quic_max_int_by_size() has been removed and is replaced by the
identical quic_max_int().

This should be backported up to 2.6.

2 years agoCLEANUP: quic: remove unused function prototype
Amaury Denoyelle [Fri, 30 Sep 2022 15:34:54 +0000 (17:34 +0200)] 
CLEANUP: quic: remove unused function prototype

Removed hexdump unusued prototype from quic_tls.c.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: fix headers
Amaury Denoyelle [Fri, 30 Sep 2022 15:44:15 +0000 (17:44 +0200)] 
CLEANUP: quic: fix headers

Clean up quic sources by adjusting headers list included depending
on the actual dependency of each source file.

On some occasion, xprt_quic.h was removed from included list. This is
useful to help reducing the dependency on this single file and cleaning
up QUIC haproxy architecture.

This should be backported up to 2.6.

2 years agoBUG/MINOR: quic: adjust quic_tls prototypes
Amaury Denoyelle [Fri, 30 Sep 2022 15:37:38 +0000 (17:37 +0200)] 
BUG/MINOR: quic: adjust quic_tls prototypes

Two prototypes in quic_tls module were not identical to the actual
function definition.

* quic_tls_decrypt2() : the second argument const attribute is not
  present, to be able to use it with EVP_CIPHER_CTX_ctlr(). As a
  consequence of this change, token field of quic_rx_packet is now
  declared as non-const.

* quic_tls_generate_retry_integrity_tag() : the second argument type
  differ between the two. Adjust this by fixing it to as unsigned char
  to match EVP_EncryptUpdate() SSL function.

This situation did not seem to have any visible effect. However, this is
clearly an undefined behavior and should be treated as a bug.

This should be backported up to 2.6.

2 years agoCLEANUP: quic: remove global var definition in quic_tls header
Amaury Denoyelle [Fri, 30 Sep 2022 15:31:18 +0000 (17:31 +0200)] 
CLEANUP: quic: remove global var definition in quic_tls header

Some variables related to QUIC TLS were defined in a header file : their
definitions are now moved properly in the implementation file, with only
declarations in the header.

This should be backported up to 2.6.

2 years agoCLEANUP: mux-quic: remove usage of non-standard ull type
Amaury Denoyelle [Fri, 30 Sep 2022 16:03:03 +0000 (18:03 +0200)] 
CLEANUP: mux-quic: remove usage of non-standard ull type

ull is a typedef to unsigned long long. It is only defined in
xprt_quic-t.h. Its usage should be limited over time to reduce xprt_quic
dependency over the whole code. It can be replaced by ullong typedef
from compat.h.

For the moment, ull references have been replaced in qmux_trace module.
They were only used for printf format and has been replaced by the true
variable type.

This change is useful to reduce dependencies on xprt_quic in other
files.

This should be backported up to 2.6.

2 years agoDOC: config: Fix pgsql-check documentation to make user param mandatory
Christopher Faulet [Mon, 3 Oct 2022 13:00:59 +0000 (15:00 +0200)] 
DOC: config: Fix pgsql-check documentation to make user param mandatory

The username is required in the Start-up message. Thus, since the 2.2, when
this health-check was refactored, the user parameter is mandatory. On prior
versions, when no username is provided, no pgsql check is performed but only
a basic tcpcheck.

This patch should be backported as far as 2.2.

2 years agoBUG/MINOR: checks: update pgsql regex on auth packet
Fatih Acar [Mon, 26 Sep 2022 15:27:11 +0000 (17:27 +0200)] 
BUG/MINOR: checks: update pgsql regex on auth packet

This patch adds support to the following authentication methods:

- AUTH_REQ_GSS (7)
- AUTH_REQ_SSPI (9)
- AUTH_REQ_SASL (10)

Note that since AUTH_REQ_SASL allows multiple authentication mechanisms
such as SCRAM-SHA-256 or SCRAM-SHA-256-PLUS, the auth payload length may
vary since the method is sent in plaintext. In order to allow this, the
regex now matches any payload length.

This partially fixes Github issue #1508 since user authentication is
still broken but should restore pre-2.2 behavior.

This should be backported up to 2.2.

Signed-off-by: Fatih Acar <facar@scaleway.com>
2 years ago[RELEASE] Released version 2.7-dev7 v2.7-dev7
Willy Tarreau [Mon, 3 Oct 2022 13:20:38 +0000 (15:20 +0200)] 
[RELEASE] Released version 2.7-dev7

Released version 2.7-dev7 with the following main changes :
    - BUG/MEDIUM: mux-quic: fix nb_hreq decrement
    - CLEANUP: httpclient: deleted unused variables
    - MINOR: httpclient: enabled the use of SNI presets
    - OPTIM: hpack-huff: reduce the cache footprint of the huffman decoder
    - BUG/MINOR: mux-quic: do not keep detached qcs with empty Tx buffers
    - REORG: mux-quic: extract traces in a dedicated source file
    - REORG: mux-quic: export HTTP related function in a dedicated file
    - MINOR: mux-quic: refactor snd_buf
    - BUG/MEDIUM: mux-quic: properly trim HTX buffer on snd_buf reset
    - BUG/MINOR: mux-h1: Account consumed output data on synchronous connection error
    - BUG/MINOR: log: improper behavior when escaping log data
    - CLEANUP: tools: removing escape_chunk() function
    - MINOR: clock: split local and global date updates
    - MINOR: pollers: only update the local date during busy polling
    - MINOR: clock: do not update the global date too often
    - REGTESTS: 4be_1srv_smtpchk_httpchk_layer47errors: Return valid SMTP replies
    - MINOR: smtpchk: Update expect rule to fully match replies to EHLO commands
    - BUG/MINOR: smtpchk: SMTP Service check should gracefully close SMTP transaction
    - MINOR: list: documenting mt_list_for_each_entry_safe() macro
    - CLEANUP: list: Fix mt_list_for_each_entry_safe indentation
    - BUG/MINOR: hlua: Remove \n in Lua error message built with memprintf
    - MINOR: hlua: Allow argument on lua-lod(-per-thread) directives
    - BUG/MINOR: anon: memory illegal accesses in tools.c with hash_anon and hash_ipanon
    - MEDIUM: mworker/cli: keep the connection of the FD that ask for a reload
    - BUG/MINOR: hlua: fixing ambiguous sizeof in hlua_load_per_thread
    - MINOR: mworker/cli: replace close() by fd_delete()
    - MINOR: mworker: store and shows loading status
    - MINOR: mworker: mworker_cli_proxy_new_listener() returns a bind_conf
    - MINOR: mworker: stores the mcli_reload bind_conf
    - MINOR: mworker/cli: the mcli_reload bind_conf only send the reload status
    - DOC: management: describe the new reload command behavior
    - CLEANUP: list: fix again some style issues in the recent comments
    - BUG/MINOR: stream: Perform errors handling in right order in stream_new()
    - BUG/MEDIUM: stconn: Reset SE descriptor when we fail to create a stream
    - BUG/MEDIUM: resolvers: Remove aborted resolutions from query_ids tree
    - DOC: management: add timeout on the "reload" command
    - BUG/MINOR: ring: fix the size check in ring_make_from_area()
    - BUG/MINOR: config: don't count trailing spaces as empty arg
    - Revert "BUG/MINOR: config: don't count trailing spaces as empty arg"
    - BUG/MINOR: hlua: fixing hlua_http_msg_del_data behavior
    - BUG/MINOR: hlua: fixing hlua_http_msg_insert_data behavior
    - MINOR: cli: Add anonymization on a missed element for 'show sess all'
    - MINOR: cli: remove error message with 'set anon on|off'
    - MINOR: tools: modify hash_ipanon in order to use it in cli
    - MINOR: cli: use hash_ipanon to anonymized address
    - MINOR: cli: Add an anonymization on a missed element in 'show server state'
    - MINOR: config: correct errors about argument number in condition in cfgparse.c
    - MINOR: config: Add other keywords when dump the anonymized configuration file
    - MINOR: config: Add option line when the configuration file is dumped
    - MINOR: cli: correct commentary and replace 'set global-key' name
    - MINOR: tools: Impprove hash_ipanon to support dgram sockets and port offsets
    - MINOR: tools: Impprove hash_ipanon to not hash FD-based addresses
    - BUG/MINOR: hlua: _hlua_http_msg_delete incorrect behavior when offset is used
    - DOC: management: httpclient can resolve server names in URLs
    - BUG/MINOR: hlua: prevent crash when loading numerous arguments using lua-load(per-thread)
    - DOC/CLEANUP: lua-api: removing duplicate date functions doc
    - MINOR: hlua: ambiguous lua_pushvalue with 0 index
    - BUG/MINOR: config: don't count trailing spaces as empty arg (v2)
    - BUG/MEDIUM: config: count line arguments without dereferencing the output
    - BUG/MAJOR: conn-idle: fix hash indexing issues on idle conns
    - BUG/MINOR: config: insufficient syntax check of the global "maxconn" value
    - BUG/MINOR: backend: only enforce turn-around state when not redispatching

2 years agoBUG/MINOR: backend: only enforce turn-around state when not redispatching
Willy Tarreau [Mon, 3 Oct 2022 12:56:34 +0000 (14:56 +0200)] 
BUG/MINOR: backend: only enforce turn-around state when not redispatching

In github issue #1878, Bart Butler reported observing turn-around states
(1 second pause) after connection retries going to different servers,
while this ought not happen.

In fact it does happen because back_handle_st_cer() enforces the TAR
state for any algo that's not round-robin. This means that even leastconn
has it, as well as hashes after the number of servers changed.

Prior to doing that, the call to stream_choose_redispatch() has already
had a chance to perform the correct choice and to check the algo and
the number of retries left. So instead we should just let that function
deal with the algo when needed (and focus on deterministic ones), and
let the former just obey. Bart confirmed that the fixed version works
as expected (no more delays during retries).

This may be backported to older releases, though it doesn't seem very
important. At least Bart would like to have it in 2.4 so let's go there
for now after it has cooked a few weeks in 2.6.

2 years agoBUG/MINOR: config: insufficient syntax check of the global "maxconn" value
Thierry Fournier [Sat, 1 Oct 2022 08:06:59 +0000 (10:06 +0200)] 
BUG/MINOR: config: insufficient syntax check of the global "maxconn" value

The maxconn value is decoded using atol(), so values like "3k" are
rightly converter as interger 3, while the user wants 3000.

This patch fixes this behavior by reporting a parsing error.

This patch could be backported on all maintained version, but it
could break some configuration. The bug is really minor, I recommend
to not backport, or backport a patch which only throws a warning in
place of a fatal error.

2 years agoBUG/MAJOR: conn-idle: fix hash indexing issues on idle conns
Willy Tarreau [Thu, 29 Sep 2022 18:32:43 +0000 (20:32 +0200)] 
BUG/MAJOR: conn-idle: fix hash indexing issues on idle conns

Idle connections do not work on 32-bit machines due to an alignment issue
causing the connection nodes to be indexed with their lower 32-bits set to
zero and the higher 32 ones containing the 32 lower bitss of the hash. The
cause is the use of ebmb_node with an aligned data, as on this platform
ebmb_node is only 32-bit aligned, leaving a hole before the following hash
which is a uint64_t:

  $ pahole -C conn_hash_node ./haproxy
  struct conn_hash_node {
        struct ebmb_node           node;                 /*     0    20 */

        /* XXX 4 bytes hole, try to pack */

        int64_t                    hash;                 /*    24     8 */
        struct connection *        conn;                 /*    32     4 */

        /* size: 40, cachelines: 1, members: 3 */
        /* sum members: 32, holes: 1, sum holes: 4 */
        /* padding: 4 */
        /* last cacheline: 40 bytes */
  };

Instead, eb64 nodes should be used when it comes to simply storing a
64-bit key, and that is what this patch does.

For backports, a variant consisting in simply marking the "hash" member
with a "packed" attribute on the struct also does the job (tested), and
might be preferable if the fix is difficult to adapt. Only 2.6 and 2.5
are affected by this.

2 years agoBUG/MEDIUM: config: count line arguments without dereferencing the output
Willy Tarreau [Mon, 3 Oct 2022 06:27:55 +0000 (08:27 +0200)] 
BUG/MEDIUM: config: count line arguments without dereferencing the output

Previous commit 8a6767d26 ("BUG/MINOR: config: don't count trailing spaces
as empty arg (v2)") was still not enough. As reported by ClusterFuzz in
issue 52049 (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52049),
there remains a case where for the sake of reporting the correct argument
count, the function may produce virtual args that span beyond the end of
the output buffer if that one is too short. That's what's happening with
a config file of one empty line followed by a large number of args.

This means that what args[] points to cannot be relied on and that a
different approach is needed. Since no output is produced for spaces and
comments, we know that args[arg] continues to point to out+outpos as long
as only comments or spaces are found, which is what we're interested in.

As such it's safe to check the last arg's pointer against the one before
the trailing zero was emitted, in order to decide to count one final arg.

No backport is needed, unless the commit above is backported.

2 years agoBUG/MINOR: config: don't count trailing spaces as empty arg (v2)
Erwan Le Goas [Fri, 23 Sep 2022 13:06:34 +0000 (15:06 +0200)] 
BUG/MINOR: config: don't count trailing spaces as empty arg (v2)

In parse_line(), spaces increment the arg count and it is incremented
again on '#' or end of line, resulting in an extra empty arg at the
end of arg's list. The visible effect is that the reported arg count
is in excess of 1. It doesn't seem to affect regular function but
specialized ones like anonymisation depends on this count.

This is the second attempt for this problem, here the explanation :

When called for the first line, no <out> was allocated yet so it's NULL,
letting the caller realloc a larger line if needed. However the words are
parsed and their respective args[arg] are filled with out+position, which
means that while the first arg is NULL, the other ones are no and fail the
test that was meant to avoid dereferencing a NULL. Let's simply check <out>
instead of <args> since the latter is always derived from the former and
cannot be NULL without the former also being.

This may need to be backported to stable versions.

2 years agoMINOR: hlua: ambiguous lua_pushvalue with 0 index
Aurelien DARRAGON [Thu, 29 Sep 2022 10:00:04 +0000 (12:00 +0200)] 
MINOR: hlua: ambiguous lua_pushvalue with 0 index

In function hlua_applet_http_send_response(), a pushvalue
is performed with index '0'.

But according to lua doc (https://www.lua.org/manual/5.3/manual.html#4.3):
"Note that 0 is never an acceptable index".

Adding a FIXME comment near to the pushvalue operation
so that this can get some chance to be reviewed later.

No backport needed.