]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
6 days agoBUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full
Aurelien DARRAGON [Wed, 18 Feb 2026 16:04:03 +0000 (17:04 +0100)] 
BUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full

Amaury reported that when the following warning is reported by haproxy:

  [WARNING]  (296347) : config: failed to get shm stats file slot for 'haproxy.stats', all slots are occupied

haproxy would segfault right after during clock update operation.

The reason for the warning being emitted is not the object of this commit
(all shm-stats-file slots occupied by simultaneous co-processes) but since
it was is intended that haproxy is able to keep working despite that
warning (ignoring the use of shm-stats-file), we should fix the crash.

The crash is caused by the fact that we detach from the shared memory while
the global_now_ns and global_now_ms clock pointers still point to the shared
memory. Instead we should revert to using our local clock instead before
detaching from the map.

It should be backported in 3.3

6 days agoMINOR: haterm: increase thread-local pool size
Willy Tarreau [Thu, 19 Feb 2026 14:30:01 +0000 (15:30 +0100)] 
MINOR: haterm: increase thread-local pool size

QUIC uses many objects and the default pool size causes a lot of
thrashing at the current request rate, taking ~12% CPU in pools.
Let's increase it to 3MB, which allows us to reach around 11M
req/s on a 80-core machine.

6 days agoMINOR: haterm: new "haterm" utility
Frederic Lecaille [Wed, 11 Feb 2026 14:11:27 +0000 (15:11 +0100)] 
MINOR: haterm: new "haterm" utility

haterm_init.c is added to implement haproxy_init_args() which overloads
the one defined by haproxy.c. This way, haterm program uses its own argv[]
parsing function. It generates its own configuration in memory that is
parsed during boot and executed by the common code.

6 days agoMINOR: haterm: add haterm HTTP server
Frederic Lecaille [Wed, 11 Feb 2026 14:05:42 +0000 (15:05 +0100)] 
MINOR: haterm: add haterm HTTP server

Contrary to haproxy, httpterm does not support all the HTTP protocols.
Furthermore, it has become easier to handle inbound/outbound
connections / streams since the rework done at conn_stream level.

This patch implements httpterm HTTP server services into haproxy. To do
so, it proceeds the same way as for the TCP checks which use only one
stream connector, but on frontend side.

The makefile is modified to handle haterm.c in additions to all the C
files for haproxy to build new haterm program into haproxy, the haterm
server also instantiates a haterm stream (hstream struct) attached to a
stream connector for each incoming connection without backend stream
connector. This is the role of sc_new_from_endp() called by the muxes to
instantiate streams/hstreams.

As for stream_new(), hstream_new() instantiates a task named
process_hstream() (see haterm.c) which has the same role as
process_stream() but for haterm streams.

haterm into haproxy takes advantage of the HTTP muxes and HTX API to
support all the HTTP protocols supported by haproxy.

6 days agoMINOR: stconn: stream instantiation from proxy callback
Frederic Lecaille [Wed, 11 Feb 2026 13:43:58 +0000 (14:43 +0100)] 
MINOR: stconn: stream instantiation from proxy callback

Add a pointer to function to proxies as ->stream_new_from_sc proxy
struct member to instantiate stream from connection as this is done by
all the muxes when they call sc_new_from_endp(). The default value for
this pointer is obviously stream_new() which is exported by this patch.

6 days agoMEDIUM: init: allow the redefinition of argv[] parsing function
Frederic Lecaille [Wed, 11 Feb 2026 10:16:39 +0000 (11:16 +0100)] 
MEDIUM: init: allow the redefinition of argv[] parsing function

This patches allows the argv[] parsing function to be redefined from
others C modules. This is done extracting the function which really
parse the argv[] array to implement haproxy_init_args(). This function
is declared as a weak symbol which may be overloaded by others C module.

Same thing for copy_argv() which checks/cleanup/modifies the argv array.
One may want this function to be redefined. This is the case when other
C modules do not handle the same command line option. Copying such
argv[] would lead to conflicts with the original haproxy argv[] during
the copy.

6 days agoMINOR: init: allow a fileless init mode
Frederic Lecaille [Wed, 11 Feb 2026 10:11:16 +0000 (11:11 +0100)] 
MINOR: init: allow a fileless init mode

This patch provides the possibility to initialize haproxy without
configuration file. This may be identified by the new global and exported
<fileless_mode> and <fileless_cfg> variables which may be used to
provide a struct cfgfile to haproxy by others means than a physical
file (built in memory).
When enabled, this fileless mode skips all the configuration files
parsing.

6 days agoMINOR: trace: add definitions for haterm streams
Frederic Lecaille [Thu, 15 Jan 2026 15:10:10 +0000 (16:10 +0100)] 
MINOR: trace: add definitions for haterm streams

Add definitions for haterm stream as arguments to be used by the TRACE API.
This will be used by the haterm module to come which will have to handle
hstream struct objects (in place of stream struct objects).

6 days agoMINOR: ssl/ckch: certificates generation from "load" "crt-store" directive
Frederic Lecaille [Thu, 5 Feb 2026 13:56:57 +0000 (14:56 +0100)] 
MINOR: ssl/ckch: certificates generation from "load" "crt-store" directive

Add "generate-dummy" on/off type keyword to "load" directive to
automatically generate dummy certificates as this is done for ACME from
ckch_conf_load_pem_or_generate() function which is called if a "crt"
keyword is also provide for this directive.

Also implement "keytype" to specify the key type used for these
certificates.  Only "RSA" or "ECDSA" is accepted. This patch also
implements "bits" keyword for the "load" directive to specify the
private key size used for RSA. For ECDSA, a new "curves" keyword is also
provided by this patch to specify the curves to be used for the EDCSA
private keys generation.

ckch_conf_load_pem_or_generate() is modified to use these parameters
provided by "keytype", "bits" and "curves" to generate the private key
with ssl_gen_EVP_PKEY() before generating the X509 certificate calling
ssl_gen_x509().

6 days agoMINOR: ssl/ckch: Move EVP_PKEY and cert code generation from acme
Frederic Lecaille [Thu, 5 Feb 2026 13:52:35 +0000 (14:52 +0100)] 
MINOR: ssl/ckch: Move EVP_PKEY and cert code generation from acme

Move acme_EVP_PKEY_gen() implementation to ssl_gencrt.c and rename it to
ssl_EVP_PKEY_gen().  Also extract from acme_gen_tmp_x509() the generic
part to implement ssl_gen_x509() into ssl_gencrt.c.

To generate a self-signed expired certificate ssl_EVP_PKEY_gen() must be
used to generate the private key. Then, ssl_gen_x509() must be called
with the private key as argument.  acme_gen_tmp_x509() is also modified
to called these two functions to generate a temporary certificate has
done before modifying this part.

Such an expired self-signed certificate should not be use on the field
but only during testing and development steps.

6 days agoDOC: configuration: add the ACME wiki page link
William Lallemand [Thu, 19 Feb 2026 12:53:50 +0000 (13:53 +0100)] 
DOC: configuration: add the ACME wiki page link

Add the ACME page link to the HAProxy github wiki.

6 days agoOPTIM: backend: reduce contention when checking MUX init with ALPN
Amaury Denoyelle [Thu, 19 Feb 2026 10:12:47 +0000 (11:12 +0100)] 
OPTIM: backend: reduce contention when checking MUX init with ALPN

In connect_server(), MUX initialization must be delayed if ALPN
negotiation is configured, unless ALPN can already be retrieved via the
server cache.

A readlock is used to consult the server cache. Prior to this patch, it
was always taken even if no ALPN is configured. The lock was thus used
for every new backend connection instantiation.

Rewrite the check so that now the lock is only used if ALPN is
configured. Thus, no lock access is done if SSL is not used or if ALPN
is not defined.

In practice, there will be no performance gain, as the read lock should
never block if ALPN is not configured. However, the code is cleaner as
it better reflect that only access to server nego_alpn requires the
path_params lock protection.

6 days agoBUG/MINOR: backend: check delay MUX before conn_prepare()
Amaury Denoyelle [Thu, 19 Feb 2026 09:53:21 +0000 (10:53 +0100)] 
BUG/MINOR: backend: check delay MUX before conn_prepare()

In connect_server(), when a new connection must be instantiated, MUX
initialization is delayed if an ALPN setting is present on the server
line configuration, as negotiation must be performed to select the
correct MUX. However, this is not the case if the ALPN can already be
retrieved on the server cache.

This check is performed too late however and may cause issue with the
QUIC stack. The problem can happen when the server ALPN is not yet set.
In the normal case, quic_conn layer is instantiated and MUX init is
delayed until the handshake completion. When the MUX is finally
instantiated, it reused without any issue app_ops from its quic_conn,
which is derived from the negotiated ALPN.

However, there is a race condition if another QUIC connection populates
the server ALPN cache. If this happens after the first quic_conn init
but prior to the MUX delay check, the MUX will thus immediately start in
connect_server(). When app_ops is retrieved from its quic_conn, a crash
occurs in qcc_install_app_ops() as the QUIC handshake is not yet
finalized :

  #0  0x000055e242a66df4 in qcc_install_app_ops (qcc=0x7f127c39da90, app_ops=0x0) at src/mux_quic.c:1697
  1697 if (app_ops->init && !app_ops->init(qcc)) {
  [Current thread is 1 (Thread 0x7f12810f06c0 (LWP 25758))]

To fix this, MUX delay check is moved up in connect_server(). It is now
performed prior conn_prepare() which is responsible for the quic_conn
layer instantiation. Thus, it ensures consistency for the QUIC stack :
MUX init is always delayed if the quic_conn does not reuses itself the
SSL session and ALPN server cache (no quic_reuse_srv_params()).

This must be backported up to 3.3.

6 days agoBUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails
David Carlier [Wed, 18 Feb 2026 21:55:00 +0000 (21:55 +0000)] 
BUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails

In acme_gen_tmp_x509(), if X509_set_issuer_name() fails, the code
jumped to the mkcert_error label without freeing the previously
allocated X509_NAME object. The other error paths after X509_NAME_new()
(X509_NAME_add_entry_by_txt and X509_set_subject_name) already properly
freed the name before jumping to mkcert_error, but this one was missed.

Fix this by freeing name before the goto, consistent with the other
error paths in the same function.

Must be backported as far as 3.3.

6 days agoDOC: remove openssl no-deprecated CI image
William Lallemand [Thu, 19 Feb 2026 09:37:15 +0000 (10:37 +0100)] 
DOC: remove openssl no-deprecated CI image

Remove the "openssl no-depcrecated" CI image status which was removed a while
ago.

6 days agoCLEANUP: mux-h1: Remove unneeded null check
Egor Shestakov [Wed, 18 Feb 2026 14:43:30 +0000 (14:43 +0000)] 
CLEANUP: mux-h1: Remove unneeded null check

Since 3.1 a task is always created when H1 connections initialize, so
the later null check before task_queue() became unneeded.

Could be backported with 3c09b3432 (BUG/MEDIUM: mux-h1: Fix how timeouts
are applied on H1 connections).

6 days agoMEDIUM: Add connect/queue/tarpit timeouts to set-timeout
Nenad Merdanovic [Wed, 18 Feb 2026 14:56:36 +0000 (15:56 +0100)] 
MEDIUM: Add connect/queue/tarpit timeouts to set-timeout

Add the ability to set connect, queue and tarpit timeouts from the
set-timeout action. This is especially useful when using set-dst to
dynamically connect to servers.

This patch also adds the relevant fe_/be_/cur_ sample fetches for these
timeouts.

7 days agoCI: github: disable windows.yml by default on unofficials repo
William Lallemand [Wed, 18 Feb 2026 17:16:21 +0000 (18:16 +0100)] 
CI: github: disable windows.yml by default on unofficials repo

Disable the windows job for repository in repositories that are not in
the "haproxy" organization. This is mostly used for portability during
development and only making noise during the maintenance cycle.

Must be backported in every branches.

7 days agoCI: vtest: move the vtest2 URL to vinyl-cache.org
William Lallemand [Wed, 18 Feb 2026 15:20:06 +0000 (16:20 +0100)] 
CI: vtest: move the vtest2 URL to vinyl-cache.org

VTest git repository was moved on vinyl-cache.org.

Must be backported in every branches.

7 days agoBUG/MEDIUM: ssl: SSL backend sessions used after free
Frederic Lecaille [Fri, 13 Feb 2026 12:30:24 +0000 (13:30 +0100)] 
BUG/MEDIUM: ssl: SSL backend sessions used after free

This bug impacts only the backends. The sessions cached could be used after been
freed because of a missing write lock into ssl_sock_handle_hs_error() when freeing
such objects. This issue could be rarely reproduced and only with QUIC with
difficulties (random CRYPTO data corruptions and instrumented code).

Must be backported as far as 2.6.

7 days agoCI: do not use ghcr.io for Quic Interop workflows
Ilia Shipitsin [Tue, 17 Feb 2026 21:41:07 +0000 (22:41 +0100)] 
CI: do not use ghcr.io for Quic Interop workflows

due to some (yet unknown) changes in ghcr.io we are not able to pull
images from it anymore. Lets temporarily switch to "local only" images
storage.

no functional change

7 days agoMINOR: config: reject configs using HTTP with large bufsize >= 256 MB
Christopher Faulet [Fri, 13 Feb 2026 14:38:08 +0000 (15:38 +0100)] 
MINOR: config: reject configs using HTTP with large bufsize >= 256 MB

the bufsize was already limited to 256 MB because of Lua and HTX
limitations. So the same limit is set on large buffers.

7 days agoMINOR: dynbuf: Add helpers to know if a buffer is a default or a large buffer
Christopher Faulet [Fri, 13 Feb 2026 08:54:53 +0000 (09:54 +0100)] 
MINOR: dynbuf: Add helpers to know if a buffer is a default or a large buffer

b_is_default() and b_is_large() can now be used to know if a buffer is a
default buffer or a large one. _b_free() now relies on it.

These functions are also used when possible (stream_free(),
stream_release_buffers() and http_wait_for_msg_body()).

7 days agoMEDIUM: http-ana: Use a large buffer if necessary when waiting for body
Christopher Faulet [Tue, 3 Feb 2026 06:59:06 +0000 (07:59 +0100)] 
MEDIUM: http-ana: Use a large buffer if necessary when waiting for body

Thanks to previous patches, it is now possible to allocate a large buffer to
store the message payload in the context of the "wait-for-body" action. To
do so, "use-large-buffer" option must be set.

It means now it is no longer necessary to increase the regular buffer size
to be able to get message payloads of some requests or responses.

7 days agoMINPR: htx: Get large chunk if necessary to perform a defrag
Christopher Faulet [Wed, 11 Feb 2026 16:46:00 +0000 (17:46 +0100)] 
MINPR: htx: Get large chunk if necessary to perform a defrag

Function performing defragmentation of an HTX message was updated to get a
chunk accordingly to the HTX message size.

7 days agoMEDIUM: http-fetch: Be able to use large chunks when necessary
Christopher Faulet [Mon, 9 Feb 2026 10:15:52 +0000 (11:15 +0100)] 
MEDIUM: http-fetch: Be able to use large chunks when necessary

The function used to fetch params was update to get a chunk accordingly to
the parameter size. The same was also performed when the message body is
retrieved.

7 days agoMEDIUM: sample: Get chunks with a size dependent on input data when necessary
Christopher Faulet [Mon, 9 Feb 2026 10:15:02 +0000 (11:15 +0100)] 
MEDIUM: sample: Get chunks with a size dependent on input data when necessary

The function used to duplicate a sample was update to support large buffers. In
addition several converters were also reviewed to deal with large buffers. For
instance, base64 encoding and decoding must use chunks of the same size than the
sample. For some of them, a retry is performed to enlarge the chunk is possible.

TODO: Review reg_sub, concat and add_item to get larger chunk if necessary

7 days agoMEDIUM: stconn: Properly handle large buffers during a receive
Christopher Faulet [Tue, 3 Feb 2026 06:53:13 +0000 (07:53 +0100)] 
MEDIUM: stconn: Properly handle large buffers during a receive

While large buffers are still unused internally, functions receiving data
from endpoint (connections or applets) were updated to block the receives
when channels are using large buffer and the data forwarding was started.

The goal of this patch is to be able to flush large buffers at the end of
the analyzis stage to return asap on regular buffers.

7 days agoMEDIUM: chunk: Add support for large chunks
Christopher Faulet [Tue, 3 Feb 2026 10:55:10 +0000 (11:55 +0100)] 
MEDIUM: chunk: Add support for large chunks

Because there is now a memory pool for large buffers, we must also add the
support for large chunks. So, if large buffers are configured, a dedicated
memory pool is created to allocate large chunks. alloc_large_trash_chunk()
must be used to allocate a large chunk. alloc_trash_chunk_sz() can be used to
allocate a chunk with the best size. However free_trash_chunk() remains the
only way to release a chunk, regular or large.

In addition, large trash buffers are also created, using the same mechanism
than for regular trash buffers. So three thread-local trash buffers are
created. get_large_trash_chunk() must be used to get a large trash buffer.
And get_trash_chunk_sz() may be used to get a trash buffer with the best
size.

7 days agoMEDIUM: dynbuf: Add a pool for large buffers with a configurable size
Christopher Faulet [Fri, 30 Jan 2026 10:23:34 +0000 (11:23 +0100)] 
MEDIUM: dynbuf: Add a pool for large buffers with a configurable size

Add the support for large bufers. A dedicated memory pool is added. The size
of these buffers must be explicitly configured by setting
"tune.bufsize.large" directive. If it is not set, the pool is not
created. In addition, if the size for large buffers is the same than for
regular buffer, the feature is automatically disable.

For now, large buffers remain unused.

7 days agoMINOR: http-fetch: Use pointer to HTX DATA block when retrieving HTX body
Christopher Faulet [Mon, 9 Feb 2026 10:11:41 +0000 (11:11 +0100)] 
MINOR: http-fetch: Use pointer to HTX DATA block when retrieving HTX body

In sample fetch functions retrieving the message payload (req.body,
res.body...), instead of copying the payload in a trash buffer, we know
directely return a pointer the payload in the HTX message. To do so, we must
be sure there is only one HTX DATA block. Thanks to previous patches, it is
possible. However, we must take care to perform a defragmentation if
necessary.

7 days agoMINOR: http-ana: Do a defrag on unaligned HTX message when waiting for payload
Christopher Faulet [Tue, 10 Feb 2026 17:33:02 +0000 (18:33 +0100)] 
MINOR: http-ana: Do a defrag on unaligned HTX message when waiting for payload

When we are waiting for the request or response payload, it is usually
because the payload will be analyzed in a way or another. So, perform a
defrag if necessary. This should ease payload analyzis.

7 days agoMEDIUM: htx: Improve detection of fragmented/unordered HTX messages
Christopher Faulet [Tue, 3 Feb 2026 17:31:38 +0000 (18:31 +0100)] 
MEDIUM: htx: Improve detection of fragmented/unordered HTX messages

First, an HTX flags was added to know when blocks are unordered. It may
happen when a header is added while part of the payload was already received
or when the start-line is replaced by an new one. In these cases, the blocks
indexes are in the right order but not the blocks payload. Knowing a message
is unordered can be useful to trigger a defragmentation, mainly to be able
to append data properly for instance.

Then, detection of fragmented messages was improved, especially when a
header or a start-line is replaced by a new one.

Finally, when data are added in a message and cannot be appended into the
previous DATA block because the message is not aligned, a defragmentation is
performed to realign the message and append data.

7 days agoMEDIUM: htx: Refactor htx defragmentation to merge data blocks
Christopher Faulet [Tue, 3 Feb 2026 10:55:58 +0000 (11:55 +0100)] 
MEDIUM: htx: Refactor htx defragmentation to merge data blocks

When an HTX message is defragmented, the HTX DATA blocks are now merged into
one block. Just like the previous commit, this will help all payload
analysis, if any. However, there is an exception when the reference on a
DATA block must be preserved, via the <blk> parameter. In that case, this
DATA block is not merged with previous block.

7 days agoMEDIUM: htx: Refactor transfer of htx blocks to merge DATA blocks if possible
Christopher Faulet [Tue, 3 Feb 2026 07:29:51 +0000 (08:29 +0100)] 
MEDIUM: htx: Refactor transfer of htx blocks to merge DATA blocks if possible

When htx_xfer_blks() is called and when HTX DATA blocks are copied, we now
merge them in one block. This will help all payload analysis, if any.

7 days agoBUG/MEDIUM: htx: Fix function used to change part of a block value when defrag
Christopher Faulet [Wed, 11 Feb 2026 14:43:51 +0000 (15:43 +0100)] 
BUG/MEDIUM: htx: Fix function used to change part of a block value when defrag

htx_replace_blk_value() is buggy when a defrag is performed. It only happens
on data expension. But in that case, because a defragmentation is performed,
the blocks data are moved and old data of the updated block are no longer
accessible.

To fix the bug, we now use a chunk to temporarily copy the new data of the
block. This way we can safely perform the HTX defragmentation and then
recopy the data from the chunk to the HTX message.

It is theorically possible to hit this bug but concretly it is pretty hard.

This patch should be backported to all stable versions.

7 days agoMEDIUM: stream: Offer buffers of default size only
Christopher Faulet [Tue, 3 Feb 2026 06:57:17 +0000 (07:57 +0100)] 
MEDIUM: stream: Offer buffers of default size only

Check the channels buffers size on release before trying to offer it to
waiting entities. Only normal buffers must be considered. This will be
mandatory when the large buffers support on channels will be added.

7 days agoMINOR: h1-htx: Disable 0-copy for buffers of different size
Christopher Faulet [Tue, 10 Feb 2026 14:24:54 +0000 (15:24 +0100)] 
MINOR: h1-htx: Disable 0-copy for buffers of different size

When a message payload is parsed, it is possible to swap buffers. We must
only take care both buffers have same size. It will be mandatory when the
large buffers support on channels will be added.

7 days agoMEDIUM: applet: Disable 0-copy for buffers of different size
Christopher Faulet [Tue, 3 Feb 2026 06:56:02 +0000 (07:56 +0100)] 
MEDIUM: applet: Disable 0-copy for buffers of different size

Just like the previous commit, we must take care to never swap buffers of
different size when data are exchanged between an applet and a SC. it will
be mandatory when the large buffers support on channels will be added.

7 days agoMEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size
Christopher Faulet [Tue, 3 Feb 2026 06:55:31 +0000 (07:55 +0100)] 
MEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size

Today, it is useless to check the buffers size before performing a 0-copy in
muxes when data are sent, but it will be mandatory when the large buffers
support on channels will be added. Indeed, muxes will still rely on normal
buffers, so we must take care to never swap buffers of different size.

7 days agoMEDIUM: compression: Be sure to never compress more than a chunk at once
Christopher Faulet [Tue, 3 Feb 2026 06:54:11 +0000 (07:54 +0100)] 
MEDIUM: compression: Be sure to never compress more than a chunk at once

When the compression is performed, a trash chunk is used. So be sure to
never compression more data than the trash size. Otherwise the commression
could fail. Today, this cannot happen. But with the large buffers support on
channels, it could be an issue.

Note that this part should be reviewed to evaluate if we should use a larger
chunk too to perform the compression, maybe via an option.

7 days agoMEDIUM: stream: Limit number of synchronous send per stream wakeup
Christopher Faulet [Tue, 3 Feb 2026 06:49:21 +0000 (07:49 +0100)] 
MEDIUM: stream: Limit number of synchronous send per stream wakeup

It is not a bug fix, because there is no way to hit the issue for now. But
there is nothing preventing a loop of synchronous sends in process_stream().
Indead, when a synchronous send is successfully performed, we restart the
SCs evaluation and at the end another synchronous send is attempted. So with
an endpoint consuming data bit by bit or with a filter fowarding few bytes
at each call, it is possible to loop for a while in process_stream().

Because it is not expected, we now limit the number of synchronous send per
wakeup to two calls. In a nominal case, it should never be more. This commit
is mandatory to be able to handle large buffers on channels

There is no reason to backport this commit except if the large buffers
support on channels are backported.

7 days agoMEDIUM: cache: Don't rely on a chunk to store messages payload
Christopher Faulet [Tue, 3 Feb 2026 06:45:03 +0000 (07:45 +0100)] 
MEDIUM: cache: Don't rely on a chunk to store messages payload

When the response payload is stored in the cache, we can avoid to use a
trash chunk as temporary space area before copying everything in the cache
in one call. Instead we can directly write each HTX block in the cache, one
by one. It should not be an issue because, most of time, there is only one
DATA block.

This commit depends on "BUG/MEDIUM: shctx: Use the next block when data
exactly filled a block".

7 days agoBUG/MINOR: config: Check buffer pool creation for failures
Christopher Faulet [Fri, 30 Jan 2026 10:10:12 +0000 (11:10 +0100)] 
BUG/MINOR: config: Check buffer pool creation for failures

The call to init_buffer() during the worker startup may fail. In that case,
an error message is displayed but the error was not properly handled. So
let's add the proper check and exit on error.

7 days agoMINOR: buffers: Swap buffers of same size only
Christopher Faulet [Wed, 28 Jan 2026 14:02:20 +0000 (15:02 +0100)] 
MINOR: buffers: Swap buffers of same size only

In b_xfer(), we now take care to swap buffers of the same size only. For
now, it is always the case. But that will change.

7 days agoMINOR: tree-wide: Use the buffer size instead of global setting when possible
Christopher Faulet [Wed, 28 Jan 2026 09:54:41 +0000 (10:54 +0100)] 
MINOR: tree-wide: Use the buffer size instead of global setting when possible

At many places, we rely on global.tune.bufsize value instead of using the buffer
size. For now, it is not a problem. But if we want to be able to deal with
buffers of different sizes, it is good to reduce as far as possible dependencies
on the global value. most of time, we can use b_size() or c_size()
functions. The main change is performed on the error snapshot where the buffer
size was added into the error_snapshot structure.

7 days agoBUG/MEDIUM: jwe: fix timing side-channel and dead code in JWE decryption
David Carlier [Sat, 14 Feb 2026 16:16:58 +0000 (16:16 +0000)] 
BUG/MEDIUM: jwe: fix timing side-channel and dead code in JWE decryption

Fix two issues in JWE token processing:

- Replace memcmp() with CRYPTO_memcmp() for authentication tag
  verification in build_and_check_tag() to prevent timing
  side-channel attacks. Also add a tag length validation check
  before the comparison to avoid potential buffer over-read when
  the decoded tag length doesn't match the expected HMAC half.

- Remove unreachable break statement after JWE_ALG_A256GCMKW case
  in decrypt_cek_aesgcmkw().

7 days agoREORG: stconn: Move functions related to channel buffers to sc_strm.h
Christopher Faulet [Wed, 28 Jan 2026 09:53:22 +0000 (10:53 +0100)] 
REORG: stconn: Move functions related to channel buffers to sc_strm.h

sc_have_buff(), sc_need_buff(), sc_have_room() and sc_need_room() are
related to the buffer's channel. So we can move them in sc_strm.h header
file. In addition, this will be mandatory for the next commit.

7 days agoMINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags
Christopher Faulet [Tue, 3 Feb 2026 17:32:19 +0000 (18:32 +0100)] 
MINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags

SC_FL_NO_FASTFWD flag was not listed in sc_show_flags() function. Let's do
so.

This patch could be backported as far as 3.0.

7 days agoBUG/MINOR: http-ana: Stop to wait for body on client error/abort
Christopher Faulet [Thu, 12 Feb 2026 10:24:27 +0000 (11:24 +0100)] 
BUG/MINOR: http-ana: Stop to wait for body on client error/abort

During the message analysis, we must take care to stop wait for the message
body if an error was reported on client side or an abort was detected with
abort-on-close configured (by default now).

The bug was introduced when the "wait-for-body" action was added. Only the
producer state was tested. So, when we were waiting for the request payload,
there was no issue. But when we were waiting for the response payload, error
or abort on client side was not considered.

This patch should be backported to all stable versions.

7 days agoBUG/MEDIUM: shctx: Use the next block when data exactly filled a block
Christopher Faulet [Tue, 3 Feb 2026 06:46:22 +0000 (07:46 +0100)] 
BUG/MEDIUM: shctx: Use the next block when data exactly filled a block

When the hot list was removed in 3.0, a regression was introduced.
Theorically, it is possible to override data in a block when new data are
appended. It happens when data are copied. If the data size is a multiple of
the block size, all data are copied and the last used block is full. But
instead of saving a reference on the next block as the restart point for the
next copies, we keep a reference on the last full one. On the next read, we
reuse this block and old data are crushed. To hit the bug, no new blocks
should be reserved between the two data copy attempts.

Concretely, for now, it seems not possible to hit the bug. But with a block
size set to 1024, if more than 1024 bytes are reseved, with a first copy of
1024 bytes and a second one with remaining data, data in the first block
will be crushed.

So to fix the bug, the reference of the last block used to write data (which
is in fact the next one to use to perform the next copy) is only updated
when a block is full. In that case the next block is used.

This patch should be backported as far as 3.0 after a period of observation.

7 days agoCLEANUP: compression: Remove unused static buffers
Christopher Faulet [Mon, 2 Feb 2026 08:31:37 +0000 (09:31 +0100)] 
CLEANUP: compression: Remove unused static buffers

Since the legacy HTTP code was removed, the global and thread-local buffers,
tmpbuf and zbuf, are no longer used. So let's removed them.

This could be backported, theorically to all supported versions. But at
least it could be good to do so as far as 3.2 as it saves 2 buffers
per-thread.

7 days agoMINOR: flt-trace: Add an option to limit the amount of data forwarded
Christopher Faulet [Mon, 16 Feb 2026 10:42:36 +0000 (11:42 +0100)] 
MINOR: flt-trace: Add an option to limit the amount of data forwarded

"max-fwd <max>" option can now be used to limit the maximum amount of data
forwarded at a time by the filter. It could be handy to make tests.

7 days agoBUG/MINOR: flt-trace: Properly compute length of the first DATA block
Christopher Faulet [Wed, 11 Feb 2026 09:20:12 +0000 (10:20 +0100)] 
BUG/MINOR: flt-trace: Properly compute length of the first DATA block

This bug is quite old. When the length of the first DATA block is computed,
the offset is used instead of the block length minus the offset. It is only
used with random forwarding and there is a test just after to prevent any
issue, so there is no effect.

It could be backported to all stable versions.

7 days agoDEV: term-events: Fix hanshake events decoding
Christopher Faulet [Tue, 17 Feb 2026 06:39:31 +0000 (07:39 +0100)] 
DEV: term-events: Fix hanshake events decoding

Handshakes events were not properly decoded. Only send errors were decoded
as expected, other events were reported with a '-'. It is now fixes.

This patch could be backported as far as 3.2.

7 days agoBUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)
Christopher Faulet [Mon, 16 Feb 2026 18:14:57 +0000 (19:14 +0100)] 
BUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)

The previous fix was wrong. When shut flags are tested for legacy applets,
to know if the I/O handler can be called or not, we must be sure shut for
reads and for writes are both set to skip the applet I/O handler.

This bug introduced regression, at least for the peer applet and for the DNS
applet.

This patch must be backported with abc1947e1 ("BUG/MEDIUM: applet: Fix test
on shut flags for legacy applets"), so as far as 3.0.

7 days agoBUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states
Christopher Faulet [Tue, 17 Feb 2026 14:56:19 +0000 (15:56 +0100)] 
BUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states

If a producer tries to send data via the fast-forward mechanism while the
message is in an unexpected state from the consumer point of view, the
fast-forward is now disabled. Concretely, we now take care that the message
is in its data/tunnel stage to proceed in h1_nego_ff().

By disabling fast-forward in that case, we will automatically fall back on
the regular sending path and be able to handle the error in h1_snd_buf().

This patch should be backported as far as 3.0

7 days agoBUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is closed
Christopher Faulet [Wed, 18 Feb 2026 08:26:02 +0000 (09:26 +0100)] 
BUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is closed

If is illegal to send data if the stream is already closed. The case is
properly handled when data are sent via snd_buf(), by draining the data. But
it was still possible to process these data via nego_ff().

So, in this patch, both for the H2 and QUIC multiplexers, the fast-forward
is disabled if the stream is closed and nothing is performed. Doing so, we
will automatically fall back on the regular sending path and be able to
drain data in snd_buf().

Thanks to Mike Walker for his investigation on the subject.

This patch should be backported as far as 3.0.

8 days agoREGTESTS: fix quoting in feature cmd which prevents test execution
Amaury Denoyelle [Tue, 17 Feb 2026 17:27:14 +0000 (18:27 +0100)] 
REGTESTS: fix quoting in feature cmd which prevents test execution

Remove extra quote in feature cmd used to test SSL compatibility with
set_ssl_cafile QUIC regtest. Due to this syntax error, the test was
never executed.

No need to backport.

8 days agoMINOR: mux-quic: add BUG_ON_STRESS() when draining data on closed stream
Amaury Denoyelle [Tue, 17 Feb 2026 17:13:54 +0000 (18:13 +0100)] 
MINOR: mux-quic: add BUG_ON_STRESS() when draining data on closed stream

Add a BUG_ON_STRESS() to be able to detect if data draining is performed
due to early stream closure.

8 days agoBUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented
Amaury Denoyelle [Mon, 16 Feb 2026 15:33:41 +0000 (16:33 +0100)] 
BUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented

HTTP/3 CONNECT transcoding is not properly implemented on the frontend
side. Neither tunnel mode of application nor extended connect are
currently functional.

Clarify this situation by rejecting any CONNETC attempts on the frontend
side. The stream is thus now closed via a RESET_STREAM with error code
REQUEST_REJECTED.

This should be backported to every stable versions.

8 days agoBUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally closed QCS"
Amaury Denoyelle [Mon, 16 Feb 2026 15:41:50 +0000 (16:41 +0100)] 
BUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally closed QCS"

This reverts commit 235e8f1afd7e9753a26051b30c47ecc398ccfd12.

Prior to the above commit, snd_buf callback for QUIC MUX was able to
deal with data even after stream closure. The excess was simply
discarded, as no STREAM frame can be emitted after FIN/RESET_STREAM.
This code was later removed and replaced by a BUG_ON() to ensure snd_buf
is never called after stream closure.

However, this approach is too strict. Indeed, there is nothing in the
haproxy stream architecture which forbids this scheduling, in part
because QUIC MUX is the sole responsible of the stream closure. As such,
it is preferable to revert to the old code to prevent any triggering of
a BUG_ON() failure.

Note that nego_ff does not implement data draining if called after
stream closure. This will be done in a future patch.

Thanks to Mike Walker for his investigation on the subject.

This must be backported up to 2.8.

8 days agoMEDIUM: backend: make "balance random" consider tg local req rate when loads are...
Aurelien DARRAGON [Mon, 16 Feb 2026 15:12:15 +0000 (16:12 +0100)] 
MEDIUM: backend: make "balance random" consider tg local req rate when loads are equal

This is a follow up to b6bdb2553 ("MEDIUM: backend: make "balance random"
consider req rate when loads are equal")

In the above patch, we used the global sess_per_sec metric to choose which
server we should be using. But the original intent was to use the per
thread group statistic.

No backport needed, the previous patch already improved the situation in
3.3, so let's not take the risk of breaking that.

9 days agoBUG/MINOR: ssl: error with ssl-f-use when no "crt"
William Lallemand [Mon, 16 Feb 2026 17:41:40 +0000 (18:41 +0100)] 
BUG/MINOR: ssl: error with ssl-f-use when no "crt"

ssl-f-use lines tries to load a crt file, but the "crt" keyword is not
mandatory. That could lead to crtlist_load_crt() being called with a
NULL path, and trying to do a stat.

In this particular case we don't need to try anything and it's better to
leave with an actual error.

Must be backported as far as 3.2.

9 days agoBUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing
William Lallemand [Mon, 16 Feb 2026 17:22:53 +0000 (18:22 +0100)] 
BUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing

crtlist_load_crt() in post_section_frontend_crt_init() won't give
details about the line being parsed, this should be done by the caller.

Modify post_section_frontend_crt_init() to ouput the right error format.

Must be backported to 3.2.

9 days agoBUG/MINOR: ssl: fix leak in ssl-f-use parser upon error
William Lallemand [Mon, 16 Feb 2026 14:56:21 +0000 (15:56 +0100)] 
BUG/MINOR: ssl: fix leak in ssl-f-use parser upon error

cfg_crt_node->filename is leaked on the error path in the ssl-f-use
configuration parser.

Could be backported as far as 3.2

9 days agoBUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser
William Lallemand [Mon, 16 Feb 2026 14:22:47 +0000 (15:22 +0100)] 
BUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser

In post_section_frontend_crt_init(), the crt_entry is populated by the
ssl_conf fromt the cfg_crt_node. On error path, the crt_list is
completely freed, including the ssl_conf structure. But the ssl_conf
structure was already freed when freeing the cfg_crt_node.

Fix the issue by doing a crtlist_dup_ssl_conf(n->ssl_conf) in the
crtlist_entry instead of an assignation.

Fix issue #3268.

Need to be backported as far as 3.2. The previous patch which adds the
crtlist_dup_ssl_conf() declaration is needed.

9 days agoBUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration
William Lallemand [Mon, 16 Feb 2026 14:10:35 +0000 (15:10 +0100)] 
BUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration

Add lacking crtlist_dup_ssl_conf() declaration in ssl_crt-list.h.

Could be backported if needed.

9 days agoDEV: gdb: use unsigned longs to display pools memory usage
Willy Tarreau [Mon, 16 Feb 2026 10:07:23 +0000 (11:07 +0100)] 
DEV: gdb: use unsigned longs to display pools memory usage

The pools memory usage calculation was done using ints by default, making
it harder to identify large ones. Let's switch to unsigned long for the
size calculations.

11 days agoCLEANUP: deviceatlas: add unlikely hints and minor code tidying
David Carlier [Sat, 14 Feb 2026 13:24:07 +0000 (13:24 +0000)] 
CLEANUP: deviceatlas: add unlikely hints and minor code tidying

Add unlikely() hints on error paths in init, conv and fetch functions.
Remove unnecessary zero-initialization of local buffers that are
always written before use. Fix indentation in da_haproxy_checkinst()
and remove unused loop variable initialization.

11 days agoMINOR: deviceatlas: precompute maxhdrlen to skip oversized headers early
David Carlier [Sat, 14 Feb 2026 13:24:06 +0000 (13:24 +0000)] 
MINOR: deviceatlas: precompute maxhdrlen to skip oversized headers early

Precompute the maximum header name length from the atlas evidence
headers at init and hot-reload time. Use it in da_haproxy_fetch() to
skip headers early that cannot match any known DeviceAtlas evidence
header, avoiding unnecessary string copies and comparisons.

11 days agoMINOR: deviceatlas: define header_evidence_entry in dummy library header
David Carlier [Sat, 14 Feb 2026 14:08:04 +0000 (14:08 +0000)] 
MINOR: deviceatlas: define header_evidence_entry in dummy library header

Add the struct header_evidence_entry definition to the dummy dac.h
to accommodate the ongoing deviceatlas module update which now
iterates over atlas header_priorities to precompute maxhdrlen.
The struct was already referenced by struct da_atlas but lacked
a definition in the dummy header.

11 days agoMINOR: deviceatlas: increase DA_MAX_HEADERS and header buffer sizes
David Carlier [Sat, 14 Feb 2026 13:24:05 +0000 (13:24 +0000)] 
MINOR: deviceatlas: increase DA_MAX_HEADERS and header buffer sizes

Increase DA_MAX_HEADERS from 24 to 32 and hbuf from 24 to 64 to
accommodate current DeviceAtlas data files which may use more headers
and longer header names.

11 days agoMINOR: deviceatlas: check getproptype return and remove pprop indirection
David Carlier [Sat, 14 Feb 2026 13:24:04 +0000 (13:24 +0000)] 
MINOR: deviceatlas: check getproptype return and remove pprop indirection

Check the return value of da_atlas_getproptype() and skip the property
on failure instead of using an uninitialized proptype. Also remove the
unnecessary pprop pointer indirection, using prop directly.

11 days agoBUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance
David Carlier [Sat, 14 Feb 2026 13:24:03 +0000 (13:24 +0000)] 
BUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance

When hot-reloading the atlas in da_haproxy_checkinst(), the configured
cache_size was not applied to the new instance, causing it to use the
default value.

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: fix deinit to only finalize when initialized
David Carlier [Sat, 14 Feb 2026 13:24:02 +0000 (13:24 +0000)] 
BUG/MINOR: deviceatlas: fix deinit to only finalize when initialized

da_fini() was called unconditionally in deinit_deviceatlas() even when
da_init() was never called. Move it inside the daset check. Also remove
the erroneous shm_unlink() call which could affect the dadwsch shared
memory used by the scheduling process.

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure
David Carlier [Sat, 14 Feb 2026 13:24:01 +0000 (13:24 +0000)] 
BUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure

In da_haproxy_checkinst(), when da_atlas_compile() failed, the cnew
buffer was leaked. Add a free(cnew) in the else branch.

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: fix double-checked locking race in checkinst
David Carlier [Sat, 14 Feb 2026 13:24:00 +0000 (13:24 +0000)] 
BUG/MINOR: deviceatlas: fix double-checked locking race in checkinst

In da_haproxy_checkinst(), base[0] was checked before acquiring the
lock but not re-checked after. Another thread could have already
processed the reload between the initial check and the lock
acquisition, leading to a race condition.

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: fix cookie vlen using wrong length after extraction
David Carlier [Sat, 14 Feb 2026 13:23:59 +0000 (13:23 +0000)] 
BUG/MINOR: deviceatlas: fix cookie vlen using wrong length after extraction

In da_haproxy_fetch(), vlen was set from v.len (the raw header value
length) instead of the truncated copy length. Also the cookie-specific
vlen calculation used an incorrect subtraction instead of the actual
extracted cookie value length (pl) returned by
http_extract_cookie_value().

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()
David Carlier [Sat, 14 Feb 2026 13:23:58 +0000 (13:23 +0000)] 
BUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()

The user-agent string copy had an off-by-one error: the buffer size
limit did not account for the null terminator, and the memcpy length
used i-1 which truncated the last character of the user-agent string.

This should be backported to lower branches.

11 days agoBUG/MEDIUM: deviceatlas: fix resource leaks on init error paths
David Carlier [Sat, 14 Feb 2026 13:23:57 +0000 (13:23 +0000)] 
BUG/MEDIUM: deviceatlas: fix resource leaks on init error paths

When da_atlas_compile() or da_atlas_open() failed in init_deviceatlas(),
atlasimgptr was leaked and da_fini() was never called. Also add a NULL
check on strdup() for the default cookie name with proper cleanup of
the atlas and image pointer on failure.

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: add NULL checks on strdup() results in config parsers
David Carlier [Sat, 14 Feb 2026 13:23:56 +0000 (13:23 +0000)] 
BUG/MINOR: deviceatlas: add NULL checks on strdup() results in config parsers

Add missing NULL checks after strdup() for the json file path in
da_json_file() and the cookie name in da_properties_cookie().

This should be backported to lower branches.

11 days agoBUG/MINOR: deviceatlas: add missing return on error in config parsers
David Carlier [Sat, 14 Feb 2026 13:23:55 +0000 (13:23 +0000)] 
BUG/MINOR: deviceatlas: add missing return on error in config parsers

da_log_level() and da_cache_size() were missing a return -1 on error,
causing fall-through to the normal return 0 path when invalid values
were provided.

This should be backported to lower branches.

11 days agoDEV: gdb: add a utility to find the post-mortem address from a core
Willy Tarreau [Sat, 14 Feb 2026 09:41:44 +0000 (10:41 +0100)] 
DEV: gdb: add a utility to find the post-mortem address from a core

More and more often, core dumps retrieved on systems that build with
-fPIE by default are becoming unexploitable. Even functions and global
symbols get relocated and gdb cannot figure their final position.
Ironically the post_mortem struct lying in its own section that was
meant to ease its finding is not exempt from this problem.

The only remaining way is to inspect the core to search for the
post-mortem magic, figure its offset from the file and look up the
corresponding virtual address with objdump. This is quite a hassle.

This patch implements a simple utility that opens a 64-bit core dump,
scans the program headers looking for a data segment which contains
the post-mortem magic, and prints it on stdout. It also places the
"pm_init" command alone on its own line to ease copy-pasting into the
gdb console. With this, at least the other commands in this directory
work again and allow to inspect the program's state. E.g:

  $ ./getpm core.57612
  Found post-mortem magic in segment 5:
    Core File Offset: 0xfc600 (0xd5000 + 0x27600)
    Runtime VAddr:    0x5613e52b6600 (0x5613e528f000 + 0x27600)
    Segment Size:     0x28000

  In gdb, copy-paste this line:

     pm_init 0x5613e52b6600

It's worth noting that the program has so few dependencies that it even
builds with nolibc, allowing to upload a static executable into containers
being debugged and lacking development tools and compilers. The build
procedure is indicated inthe source code.

12 days agoMEDIUM: filters: use per-channel filter list when relevant
Aurelien DARRAGON [Thu, 5 Feb 2026 12:55:36 +0000 (13:55 +0100)] 
MEDIUM: filters: use per-channel filter list when relevant

In the historical implementation, all filter related information where
stored at the stream level (using struct strm_flt * context), and filters
iteration was performed at the stream level also.

We identified that this was not ideal and would make the implementation of
future filters more complex since filters ordering should be handled in
a different order during request and response handling for decompression
for instance.

To make such thing possible, in this commit we migrate some channel
specific filter contexts in the channel directly (request or response),
and we implement 2 additional filter lists, one on the request channel
and another on the response channel. The historical stream filter list
is kept as-is because in some contexts only the stream is available and
we have to iterate on all filters. But for functions where we only are
interested in request side or response side filters, we now use dedicated
channel filters list instead.

The only overhead is that the "struct filter" was expanded by two "struct
list".

For now, no change of behavior is expected.

12 days agoMINOR: filters: rework filter iteration for channel related callback functions
Aurelien DARRAGON [Thu, 5 Feb 2026 20:02:03 +0000 (21:02 +0100)] 
MINOR: filters: rework filter iteration for channel related callback functions

Multiple channel related functions have the same construction: they use
list_for_each_entry() to work on a given filter from the stream+channel
combination. In future commits we will try to use filter list from
dedicated channel list instead of the stream one, thus in this patch we
need as a prerequisite to implement and use the flt_list_{start,next} API
to iterate over filter list, giving the API the responsibility to iterate
over the correct list depending on the context, while the calling function
remains free to use the iteration construction it needs. This way we will
be able to easily change the way we iterate over filter list without
duplicating the code for requests and responses.

12 days agoMINOR: filters: rework RESUME_FILTER_* macros as inline functions
Aurelien DARRAGON [Thu, 5 Feb 2026 19:36:23 +0000 (20:36 +0100)] 
MINOR: filters: rework RESUME_FILTER_* macros as inline functions

There is no need to have those helpers defined as macro, and since it
is not mandatory, code maintenance is much easier using functions,
thus let's switch to function definitions.

Also, we change the way we iterate over the list so that the calling
function now has a pseudo API to get and iterate over filter pointers
while keeping control on how they implement the iterating logic.

One benefit of this is that we will also be able to switch between lists
depending on the channel type, which is a prerequisite for upcoming
rework that split the filter list over request and response channels
(commit will follow)

No change of behavior is expected.

13 days agoSCRIPTS: build-vtest: allow to set a TMPDIR and a DESTDIR 20260212-build-vtest flx04/20260212-build-vtest
William Lallemand [Thu, 12 Feb 2026 17:48:09 +0000 (18:48 +0100)] 
SCRIPTS: build-vtest: allow to set a TMPDIR and a DESTDIR

Implement a way to set a destination directory using DESTDIR, and a tmp
directory using TMPDIR.

By default:

- DESTDIR is ../vtest like it was done previously
- TMPDIR  is mktemp -d

Only the vtest binary is copied in DESTDIR.

Example:

TMPDIR=/dev/shm/ DESTDIR=/home/user/.local/bin/ ./scripts/build-vtest.sh

13 days agoMINOR: startup: show the list of detected features at runtime with haproxy -vv
William Lallemand [Thu, 12 Feb 2026 16:49:11 +0000 (17:49 +0100)] 
MINOR: startup: show the list of detected features at runtime with haproxy -vv

Features prefixed by "HAVE_WORKING_" in the haproxy -vv feature list,
are features that are detected during runtime.

This patch splits these features on another line in haproxy -vv. This
line is named "Detected feature list".

13 days agoMINOR: startup: sort the feature list in haproxy -vv
William Lallemand [Thu, 12 Feb 2026 16:41:31 +0000 (17:41 +0100)] 
MINOR: startup: sort the feature list in haproxy -vv

The feature list in haproxy -vv is partly generated from the Makefile
using the USE_* keywords, but it's also possible to add keywords in the
feature list using hap_register_feature(), which adds the keyword at the
end of list. When doing so, the list is not correctly sorted anymore.

This patch fixes the problem by splitting the string using an array of
ist and applying a qsort() on it.

13 days agoMINOR: startup: Add HAVE_WORKING_TCP_MD5SIG in haproxy -vv
William Lallemand [Wed, 11 Feb 2026 14:34:43 +0000 (15:34 +0100)] 
MINOR: startup: Add HAVE_WORKING_TCP_MD5SIG in haproxy -vv

the TCP_MD5SIG ifdef is not enough to check if the feature is usable.
The code might compile but the OS could prevent to use it.

This patch tries to use the TCP_MD5SIG setsockopt before adding
HAVE_WORKING_TCP_MD5SIG in the feature list.  so it would prevent to
start reg-tests if the OS can't run it.

13 days agoREGTESTS: jwt: Add new "jwt_decrypt_jwk" tests
Remi Tricot-Le Breton [Tue, 10 Feb 2026 14:30:01 +0000 (15:30 +0100)] 
REGTESTS: jwt: Add new "jwt_decrypt_jwk" tests

Test the new "jwt_decrypt_jwk" converter that takes a JWK as argument,
either as a string or in a variable.
Only "RSA" and "oct" types are managed for now.

13 days agoMINOR: jwt: Add new jwt_decrypt_jwk converter
Remi Tricot-Le Breton [Tue, 10 Feb 2026 14:30:00 +0000 (15:30 +0100)] 
MINOR: jwt: Add new jwt_decrypt_jwk converter

This converter takes a private key in the JWK format (RFC7517) that can
be provided as a string of via a variable.
The only keys managed for now are of type 'RSA' or 'oct'.

13 days agoMINOR: jwt: Convert an RSA JWK into an EVP_PKEY
Remi Tricot-Le Breton [Tue, 10 Feb 2026 14:29:59 +0000 (15:29 +0100)] 
MINOR: jwt: Convert an RSA JWK into an EVP_PKEY

Add helper functions that take a JWK (JSON representation of an RSA
private key) into an EVP_PKEY (containing the private key).
Those functions are not used yet, they will be used in the upcoming
'jwt_decrypt_jwk' converter.

13 days agoMINOR: ssl: Missing '\n' in error message
Remi Tricot-Le Breton [Wed, 11 Feb 2026 10:11:49 +0000 (11:11 +0100)] 
MINOR: ssl: Missing '\n' in error message

Fix missing '\n' in error message raised when trying to load a password
protected private key.

13 days agoBUG/MAJOR: quic: fix parsing frame type
Amaury Denoyelle [Mon, 9 Feb 2026 08:09:33 +0000 (09:09 +0100)] 
BUG/MAJOR: quic: fix parsing frame type

QUIC frame type is encoded as a varint. Initially, haproxy parsed it as
a single byte, which was enough to cover frames defined in RFC9000.

The code has been extended recently to support multi-bytes encoded
value, in anticipation of QUIC frames extension support. However, there
was no check on the varint format. This is interpreted erroneously as a
PADDING frame as this serves as the initial value. Thus the rest of the
packet is incorrectly handled, with various resulting effects, including
infinite loops and/or crashes.

This patch fixes this by checking the return value of quic_dec_int(). If
varint cannot be parsed, the connection is immediately closed.

This issue is assigned to CVE-2026-26080 report.

This must be backported up to 3.2.

Reported-by: Asim Viladi Oglu Manizada <manizada@pm.me>
13 days agoBUG/MAJOR: quic: reject invalid token
Amaury Denoyelle [Mon, 9 Feb 2026 08:04:13 +0000 (09:04 +0100)] 
BUG/MAJOR: quic: reject invalid token

Token parsing code on INITIAL packet for the NEW_TOKEN format is not
robust enough and may even crash on some rare malformed packets.

This patch fixes this by adding a check on the expected length of the
received token. The packet is now rejected if the token does not match
QUIC_TOKEN_LEN. This check is legitimate as haproxy should only parse
tokens emitted by itself.

This issue has been introduced with the implementation of NEW_TOKEN
tokens parsing required for 0-RTT support.

This issue is assigned to CVE-2026-26081 report.

This must be backported up to 3.0.

Reported-by: Asim Viladi Oglu Manizada <manizada@pm.me>
13 days agoBUG/MINOR: quic: ensure handshake speed up is only run once per conn
Amaury Denoyelle [Wed, 11 Feb 2026 10:34:15 +0000 (11:34 +0100)] 
BUG/MINOR: quic: ensure handshake speed up is only run once per conn

When a duplicated CRYPTO frame is received during handshake, a server
may consider that there was a packet loss and immediately retransmit its
pending CRYPTO data without having to wait for PTO expiration. However,
RFC 9002 indicates that this should only be performed at most once per
connection to avoid excessive packet transmission.

QUIC connection is flagged with QUIC_FL_CONN_HANDSHAKE_SPEED_UP to mark
that a fast retransmit has been performed. However, during the
refactoring on CRYPTO handling with the storage conversion from ncbuf to
ncbmbuf, the check on the flag was accidentely removed. The faulty patch
is the following one :

  commit f50425c021eceb324add6873b58cc5f366554d31
  MINOR: quic: remove received CRYPTO temporary tree storage

This patch adds again the check on QUIC_FL_CONN_HANDSHAKE_SPEED_UP
before initiating fast retransmit. This ensures this is only performed
once per connection.

This must be backported up to 3.3.

13 days agoMINOR: servers: Call process_srv_queue() without lock when possible
Olivier Houchard [Tue, 3 Feb 2026 01:54:56 +0000 (02:54 +0100)] 
MINOR: servers: Call process_srv_queue() without lock when possible

In server_warmup(), call process_srv_queue() only once we released the
server lock, as we don't need it.

13 days agoMINOR: queues: Check minconn first in srv_dynamic_maxconn()
Olivier Houchard [Wed, 11 Feb 2026 06:53:21 +0000 (07:53 +0100)] 
MINOR: queues: Check minconn first in srv_dynamic_maxconn()

In srv_dynamic_maxconn(), we'll decide that the max number of connection
is the server's maxconn if 1) the proxy's number of connection is over
fullconn, or if minconn was not set.
Check if minconn is not set first, as it will be true most of the time,
and as the proxy's "beconn" variable is in a busy cache line, it can be
costly to access it, while minconn/maxconn is in a cache line that
should very rarely change.