]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 months agoCLEANUP: quic: remove unused cbuf module
Amaury Denoyelle [Wed, 21 May 2025 10:03:47 +0000 (12:03 +0200)] 
CLEANUP: quic: remove unused cbuf module

Cbuf are not used anymore. Remove the related source and header files,
as well as include statements in the rest of QUIC source files.

2 months agoEXAMPLES: lua: avoid screen refresh effect in "trisdemo"
Baptiste Assmann [Wed, 23 Apr 2025 08:36:37 +0000 (10:36 +0200)] 
EXAMPLES: lua: avoid screen refresh effect in "trisdemo"

In current version of the game, there is a "screen refresh" effect: the
screen is cleared before being re-drawn.
I moved the clear right after the connection is opened and removed it
from rendering time.

2 months agoBUG/MINOR: acme: fix formatting issue in error and logs
William Lallemand [Wed, 21 May 2025 09:36:46 +0000 (11:36 +0200)] 
BUG/MINOR: acme: fix formatting issue in error and logs

Stop emitting \n in errmsg for intermediate error messages, this was
emitting multiline logs and was returning to a new line in the middle of
sentences.

We don't need to emit them in acme_start_task() since the errmsg is
ouput in a send_log which already contains a \n or on the CLI which
also emits it.

2 months agoBUG/MEDIUM: acme: check if acme domains are configured
William Lallemand [Wed, 21 May 2025 09:13:09 +0000 (11:13 +0200)] 
BUG/MEDIUM: acme: check if acme domains are configured

When starting the ACME task with a ckch_conf which does not contain the
domains, the ACME task would segfault because it will try to dereference
a NULL in this case.

The patch fix the issue by emitting a warning when no domains are
configured. It's not done at configuration parsing because it is not
easy to emit the warning because there are is no callback system which
give access to the whole ckch_conf once a line is parsed.

No backport needed.

2 months agoDOC: watchdog: update the doc to reflect the recent changes
Willy Tarreau [Wed, 21 May 2025 09:34:07 +0000 (11:34 +0200)] 
DOC: watchdog: update the doc to reflect the recent changes

The watchdog was improved and fixed a few months ago, but the doc had
not been updated to reflect this. That's now done.

2 months agoBUG/MEDIUM: mux-quic: fix BUG_ON() on rxbuf alloc error
Amaury Denoyelle [Wed, 21 May 2025 09:24:57 +0000 (11:24 +0200)] 
BUG/MEDIUM: mux-quic: fix BUG_ON() on rxbuf alloc error

RX buffer allocation has been reworked in current dev tree. The
objective is to support multiple buffers per QCS to improve upload
throughput.

RX buffer allocation failure is handled simply : the whole connection is
closed. This is done via qcc_set_error(), with INTERNAL_ERROR as error
code. This function contains a BUG_ON() to ensure it is called only one
time per connection instance.

On RX buffer alloc failure, the aformentioned BUG_ON() crashes due to a
double invokation of qcc_set_error(). First by qcs_get_rxbuf(), and
immediately after it by qcc_recv(), which is the caller of the previous
one. This regression was introduced by the following commit.

  60f64449fbba7bb6e351e8343741bb3c960a2e6d
  MAJOR: mux-quic: support multiple QCS RX buffers

To fix this, simply remove qcc_set_error() invocation in
qcs_get_rxbuf(). On buffer alloc failture, qcc_recv() is responsible to
set the error.

This does not need to be backported.

2 months agoDOC: management: precise some of the fields of "show servers conn"
Willy Tarreau [Wed, 21 May 2025 08:45:07 +0000 (10:45 +0200)] 
DOC: management: precise some of the fields of "show servers conn"

As reported in issue #2970, the output of "show servers conn" is not
clear. It was essentially meant as a debugging tool during some changes
to idle connections management, but if some users want to monitor or
graph them, more info is needed. The doc mentions the currently known
list of fields, and reminds that this output is not meant to be stable
over time, but as long as it does not change, it can provide some useful
metrics to some users.

2 months agoBUILD: acme: fix build issue on 32-bit archs with 64-bit time_t
Willy Tarreau [Wed, 21 May 2025 08:18:47 +0000 (10:18 +0200)] 
BUILD: acme: fix build issue on 32-bit archs with 64-bit time_t

The build failed on mips32 with a 64-bit time_t here:

  https://github.com/haproxy/haproxy/actions/runs/15150389164/job/42595310111

Let's just turn the "remain" variable used to show the remaining time
into a more portable ullong and use %llu for all format specifiers,
since long remains limited to 32-bit on 32-bit archs.

No backport needed.

2 months agoBUILD: ssl: avoid possible printf format warning in traces
Willy Tarreau [Wed, 21 May 2025 08:01:14 +0000 (10:01 +0200)] 
BUILD: ssl: avoid possible printf format warning in traces

When building on MIPS-32 with gcc-9.5 and glibc-2.31, I got this:

  src/ssl_trace.c: In function 'ssl_trace':
  src/ssl_trace.c:118:42: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'ssize_t' {aka 'const int'} [-Wformat=]
    118 |     chunk_appendf(&trace_buf, " : size=%ld", *size);
        |                                        ~~^   ~~~~~
        |                                          |   |
        |                                          |   ssize_t {aka const int}
        |                                          long int
        |                                        %d

Let's just cast the type. No backport needed.

2 months agoCLEANUP: wdt: clarify the comments on the common exit path
Willy Tarreau [Tue, 20 May 2025 14:19:50 +0000 (16:19 +0200)] 
CLEANUP: wdt: clarify the comments on the common exit path

The condition in which we reach the check for ha_panic() and
ha_stuck_warning() are not super clear, let's reformulate them.

2 months agoBUG/MEDIUM: wdt: always ignore the first watchdog wakeup
Willy Tarreau [Tue, 20 May 2025 13:52:44 +0000 (15:52 +0200)] 
BUG/MEDIUM: wdt: always ignore the first watchdog wakeup

With commit a06c215f08 ("MEDIUM: wdt: always make the faulty thread
report its own warnings"), when the TH_FL_STUCK flag was flipped on,
we'd then go to the panic code instead of giving a second chance like
before the commit. This can trigger rare cases that only happen with
moderate loads like was addressed by commit 24ce001771 ("BUG/MEDIUM:
wdt: fix the stuck detection for warnings"). This is in fact due to
the loss of the common "goto update_and_leave" that used to serve
both the warning code and the flag setting for probation, and it's
apparently what hit Christian in issue #2980.

Let's make sure we exit naturally when turning the bit on for the
first time. Let's also update the confusing comment at the end of
the check that was left over by latest change.

Since the first commit was backported to 3.1, this commit should be
backported there as well.

2 months agoDOC: management: update 'acme status'
William Lallemand [Tue, 20 May 2025 14:08:57 +0000 (16:08 +0200)] 
DOC: management: update 'acme status'

Update the 'acme status' section with the "Stopped" status and fix the
description.

2 months agoDOC: update INSTALL for QUIC with OpenSSL 3.5 usages
Frederic Lecaille [Mon, 19 May 2025 16:59:43 +0000 (18:59 +0200)] 
DOC: update INSTALL for QUIC with OpenSSL 3.5 usages

Update the QUIC sections which mention the OpenSSL library use cases.

2 months agoMINOR: quic: OpenSSL 3.5 trick to support 0-RTT
Frederic Lecaille [Mon, 19 May 2025 15:39:58 +0000 (17:39 +0200)] 
MINOR: quic: OpenSSL 3.5 trick to support 0-RTT

For an unidentified reason, SSL_do_hanshake() succeeds at its first call when 0-RTT
is enabled for the connection. This behavior looks very similar by the one encountered
by AWS-LC stack. That said, it was documented by AWS-LC. This issue leads the
connection to stop sending handshake packets after having release the handshake
encryption level. In fact, no handshake packets could even been sent leading
the handshake to always fail.

To fix this, this patch simulates a "handshake in progress" state waiting
for the application level read secret to be established by the TLS stack.
This may happen only after the QUIC listener has completed/confirmed the handshake
upon handshake CRYPTO data receipt from the peer.

2 months agoMINOR: quic: OpenSSL 3.5 internal QUIC custom extension for transport parameters...
Frederic Lecaille [Mon, 19 May 2025 15:36:19 +0000 (17:36 +0200)] 
MINOR: quic: OpenSSL 3.5 internal QUIC custom extension for transport parameters reset

A QUIC must sent its transport parameter using a TLS custom extention. This
extension is reset by SSL_set_SSL_CTX(). It can be restored calling
quic_ssl_set_tls_cbs() (which calls SSL_set_quic_tls_cbs()).

2 months agoMINOR: quic: implement all remaining callbacks for OpenSSL 3.5 QUIC API
Frederic Lecaille [Mon, 19 May 2025 15:04:21 +0000 (17:04 +0200)] 
MINOR: quic: implement all remaining callbacks for OpenSSL 3.5 QUIC API

The quic_conn struct is modified for two reasons. The first one is to store
the encoded version of the local tranport parameter as this is done for
USE_QUIC_OPENSSL_COMPAT. Indeed, the local transport parameter "should remain
valid until after the parameters have been sent" as mentionned by
SSL_set_quic_tls_cbs(3) manual. In our case, the buffer is a static buffer
attached to the quic_conn object. qc_ssl_set_quic_transport_params() function
whose role is to call SSL_set_tls_quic_transport_params() (aliased by
SSL_set_quic_transport_params() to set these local tranport parameter into
the TLS stack from the buffer attached to the quic_conn struct.

The second quic_conn struct modification is the addition of the  new ->prot_level
(SSL protection level) member added to the quic_conn struct to store "the most
recent write encryption level set via the OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn
callback (if it has been called)" as mentionned by SSL_set_quic_tls_cbs(3) manual.

This patches finally implements the five remaining callacks to make the haproxy
QUIC implementation work.

OSSL_FUNC_SSL_QUIC_TLS_crypto_send_fn() (ha_quic_ossl_crypto_send) is easy to
implement. It calls ha_quic_add_handshake_data() after having converted
qc->prot_level TLS protection level value to the correct ssl_encryption_level_t
(boringSSL API/quictls) value.

OSSL_FUNC_SSL_QUIC_TLS_crypto_recv_rcd_fn() (ha_quic_ossl_crypto_recv_rcd())
provide the non-contiguous addresses to the TLS stack, without releasing
them.

OSSL_FUNC_SSL_QUIC_TLS_crypto_release_rcd_fn() (ha_quic_ossl_crypto_release_rcd())
release these non-contiguous buffer relying on the fact that the list of
encryption level (qc->qel_list) is correctly ordered by SSL protection level
secret establishements order (by the TLS stack).

OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn() (ha_quic_ossl_got_transport_params())
is a simple wrapping function over ha_quic_set_encryption_secrets() which is used
by boringSSL/quictls API.

OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn() (ha_quic_ossl_got_transport_params())
role is to store the peer received transport parameters. It simply calls
quic_transport_params_store() and set them into the TLS stack calling
qc_ssl_set_quic_transport_params().

Also add some comments for all the OpenSSL 3.5 QUIC API callbacks.

This patch have no impact on the other use of QUIC API provided by the others TLS
stacks.

2 months agoMINOR: quic: Allow the use of the new OpenSSL 3.5.0 QUIC TLS API (to be completed)
Frederic Lecaille [Tue, 13 May 2025 15:00:33 +0000 (17:00 +0200)] 
MINOR: quic: Allow the use of the new OpenSSL 3.5.0 QUIC TLS API (to be completed)

This patch allows the use of the new OpenSSL 3.5.0 QUIC TLS API when it is
available and detected at compilation time. The detection relies on the presence of the
OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_SEND macro from openssl-compat.h. Indeed this
macro is defined by OpenSSL since 3.5.0 version. It is not defined by quictls.
This helps in distinguishing these two TLS stacks. When the detection succeeds,
HAVE_OPENSSL_QUIC is also defined by openssl-compat.h. Then, this is this new macro
which is used to detect the availability of the new OpenSSL 3.5.0 QUIC TLS API.

Note that this detection is done only if USE_QUIC_OPENSSL_COMPAT is not asked.
So, USE_QUIC_OPENSSL_COMPAT and HAVE_OPENSSL_QUIC are exclusive.

At the same location, from openssl-compat.h, ssl_encryption_level_t enum is
defined. This enum was defined by quictls and expansively used by the haproxy
QUIC implementation. SSL_set_quic_transport_params() is replaced by
SSL_set_quic_tls_transport_params. SSL_set_quic_early_data_enabled() (quictls) is also replaced
by SSL_set_quic_tls_early_data_enabled() (OpenSSL). SSL_quic_read_level() (quictls)
is not defined by OpenSSL. It is only used by the traces to log the current
TLS stack decryption level (read). A macro makes it return -1 which is an
usused values.

The most of the differences between quictls and OpenSSL QUI APIs are in quic_ssl.c
where some callbacks must be defined for these two APIs. This is why this
patch modifies quic_ssl.c to define an array of OSSL_DISPATCH structs: <ha_quic_dispatch>.
Each element of this arry defines a callback. So, this patch implements these
six callabcks:

  - ha_quic_ossl_crypto_send()
  - ha_quic_ossl_crypto_recv_rcd()
  - ha_quic_ossl_crypto_release_rcd()
  - ha_quic_ossl_yield_secret()
  - ha_quic_ossl_got_transport_params() and
  - ha_quic_ossl_alert().

But at this time, these implementations which must return an int return 0 interpreted
as a failure by the OpenSSL QUIC API, except for ha_quic_ossl_alert() which
is implemented the same was as for quictls. The five remaining functions above
will be implemented by the next patches to come.

ha_quic_set_encryption_secrets() and ha_quic_add_handshake_data() have been moved
to be defined for both quictls and OpenSSL QUIC API.

These callbacks are attached to the SSL objects (sessions) calling qc_ssl_set_cbs()
new function. This latter callback the correct function to attached the correct
callbacks to the SSL objects (defined by <ha_quic_method> for quictls, and
<ha_quic_dispatch> for OpenSSL).

The calls to SSL_provide_quic_data() and SSL_process_quic_post_handshake()
have been also disabled. These functions are not defined by OpenSSL QUIC API.
At this time, the functions which call them are still defined when HAVE_OPENSSL_QUIC
is defined.

2 months agoMINOR: quic: Add useful error traces about qc_ssl_sess_init() failures
Frederic Lecaille [Thu, 15 May 2025 08:18:09 +0000 (10:18 +0200)] 
MINOR: quic: Add useful error traces about qc_ssl_sess_init() failures

There were no traces to diagnose qc_ssl_sess_init() failures from QUIC traces.
This patch add calls to TRACE_DEVEL() into qc_ssl_sess_init() and its caller
(qc_alloc_ssl_sock_ctx()). This was useful at least to diagnose SSL context
initialization failures when porting QUIC to the new OpenSSL 3.5 QUIC API.

Should be easily backported as far as 2.6.

2 months agoCLEANUP: quic: Useless BIO_METHOD initialization
Frederic Lecaille [Tue, 13 May 2025 14:15:51 +0000 (16:15 +0200)] 
CLEANUP: quic: Useless BIO_METHOD initialization

This code is there from QUIC implementation start. It was supposed to
initialize <ha_quic_meth> as a BIO_METHOD static object. But this
BIO_METHOD is not used at all!

Should be backported as far as 2.6 to help integrate the next patches to come.

2 months agoMINOR: acme: renewal notification over the dpapi sink
William Lallemand [Mon, 19 May 2025 13:56:54 +0000 (15:56 +0200)] 
MINOR: acme: renewal notification over the dpapi sink

Output a sink message when the certificate was renewed by the ACME
client.

The message is emitted on the "dpapi" sink, and ends by \n\0.
Since the message contains this binary character, the right -0 parameter
must be used when consulting the sink over the CLI:

Example:

$ echo "show events dpapi -nw -0" | socat -t9999 /tmp/haproxy.sock -
<0>2025-05-19T15:56:23.059755+02:00 acme newcert foobar.pem.rsa\n\0

When used with the master CLI, @@1 should be used instead of @1 in order
to keep the connection to the worker.

Example:

$ echo "@@1 show events dpapi -nw -0" | socat -t9999 /tmp/master.sock -
<0>2025-05-19T15:56:23.059755+02:00 acme newcert foobar.pem.rsa\n\0

2 months agoBUG/MAJOR: leastconn: never reuse the node after dropping the lock
Willy Tarreau [Mon, 19 May 2025 13:57:03 +0000 (15:57 +0200)] 
BUG/MAJOR: leastconn: never reuse the node after dropping the lock

On ARM with 80 cores and a single server, it's sometimes possible to see
a segfault in fwlc_get_next_server() around 600-700k RPS. It seldom
happens as well on x86 with 128 threads with the same config around 1M
rps. It turns out that in fwlc_get_next_server(), before calling
fwlc_srv_reposition(), we have to drop the lock and that one takes it
back again.

The problem is that anything can happen to our node during this time,
and it can be freed. Then when continuing our work, we later iterate
over it and its next to find a node with an acceptable key, and by
doing so we can visit either uninitialized memory or simply nodes that
are no longer in the tree.

A first attempt at fixing this consisted in artificially incrementing
the elements count before dropping the lock, but that turned out to be
even worse because other threads could loop forever on such an element
looking for an entry that does not exist. Maintaining a separate
refcount didn't work well either, and it required to deal with the
memory release while dropping it, which is really not convenient.

Here we're taking a different approach consisting in simply not
trusting this node anymore and going back to the beginning of the
loop, as is done at a few other places as well. This way we can
safely ignore the possibly released node, and the test runs reliably
both on the arm and the x86 platforms mentioned above. No performance
regression was observed either, likely because this operation is quite
rare.

No backport is needed since this appeared with the leastconn rework
in 3.2.

2 months agoBUG/MINOR: quic: fix crash on quic_conn alloc failure
Amaury Denoyelle [Mon, 19 May 2025 09:02:46 +0000 (11:02 +0200)] 
BUG/MINOR: quic: fix crash on quic_conn alloc failure

If there is an alloc failure during qc_new_conn(), cleaning is done via
quic_conn_release(). However, since the below commit, an unchecked
dereferencing of <qc.path> is performed in the latter.

  e841164a4402118bd7b2e2dc2b5068f21de5d9d2
  MINOR: quic: account for global congestion window

To fix this, simply check <qc.path> before dereferencing it in
quic_conn_release(). This is safe as it is properly initialized to NULL
on qc_new_conn() first stage.

This does not need to be backported.

2 months agoBUG/MAJOR: queue: properly keep count of the queue length
Willy Tarreau [Sat, 17 May 2025 08:28:50 +0000 (10:28 +0200)] 
BUG/MAJOR: queue: properly keep count of the queue length

The queue length was moved to its own variable in commit 583303c48
("MINOR: proxies/servers: Calculate queueslength and use it."), however a
few places were missed in pendconn_unlink() and assign_server_and_queue()
resulting in never decreasing counts on aborted streams. This was
reproduced when injecting more connections than the total backend
could stand in TCP mode and letting some of them time out in the
queue. No backport is needed, this is only 3.2.

2 months agoBUG/MAJOR: leastconn: do not loop forever when facing saturated servers
Willy Tarreau [Sat, 17 May 2025 07:54:49 +0000 (09:54 +0200)] 
BUG/MAJOR: leastconn: do not loop forever when facing saturated servers

Since commit 9fe72bba3 ("MAJOR: leastconn; Revamp the way servers are
ordered."), there's no way to escape the loop visiting the mt_list heads
in fwlc_get_next_server if all servers in the list are saturated,
resulting in a watchdog panic. It can be reproduced with this config
and injecting with more than 2 concurrent conns:

    balance leastconn
    server s1 127.0.0.1:8000 maxconn 1
    server s2 127.0.0.1:8000 maxconn 1

Here we count the number of saturated servers that were encountered, and
escape the loop once the number of remaining servers exceeds the number
of saturated ones. No backport is needed since this arrived in 3.2.

2 months agoIMPORT: slz: silence a build warning on non-x86 non-arm
Willy Tarreau [Fri, 16 May 2025 14:19:04 +0000 (16:19 +0200)] 
IMPORT: slz: silence a build warning on non-x86 non-arm

Building with clang 16 on MIPS64 yields this warning:

  src/slz.c:931:24: warning: unused function 'crc32_uint32' [-Wunused-function]
  static inline uint32_t crc32_uint32(uint32_t data)
                         ^

Let's guard it using UNALIGNED_LE_OK which is the only case where it's
used. This saves us from introducing a possibly non-portable attribute.

This is libslz upstream commit f5727531dba8906842cb91a75c1ffa85685a6421.

2 months agoIMPORT: slz: fix header used for empty zlib message
Willy Tarreau [Mon, 26 Jun 2023 16:00:39 +0000 (18:00 +0200)] 
IMPORT: slz: fix header used for empty zlib message

Calling slz_rfc1950_finish() without emitting any data would result in
incorrectly emitting a gzip header (rfc1952) instead of a zlib header
(rfc1950) due to a copy-paste between the two wrappers. The impact is
almost inexistent since the zlib format is almost never used in this
context, and compressing totally empty messages is quite rare as well.
Let's take this opportunity for fixing another mistake on an RFC number
in a comment.

This is slz upstream commit 7f3fce4f33e8c2f5e1051a32a6bca58e32d4f818.

2 months agoIMPORT: slz: use a better hash for machines with a fast multiply
Willy Tarreau [Sun, 9 Apr 2023 09:50:15 +0000 (11:50 +0200)] 
IMPORT: slz: use a better hash for machines with a fast multiply

The current hash involves 3 simple shifts and additions so that it can
be mapped to a multiply on architecures having a fast multiply. This is
indeed what the compiler does on x86_64. A large range of values was
scanned to try to find more optimal factors on machines supporting such
a fast multiply, and it turned out that new factor 0x1af42f resulted in
smoother hashes that provided on average 0.4% better compression on both
the Silesia corpus and an mbox file composed of very compressible emails
and uncompressible attachments. It's even slightly better than CRC32C
while being faster on Skylake. This patch enables this factor on archs
with a fast multiply.

This is slz upstream commit 82ad1e75c13245a835c1c09764c89f2f6e8e2a40.

2 months agoIMPORT: slz: support crc32c for lookup hash on sse4 but only if requested
Willy Tarreau [Sun, 9 Apr 2023 09:35:19 +0000 (11:35 +0200)] 
IMPORT: slz: support crc32c for lookup hash on sse4 but only if requested

If building for sse4 and USE_CRC32C_HASH is defined, then we can use
crc32c to calculate the lookup hash. By default we don't do it because
even on skylake it's slower than the current hash, which only involves
a short multiply (~5% slower). But the gains are marginal (0.3%).

This is slz upstream commit 44ae4f3f85eb275adba5844d067d281e727d8850.

Note: this is not used by default and only merged in order to avoid
divergence between the code bases.

2 months agoIMPORT: slz: avoid multiple shifts on 64-bits
Willy Tarreau [Sun, 9 Apr 2023 08:23:18 +0000 (10:23 +0200)] 
IMPORT: slz: avoid multiple shifts on 64-bits

On 64-bit platforms, disassembling the code shows that send_huff() performs
a left shift followed by a right one, which are the result of integer
truncation and zero-extension caused solely by using different types at
different levels in the call chain. By making encode24() take a 64-bit
int on input and send_huff() take one optionally, we can remove one shift
in the hot path and gain 1% performance without affecting other platforms.

This is slz upstream commit fd165b36c4621579c5305cf3bb3a7f5410d3720b.

2 months agoBUILD: debug: mark ha_crash_now() as attribute(noreturn)
Willy Tarreau [Fri, 16 May 2025 14:12:12 +0000 (16:12 +0200)] 
BUILD: debug: mark ha_crash_now() as attribute(noreturn)

Building on MIPS64 with clang16 incorrectly reports some uninitialized
value warnings in stats-proxy.c due to some calls to ABORT_NOW() where
the compiler didn't know the code wouldn't return. Let's properly mark
the function as noreturn, and take this opportunity for also marking it
unused to avoid possible warnings depending on the build options (if
ABORT_NOW is not used). No backport needed though it will not harm.

2 months agoDOC: management: change reference to configuration manual
William Lallemand [Fri, 16 May 2025 13:57:13 +0000 (15:57 +0200)] 
DOC: management: change reference to configuration manual

Since e24b77e7 ('DOC: config: move the extraneous sections out of the
"global" definition') the ACME section of the configuration manual was
move from 3.13 to 12.8.

Change the reference to that section in "acme renew".

2 months agoDOC: config: properly index "table and "stick-table" in their section
Willy Tarreau [Fri, 16 May 2025 13:37:03 +0000 (15:37 +0200)] 
DOC: config: properly index "table and "stick-table" in their section

Tim reported in issue #2953 that "stick-table" and "table" were not
indexed as keywords. The issue was the indent level. Also let's make
sure to put a box around the "store" arguments as well.

2 months agoBUG/MEDIUM: h1/h2/h3: reject forbidden chars in the Host header field
Willy Tarreau [Fri, 16 May 2025 12:58:52 +0000 (14:58 +0200)] 
BUG/MEDIUM: h1/h2/h3: reject forbidden chars in the Host header field

In continuation with 9a05c1f574 ("BUG/MEDIUM: h2/h3: reject some
forbidden chars in :authority before reassembly") and the discussion
in issue #2941, @DemiMarie rightfully suggested that Host should also
be sanitized, because it is sometimes used in concatenation, such as
this:

    http-request set-url https://%[req.hdr(host)]%[pathq]

which was proposed as a workaround for h2 upstream servers that require
:authority here:

    https://www.mail-archive.com/haproxy@formilux.org/msg43261.html

The current patch then adds the same check for forbidden chars in the
Host header, using the same function as for the patch above, since in
both cases we validate the host:port part of the authority. This way
we won't reconstruct ambiguous URIs by concatenating Host and path.

Just like the patch above, this can be backported afer a period of
observation.

2 months agoBUG/MINOR: h3: don't insert more than one Host header
Willy Tarreau [Fri, 16 May 2025 12:51:13 +0000 (14:51 +0200)] 
BUG/MINOR: h3: don't insert more than one Host header

Let's make sure we drop extraneous Host headers after having compared
them. That also works when :authority was already present. This way,
like for h1 and h2, we only keep one copy of it, while still making
sure that Host matches :authority. This way, if a request has both
:authority and Host, only one Host header will be produced (from
:authority). Note that due to the different organization of the code
and wording along the evolving RFCs, here we also check that all
duplicates are identical, while h2 ignores them as per RFC7540, but
this will be re-unified later.

This should be backported to stable versions, at least 2.8, though
thanks to the existing checks the impact is probably nul.

2 months agoBUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload
Christopher Faulet [Fri, 16 May 2025 12:19:52 +0000 (14:19 +0200)] 
BUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload

It is especially a problem with Lua filters, but it is important to disable
the 0-copy forwarding if a filter alters the payload, or at least to be able
to disable it. While the filter is registered on the data filtering, it is
not an issue (and it is the common case) because, there is now way to
fast-forward data at all. But it may be an issue if a filter decides to
alter the payload and to unregister from data filtering. In that case, the
0-copy forwarding can be re-enabled in a hardly precdictable state.

To fix the issue, a SC flags was added to do so. The HTTP compression filter
set it and lua filters too if the body length is changed (via
HTTPMessage.set_body_len()).

Note that it is an issue because of a bad design about the HTX. Many info
about the message are stored in the HTX structure itself. It must be
refactored to move several info to the stream-endpoint descriptor. This
should ease modifications at the stream level, from filter or a TCP/HTTP
rules.

This should be backported as far as 3.0. If necessary, it may be backported
on lower versions, as far as 2.6. In that case, it must be reviewed and
adapted.

2 months agoMEDIUM: hlua: Add function to change the body length of an HTTP Message
Christopher Faulet [Fri, 16 May 2025 12:10:31 +0000 (14:10 +0200)] 
MEDIUM: hlua: Add function to change the body length of an HTTP Message

There was no function for a lua filter to change the body length of an HTTP
Message. But it is mandatory to be able to alter the message payload. It is
not possible update to directly update the message headers because the
internal state of the message must also be updated accordingly.

It is the purpose of HTTPMessage.set_body_len() function. The new body
length myst be passed as argument. If it is an integer, the right
"Content-Length" header is set. If the "chunked" string is used, it forces
the message to be chunked-encoded and in that case the "Transfer-Encoding"
header.

This patch should fix the issue #2837. It could be backported as far as 2.6.

2 months agoBUG/MEDIUM: peers: also limit the number of incoming updates
Willy Tarreau [Thu, 15 May 2025 13:41:50 +0000 (15:41 +0200)] 
BUG/MEDIUM: peers: also limit the number of incoming updates

There's a configurable limit to the number of messages sent to a
peer (tune.peers.max-updates-at-once), but this one is not applied to
the receive side. While it can usually be OK with default settings,
setups involving a large tune.bufsize (1MB and above) regularly
experience high latencies and even watchdogs during reloads because
the full learning process sends a lot of data that manages to fill
the entire buffer, and due to the compactness of the protocol, 1MB
of buffer can contain more than 100k updates, meaning taking locks
etc during this time, which is not workable.

Let's make sure the receiving side also respects the max-updates-at-once
setting. For this it counts incoming updates, and refrains from
continuing once the limit is reached. It's a bit tricky to do because
after receiving updates we still have to send ours (and possibly some
ACKs) so we cannot just leave the loop.

This issue was reported on 3.1 but it should progressively be backported
to all versions having the max-updates-at-once option available.

2 months agoBUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers
Aurelien DARRAGON [Thu, 15 May 2025 13:54:13 +0000 (15:54 +0200)] 
BUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers

using "send-proxy" or "send-proxy-v2" option on a ring server is not
relevant nor supported. Worse, on 2.4 it causes haproxy process to
crash as reported in GH #2965.

Let's be more explicit about the fact that this keyword is not supported
under "ring" context by ignoring the option and emitting a warning message
to inform the user about that.

Ideally, we should do the same for peers and log servers. The proper way
would be to check servers options during postparsing but we currently lack
proper cross-type server postparsing hooks. This will come later and thus
will give us a chance to perform the compatibilty checks for server
options depending on proxy type. But for now let's simply fix the "ring"
case since it is the only one that's known to cause a crash.

It may be backported to all stable versions.

2 months agoDOC: configuration: explicit multi-choice on bind shards option
Basha Mougamadou [Wed, 14 May 2025 15:50:47 +0000 (15:50 +0000)] 
DOC: configuration: explicit multi-choice on bind shards option

From the documentation, this wasn't clear enough that shards should
be followed by one of the options number / by-thread / by-group.
Align it with existing options in documentation so that it becomes
more explicit.

2 months ago[RELEASE] Released version 3.2-dev16 v3.2-dev16
Willy Tarreau [Wed, 14 May 2025 15:01:46 +0000 (17:01 +0200)] 
[RELEASE] Released version 3.2-dev16

Released version 3.2-dev16 with the following main changes :
    - BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
    - DEBUG: pool: permit per-pool UAF configuration
    - MINOR: acme: add the global option 'acme.scheduler'
    - DEBUG: pools: add a new integrity mode "backup" to copy the released area
    - MEDIUM: sock-inet: re-check IPv6 connectivity every 30s
    - BUG/MINOR: ssl: doesn't fill conf->crt with first arg
    - BUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line
    - BUG/MINOR: ssl/ckch: always free() the previous entry during parsing
    - MINOR: tools: ha_freearray() frees an array of string
    - BUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing
    - MINOR: ssl/ckch: warn when the same keyword was used twice
    - BUG/MINOR: threads: fix soft-stop without multithreading support
    - BUG/MINOR: tools: improve parse_line()'s robustness against empty args
    - BUG/MINOR: cfgparse: improve the empty arg position report's robustness
    - BUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()
    - BUG/MINOR: server: perform lbprm deinit for dynamic servers
    - MINOR: http: add a function to validate characters of :authority
    - BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly
    - MINOR: quic: account Tx data per stream
    - MINOR: mux-quic: account Rx data per stream
    - MINOR: quic: add stream format for "show quic"
    - MINOR: quic: display QCS info on "show quic stream"
    - MINOR: quic: display stream age
    - BUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters
    - MINOR: cpu-topo: add a new "group-by-ccx" CPU policy
    - MINOR: cpu-topo: provide a function to sort clusters by average capacity
    - MEDIUM: cpu-topo: change "performance" to consider per-core capacity
    - MEDIUM: cpu-topo: change "efficiency" to consider per-core capacity
    - MEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"
    - MEDIUM: config: change default limits to 1024 threads and 32 groups
    - BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation
    - DOC: config: Fix a typo in the "term_events" definition
    - BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state
    - BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received
    - BUG/MINOR: mux-spop: Make the demux stream ID a signed integer
    - BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
    - MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
    - BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
    - BUG/MEDIUM: mux-spop: Properly handle CLOSING state
    - BUG/MEDIUM: spop-conn: Report short read for partial frames payload
    - BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error
    - BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data
    - DEBUG: mux-spop: Review some trace messages to adjust the message or the level
    - DOC: config: move address formats definition to section 2
    - DOC: config: move stick-tables and peers to their own section
    - DOC: config: move the extraneous sections out of the "global" definition
    - CI: AWS-LC(fips): enable unit tests
    - CI: AWS-LC: enable unit tests
    - CI: compliance: limit run on forks only to manual + cleanup
    - CI: musl: enable unit tests
    - CI: QuicTLS (weekly): limit run on forks only to manual dispatch
    - CI: WolfSSL: enable unit tests

2 months agoCI: WolfSSL: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:38:45 +0000 (20:38 +0200)] 
CI: WolfSSL: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: QuicTLS (weekly): limit run on forks only to manual dispatch
Ilia Shipitsin [Tue, 13 May 2025 18:38:10 +0000 (20:38 +0200)] 
CI: QuicTLS (weekly): limit run on forks only to manual dispatch

2 months agoCI: musl: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:37:35 +0000 (20:37 +0200)] 
CI: musl: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: compliance: limit run on forks only to manual + cleanup
Ilia Shipitsin [Tue, 13 May 2025 18:36:41 +0000 (20:36 +0200)] 
CI: compliance: limit run on forks only to manual + cleanup

2 months agoCI: AWS-LC: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:36:17 +0000 (20:36 +0200)] 
CI: AWS-LC: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: AWS-LC(fips): enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:35:29 +0000 (20:35 +0200)] 
CI: AWS-LC(fips): enable unit tests

Run the new make unit-tests on the CI.

2 months agoDOC: config: move the extraneous sections out of the "global" definition
Willy Tarreau [Wed, 14 May 2025 13:54:58 +0000 (15:54 +0200)] 
DOC: config: move the extraneous sections out of the "global" definition

Due to some historic mistakes that have spread to newly added sections,
a number of of recently added small sections found themselves described
under section 3 "global parameters" which is specific to "global" section
keywords. This is highly confusing, especially given that sections 3.1,
3.2, 3.3 and 3.10 directly start with keywords valid in the global section,
while others start with keywords that describe a new section.

Let's just create a new chapter "12. other sections" and move them all
there. 3.10 "HTTPclient tuning" however was moved to 3.4 as it's really
a definition of the global options assigned to the HTTP client. The
"programs" that are going away in 3.3 were moved at the end to avoid a
renumbering later.

Another nice benefit is that it moves a lot of text that was previously
keeping the global and proxies sections apart.

2 months agoDOC: config: move stick-tables and peers to their own section
Willy Tarreau [Wed, 14 May 2025 12:26:38 +0000 (14:26 +0200)] 
DOC: config: move stick-tables and peers to their own section

As suggested by Tim in issue #2953, stick-tables really deserve their own
section to explain the configuration. And peers have to move there as well
since they're totally dedicated to stick-tables.

Now we introduce a new section "Stick-tables and Peers", explaining the
concepts, and under which there is one subsection for stick-tables
configuration and one for the peers (which mostly keeps the existing
peers section).

2 months agoDOC: config: move address formats definition to section 2
Willy Tarreau [Wed, 14 May 2025 13:39:15 +0000 (15:39 +0200)] 
DOC: config: move address formats definition to section 2

Section 2 describes the config file format, variables naming etc, so
there's no reason why the address format used in this file should be
in a separate section, let's bring it into section 2 as well.

2 months agoDEBUG: mux-spop: Review some trace messages to adjust the message or the level
Christopher Faulet [Wed, 14 May 2025 07:39:03 +0000 (09:39 +0200)] 
DEBUG: mux-spop: Review some trace messages to adjust the message or the level

Some trace messages were not really accurrate, reporting a CLOSED connection
while only an error was reported on it. In addition, an TRACE_ERROR() was
used to report a short read on HELLO/DISCONNECT frames header. But it is not
an error. a TRACE_DEVEL() should be used instead.

This patch could be backported to 3.1 to ease future backports.

2 months agoBUG/MEDIUM: mux-spop; Don't report a read error if there are pending data
Christopher Faulet [Wed, 14 May 2025 07:33:46 +0000 (09:33 +0200)] 
BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data

When an read error is detected, no error must be reported on the SPOP
connection is there are still some data to parse. It is important to be sure
to process all data before reporting the error and be sure to not truncate
received frames. However, we must also take care to handle short read case
to not wait data that will never be received.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error
Christopher Faulet [Wed, 14 May 2025 07:22:45 +0000 (09:22 +0200)] 
BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error

There was no test in the demux part to detect truncated frames and to report
an error at the connection level. The SPOP streams were properly switch to
half-closed state. But waiting the associated SPOE applets were woken up and
released, the SPOP connection could be woken up several times for nothing. I
never triggered the watchdog in that case, but it is not excluded.

Now, at the end of the demux function, if a specific test was added to
detect truncated frames to report an error and close the connection.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: spop-conn: Report short read for partial frames payload
Christopher Faulet [Wed, 14 May 2025 07:20:08 +0000 (09:20 +0200)] 
BUG/MEDIUM: spop-conn: Report short read for partial frames payload

When a frame was not fully received, a short read must be reported on the
SPOP connection to help the demux to handle truncated frames. This was
performed for frames truncated on the header part but not on the payload
part. It is now properly detected.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Properly handle CLOSING state
Christopher Faulet [Tue, 13 May 2025 17:04:01 +0000 (19:04 +0200)] 
BUG/MEDIUM: mux-spop: Properly handle CLOSING state

The CLOSING state was not handled at all by the SPOP multiplexer while it is
mandatory when a DISCONNECT frame was sent and the mux should wait for the
DISCONNECT frame in reply from the agent. Thanks to this patch, it should be
fixed.

In addition, if an error occurres during the AGENT HELLO frame parsing, the
SPOP connection is no longer switched to CLOSED state and remains in ERROR
state instead. It is important to be able to send the DISCONNECT frame to
the agent instead of closing the TCP connection immediately.

This patch depends on following commits:

  * BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
  * MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
  * BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
  * BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

All the series must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
Christopher Faulet [Tue, 13 May 2025 16:55:32 +0000 (18:55 +0200)] 
BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state

SPOP_CS_FRAME_H and SPOP_CS_FRAME_P states, that were used to handle frame
parsing, were removed. The demux process now relies on the demux stream ID
to know if it is waiting for the frame header or the frame
payload. Concretly, when the demux stream ID is not set (dsi == -1), the
demuxer is waiting for the next frame header. Otherwise (dsi >= 0), it is
waiting for the frame payload. It is especially important to be able to
properly handle DISCONNECT frames sent by the agents.

SPOP_CS_RUNNING state is introduced to know the hello handshake was finished
and the SPOP connection is able to open SPOP streams and exchange NOTIFY/ACK
frames with the agents.

It depends on the following fixes:

  * MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
  * BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

This change will be mandatory for the next fix. It must be backported to 3.1
with the commits above.

2 months agoMINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
Christopher Faulet [Tue, 13 May 2025 16:41:09 +0000 (18:41 +0200)] 
MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing

After the ACK frame was parsed, it is useless to set the SPOP connection
state to SPOP_CS_FRAME_H state because this will be automatically handled by
the demux function. If it is not an issue, but this will simplify changes
for the next commit.

2 months agoBUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
Christopher Faulet [Tue, 13 May 2025 16:35:29 +0000 (18:35 +0200)] 
BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error

Till now, only SPOP connections fully closed or those with a TCP connection on
error were concerned. But available streams could be reported for SPOP
connections in error or closing state. But in these states, no NOTIFY frames
will be sent and no ACK frames will be parsed. So, no new SPOP streams should be
opened.

This patch should be backported to 3.1.

2 months agoBUG/MINOR: mux-spop: Make the demux stream ID a signed integer
Christopher Faulet [Tue, 13 May 2025 16:26:25 +0000 (18:26 +0200)] 
BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

The demux stream ID of a SPOP connection, used when received frames are
parsed, must be a signed integer because it is set to -1 when the SPOP
connection is initialized. It will be important for the next fix.

This patch must be backported to 3.1.

2 months agoBUG/MINOR: mux-spop: Don't report error for stream if ACK was already received
Christopher Faulet [Tue, 13 May 2025 16:05:26 +0000 (18:05 +0200)] 
BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received

When a SPOP connection was closed or was in error, an error was
systematically reported on all its SPOP streams. However, SPOP streams that
already received their ACK frame must be excluded. Otherwise if an agent
sends a ACK and close immediately, the ACK will be ignored because the SPOP
stream will handle the error first.

This patch must be backported to 3.1.

2 months agoBUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state
Christopher Faulet [Tue, 13 May 2025 15:45:18 +0000 (17:45 +0200)] 
BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state

When the SPOE applet was released, if a SPOE filter context was still
attached to it, an error was reported to the filter. However, there is no
reason to report an error if the ACK message was already received. Because
of this bug, if the ACK message is received and the SPOE connection is
immediately closed, this prevents the ACK message to be processed.

This patch should be backported to 3.1.

2 months agoDOC: config: Fix a typo in the "term_events" definition
Christopher Faulet [Tue, 13 May 2025 12:26:37 +0000 (14:26 +0200)] 
DOC: config: Fix a typo in the "term_events" definition

A space was missing before the colon.

2 months agoBUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation
Christopher Faulet [Mon, 12 May 2025 14:12:13 +0000 (16:12 +0200)] 
BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation

When the channel API was revisted, the both functions above was added. An
offset can be passed as argument. However, this parameter could be reported
to be out of range if there was not enough input data was received yet. It
is an issue, especially with a tcp rule, because more data could be
received. If an error is reported too early, this prevent the rule to be
reevaluated later. In fact, an error should only be reported if the offset
is part of the output data.

Another issue is about the conditions to report 'nil' instead of an empty
string. 'nil' was reported when no data was found. But it is not aligned
with the documentation. 'nil' must only be returned if no more data cannot
be received and there is no input data at all.

This patch should fix the issue #2716. It should be backported as far as 2.6.

2 months agoMEDIUM: config: change default limits to 1024 threads and 32 groups
Willy Tarreau [Tue, 13 May 2025 15:58:28 +0000 (17:58 +0200)] 
MEDIUM: config: change default limits to 1024 threads and 32 groups

A test run on a dual-socket EPYC 9845 (2x160 cores) showed that we'll
be facing new limits during the lifetime of 3.2 with our current 16
groups and 256 threads max:

  $ cat test.cfg
  global
      cpu-policy perforamnce

  $ ./haproxy -dc -c -f test.cfg
  ...
  Thread CPU Bindings:
    Tgrp/Thr  Tid        CPU set
    1/1-32    1-32       32: 0-15,320-335
    2/1-32    33-64      32: 16-31,336-351
    3/1-32    65-96      32: 32-47,352-367
    4/1-32    97-128     32: 48-63,368-383
    5/1-32    129-160    32: 64-79,384-399
    6/1-32    161-192    32: 80-95,400-415
    7/1-32    193-224    32: 96-111,416-431
    8/1-32    225-256    32: 112-127,432-447

Raising the default limit to 1024 threads and 32 groups is sufficient
to buy us enough margin for a long time (hopefully, please don't laugh,
you, reader from the future):

  $ ./haproxy -dc -c -f test.cfg
  ...
  Thread CPU Bindings:
    Tgrp/Thr  Tid        CPU set
    1/1-32    1-32       32: 0-15,320-335
    2/1-32    33-64      32: 16-31,336-351
    3/1-32    65-96      32: 32-47,352-367
    4/1-32    97-128     32: 48-63,368-383
    5/1-32    129-160    32: 64-79,384-399
    6/1-32    161-192    32: 80-95,400-415
    7/1-32    193-224    32: 96-111,416-431
    8/1-32    225-256    32: 112-127,432-447
    9/1-32    257-288    32: 128-143,448-463
    10/1-32   289-320    32: 144-159,464-479
    11/1-32   321-352    32: 160-175,480-495
    12/1-32   353-384    32: 176-191,496-511
    13/1-32   385-416    32: 192-207,512-527
    14/1-32   417-448    32: 208-223,528-543
    15/1-32   449-480    32: 224-239,544-559
    16/1-32   481-512    32: 240-255,560-575
    17/1-32   513-544    32: 256-271,576-591
    18/1-32   545-576    32: 272-287,592-607
    19/1-32   577-608    32: 288-303,608-623
    20/1-32   609-640    32: 304-319,624-639

We can change this default now because it has no functional effect
without any configured cpu-policy, so this will only be an opt-in
and it's better to do it now than to have an effect during the
maintenance phase. A tiny effect is a doubling of the number of
pool buckets and stick-table shards internally, which means that
aside slightly reducing contention in these areas, a dump of tables
can enumerate keys in a different order (hence the adjustment in the
vtc).

The only really visible effect is a slightly higher static memory
consumption (29->35 MB on a small config), but that difference
remains even with 50k servers so that's pretty much acceptable.

Thanks to Erwan Velu for the quick tests and the insights!

2 months agoMEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"
Willy Tarreau [Tue, 13 May 2025 14:20:53 +0000 (16:20 +0200)] 
MEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"

Most of the time, machines made of multiple CPU types use the same L3
for them, and grouping CPUs by frequencies to form groups doesn't bring
any value and on the opposite can impair the incoming connection balancing.
This choice of grouping by cluster was made in order to constitute a good
choice on homogenous machines as well, so better rely on the per-CCX
grouping than the per-cluster one in this case. This will create less
clusters on machines where it counts without affecting other ones.

It doesn't seem necessary to change anything for the "resource" policy
since it selects a single cluster.

2 months agoMEDIUM: cpu-topo: change "efficiency" to consider per-core capacity
Willy Tarreau [Tue, 13 May 2025 14:18:25 +0000 (16:18 +0200)] 
MEDIUM: cpu-topo: change "efficiency" to consider per-core capacity

This is similar to the previous change to the "performance" policy but
it applies to the "efficiency" one. Here we're changing the sorting
method to sort CPU clusters by average per-CPU capacity, and we evict
clusters whose per-CPU capacity is above 125% of the previous one.
Per-core capacity allows to detect discrepancies between CPU cores,
and to continue to focus on efficient ones as a priority.

2 months agoMEDIUM: cpu-topo: change "performance" to consider per-core capacity
Willy Tarreau [Tue, 13 May 2025 14:12:52 +0000 (16:12 +0200)] 
MEDIUM: cpu-topo: change "performance" to consider per-core capacity

Running the "performance" policy on highly heterogenous systems yields
bad choices when there are sufficiently more small than big cores,
and/or when there are multiple cluster types, because on such setups,
the higher the frequency, the lower the number of cores, despite small
differences in frequencies. In such cases, we quickly end up with
"performance" only choosing the small or the medium cores, which is
contrary to the original intent, which was to select performance cores.
This is what happens on boards like the Orion O6 for example where only
the 4 medium cores and 2 big cores are choosen, evicting the 2 biggest
cores and the 4 smallest ones.

Here we're changing the sorting method to sort CPU clusters by average
per-CPU capacity, and we evict clusters whose per-CPU capacity falls
below 80% of the previous one. Per-core capacity allows to detect
discrepancies between CPU cores, and to continue to focus on high
performance ones as a priority.

2 months agoMINOR: cpu-topo: provide a function to sort clusters by average capacity
Willy Tarreau [Tue, 13 May 2025 14:00:23 +0000 (16:00 +0200)] 
MINOR: cpu-topo: provide a function to sort clusters by average capacity

The current per-capacity sorting function acts on a whole cluster, but
in some setups having many small cores and few big ones, it becomes
easy to observe an inversion of metrics where the many small cores show
a globally higher total capacity than the few big ones. This does not
necessarily fit all use cases. Let's add new a function to sort clusters
by their per-cpu average capacity to cover more use cases.

2 months agoMINOR: cpu-topo: add a new "group-by-ccx" CPU policy
Willy Tarreau [Tue, 13 May 2025 13:39:35 +0000 (15:39 +0200)] 
MINOR: cpu-topo: add a new "group-by-ccx" CPU policy

This cpu-policy will only consider CCX and not clusters. This makes
a difference on machines with heterogenous CPUs that generally share
the same L3 cache, where it's not desirable to create multiple groups
based on the CPU types, but instead create one with the different CPU
types. The variants "group-by-2/3/4-ccx" have also been added.

Let's also add some text explaining the difference between cluster
and CCX.

2 months agoBUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters
Willy Tarreau [Tue, 13 May 2025 09:40:44 +0000 (11:40 +0200)] 
BUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters

Some (rare) boards have their clusters in an erratic order. This is
the case for the Radxa Orion O6 where one of the big cores appears as
CPU0 due to booting from it, then followed by the small cores, then the
medium cores, then the remaining big cores. This results in clusters
appearing this order: 0,2,1,0.

The core in cpu_policy_group_by_cluster() expected ordered clusters,
and performs ordered comparisons to decide whether a CPU's cluster has
already been taken care of. On the board above this doesn't work, only
clusters 0 and 2 appear and 1 is skipped.

Let's replace the cluster number comparison with a cpuset to record
which clusters have been taken care of. Now the groups properly appear
like this:

  Tgrp/Thr  Tid        CPU set
  1/1-2     1-2        2: 0,11
  2/1-4     3-6        4: 1-4
  3/1-6     7-12       6: 5-10

No backport is needed, this is purely 3.2.

2 months agoMINOR: quic: display stream age
Amaury Denoyelle [Fri, 9 May 2025 15:30:27 +0000 (17:30 +0200)] 
MINOR: quic: display stream age

Add a field to save the creation date of qc_stream_desc instance. This
is useful to display QUIC stream age in "show quic stream" output.

2 months agoMINOR: quic: display QCS info on "show quic stream"
Amaury Denoyelle [Wed, 7 May 2025 15:38:15 +0000 (17:38 +0200)] 
MINOR: quic: display QCS info on "show quic stream"

Complete stream output for "show quic" by displaying information from
its upper QCS. Note that QCS may be NULL if already released, so a
default output is also provided.

2 months agoMINOR: quic: add stream format for "show quic"
Amaury Denoyelle [Wed, 7 May 2025 14:28:39 +0000 (16:28 +0200)] 
MINOR: quic: add stream format for "show quic"

Add a new format for "show quic" command labelled as "stream". This is
an equivalent of "show sess", dedicated to the QUIC stack. Each active
QUIC streams are listed on a line with their related infos.

The main objective of this command is to ensure there is no freeze
streams remaining after a transfer.

2 months agoMINOR: mux-quic: account Rx data per stream
Amaury Denoyelle [Mon, 24 Mar 2025 10:27:27 +0000 (11:27 +0100)] 
MINOR: mux-quic: account Rx data per stream

Add counters to measure Rx buffers usage per QCS. This reused the newly
defined bdata_ctr type already used for Tx accounting.

Note that for now, <tot> value of bdata_ctr is not used. This is because
it is not easy to account for data accross contiguous buffers.

These values are displayed both on log/traces and "show quic" output.

2 months agoMINOR: quic: account Tx data per stream
Amaury Denoyelle [Wed, 7 May 2025 15:32:46 +0000 (17:32 +0200)] 
MINOR: quic: account Tx data per stream

Add accounting at qc_stream_desc level to be able to report the number
of allocated Tx buffers and the sum of their data. This represents data
ready for emission or already emitted and waiting on ACK.

To simplify this accounting, a new counter type bdata_ctr is defined in
quic_utils.h. This regroups both buffers and data counter, plus a
maximum on the buffer value.

These values are now displayed on QCS info used both on logline and
traces, and also on "show quic" output.

2 months agoBUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly
Willy Tarreau [Mon, 12 May 2025 15:45:33 +0000 (17:45 +0200)] 
BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly

As discussed here:
   https://github.com/httpwg/http2-spec/pull/936
   https://github.com/haproxy/haproxy/issues/2941

It's important to take care of some special characters in the :authority
pseudo header before reassembling a complete URI, because after assembly
it's too late (e.g. the '/'). This patch does this, both for h2 and h3.

The impact on H2 was measured in the worst case at 0.3% of the request
rate, while the impact on H3 is around 1%, but H3 was about 1% faster
than H2 before and is now on par.

It may be backported after a period of observation, and in this case it
relies on this previous commit:

   MINOR: http: add a function to validate characters of :authority

Thanks to @DemiMarie for reviving this topic in issue #2941 and bringing
new potential interesting cases.

2 months agoMINOR: http: add a function to validate characters of :authority
Willy Tarreau [Mon, 12 May 2025 15:39:08 +0000 (17:39 +0200)] 
MINOR: http: add a function to validate characters of :authority

As discussed here:
  https://github.com/httpwg/http2-spec/pull/936
  https://github.com/haproxy/haproxy/issues/2941

It's important to take care of some special characters in the :authority
pseudo header before reassembling a complete URI, because after assembly
it's too late (e.g. the '/').

This patch adds a specific function which was checks all such characters
and their ranges on an ist, and benefits from modern compilers
optimizations that arrange the comparisons into an evaluation tree for
faster match. That's the version that gave the most consistent performance
across various compilers, though some hand-crafted versions using bitmaps
stored in register could be slightly faster but super sensitive to code
ordering, suggesting that the results might vary with future compilers.
This one takes on average 1.2ns per character at 3 GHz (3.6 cycles per
char on avg). The resulting impact on H2 request processing time (small
requests) was measured around 0.3%, from 6.60 to 6.618us per request,
which is a bit high but remains acceptable given that the test only
focused on req rate.

The code was made usable both for H2 and H3.

2 months agoBUG/MINOR: server: perform lbprm deinit for dynamic servers
Aurelien DARRAGON [Mon, 12 May 2025 14:27:43 +0000 (16:27 +0200)] 
BUG/MINOR: server: perform lbprm deinit for dynamic servers

Last commit 7361515 ("BUG/MINOR: server: dont depend on proxy for server
cleanup in srv_drop()") introduced a regression because the lbprm
server_deinit is not evaluated anymore with dynamic servers, possibly
resulting in a memory leak.

To fix the issue, in addition to free_proxy(), the server deinit check
should be manually performed in cli_parse_delete_server() as well.

No backport needed.

2 months agoBUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()
Aurelien DARRAGON [Mon, 12 May 2025 14:09:15 +0000 (16:09 +0200)] 
BUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()

In commit b5ee8bebfc ("MINOR: server: always call ssl->destroy_srv when
available"), we made it so srv_drop() doesn't depend on proxy to perform
server cleanup.

It turns out this is now mandatory, because during deinit, free_proxy()
can occur before the final srv_drop(). This is the case when using Lua
scripts for instance.

In 2a9436f96 ("MINOR: lbprm: Add method to deinit server and proxy") we
added a freeing check under srv_drop() that depends on the proxy.
Because of that UAF may occur during deinit when using a Lua script that
manipulate server objects.

To fix the issue, let's perform the lbprm server deinit logic under
free_proxy() directly, where the DEINIT server hooks are evaluated.

Also, to prevent similar bugs in the future, let's explicitly document
in srv_drop() that server cleanups should assume that the proxy may
already be freed.

No backport needed unless 2a9436f96 is.

2 months agoBUG/MINOR: cfgparse: improve the empty arg position report's robustness
Willy Tarreau [Mon, 12 May 2025 14:06:28 +0000 (16:06 +0200)] 
BUG/MINOR: cfgparse: improve the empty arg position report's robustness

OSS Fuzz found that the previous fix ebb19fb367 ("BUG/MINOR: cfgparse:
consider the special case of empty arg caused by \x00") was incomplete,
as the output can sometimes be larger than the input (due to variables
expansion) in which case the work around to try to report a bad arg will
fail. While the parse_line() function has been made more robust now in
order to avoid this condition, let's fix the handling of this special
case anyway by just pointing to the beginning of the line if the supposed
error location is out of the line's buffer.

All details here:
   https://oss-fuzz.com/testcase-detail/5202563081502720

No backport is needed unless the fix above is backported.

2 months agoBUG/MINOR: tools: improve parse_line()'s robustness against empty args
Willy Tarreau [Mon, 12 May 2025 14:01:27 +0000 (16:01 +0200)] 
BUG/MINOR: tools: improve parse_line()'s robustness against empty args

The fix in 10e6d0bd57 ("BUG/MINOR: tools: only fill first empty arg when
not out of range") was not that good. It focused on protecting against
<arg> becoming out of range to detect we haven't emitted anything, but
it's not the right way to detect this. We're always maintaining arg_start
as a copy of outpos, and that later one is incremented when emitting a
char, so instead of testing args[arg] against out+arg_start, we should
instead check outpos against arg_start, thereby eliminating the <out>
offset and the need to access args[]. This way we now always know if
we've emitted an empty arg without dereferencing args[].

There's no need to backport this unless the fix above is also backported.

2 months agoBUG/MINOR: threads: fix soft-stop without multithreading support
Aurelien DARRAGON [Mon, 12 May 2025 09:57:39 +0000 (11:57 +0200)] 
BUG/MINOR: threads: fix soft-stop without multithreading support

When thread support is disabled ("USE_THREAD=" or "USE_THREAD=0" when
building), soft-stop doesn't work as haproxy never ends after stopping
the proxies.

This used to work fine in the past but suddenly stopped working with
ef422ced91 ("MEDIUM: thread: make stopping_threads per-group and add
stopping_tgroups") because the "break;" instruction under the stopping
condition is never executed when support for multithreading is disabled.

To fix the issue, let's add an "else" block to run the "break;"
instruction when USE_THREAD is not defined.

It should be backported up to 2.8

2 months agoMINOR: ssl/ckch: warn when the same keyword was used twice
William Lallemand [Fri, 9 May 2025 17:18:38 +0000 (19:18 +0200)] 
MINOR: ssl/ckch: warn when the same keyword was used twice

When using a crt-list or a crt-store, keywords mentionned twice on the
same line overwritte the previous value.

This patch emits a warning when the same keyword is found another time
on the same line.

2 months agoBUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing
William Lallemand [Fri, 9 May 2025 17:16:02 +0000 (19:16 +0200)] 
BUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing

The ckch_conf_parse() function is the generic function which parses
crt-store keywords from the crt-store section, and also from a
crt-list.

When having multiple time the same keyword, a leak of the previous
value happens. This patch ensure that the previous value is always
freed before overwriting it.

This is the same problem as the previous "BUG/MINOR: ssl/ckch: always
free() the previous entry during parsing" patch, however this one
applies on PARSE_TYPE_ARRAY_SUBSTR.

No backport needed.

2 months agoMINOR: tools: ha_freearray() frees an array of string
William Lallemand [Fri, 9 May 2025 17:09:12 +0000 (19:09 +0200)] 
MINOR: tools: ha_freearray() frees an array of string

ha_freearray() is a new function which free() an array of strings
terminated by a NULL entry.

The pointer to the array will be free and set to NULL.

2 months agoBUG/MINOR: ssl/ckch: always free() the previous entry during parsing
William Lallemand [Fri, 9 May 2025 17:01:28 +0000 (19:01 +0200)] 
BUG/MINOR: ssl/ckch: always free() the previous entry during parsing

The ckch_conf_parse() function is the generic function which parses
crt-store keywords from the crt-store section, and also from a crt-list.

When having multiple time the same keyword, a leak of the previous value
happens. This patch ensure that the previous value is always freed
before overwriting it.

This patch should be backported as far as 3.0.

2 months agoBUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line
William Lallemand [Fri, 9 May 2025 16:52:09 +0000 (18:52 +0200)] 
BUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line

The 'ssl-f-use' implementation doesn't prevent to have multiple time the
'crt' keyword, which overwrite the previous value. Letting users think
that is it possible to use multiple certificates on the same line, which
is not the case.

This patch emits an alert when setting the 'crt' keyword multiple times
on the same ssl-f-use line.

Should fix issue #2966.

No backport needed.

2 months agoBUG/MINOR: ssl: doesn't fill conf->crt with first arg
William Lallemand [Fri, 9 May 2025 16:23:06 +0000 (18:23 +0200)] 
BUG/MINOR: ssl: doesn't fill conf->crt with first arg

Commit c7f29afc ("MEDIUM: ssl: replace "crt" lines by "ssl-f-use"
lines") forgot to remove an the allocation of the crt field which was
done with the first argument.

Since ssl-f-use takes keywords, this would put the first keyword in
"crt" instead of the certificate name.

2 months agoMEDIUM: sock-inet: re-check IPv6 connectivity every 30s
Willy Tarreau [Fri, 9 May 2025 13:23:10 +0000 (15:23 +0200)] 
MEDIUM: sock-inet: re-check IPv6 connectivity every 30s

IPv6 connectivity might start off (e.g. network not fully up when
haproxy starts), so for features like resolvers, it would be nice to
periodically recheck.

With this change, instead of having the resolvers code rely on a variable
indicating connectivity, it will now call a function that will check for
how long a connectivity check hasn't been run, and will perform a new one
if needed. The age was set to 30s which seems reasonable considering that
the DNS will cache results anyway. There's no saving in spacing it more
since the syscall is very check (just a connect() without any packet being
emitted).

The variables remain exported so that we could present them in show info
or anywhere else.

This way, "dns-accept-family auto" will now stay up to date. Warning
though, it does perform some caching so even with a refreshed IPv6
connectivity, an older record may be returned anyway.

2 months agoDEBUG: pools: add a new integrity mode "backup" to copy the released area
Willy Tarreau [Thu, 8 May 2025 13:28:18 +0000 (15:28 +0200)] 
DEBUG: pools: add a new integrity mode "backup" to copy the released area

This way we can preserve the entire contents of the released area for
later inspection. This automatically enables comparison at reallocation
time as well (like "integrity" does). If used in combination with
integrity, the comparison is disabled but the check of non-corruption
of the area mangled by integrity is still operated.

2 months agoMINOR: acme: add the global option 'acme.scheduler'
William Lallemand [Fri, 9 May 2025 11:45:48 +0000 (13:45 +0200)] 
MINOR: acme: add the global option 'acme.scheduler'

The automatic scheduler is useful but sometimes you don't want to use,
or schedule manually.

This patch adds an 'acme.scheduler' option in the global section, which
can be set to either 'auto' or 'off'. (auto is the default value)

This also change the ouput of the 'acme status' command so it does not
shows scheduled values. The state will be 'Stopped' instead of
'Scheduled'.

2 months agoDEBUG: pool: permit per-pool UAF configuration
Willy Tarreau [Thu, 8 May 2025 17:52:16 +0000 (19:52 +0200)] 
DEBUG: pool: permit per-pool UAF configuration

The new MEM_F_UAF flag can be set just after a pool's creation to make
this pool UAF for debugging purposes. This allows to maintain a better
overall performance required to reproduce issues while still having a
chance to catch UAF. It will only be used by developers who will manually
add it to areas worth being inspected, though.

2 months agoBUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
Amaury Denoyelle [Fri, 9 May 2025 08:54:40 +0000 (10:54 +0200)] 
BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference

Emission of flow-control frames have been recently modified. Now, each
frame is sent one by one, via a single entry list. If a failure occurs,
emission is interrupted and frame is reinserted into the original
<qcc.lfctl.frms> list.

This code is incorrect as it only checks if qcc_send_frames() returns an
error code to perform the reinsert operation. However, an error here
does not always mean that the frame was not properly emitted by lower
quic-conn layer. As such, an extra test LIST_ISEMPTY() must be performed
prior to reinsert the frame.

This bug would cause a heap overflow. Indeed, the reinsert frame would
be a random value. A crash would occur as soon as it would be
dereferenced via <qcc.lfctl.frms> list.

This was reproduced by issuing a POST with a big file and interrupt it
after just a few seconds. This results in a crash in about a third of
the tests. Here is an example command using ngtcp2 :

 $ ngtcp2-client -q --no-quic-dump --no-http-dump \
   -m POST -d ~/infra/html/1g 127.0.0.1 20443 "http://127.0.0.1:20443/post"

Heap overflow was detected via a BUG_ON() statement from qc_frm_free()
via qcc_release() caller :

  FATAL: bug condition "!((&((*frm)->reflist))->n == (&((*frm)->reflist)))" matched at src/quic_frame.c:1270

This does not need to be backported.

2 months ago[RELEASE] Released version 3.2-dev15 v3.2-dev15
Willy Tarreau [Fri, 9 May 2025 08:51:30 +0000 (10:51 +0200)] 
[RELEASE] Released version 3.2-dev15

Released version 3.2-dev15 with the following main changes :
    - BUG/MEDIUM: stktable: fix sc_*(<ctr>) BUG_ON() regression with ctx > 9
    - BUG/MINOR: acme/cli: don't output error on success
    - BUG/MINOR: tools: do not create an empty arg from trailing spaces
    - MEDIUM: config: warn about the consequences of empty arguments on a config line
    - MINOR: tools: make parse_line() provide hints about empty args
    - MINOR: cfgparse: visually show the input line on empty args
    - BUG/MINOR: tools: always terminate empty lines
    - BUG/MINOR: tools: make parseline report the required space for the trailing 0
    - DEBUG: threads: don't keep lock label "OTHER" in the per-thread history
    - DEBUG: threads: merge successive idempotent lock operations in history
    - DEBUG: threads: display held locks in threads dumps
    - BUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends
    - Revert "BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame"
    - MINOR: acme/cli: 'acme status' show the status acme-configured certificates
    - MEDIUM: acme/ssl: remove 'acme ps' in favor of 'acme status'
    - DOC: configuration: add "acme" section to the keywords list
    - DOC: configuration: add the "crt-store" keyword
    - BUG/MAJOR: queue: lock around the call to pendconn_process_next_strm()
    - MINOR: ssl: add filename and linenum for ssl-f-use errors
    - BUG/MINOR: ssl: can't use crt-store some certificates in ssl-f-use
    - BUG/MINOR: tools: only fill first empty arg when not out of range
    - MINOR: debug: bump the dump buffer to 8kB
    - MINOR: stick-tables: add "ipv4" as an alias for the "ip" type
    - MINOR: quic: extend return value during TP parsing
    - BUG/MINOR: quic: use proper error code on missing CID in TPs
    - BUG/MINOR: quic: use proper error code on invalid server TP
    - BUG/MINOR: quic: reject retry_source_cid TP on server side
    - BUG/MINOR: quic: use proper error code on invalid received TP value
    - BUG/MINOR: quic: fix TP reject on invalid max-ack-delay
    - BUG/MINOR: quic: reject invalid max_udp_payload size
    - BUG/MEDIUM: peers: hold the refcnt until updating ts->seen
    - BUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()
    - BUG/MINOR: cli: fix too many args detection for commands
    - MINOR: server: ensure server postparse tasks are run for dynamic servers
    - BUG/MEDIUM: stick-table: always remove update before adding a new one
    - BUG/MEDIUM: quic: free stream_desc on all data acked
    - BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
    - DOC: config: recommend disabling libc-based resolution with resolvers

2 months agoDOC: config: recommend disabling libc-based resolution with resolvers
Willy Tarreau [Fri, 9 May 2025 08:30:30 +0000 (10:30 +0200)] 
DOC: config: recommend disabling libc-based resolution with resolvers

Using both libc and haproxy resolvers can lead to hard to diagnose issues
when their bevahiour diverges; recommend using only one type of resolver.

Should be backported to stable versions.

Link: https://www.mail-archive.com/haproxy@formilux.org/msg45663.html
Co-authored-by: Lukas Tribus <lukas@ltri.eu>
2 months agoBUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
Willy Tarreau [Fri, 9 May 2025 07:55:39 +0000 (09:55 +0200)] 
BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00

The reporting of the empty arg location added with commit 08d3caf30
("MINOR: cfgparse: visually show the input line on empty args") falls
victim of a special case detected by OSS Fuzz:

     https://issues.oss-fuzz.com/issues/415850462

In short, making an argument start with "\x00" doesn't make it empty for
the parser, but still emits an empty string which is detected and
displayed. Unfortunately in this case the error pointer is not set so
the sanitization function crashes.

What we're doing in this case is that we fall back to the position of
the output argument as an estimate of where it was located in the input.
It's clearly inexact (quoting etc) but will still help the user locate
the problem.

No backport is needed unless the commit above is backported.

2 months agoBUG/MEDIUM: quic: free stream_desc on all data acked
Amaury Denoyelle [Wed, 7 May 2025 15:08:42 +0000 (17:08 +0200)] 
BUG/MEDIUM: quic: free stream_desc on all data acked

The following patch simplifies qc_stream_desc_ack(). The qc_stream_desc
instance is not freed anymore, even if all data were acknowledged. As
implies by the commit message, the caller is responsible to perform this
cleaning operation.
  f4a83fbb14bdd14ed94752a2280a2f40c1b690d2
  MINOR: quic: do not remove qc_stream_desc automatically on ACK handling

However, despite the commit instruction, qc_stream_desc_free()
invokation was not moved in the caller. This commit fixes this by adding
it after stream ACK handling. This is performed only when a transfer is
completed : all data is acknowledged and qc_stream_desc has been
released by its MUX stream instance counterpart.

This bug may cause a significant increase in memory usage when dealing
with long running connection. However, there is no memory leak, as every
qc_stream_desc attached to a connection are finally freed when quic_conn
instance is released.

This must be backported up to 3.1.

2 months agoBUG/MEDIUM: stick-table: always remove update before adding a new one
Willy Tarreau [Thu, 8 May 2025 21:21:25 +0000 (23:21 +0200)] 
BUG/MEDIUM: stick-table: always remove update before adding a new one

Since commit 388539faa ("MEDIUM: stick-tables: defer adding updates to a
tasklet"), between the entry creation and its arrival in the updates tree,
there is time for scheduling, and it now becomes possible for an stksess
entry to be requeued into the list while it's still in the tree as a remote
one. Only local updates were removed prior to being inserted. In this case
we would re-insert the entry, causing it to appear as the parent of two
distinct nodes or leaves, and to be visited from the first leaf during a
delete() after having already been removed and freed, causing a crash,
as Christian reported in issue #2959.

There's no reason to backport this as this appeared with the commit above
in 3.2-dev13.

2 months agoMINOR: server: ensure server postparse tasks are run for dynamic servers
Aurelien DARRAGON [Wed, 7 May 2025 21:50:46 +0000 (23:50 +0200)] 
MINOR: server: ensure server postparse tasks are run for dynamic servers

commit 29b76cae4 ("BUG/MEDIUM: server/log: "mode log" after server
keyword causes crash") introduced some postparsing checks/tasks for
server

Initially they were mainly meant for "mode log" servers postparsing, but
we already have a check dedicated to "tcp/http" servers (ie: only tcp
proto supported)

However when dynamic servers are added they bypass _srv_postparse() since
the REGISTER_POST_SERVER_CHECK() is only executed for servers defined in
the configuration.

To ensure consistency between dynamic and static servers, and ensure no
post-check init routine is missed, let's manually invoke _srv_postparse()
after creating a dynamic server added via the cli.

2 months agoBUG/MINOR: cli: fix too many args detection for commands
Aurelien DARRAGON [Wed, 7 May 2025 23:01:28 +0000 (01:01 +0200)] 
BUG/MINOR: cli: fix too many args detection for commands

d3f928944 ("BUG/MINOR: cli: Issue an error when too many args are passed
for a command") added a new check to prevent the command to run when
too many arguments are provided. In this case an error is reported.

However it turns out this check (despite marked for backports) was
ineffective prior to 20ec1de21 ("MAJOR: cli: Refacor parsing and
execution of pipelined commands") as 'p' pointer was reset to the end of
the buffer before the check was executed.

Now since 20ec1de21, the check works, but we have another issue: we may
read past initialized bytes in the buffer because 'p' pointer is always
incremented in a while loop without checking if we increment it past 'end'
(This was detected using valgrind)

To fix the issue introduced by 20ec1de21, let's only increment 'p' pointer
if p < end.

For 3.2 this is it, now for older versions, since d3f928944 was marked for
backport, a sligthly different approach is needed:

 - conditional p increment must be done in the loop (as in this patch)
 - max arg check must moved above "fill unused slots" comment where p is
   assigned to the end of the buffer

This patch should be backported with d3f928944.

2 months agoBUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()
Willy Tarreau [Wed, 7 May 2025 16:43:57 +0000 (18:43 +0200)] 
BUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()

It might be possible not to see the element in the tree, then not to
see it in the update list, thus not to take the lock before deleting.
But an element in the list could have moved to the tree during the
check, and be removed later without the updt_lock.

Let's delete prior to checking the presence in the tree to avoid
this situation. No backport is needed since this arrived in -dev13
with the update list.