]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 hours agoMINOR: acme: update the log for DNS-01 master
William Lallemand [Fri, 1 Aug 2025 16:08:43 +0000 (18:08 +0200)] 
MINOR: acme: update the log for DNS-01

Update the log for DNS-01 by mentionning the challenge_ready command
over the CLI.

2 hours agoMEDIUM: acme: allow to wait and restart the task for DNS-01
William Lallemand [Fri, 1 Aug 2025 15:57:29 +0000 (17:57 +0200)] 
MEDIUM: acme: allow to wait and restart the task for DNS-01

DNS-01 needs a external process which would register a TXT record on a
DNS provider, using a REST API or something else.

To achieve this, the process should read the dpapi sink and wait for
events. With the DNS-01 challenge, HAProxy will put the task to sleep
before asking the ACME server to achieve the challenge. The task then
need to be woke up, using the command implemented by this patch.

This patch implements the "acme challenge_ready" command which should be
used by the agent once the challenge was configured in order to wake the
task up.

Example:
    echo "@1 acme challenge_ready foobar.pem.rsa domain kikyo" | socat /tmp/master.sock -

3 hours agoMINOR: acme: emit the DNS-01 challenge details on the dpapi sink
William Lallemand [Fri, 1 Aug 2025 14:25:57 +0000 (16:25 +0200)] 
MINOR: acme: emit the DNS-01 challenge details on the dpapi sink

This commit adds a new message to the dpapi sink which is emitted during
the new authorization request.

One message is emitted by challenge to resolve. The certificate name as
well as the thumprint of the account key are on the first line of the
message. A dump of the JSON response for 1 challenge is dumped, en the
message ends with a \0.

The agent consuming these messages MUST NOT access the URLs, and SHOULD
only uses the thumbprint, dns and token to configure a challenge.

Example:

    $ ( echo "@@1 show events dpapi -w -0"; cat - ) | socat /tmp/master.sock -  | cat -e
    <0>2025-08-01T16:23:14.797733+02:00 acme deploy foobar.pem.rsa thumbprint Gv7pmGKiv_cjo3aZDWkUPz5ZMxctmd-U30P2GeqpnCo$
    {$
       "status": "pending",$
       "identifier": {$
          "type": "dns",$
          "value": "foobar.com"$
       },$
       "challenges": [$
          {$
             "type": "dns-01",$
             "url": "https://0.0.0.0:14000/chalZ/1o7sxLnwcVCcmeriH1fbHJhRgn4UBIZ8YCbcrzfREZc",$
             "token": "tvAcRXpNjbgX964ScRVpVL2NXPid1_V8cFwDbRWH_4Q",$
             "status": "pending"$
          },$
          {$
             "type": "dns-account-01",$
             "url": "https://0.0.0.0:14000/chalZ/z2_WzibwTPvE2zzIiP3BF0zNy3fgpU_8Nj-V085equ0",$
             "token": "UedIMFsI-6Y9Nq3oXgHcG72vtBFWBTqZx-1snG_0iLs",$
             "status": "pending"$
          },$
          {$
             "type": "tls-alpn-01",$
             "url": "https://0.0.0.0:14000/chalZ/AHnQcRvZlFw6e7F6rrc7GofUMq7S8aIoeDileByYfEI",$
             "token": "QhT4ejBEu6ZLl6pI1HsOQ3jD9piu__N0Hr8PaWaIPyo",$
             "status": "pending"$
          },$
          {$
             "type": "http-01",$
             "url": "https://0.0.0.0:14000/chalZ/Q_qTTPDW43-hsPW3C60NHpGDm_-5ZtZaRfOYDsK3kY8",$
             "token": "g5Y1WID1v-hZeuqhIa6pvdDyae7Q7mVdxG9CfRV2-t4",$
             "status": "pending"$
          }$
       ],$
       "expires": "2025-08-01T15:23:14Z"$
    }$
    ^@

4 hours agoMINOR: acme: emit a log for DNS-01 challenge response
William Lallemand [Fri, 1 Aug 2025 14:04:12 +0000 (16:04 +0200)] 
MINOR: acme: emit a log for DNS-01 challenge response

This commit emits a log which output the TXT entry to create in case of
DNS-01. This is useful in cases you want to update your TXT entry
manually.

Example:

    acme: foobar.pem.rsa: DNS-01 requires to set the "acme-challenge.example.com" TXT record to "7L050ytWm6ityJqolX-PzBPR0LndHV8bkZx3Zsb-FMg"

28 hours agoBUILD: acme: avoid declaring TRACE_SOURCE in acme-t.h
William Lallemand [Thu, 31 Jul 2025 14:03:28 +0000 (16:03 +0200)] 
BUILD: acme: avoid declaring TRACE_SOURCE in acme-t.h

Files ending with '-t.h' are supposed to be used for structure
definitions and could be included in the same file to check API
definitions.

This patch removes TRACE_SOURCE from acme-t.h to avoid conflicts with
other TRACE_SOURCE definitions.

28 hours agoBUG/MEDIUM: mux-quic: ensure Early-data header is set quic-interop
Amaury Denoyelle [Thu, 31 Jul 2025 09:51:24 +0000 (09:51 +0000)] 
BUG/MEDIUM: mux-quic: ensure Early-data header is set

QUIC MUX may be initialized prior to handshake completion, when 0-RTT is
used. In this case, connection is flagged with CO_FL_EARLY_SSL_HS, which
is notably used by wait-for-hs http rule.

Early data may be subject to replay attacks. For this reason, haproxy
adds the header 'Early-data: 1' to all requests handled as TLS early
data. Thus the server can reject it if it is deemed unsafe. This header
injection is implemented by http-ana. However, it was not functional
with QUIC due to missing CO_FL_EARLY_DATA connection flag.

Fix this by ensuring that QUIC MUX sets CO_FL_EARLY_DATA when needed.
This is performed during qcc_recv() for STREAM frame reception. It is
only set if QC_CF_WAIT_HS is set, meaning that the handshake is not yet
completed. After this, the request is considered safe and Early-data
header is not necessary anymore.

This should fix github issue #3054.

This must be backported up to 3.2 at least. If possible, it should be
backported to all stable releases as well. On these versions, the
current patch relies on the following refactoring commit :
  commit 0a53a008d032b69377869c8caaec38f81bdd5bd6
  MINOR: mux-quic: refactor wait-for-handshake support

2 days agoMINOR: muxes: refactor private connection detach
Amaury Denoyelle [Wed, 30 Jul 2025 14:13:42 +0000 (16:13 +0200)] 
MINOR: muxes: refactor private connection detach

Following the latest adjustment on session_add_conn() /
session_check_idle_conn(), detach muxes callbacks were rewritten for
private connection handling.

Nothing really fancy here : some more explicit comments and the removal
of a duplicate checks on idle conn status for muxes with true
multipexing support.

2 days agoMINOR: session: streamline session_check_idle_conn() usage
Amaury Denoyelle [Wed, 30 Jul 2025 09:56:05 +0000 (11:56 +0200)] 
MINOR: session: streamline session_check_idle_conn() usage

session_check_idle_conn() is called by muxes when a connection becomes
idle. It ensures that the session idle limit is not yet reached. Else,
the connection is removed from the session and it can be freed.

Prior to this patch, session_check_idle_conn() was compatible with a
NULL session argument. In this case, it would return true, considering
that no limit was reached and connection not removed.

However, this renders the function error-prone and subject to future
bugs. This patch streamlines it by ensuring it is never called with a
NULL argument. Thus it can now only returns true if connection is kept
in the session or false if it was removed, as first intended.

2 days agoMINOR: session: do not release conn in session_check_idle_conn()
Amaury Denoyelle [Thu, 24 Jul 2025 09:29:50 +0000 (11:29 +0200)] 
MINOR: session: do not release conn in session_check_idle_conn()

session_check_idle_conn() is called to flag a connection already
inserted in a session list as idle. If the session limit on the number
of idle connections (max-session-srv-conns) is exceeded, the connection
is removed from the session list.

In addition to the connection removal, session_check_idle_conn()
directly calls MUX destroy callback on the connection. This means the
connection is freed by the function itself and should not be used by the
caller anymore.

This is not practical when an alternative connection closure method
should be used, such as a graceful shutdown with QUIC. As such, remove
MUX destroy invokation : this is now the responsability of the caller to
either close or release immediately the connection.

2 days agoMINOR: session: strengthen idle conn limit check
Amaury Denoyelle [Wed, 30 Jul 2025 07:55:37 +0000 (09:55 +0200)] 
MINOR: session: strengthen idle conn limit check

Add a BUG_ON() on session_check_idle_conn() to ensure the connection is
not already flagged as CO_FL_SESS_IDLE.

This checks that this function is only called one time per connection
transition from active to idle. This is necessary to ensure that session
idle counter is only incremented one time per connection.

2 days agoMINOR: session: remove redundant target argument from session_add_conn()
Amaury Denoyelle [Thu, 24 Jul 2025 09:53:13 +0000 (11:53 +0200)] 
MINOR: session: remove redundant target argument from session_add_conn()

session_add_conn() uses three argument : connection and session
instances, plus a void pointer labelled as target. Typically, it
represents the server, but can also be a backend instance (for example
on dispatch).

In fact, this argument is redundant as <target> is already a member of
the connection. This commit simplifies session_add_conn() by removing
it. A BUG_ON() on target is extended to ensure it is never NULL.

2 days agoMINOR: session: strengthen connection attach to session
Amaury Denoyelle [Wed, 23 Jul 2025 08:03:51 +0000 (10:03 +0200)] 
MINOR: session: strengthen connection attach to session

This commit is the first one of a serie to refactor insertion of backend
private connection into the session list.

session_add_conn() is used to attach a connection into a session list.
Previously, this function would report an error if the connection
specified was already attached to another session. However, this case
currently never happens and thus can be considered as buggy.

Remove this check and replace it with a BUG_ON(). This allows to ensure
that session insertion remains consistent. The same check is also
transformed in session_check_idle_conn().

2 days agoMINOR: mux-quic: release conn after shutdown on BE reuse failure
Amaury Denoyelle [Wed, 30 Jul 2025 07:51:21 +0000 (09:51 +0200)] 
MINOR: mux-quic: release conn after shutdown on BE reuse failure

On stream detach on backend side, connection is inserted in the proper
server/session list to be able to reuse it later. If insertion fails and
the connection is idle, the connection can be removed immediately.

If this occurs on a QUIC connection, QUIC MUX implements graceful
shutdown to ensure the server is notified of the closure. However, the
connection instance is not freed. Change this to ensure that both
shutdown and release is performed.

3 days agoMINOR: clock: make global_now_ns a pointer as well
Aurelien DARRAGON [Thu, 26 Jun 2025 10:58:07 +0000 (12:58 +0200)] 
MINOR: clock: make global_now_ns a pointer as well

Similar to previous commit but for global_now_ns

3 days agoMINOR: clock: make global_now_ms a pointer
Aurelien DARRAGON [Fri, 30 May 2025 10:04:53 +0000 (12:04 +0200)] 
MINOR: clock: make global_now_ms a pointer

This is preparation work for shared counters between co-processes. As
co-processes will need to share a common date. global_now_ms will be used
for that as it will point to the shm when sharing is enabled.

Thus in this patch we turn global_now_ms into a pointer (and adjust the
places where it is written to and read from, hopefully atomic operations
through pointer are already used so the change is trivial)

For now global_now_ms points to process-local _global_now_ms which is a
fallback for when sharing through the shm is not enabled.

3 days agoCLEANUP: counters: rename counters_be_shared_init to counters_be_shared_prepare
Aurelien DARRAGON [Tue, 29 Jul 2025 12:16:05 +0000 (14:16 +0200)] 
CLEANUP: counters: rename counters_be_shared_init to counters_be_shared_prepare

75e480d10 ("MEDIUM: stats: avoid 1 indirection by storing the shared
stats directly in counters struct") took care of renaming
counters_fe_shared_init() but we forgot counters_be_shared_init().

Let's fix that for consistency

3 days agoBUG/MINOR: hlua: take default-path into account with lua-load-per-thread
Aurelien DARRAGON [Mon, 28 Jul 2025 18:14:53 +0000 (20:14 +0200)] 
BUG/MINOR: hlua: take default-path into account with lua-load-per-thread

As discussed in GH #3051, default-path is not taken into account when
loading files using lua-load-per-thread. In fact, the initial
hlua_load_state() (performed on first thread which parses the config)
is successful, but other threads run hlua_load_state() later based
on config hints which were saved by the first thread, and those config
hints only contain the file path provided on the lua-load-per-thread
config line, not the absolute one. Indeed, `default-path` directive
changes the current working directory only for the thread parsing the
configuration.

To fix the issue, when storing config hints under hlua_load_per_thread()
we now make sure to save the absolute file path for `lua-load-per-thread'
argument.

Thanks to GH user @zhanhb for having reported the issue

It may be backported to all stable versions.

3 days agoMINOR: acme: implement traces
William Lallemand [Tue, 29 Jul 2025 15:12:33 +0000 (17:12 +0200)] 
MINOR: acme: implement traces

Implement traces for the ACME protocol.

 -dt acme:data:complete will dump every input and output buffers,
 including decoded buffers before being converted to JWS.
 It will also dump certificates in the traces.

 -dt acme:user:complete will only dump the state of the task handler.

4 days ago[RELEASE] Released version 3.3-dev5 v3.3-dev5
Willy Tarreau [Mon, 28 Jul 2025 09:26:22 +0000 (11:26 +0200)] 
[RELEASE] Released version 3.3-dev5

Released version 3.3-dev5 with the following main changes :
    - BUG/MEDIUM: queue/stats: also use stream_set_srv_target() for pendconns
    - DOC: list missing global QUIC settings

4 days agoDOC: list missing global QUIC settings
Amaury Denoyelle [Mon, 28 Jul 2025 09:10:12 +0000 (11:10 +0200)] 
DOC: list missing global QUIC settings

Complete list of global keywords with missing QUIC entries.

This could be backported to stable versions. This requires to take into
account the version of introduction for each keyword.
* limited-quic, introduced in 2.8
* no-quic, introduced in 2.8
* tune.quic.cc.cubic.min-losses, introduced in 3.1

4 days agoBUG/MEDIUM: queue/stats: also use stream_set_srv_target() for pendconns
Aurelien DARRAGON [Sat, 26 Jul 2025 09:28:19 +0000 (11:28 +0200)] 
BUG/MEDIUM: queue/stats: also use stream_set_srv_target() for pendconns

Following c24de07 ("OPTIM: stats: store fast sharded counters pointers
at session and stream level") some crashes were observed in
connect_server():

  #0  0x00000000007ba39c in connect_server (s=0x65117b0) at src/backend.c:2101
  2101                            _HA_ATOMIC_INC(&s->sv_tgcounters->connect);
  Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 nss-softokn-freebl-3.67.0-3.el7_9.x86_64 pcre-8.32-17.el7.x86_64
  (gdb) bt
  #0  0x00000000007ba39c in connect_server (s=0x65117b0) at src/backend.c:2101
  #1  0x00000000007baff8 in back_try_conn_req (s=0x65117b0) at src/backend.c:2378
  #2  0x00000000006c0e9f in process_stream (t=0x650f180, context=0x65117b0, state=8196) at src/stream.c:2366
  #3  0x0000000000bd3e51 in run_tasks_from_lists (budgets=0x7ffd592752e0) at src/task.c:655
  #4  0x0000000000bd49ef in process_runnable_tasks () at src/task.c:889
  #5  0x0000000000851169 in run_poll_loop () at src/haproxy.c:2834
  #6  0x0000000000851865 in run_thread_poll_loop (data=0x1a03580 <ha_thread_info>) at src/haproxy.c:3050
  #7  0x0000000000852a53 in main (argc=7, argv=0x7ffd592755f8) at src/haproxy.c:3637

Here the crash occurs during the atomic inc of a sv_tgcounters metric from
the stream pointer, which tells us the pointer is likely garbage.

In fact, we assign s->sv_tgcounters each time the stream target is set to
a valid server. For that we use stream_set_srv_target() helper which does
assigment for us. By reviewing the code, in turns out we forgot to call
stream_set_srv_target() in pendconn_dequeue(), where the stream target
is set to the server who picked the pendconn.

Let's fix the bug by using stream_set_srv_target() there.

No backport needed unless c24de07 is.

6 days ago[RELEASE] Released version 3.3-dev4 v3.3-dev4
Willy Tarreau [Sat, 26 Jul 2025 07:55:26 +0000 (09:55 +0200)] 
[RELEASE] Released version 3.3-dev4

Released version 3.3-dev4 with the following main changes :
    - CLEANUP: server: do not check for duplicates anymore in findserver()
    - REORG: server: move findserver() from proxy.c to server.c
    - MINOR: server: use the tree to look up the server name in findserver()
    - CLEANUP: server: rename server_find_by_name() to server_find()
    - CLEANUP: server: rename findserver() to server_find_by_name()
    - CLEANUP: server: use server_find_by_name() where relevant
    - CLEANUP: cfgparse: lookup proxy ID using existing functions
    - CLEANUP: stream: lookup server ID using standard functions
    - CLEANUP: server: simplify server_find_by_id()
    - CLEANUP: server: add server_find_by_addr()
    - CLEANUP: stream: use server_find_by_addr() in sticking_rule_find_target()
    - CLEANUP: server: be sure never to compare src against a non-existing defsrv
    - MEDIUM: proxy: take the defsrv out of the struct proxy
    - MINOR: proxy: add checks for defsrv's validity
    - MEDIUM: proxy: no longer allocate the default-server entry by default
    - MEDIUM: proxy: register a post-section cleanup function
    - MINOR: debug: report haproxy and operating system info in panic dumps
    - BUG/MEDIUM: h3: do not overwrite interim with final response
    - BUG/MINOR: h3: properly realloc buffer after interim response encoding
    - BUG/MINOR: h3: ensure that invalid status code are not encoded (FE side)
    - MINOR: qmux: change API for snd_buf FIN transmission
    - BUG/MEDIUM: h3: handle interim response properly on FE side
    - BUG/MINOR: h3: properly handle interim response on BE side
    - BUG/MINOR: quic: Wrong source address use on FreeBSD
    - MINOR: h3: remove unused outbuf in h3_resp_headers_send()
    - BUG/MINOR: applet: Don't trigger BUG_ON if the tid is not on appctx init
    - DEV: gdb: add a memprofile decoder to the debug tools
    - MINOR: quic: Get rid of qc_is_listener()
    - DOC: connection: explain the rules for idle/safe/avail connections
    - BUG/MEDIUM: quic-be: CC buffer released from wrong pool
    - BUG/MINOR: halog: exit with error when some output filters are set simultaneosly
    - MINOR: cpu-topo: split cpu_dump_topology() to show its summary in show dev
    - MINOR: cpu-topo: write thread-cpu bindings into trash buffer
    - MINOR: debug: align output style of debug_parse_cli_show_dev with cpu_dump_topology
    - MINOR: debug: add thread-cpu bindings info in 'show dev' output
    - MINOR: quic: Remove pool_head_quic_be_cc_buf pool
    - BUILD: debug: add missed guard USE_CPU_AFFINITY to show cpu bindings
    - BUG/MEDIUM: threads: Disable the workaround to load libgcc_s on macOS
    - BUG/MINOR: logs: fix log-steps extra log origins selection
    - BUG/MINOR: hq-interop: fix FIN transmission
    - MINOR: ssl: Add ciphers in ssl traces
    - MINOR: ssl: Add curve id to curve name table and mapping functions
    - MINOR: ssl: Add curves in ssl traces
    - MINOR: ssl: Dump ciphers and sigalgs details in trace with 'advanced' verbosity
    - MINOR: ssl: Remove ClientHello specific traces if !HAVE_SSL_CLIENT_HELLO_CB
    - MINOR: h3: use smallbuf for request header emission
    - MINOR: h3: add traces to h3_req_headers_send()
    - BUG/MINOR: h3: fix uninitialized value in h3_req_headers_send()
    - MINOR: log: explicitly ignore "log-steps" on backends
    - BUG/MEDIUM: acme: use POST-as-GET instead of GET for resources
    - BUG/MINOR mux-quic: apply correctly timeout on output pending data
    - BUG/MINOR: mux-quic: ensure close-spread-time is properly applied
    - MINOR: mux-quic: refactor timeout code
    - MINOR: mux-quic: correctly implement backend timeout
    - MINOR: mux-quic: disable glitch on backend side
    - MINOR: mux-quic: store session in QCS instance
    - MEDIUM: mux-quic: implement be connection reuse
    - MINOR: mux-quic: do not reuse connection if app already shut
    - MEDIUM: mux-quic: support backend private connection
    - MINOR: acme: remove acme_req_auth() and use acme_post_as_get() instead
    - BUG/MINOR: acme: allow "processing" in challenge requests
    - CLEANUP: acme: fix wrong spelling of "resources"
    - CLEANUP: ssl: Use only NIDs in curve name to id table
    - MINOR: acme: add ACME to the haproxy -vv feature list
    - BUG/MINOR: hlua: Skip headers when a receive is performed on an HTTP applet
    - BUG/MEDIUM: applet: State inbuf is no longer full if input data are skipped
    - BUG/MEDIUM: stconn: Fix conditions to know an applet can get data from stream
    - BUG/MINOR: applet: Fix applet_getword() to not return one extra byte
    - BUG/MEDIUM: Remove sync sends from streams to applets
    - MINOR: applet: Add HTX versions for applet_input_data() and applet_output_room()
    - MINOR: applet: Improve applet API to take care of inbuf/outbuf alloc failures
    - MEDIUM: hlua: Update the tcp applet to use its own buffers
    - MINOR: hlua: Fill the request array on the first HTTP applet run
    - MINOR: hlua: Use the buffer instead of the HTTP message to get HTTP headers
    - MEDIUM: hlua: Update the http applet to use its own buffers
    - BUG/MEDIUM: hlua: Report to SC when data were consumed on a lua socket
    - BUG/MEDIUM: hlua: Report to SC when output data are blocked on a lua socket
    - MEDIUM: hlua: Update the socket applet to use its own buffers
    - BUG/MEDIUM: dns: Reset reconnect tempo when connection is finally established
    - MEDIUM: dns: Update the dns_session applet to use its own buffers
    - CLEANUP: http-client: Remove useless indentation when sending request body
    - MINOR: http-client: Try to send request body with headers if possible
    - MINOR: http-client: Trigger an error if first response block isn't a start-line
    - BUG/MINOR: httpclient-cli: Don't try to dump raw headers in HTX mode
    - MINOR: httpclient-cli: Reset httpclient HTX buffer instead of removing blocks
    - MEDIUM: http-client: Update the http-client applet to use its own buffers
    - MEDIUM: log: Update the log applet to use its own buffers
    - MEDIUM: sink: Update the sink applets to use their own buffers
    - MEDIUM: peers: Update the peer applet to use its own buffers
    - MEDIUM: promex: Update the promex applet to use their own buffers
    - MINOR: applet: Add support for flags on applets with a flag about the new API
    - MEDIUM: applet: Emit a warning when a legacy applet is spawned
    - BUG/MEDIUM: logs: fix sess_build_logline_orig() recursion with options
    - MEDIUM: stats: avoid 1 indirection by storing the shared stats directly in counters struct
    - CLEANUP: compiler: prefer char * over void * for pointer arithmetic
    - CLEANUP: include: replace hand-rolled offsetof to avoid UB
    - CLEANUP: peers: remove unused peer_session_target()
    - OPTIM: stats: store fast sharded counters pointers at session and stream level

7 days agoOPTIM: stats: store fast sharded counters pointers at session and stream level
Aurelien DARRAGON [Thu, 24 Jul 2025 17:46:36 +0000 (19:46 +0200)] 
OPTIM: stats: store fast sharded counters pointers at session and stream level

Following commit 75e480d10 ("MEDIUM: stats: avoid 1 indirection by storing
the shared stats directly in counters struct"), in order to minimize the
impact of the recent sharded counters work, we try to push things a bit
further in this patch by storing and using "fast" pointers at the session
and stream levels when available to avoid costly indirections and
systematic "tgid" resolution (which can not be cached by the CPU due to
its THREAD-local nature).

Indeed, we know that a session/stream is tied to a given CPU, thanks to
this we know that the tgid for a given session/stream will never change.

Given that, we are able to store sharded frontend and listener counters
pointer at the session level (namely sess->fe_tgcounters and
sess->li_tgcounters), and once the backend and the server are selected,
we are also able to store backend and server sharded counters
pointer at the stream level (namely s->be_tgcounters and s->sv_tgcounters)

Everywhere we rely on these counters and the stream or session context is
available, we use the fast pointers it instead of the indirect pointers
path to make the pointer resolution a bit faster.

This optimization proved to bring a few percents back, and together with
the previous 75e480d10 commit we now fixed the performance regression (we
are back to back with 3.2 stats performance)

7 days agoCLEANUP: peers: remove unused peer_session_target()
Aurelien DARRAGON [Fri, 25 Jul 2025 15:17:03 +0000 (17:17 +0200)] 
CLEANUP: peers: remove unused peer_session_target()

Since commit 7293eb68 ("MEDIUM: peers: use server as stream target") peer
session target always point to server in order to benefit from existing
server transport options.

Thanks to that, it is no longer necessary to have peer_session_target()
helper function, because all it does is return the pointer to the
server object. Let's get rid of that

7 days agoCLEANUP: include: replace hand-rolled offsetof to avoid UB
Ben Kallus [Sun, 20 Jul 2025 16:48:07 +0000 (12:48 -0400)] 
CLEANUP: include: replace hand-rolled offsetof to avoid UB

The C standard specifies that it's undefined behavior to dereference
NULL (even if you use & right after). The hand-rolled offsetof idiom
&(((s*)NULL)->f) is thus technically undefined. This clutters the
output of UBSan and is simple to fix: just use the real offsetof when
it's available.

Note that there's no clear statement about this point in the spec,
only several points which together converge to this:

- From N3220, 6.5.3.4:
  A postfix expression followed by the -> operator and an identifier
  designates a member of a structure or union object. The value is
  that of the named member of the object to which the first expression
  points, and is an lvalue.

- From N3220, 6.3.2.1:
  An lvalue is an expression (with an object type other than void) that
  potentially designates an object; if an lvalue does not designate an
  object when it is evaluated, the behavior is undefined.

- From N3220, 6.5.4.4 p3:
  The unary & operator yields the address of its operand. If the
  operand has type "type", the result has type "pointer to type". If
  the operand is the result of a unary * operator, neither that operator
  nor the & operator is evaluated and the result is as if both were
  omitted, except that the constraints on the operators still apply and
  the result is not an lvalue. Similarly, if the operand is the result
  of a [] operator, neither the & operator nor the unary * that is
  implied by the [] is evaluated and the result is as if the & operator
  were removed and the [] operator were changed to a + operator.

=> In short, this is saying that C guarantees these identities:
    1. &(*p) is equivalent to p
    2. &(p[n]) is equivalent to p + n

As a consequence, &(*p) doesn't result in the evaluation of *p, only
the evaluation of p (and similar for []). There is no corresponding
special carve-out for ->.

See also: https://pvs-studio.com/en/blog/posts/cpp/0306/

After this patch, HAProxy can run without crashing after building w/
clang-19 -fsanitize=undefined -fno-sanitize=function,alignment

7 days agoCLEANUP: compiler: prefer char * over void * for pointer arithmetic
Ben Kallus [Sun, 20 Jul 2025 16:48:07 +0000 (12:48 -0400)] 
CLEANUP: compiler: prefer char * over void * for pointer arithmetic

This patch changes two instances of pointer arithmetic on void *
to use char * instead, to avoid UB. This is essentially to please
UB analyzers, though.

7 days agoMEDIUM: stats: avoid 1 indirection by storing the shared stats directly in counters...
Aurelien DARRAGON [Tue, 22 Jul 2025 15:15:02 +0000 (17:15 +0200)] 
MEDIUM: stats: avoid 1 indirection by storing the shared stats directly in counters struct

Between 3.2 and 3.3-dev we noticed a noticeable performance regression
due to stats handling. After bisecting, Willy found out that recent
work to split stats computing accross multiple thread groups (stats
sharding) was responsible for that performance regression. We're looking
at roughly 20% performance loss.

More precisely, it is the added indirections, multiplied by the number
of statistics that are updated for each request, which in the end causes
a significant amount of time being spent resolving pointers.

We noticed that the fe_counters_shared and be_counters_shared structures
which are currently allocated in dedicated memory since a0dcab5c
("MAJOR: counters: add shared counters base infrastructure")
are no longer huge since 16eb0fab31 ("MAJOR: counters: dispatch counters
over thread groups") because they now essentially hold flags plus the
per-thread group id pointer mapping, not the counters themselves.

As such we decided to try merging fe_counters_shared and
be_counters_shared in their parent structures. The cost is slight memory
overhead for the parent structure, but it allows to get rid of one
pointer indirection. This patch alone yields visible performance gains
and almost restores 3.2 stats performance.

counters_fe_shared_get() was renamed to counters_fe_shared_prepare() and
now returns either failure or success instead of a pointer because we
don't need to retrieve a shared pointer anymore, the function takes care
of initializing existing pointer.

7 days agoBUG/MEDIUM: logs: fix sess_build_logline_orig() recursion with options
Aurelien DARRAGON [Fri, 25 Jul 2025 14:03:21 +0000 (16:03 +0200)] 
BUG/MEDIUM: logs: fix sess_build_logline_orig() recursion with options

Since ccc43412 ("OPTIM: log: use thread local lf_buildctx to stop pushing
it on the stack"), recursively calling sess_build_logline_orig(), which
may for instance happen when leveraging %ID (or unique-id fetch) for the
first time, would lead to undefined behavior because the parent
sess_build_logline_orig() build context was shared between recursive calls
(only one build ctx per thread to avoid pushing it on the stack for each
call)

In short, the parent build ctx would be altered by the recursive calls,
which is obviously not expected and could result in log formatting errors.

To fix the issue but still avoid polluting the stack with large lf_buildctx
struct, let's move the static 256 bytes build buffer out of the buildctx
so that the buildctx is now stored in the stack again (each function
invokation has its own dedicated build ctx). On the other hand, it's
acceptable to have only 1 256 bytes build buffer per thread because the
build buffer is not involved in recursives calls (unlike the build ctx)

Thanks to Willy and Vincent Gramer for spotting the bug and providing
useful repro.

It should be backported in 3.0 with ccc43412.

7 days agoMEDIUM: applet: Emit a warning when a legacy applet is spawned
Christopher Faulet [Fri, 25 Jul 2025 13:44:47 +0000 (15:44 +0200)] 
MEDIUM: applet: Emit a warning when a legacy applet is spawned

To motivate developers to support the new applets API, a warning is now
emitted when a legacy applet is spawned. To not flood users, this warning is
only emitted once per legacy applet. To do so, the applet flag
APPLET_FL_WARNED was added. It is set when the warning is emitted.

Note that test and set on this flag are not performed via atomic operations.
So it is possible to have more than one warning for a given applet if it is
spawned in same time on several threads. At worrst, there is one warning per
thread.

7 days agoMINOR: applet: Add support for flags on applets with a flag about the new API
Christopher Faulet [Fri, 25 Jul 2025 13:40:29 +0000 (15:40 +0200)] 
MINOR: applet: Add support for flags on applets with a flag about the new API

A new field was added in the applet structure to be able to set flags on the
applets The first one is related to the new API. APPLET_FL_NEW_API is set
for applets based on the new API. It was set on all HAProxy's applets.

8 days agoMEDIUM: promex: Update the promex applet to use their own buffers
Christopher Faulet [Wed, 23 Jul 2025 09:19:29 +0000 (11:19 +0200)] 
MEDIUM: promex: Update the promex applet to use their own buffers

Thanks to this patch, the promex applet is now using its own buffers.
.rcv_buf and .snd_buf callback functions are now defined to use the default
HTX functions. Parts to receive and send data have also been updated to use
the applet API and to remove any dependencies on the stream-connectors and
the channels.

8 days agoMEDIUM: peers: Update the peer applet to use its own buffers
Christopher Faulet [Tue, 22 Jul 2025 17:01:10 +0000 (19:01 +0200)] 
MEDIUM: peers: Update the peer applet to use its own buffers

Thanks to this patch, the peer applet is now using its own buffers. .rcv_buf
and .snd_buf callback functions are now defined to use the default raw
functions. The applet API is now used and any dependencies on the
stream-connectors and the channels were removed.

8 days agoMEDIUM: sink: Update the sink applets to use their own buffers
Christopher Faulet [Tue, 22 Jul 2025 16:46:38 +0000 (18:46 +0200)] 
MEDIUM: sink: Update the sink applets to use their own buffers

Thanks to this patch, the sink applets is now using their own buffers.
.rcv_buf and .snd_buf callback functions are now defined to use the default
raw functions. The applet API is now used and any dependencies on the
stream-connectors and the channels were removed.

8 days agoMEDIUM: log: Update the log applet to use its own buffers
Christopher Faulet [Tue, 22 Jul 2025 16:27:54 +0000 (18:27 +0200)] 
MEDIUM: log: Update the log applet to use its own buffers

Thanks to this patch, the log applet is now using its own buffers. .rcv_buf
and .snd_buf callback functions are now defined to use the default raw
functions. The applet API is now used and any dependencies on the
stream-connectors and the channels were removed.

8 days agoMEDIUM: http-client: Update the http-client applet to use its own buffers
Christopher Faulet [Tue, 22 Jul 2025 14:01:07 +0000 (16:01 +0200)] 
MEDIUM: http-client: Update the http-client applet to use its own buffers

Thanks to this patch, the http-client applet is now using its own buffers.
.rcv_buf and .snd_buf callback functions are now defined to use the default
HTX functions. Parts to receive and send data have also been updated to use
the applet API and to remove any dependencies on the stream-connectors and
the channels.

8 days agoMINOR: httpclient-cli: Reset httpclient HTX buffer instead of removing blocks
Christopher Faulet [Tue, 22 Jul 2025 13:18:46 +0000 (15:18 +0200)] 
MINOR: httpclient-cli: Reset httpclient HTX buffer instead of removing blocks

In the CLI I/O handler interacting with the HTTP client, in HTX mode, after
a dump of the HTX message, data must be removed. Instead of removng all
blocks one by one, we can call htx_reset() because all the message must be
flushed.

8 days agoBUG/MINOR: httpclient-cli: Don't try to dump raw headers in HTX mode
Christopher Faulet [Tue, 22 Jul 2025 13:17:50 +0000 (15:17 +0200)] 
BUG/MINOR: httpclient-cli: Don't try to dump raw headers in HTX mode

In the CLI I/O handler interacting with the HTTP client, we must not try to
push raw headers in HTX mode, because there is no raw data in this
mode. This prevent the HTX dump at the end of the I/O handle.

It is a 3.3-specific issue. No backport needed.

8 days agoMINOR: http-client: Trigger an error if first response block isn't a start-line
Christopher Faulet [Tue, 22 Jul 2025 06:22:06 +0000 (08:22 +0200)] 
MINOR: http-client: Trigger an error if first response block isn't a start-line

The first HTX block of a response must be a start-line. There is no reason
to wait for something else. And if there are output data in the response
channel buffer, it means we must found the start-line.

8 days agoMINOR: http-client: Try to send request body with headers if possible
Christopher Faulet [Tue, 22 Jul 2025 06:16:14 +0000 (08:16 +0200)] 
MINOR: http-client: Try to send request body with headers if possible

There is no reason to yield after sending the request headers, except if the
request was fully sent. If there is a payload, it is better to send it as
well. However, when the whole request was sent, we can leave the I/O handler.

8 days agoCLEANUP: http-client: Remove useless indentation when sending request body
Christopher Faulet [Tue, 22 Jul 2025 06:14:24 +0000 (08:14 +0200)] 
CLEANUP: http-client: Remove useless indentation when sending request body

It was useless to have an indentation to handle HTTPCLIENT_S_REQ_BODY state
in the http-client I/O handler.

8 days agoMEDIUM: dns: Update the dns_session applet to use its own buffers
Christopher Faulet [Mon, 21 Jul 2025 09:39:08 +0000 (11:39 +0200)] 
MEDIUM: dns: Update the dns_session applet to use its own buffers

Thanks to this patch, the dns_session applet is now using its own
buffers. .rcv_buf and .snd_buf callback functions are now defined to use the
default raw functions. Functions to receive and send data have also been
updated to use the applet API and to remove any dependencies on the
stream-connectors and the channels.

8 days agoBUG/MEDIUM: dns: Reset reconnect tempo when connection is finally established
Christopher Faulet [Mon, 21 Jul 2025 09:30:41 +0000 (11:30 +0200)] 
BUG/MEDIUM: dns: Reset reconnect tempo when connection is finally established

The issue was introduced by commit 27236f221 ("BUG/MINOR: dns: add tempo
between 2 connection attempts for dns servers"). In this patch, to delay the
reconnection, a timer is used on the appctx when it is created. This
postpones the appctx initialization. However, once initialized, the
expiration time of the underlying task is not reset. So, it is always
considered as expired and the appctx is woken up in loop.

The fix is quite simple. In dns_session_init(), the expiration time of the
appctx's task is alwaus set to TICK_ETERNITY.

This patch must be backported everywhere the commit above was backported. So
as far as 2.8 for now but possibly to all stable versions.

8 days agoMEDIUM: hlua: Update the socket applet to use its own buffers
Christopher Faulet [Fri, 18 Jul 2025 14:53:20 +0000 (16:53 +0200)] 
MEDIUM: hlua: Update the socket applet to use its own buffers

Thanks to this patch, the lua cosocket applet is now using its own
buffers. .rcv_buf and .snd_buf callback functions are now defined to use the
default raw functions. Functions to receive and send data have also been
updated to use the applet API and to remove any dependencies on the
stream-connectors and the channels.

8 days agoBUG/MEDIUM: hlua: Report to SC when output data are blocked on a lua socket
Christopher Faulet [Fri, 18 Jul 2025 14:09:20 +0000 (16:09 +0200)] 
BUG/MEDIUM: hlua: Report to SC when output data are blocked on a lua socket

It is a fix similar to the previous one ("BUG/MEDIUM: hlua: Report to SC
when data were consumed on a lua socket"), but for the write side. The
writer must notify the cosocket it needs more space in the request buffer to
produce more data by calling sc_need_room(). Otherwise, there is nothing to
prevent to wake the cosocket applet up again and again.

This patch must be backported as far as 2.8, and maybe to 2.6 too.

8 days agoBUG/MEDIUM: hlua: Report to SC when data were consumed on a lua socket
Christopher Faulet [Fri, 18 Jul 2025 14:07:16 +0000 (16:07 +0200)] 
BUG/MEDIUM: hlua: Report to SC when data were consumed on a lua socket

The lua cosocket are quite strange. There is an applet used to handle the
connection and writer and readers subscribed on it to write or read
data. Writers and readers are tasks woken up by the cosocket applet when
data can be consumed or produced, depending on the channels buffers
state. Then the cosocket applet is woken up by writers and readers when read
or write events were performed.

It means the cosocket applet has only few information on what was produced
or consumed. It is the writers and readers responsibility to notify any
blocking. Among other things, the readers must take care to notify the
stream on top of the cosocket applet that some data was consumed. Otherwise,
it may remain blocked, waiting for a write event (a write event from the
stream point of view is a read event from the cosocket point of view).

Thie patch must be backported as far as 2.8, and maybe to 2.6 too.

8 days agoMEDIUM: hlua: Update the http applet to use its own buffers
Christopher Faulet [Fri, 18 Jul 2025 10:07:20 +0000 (12:07 +0200)] 
MEDIUM: hlua: Update the http applet to use its own buffers

Thanks to this patch, the lua HTTP applet is now using its own buffers.
.rcv_buf and .snd_buf callback functions are now defined to use the default
HTX functions. Functions to receive and send data have also been updated to
use the applet API and to remove any dependencies on the stream-connectors
and the channels.

8 days agoMINOR: hlua: Use the buffer instead of the HTTP message to get HTTP headers
Christopher Faulet [Fri, 18 Jul 2025 10:07:05 +0000 (12:07 +0200)] 
MINOR: hlua: Use the buffer instead of the HTTP message to get HTTP headers

hlua_http_get_headers() function was using the HTTP message from the stream
TXN to retrieve headers from a message. However, this will be an issue to
update the lua HTTP applet to use its own buffers. Indeed, in that case,
information from the channels will be unavailable. So now,
hlua_http_get_headers() is now using a buffer containing an HTX message. It
is just an API change bacause, internally, the function was already
manipulation an HTX message.

8 days agoMINOR: hlua: Fill the request array on the first HTTP applet run
Christopher Faulet [Thu, 17 Jul 2025 09:58:29 +0000 (11:58 +0200)] 
MINOR: hlua: Fill the request array on the first HTTP applet run

When a lua HTTP applet is created, a "request" object is created, filled
with the request information (method, path, headers...), to be able to
easily retrieve these information from the script. However, this was done
when thee appctx was created, retrieving the info from the request channel.

To be ale to update the applet to use its own buffer, it is now performed on
the first applet run. Indead, when the applet is created, the info are not
forwarded yet and should not be accessed. Note that for now, information are
still retrieved from the channel.

8 days agoMEDIUM: hlua: Update the tcp applet to use its own buffers
Christopher Faulet [Wed, 16 Jul 2025 13:28:11 +0000 (15:28 +0200)] 
MEDIUM: hlua: Update the tcp applet to use its own buffers

Thanks to this patch, the lua TCP applet is now using its own buffers.
.rcv_buf and .snd_buf callback functions are now defined to use the default
raw functions. Other changes are quite light. Mainly, end of stream and
errors are reported on the appctx instead of the stream-endpoint descriptor.

8 days agoMINOR: applet: Improve applet API to take care of inbuf/outbuf alloc failures
Christopher Faulet [Thu, 17 Jul 2025 13:08:55 +0000 (15:08 +0200)] 
MINOR: applet: Improve applet API to take care of inbuf/outbuf alloc failures

applet_get_inbuf() and applet_get_outbuf() functions were not testing if the
buffers were available. So, the caller had to check them before calling one
of these functions. It is not really handy. So now, these functions take
care to have a fully usable buffer before returning. Otherwise NULL is
returned.

8 days agoMINOR: applet: Add HTX versions for applet_input_data() and applet_output_room()
Christopher Faulet [Thu, 17 Jul 2025 13:45:36 +0000 (15:45 +0200)] 
MINOR: applet: Add HTX versions for applet_input_data() and applet_output_room()

It will be useful for HTX applets because availale data in the input buffer and
available space in the output buffer are computed from the HTX message and not
the buffer itself. So now, applet_htx_input_data() and applet_htx_output_room()
functions can be used.

8 days agoBUG/MEDIUM: Remove sync sends from streams to applets
Christopher Faulet [Tue, 22 Jul 2025 13:15:34 +0000 (15:15 +0200)] 
BUG/MEDIUM: Remove sync sends from streams to applets

When the applet API was reviewed to use dedicated buffers, the support for
sends from the streams to applets was added. Unfortunately, it was not a
good idea because this way it is possible to deliver data to an applet and
release it just after, truncated data. Indeed, the release stage for applets
is related to the stream release itself. However, unlike the multiplexers,
the applets cannot survive to a stream for now.

So, for now, the sync sends from the streams is removed for applets, waiting
for a better way to handle the applets release stage.

Note that this only concerns applets using their own buffers. And of now,
the bug is harmless because all refactored applets are on server side and
consume data first. But this will be an issue with the HTTP client.

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

8 days agoBUG/MINOR: applet: Fix applet_getword() to not return one extra byte
Christopher Faulet [Tue, 22 Jul 2025 16:23:57 +0000 (18:23 +0200)] 
BUG/MINOR: applet: Fix applet_getword() to not return one extra byte

applet_getword() function is returning one extra byte when a string is
returned because the "ret" variable is not reset before the loop on the
data. The patch also fixes applet_getline().

It is a 3.3-specific issue. No need to backport.

8 days agoBUG/MEDIUM: stconn: Fix conditions to know an applet can get data from stream
Christopher Faulet [Fri, 18 Jul 2025 07:09:28 +0000 (09:09 +0200)] 
BUG/MEDIUM: stconn: Fix conditions to know an applet can get data from stream

sc_is_send_allowed() function is used to know if an applet is able to
receive data from the stream. But this function was designed for applets
using the channels buffer. It is not adapted to applets using their own
buffers.

when the SE_FL_WAIT_DATA flag is set, it means the applet is waiting for
more data and should not be woken up without new data. For applets using
channels buffer, just testing the flag is enough because process_stream()
will remove if when more data will be available. For applets using their own
buffers, it is more complicated. Some data may be blocked in the output
channel buffer. In that case, and when the applet input buffer can receive
daa, the applet can be woken up.

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

8 days agoBUG/MEDIUM: applet: State inbuf is no longer full if input data are skipped
Christopher Faulet [Fri, 18 Jul 2025 07:05:45 +0000 (09:05 +0200)] 
BUG/MEDIUM: applet: State inbuf is no longer full if input data are skipped

When data are skipped from the input buffer of an applet, we must take care
to notify the input buffer is no longer full. Otherwise, this could prevent
the stream to push data to the applet.

It is 3.3-specific. No backport needed.

8 days agoBUG/MINOR: hlua: Skip headers when a receive is performed on an HTTP applet
Christopher Faulet [Fri, 18 Jul 2025 09:14:26 +0000 (11:14 +0200)] 
BUG/MINOR: hlua: Skip headers when a receive is performed on an HTTP applet

When an HTTP applet tries to retrieve data, the request headers are still in
the buffer. But, instead of being silently removed, their size is removed
from the amount of data retrieved. When the request payload is fully
retrieved, it is not an issue. But it is a problem when a length is
specified. The data are shorten from the headers size.

So now, we take care to silently remove headers.

This patch must be backported to all stable versions.

8 days agoMINOR: acme: add ACME to the haproxy -vv feature list
William Lallemand [Thu, 24 Jul 2025 09:47:20 +0000 (11:47 +0200)] 
MINOR: acme: add ACME to the haproxy -vv feature list

Add "ACME" in the feature list in order to check if the support was
built successfully.

8 days agoCLEANUP: ssl: Use only NIDs in curve name to id table
Remi Tricot-Le Breton [Thu, 24 Jul 2025 08:51:29 +0000 (10:51 +0200)] 
CLEANUP: ssl: Use only NIDs in curve name to id table

The curve name to curve id mapping table was built out of multiple
internal tables found in openssl sources, namely the 'nid_to_group'
table found in 'ssl/t1_lib.c' which maps openssl specific NIDs to public
IANA curve identifiers. In this table, there were two instances of
EVP_PKEY_XXX ids being used while all the other ones are NID_XXX
identifiers.
Since the two EVP_PKEY are actually equal to their NID equivalent in
'include/openssl/evp.h' we can use NIDs all along for better coherence.

8 days agoCLEANUP: acme: fix wrong spelling of "resources"
Ilia Shipitsin [Wed, 23 Jul 2025 19:58:36 +0000 (21:58 +0200)] 
CLEANUP: acme: fix wrong spelling of "resources"

"ressources" was used as a variable name, let's use English variant
to make spell check happier

9 days agoBUG/MINOR: acme: allow "processing" in challenge requests
William Lallemand [Wed, 23 Jul 2025 12:32:18 +0000 (14:32 +0200)] 
BUG/MINOR: acme: allow "processing" in challenge requests

Allow the "processing" status in the challenge object when requesting
to do the challenge, in addition to "pending".

According to RFC 8555 https://datatracker.ietf.org/doc/html/rfc8555/#section-7.1.6

   Challenge objects are created in the "pending" state.  They
   transition to the "processing" state when the client responds to the
   challenge (see Section 7.5.1)

However some CA could respond with a "processing" state without ever
transitioning to "pending".

Must be backported to 3.2.

9 days agoMINOR: acme: remove acme_req_auth() and use acme_post_as_get() instead
William Lallemand [Wed, 23 Jul 2025 12:05:16 +0000 (14:05 +0200)] 
MINOR: acme: remove acme_req_auth() and use acme_post_as_get() instead

acme_req_auth() is only a call to acme_post_as_get() now, there's no
reason to keep the function. This patch removes it.

9 days agoMEDIUM: mux-quic: support backend private connection
Amaury Denoyelle [Tue, 22 Jul 2025 14:45:39 +0000 (16:45 +0200)] 
MEDIUM: mux-quic: support backend private connection

If a backend connection is private, it should not be reused outside of
its original attached session. As such, on stream detach operation, such
connection is never inserted into server idle/avail list. Instead, it is
stored directly on the session.

The purpose of this commit is to implement proper handling of private
backend connections via QUIC multiplexer.

9 days agoMINOR: mux-quic: do not reuse connection if app already shut
Amaury Denoyelle [Wed, 23 Jul 2025 07:41:46 +0000 (09:41 +0200)] 
MINOR: mux-quic: do not reuse connection if app already shut

QUIC connection graceful closure is performed in two steps. First, the
application layer is closed. In the context of HTTP/3, this is done with
a GOAWAY frame emission, which forbids opening of new streams. Then the
whole connection is terminated via CONNECTION_CLOSE which is the final
emitted frame.

This commit ensures that when app layer is shut for a backend
connection, this connection is removed from either idle or avail server
tree. The objective is to prevent stream layer to try to reuse a
connection if no new stream can be attached on it.

New BUG_ON checks are inserted in qmux_strm_attach() and h3_attach() to
ensure that this assertion is always true.

9 days agoMEDIUM: mux-quic: implement be connection reuse
Amaury Denoyelle [Tue, 22 Jul 2025 09:36:34 +0000 (11:36 +0200)] 
MEDIUM: mux-quic: implement be connection reuse

Implement support for QUIC connection reuse on the backend side. The
main change is done during detach stream operation. If a connection is
idle, it is inserted in the server list. Else, it is stored in the
server avail tree if there is room for more streams.

For non idle connection, qmux_avail_streams() is reused to detect that
stream flow-control limit is not yet reached. If this is the case, the
connection is not inserted in the avail tree, so it cannot be reuse,
even if flow-control is unblocked later by the peer. This latter point
could be improved in the future.

Note that support for QUIC private connections is still missing. Reuse
code will evolved to fully support this case.

9 days agoMINOR: mux-quic: store session in QCS instance
Amaury Denoyelle [Tue, 22 Jul 2025 16:27:40 +0000 (18:27 +0200)] 
MINOR: mux-quic: store session in QCS instance

Add a new <sess> member into QCS structure. It is used to store the
parent session of the stream on attach operation. This is only done for
backend side.

This new member will become necessary when connection reuse will be
implemented. <owner> member of connection is not suitable as it could be
set to NULL, notably after a session_add_conn() failure.

Also, a single BE conn can be shared along different session instance,
in particular when using aggressive/always reuse mode. Thus it is
necessary to linked each QCS instance with its session.

9 days agoMINOR: mux-quic: disable glitch on backend side
Amaury Denoyelle [Wed, 23 Jul 2025 12:36:17 +0000 (14:36 +0200)] 
MINOR: mux-quic: disable glitch on backend side

For now, QUIC glitch limit counter is only available on the frontend
side. Thus, disable incrementation on the backend side for now. Also,
session is only available as conn <owner> reliably on the frontend side,
so session_add_glitch_ctr() operation is also securised.

9 days agoMINOR: mux-quic: correctly implement backend timeout
Amaury Denoyelle [Tue, 22 Jul 2025 13:44:17 +0000 (15:44 +0200)] 
MINOR: mux-quic: correctly implement backend timeout

qcc_refresh_timeout() is the function called on QUIC MUX activity. Its
purpose is to update the timeout by selecting the correct value
depending on the connection state.

Prior to this patch, backend connections were mostly ignored by the
function. However, the default server timeout was selecting as a
fallback. This is incompatible with backend connections reuse.

This patch fixes timeout applied on backend connections. Only values
specific to frontend which are http-request and http-keep-alive timeouts
are now ignored for a backend connection. Also, fallback timeout is only
used for frontend connections.

This patch ensures that an idle backend connection won't be deleted due
to server timeout. This is necessary for proper connection reuse which
will be implemented in a future patch.

9 days agoMINOR: mux-quic: refactor timeout code
Amaury Denoyelle [Tue, 8 Jul 2025 08:44:44 +0000 (10:44 +0200)] 
MINOR: mux-quic: refactor timeout code

This commit is a small reorganization of condition used into
qcc_refresh_timeout(). Its objective is to render the code more logical
before the next patch which will ensure that timeout is properly set for
backend connections.

9 days agoBUG/MINOR: mux-quic: ensure close-spread-time is properly applied
Amaury Denoyelle [Tue, 8 Jul 2025 08:31:46 +0000 (10:31 +0200)] 
BUG/MINOR: mux-quic: ensure close-spread-time is properly applied

If a connection remains on a proxy currently disabled or stopped, a
special spread timeout is set if active close is configured. For QUIC
MUX, this is set via qcc_refresh_timeout() as with all other timeout
values.

Fix this closing timeout setting : it is now used as an override to any
other timeout that may have been chosen if calculated spread time is
lower than the previously selected value. This is done for backend
connections as well.

This should be backported up to 2.6 after a period of observation.

9 days agoBUG/MINOR mux-quic: apply correctly timeout on output pending data
Amaury Denoyelle [Tue, 8 Jul 2025 08:30:46 +0000 (10:30 +0200)] 
BUG/MINOR mux-quic: apply correctly timeout on output pending data

When no stream is attached, mux layer is responsible to maintain a
timeout. The first criteria is to apply client/server timeout if there
is still data waiting for emission.

Previously, <hreq> qcc member was used to determine this state. However,
this only covers bidirectional streams. Fix this by testing if
<send_list> is empty or not. This is enough to take into account both
bidi and uni streams.

Theorically, this should be backported to every stable versions.
However, send-list is not available on 2.6 and there is no alternative
to quickly determine if there is waiting output data. Thus, it's better
to backport it up to 2.8 only.

9 days agoBUG/MEDIUM: acme: use POST-as-GET instead of GET for resources
William Lallemand [Wed, 23 Jul 2025 10:32:34 +0000 (12:32 +0200)] 
BUG/MEDIUM: acme: use POST-as-GET instead of GET for resources

The requests that checked the status of the challenge and the retrieval
of the certificate were done using a GET.

This is working with letsencrypt and other CA providers, but it might
not work everywhere. RFC 8555 specifies that only the directory and
newNonce resources MUST work with a GET requests, but everything else
must use POST-as-GET.

Must be backported to 3.2.

10 days agoMINOR: log: explicitly ignore "log-steps" on backends
Aurelien DARRAGON [Tue, 22 Jul 2025 08:14:47 +0000 (10:14 +0200)] 
MINOR: log: explicitly ignore "log-steps" on backends

"log-steps" was already ignored if directly defined in a backend section,
however, when defined in a defaults section it was inherited to all
proxies no matter their capability (ie: including backends).

As configurations often contain more backends than frontends, this would
result in wasted memory given that the log-steps setting is only
considered on frontends.

Let's fix that by preventing the inheritance from defaults section to
anything else than frontends. Also adjust the documentation to mention
that the setting in not relevant for backends.

10 days agoBUG/MINOR: h3: fix uninitialized value in h3_req_headers_send()
Amaury Denoyelle [Tue, 22 Jul 2025 07:39:27 +0000 (09:39 +0200)] 
BUG/MINOR: h3: fix uninitialized value in h3_req_headers_send()

Due to the introduction of smallbuf usage for HTTP/3 headers emission,
ret variable may be used uninitialized if buffer allocation fails due to
not enough room in QUIC connection window.

Fix this by setting ret value to 0.

Function variable declaration are also adjusted so that the pattern is
similar to h3_resp_headers_send(). Finally, outbuf buffer is also
removed as it is now unused.

No need to backport.

11 days agoMINOR: h3: add traces to h3_req_headers_send()
Amaury Denoyelle [Fri, 18 Jul 2025 13:52:47 +0000 (15:52 +0200)] 
MINOR: h3: add traces to h3_req_headers_send()

Add traces during HTTP/3 request encoding. This operation is performed
on the backend side.

11 days agoMINOR: h3: use smallbuf for request header emission
Amaury Denoyelle [Wed, 16 Jul 2025 15:32:52 +0000 (17:32 +0200)] 
MINOR: h3: use smallbuf for request header emission

Similarly to HTTP/3 response encoding, a small buffer is first allocated
for the request encoding on the backend side. If this is not sufficient,
the smallbuf is replaced by a standard buffer and encoding is restarted.

This is useful to reduce the window usage over a connection of smaller
requests.

11 days agoMINOR: ssl: Remove ClientHello specific traces if !HAVE_SSL_CLIENT_HELLO_CB
Remi Tricot-Le Breton [Tue, 15 Jul 2025 08:45:11 +0000 (10:45 +0200)] 
MINOR: ssl: Remove ClientHello specific traces if !HAVE_SSL_CLIENT_HELLO_CB

SSL libraries like wolfSSL that don't have the clienthello callback
mechanism enabled do not need to have the traces that are only called
from the said callback.
The code added to parse the ciphers relied on a function that wes not
defined in wolfSSL (SSL_CIPHER_find).

11 days agoMINOR: ssl: Dump ciphers and sigalgs details in trace with 'advanced' verbosity
Remi Tricot-Le Breton [Tue, 15 Jul 2025 08:45:10 +0000 (10:45 +0200)] 
MINOR: ssl: Dump ciphers and sigalgs details in trace with 'advanced' verbosity

The contents of the extensions were only dumped with verbosity
'complete' which meant that the 'advanced' verbosity was pretty much
useless despite what its name implies (it was the same as the 'simple'
one).
The 'advanced' verbosity is now the "maximum" one, using 'complete'
would not add any extra information yet, but it leaves more room for
some actually large traces to be dumped later on (some complete
ClientHello dumps for instance).

11 days agoMINOR: ssl: Add curves in ssl traces
Remi Tricot-Le Breton [Tue, 15 Jul 2025 08:45:09 +0000 (10:45 +0200)] 
MINOR: ssl: Add curves in ssl traces

Dump the ClientHello curves in the SSL traces.

11 days agoMINOR: ssl: Add curve id to curve name table and mapping functions
Remi Tricot-Le Breton [Tue, 15 Jul 2025 08:45:08 +0000 (10:45 +0200)] 
MINOR: ssl: Add curve id to curve name table and mapping functions

The SSL libraries like OpenSSL for instance do not seem to actually
provide a public mapping between IANA defined curve IDs and curve names,
or even a mapping between curve IDs and internal NIDs.
This new table regroups all those information in a single table so that
we can convert curve names (be it SECG or NIST format) to curve IDs or
NIDs.
The previously existing 'curves2nid' function now uses the new table,
and a new 'curveid2str' one is added.

11 days agoMINOR: ssl: Add ciphers in ssl traces
Remi Tricot-Le Breton [Tue, 15 Jul 2025 08:45:07 +0000 (10:45 +0200)] 
MINOR: ssl: Add ciphers in ssl traces

Decode the contents of the ClientHello ciphers extension and dump a
human readable list in the ssl traces.

11 days agoBUG/MINOR: hq-interop: fix FIN transmission
Amaury Denoyelle [Mon, 21 Jul 2025 09:29:34 +0000 (11:29 +0200)] 
BUG/MINOR: hq-interop: fix FIN transmission

Since the following patch, app_ops layer is now responsible to report
that HTX block was the last transmitted so that FIN STREAM can be set.
This is mandatory to properly support HTTP 1xx interim responses.

  f349df44b4e21d8bf9b575a0aa869056a2ebaa58
  MINOR: qmux: change API for snd_buf FIN transmission

This change was correctly implemented in HTTP/3 code, however an issue
appeared on hq-interop transcoder in case zero-copy DATA transfer is
performed when HTX buffer is swapped. If this occured during the
transfer of the last HTX block, EOM is not detected and thus STREAM FIN
is never set.

Most of the times, QMUX shut callback is called immediately after. This
results in an emission of a RESET_STREAM to the client, which prevents
the data transfer.

To fix this, use the same method as HTTP/3 : HTX EOM flag status is
checked before any transfer, thus preserving it even after a zero-copy.

Criticity of this bug is low as hq-interop is experimental and is mostly
used for interop testing.

This should fix github issue #3038.

This patch must be backported wherever the above one is.

11 days agoBUG/MINOR: logs: fix log-steps extra log origins selection
Aurelien DARRAGON [Mon, 21 Jul 2025 13:18:37 +0000 (15:18 +0200)] 
BUG/MINOR: logs: fix log-steps extra log origins selection

Willy noticed that it was not possible to select extra log origins using
log-steps directive. Extra origins are the one registered using
log_orig_register() such as http-req.

Reason was the error path was always executed during extra log origin
matching for log-steps parser, while it should only be executed if no
match was found.

It should be backported to 3.1.

11 days agoBUG/MEDIUM: threads: Disable the workaround to load libgcc_s on macOS
Olivier Houchard [Thu, 17 Jul 2025 17:27:39 +0000 (19:27 +0200)] 
BUG/MEDIUM: threads: Disable the workaround to load libgcc_s on macOS

Don't use the workaround to load libgcc_s on macOS. It is not needed
there, and it causes issues, as recent macOS dislike processes that fork
after threads where created (and the workaround creates a temporary
thread). This fixes crashes on macOS at least when using master-worker,
and using the system resolver.

This should fix Github issue #3035

This should be backported up to 2.8.

11 days agoBUILD: debug: add missed guard USE_CPU_AFFINITY to show cpu bindings
Valentine Krasnobaeva [Mon, 21 Jul 2025 09:07:47 +0000 (11:07 +0200)] 
BUILD: debug: add missed guard USE_CPU_AFFINITY to show cpu bindings

Not all platforms support thread-cpu bindings, so let's put
cpu_topo_dump_summary() under USE_CPU_AFFINITY guards.

Only needs to be backported if 1cc0e023ce ("MINOR: debug: add thread-cpu
bindings info in 'show dev' output") is backported.

2 weeks agoMINOR: quic: Remove pool_head_quic_be_cc_buf pool
Frederic Lecaille [Thu, 17 Jul 2025 17:23:50 +0000 (19:23 +0200)] 
MINOR: quic: Remove pool_head_quic_be_cc_buf pool

This patch impacts the QUIC frontends. It reverts this patch

    MINOR: quic-be: add a "CC connection" backend TX buffer pool

which adds <pool_head_quic_be_cc_buf> new pool to allocate CC (connection closed state)
TX buffers with bigger object size than the one for <pool_head_quic_cc_buf>.
Indeed the QUIC backends must be able to send at least 1200 bytes Initial packets.

For now on, both the QUIC frontends and backend use the same pool with
MAX(QUIC_INITIAL_IPV6_MTU, QUIC_INITIAL_IPV4_MTU)(1252 bytes) as object size.

2 weeks agoMINOR: debug: add thread-cpu bindings info in 'show dev' output
Valentine Krasnobaeva [Thu, 17 Jul 2025 10:05:46 +0000 (12:05 +0200)] 
MINOR: debug: add thread-cpu bindings info in 'show dev' output

Add thread-cpu bindings info in 'show dev' output, as it can be useful for
debugging.

2 weeks agoMINOR: debug: align output style of debug_parse_cli_show_dev with cpu_dump_topology
Valentine Krasnobaeva [Thu, 17 Jul 2025 10:03:47 +0000 (12:03 +0200)] 
MINOR: debug: align output style of debug_parse_cli_show_dev with cpu_dump_topology

Align titles style of debug_parse_cli_show_dev() with
cpu_dump_topology(). We will call the latter inside of
debug_parse_cli_show_dev() to show thread-cpu bindings info.

2 weeks agoMINOR: cpu-topo: write thread-cpu bindings into trash buffer
Valentine Krasnobaeva [Thu, 17 Jul 2025 16:18:20 +0000 (18:18 +0200)] 
MINOR: cpu-topo: write thread-cpu bindings into trash buffer

Write thread-cpu bindings and cluster summary into provided trash buffer.
Like this we can call this function in any place, when this info is needed.

2 weeks agoMINOR: cpu-topo: split cpu_dump_topology() to show its summary in show dev
Valentine Krasnobaeva [Thu, 17 Jul 2025 10:05:33 +0000 (12:05 +0200)] 
MINOR: cpu-topo: split cpu_dump_topology() to show its summary in show dev

cpu_dump_topology() prints details about each enabled CPU and a summary with
clusters info and thread-cpu bindings. The latter is often usefull for
debugging and we want to add it in the 'show dev' output.

So, let's split cpu_dump_topology() in two parts: cpu_topo_debug() to print the
details about each enabled CPU; and cpu_topo_dump_summary() to print only the
summary.

In the next commit we will modify cpu_topo_dump_summary() to write into local
trash buffer and it could be easily called from debug_parse_cli_show_dev().

2 weeks agoBUG/MINOR: halog: exit with error when some output filters are set simultaneosly
Valentine Krasnobaeva [Wed, 16 Jul 2025 12:35:28 +0000 (14:35 +0200)] 
BUG/MINOR: halog: exit with error when some output filters are set simultaneosly

Exit with an error if multiple output filters (-ic, -srv, -st, -tc, -u*, etc.)
are used at the same time.

halog is designed to process and display output for only one filter at a time.
Using multiple filters simultaneously can cause a crash because the program is
not designed to manage multiple, separate result sets (e.g., one for
IP counts, another for URLs).

Supporting simultaneous filters would require a redesign to collect entries for
each filter in separate ebtree. This would negatively impact performance and is
not requested for the moment. This patch prevents the crash by checking filter
combinations just after the command line parsing.

This issue was reported in GitHUB #3031.
This should be backported in all stable versions.

2 weeks agoBUG/MEDIUM: quic-be: CC buffer released from wrong pool
Frederic Lecaille [Thu, 17 Jul 2025 09:27:59 +0000 (11:27 +0200)] 
BUG/MEDIUM: quic-be: CC buffer released from wrong pool

The "connection close state" TX buffer is used to build the datagram with
basically a CONNECTION_CLOSE frame to notify the peer about the connection
closure. It allows the quic_conn memory release and its replacement by a lighter
quic_cc_conn struct.

For the QUIC backend, there is a dedicated pool to build such datagrams from
bigger TX buffers. But from quic_conn_release(), this is the pool dedicated
to the QUIC frontends which was used to release the QUIC backend TX buffers.

This patch simply adds a test about the target of the connection to release
the "connection close state" TX buffers from the correct pool.

No backport needed.

2 weeks agoDOC: connection: explain the rules for idle/safe/avail connections
Willy Tarreau [Wed, 16 Jul 2025 16:52:09 +0000 (18:52 +0200)] 
DOC: connection: explain the rules for idle/safe/avail connections

It's super difficult to find the rules that operate idle conns depending
on their idle/safe/avail/private status. Some are in lists, others not.
Some are in trees, others not. Some have a flag set, others not. This
documents the rules before the definitions in connection-t.h. It could
even be backported to help during backport sessions.

2 weeks agoMINOR: quic: Get rid of qc_is_listener()
Frederic Lecaille [Wed, 16 Jul 2025 14:35:31 +0000 (16:35 +0200)] 
MINOR: quic: Get rid of qc_is_listener()

Replace all calls to qc_is_listener() (resp. !qc_is_listener()) by calls to
objt_listener() (resp. objt_server()).
Remove qc_is_listener() implement and QUIC_FL_CONN_LISTENER the flag it
relied on.

2 weeks agoDEV: gdb: add a memprofile decoder to the debug tools
Willy Tarreau [Wed, 16 Jul 2025 12:42:34 +0000 (14:42 +0200)] 
DEV: gdb: add a memprofile decoder to the debug tools

"memprof_dump" will visit memprofile entries and dump them in a
synthetic format counting allocations/releases count/size, type
and calling address.

2 weeks agoBUG/MINOR: applet: Don't trigger BUG_ON if the tid is not on appctx init
Christopher Faulet [Wed, 16 Jul 2025 09:29:49 +0000 (11:29 +0200)] 
BUG/MINOR: applet: Don't trigger BUG_ON if the tid is not on appctx init

When an appctx is initialized, there is a BUG_ON() to be sure the appctx is
really initialized on the right thread to avoid bugs on the thread
affinity. However, it is possible to not choose the thread when the appctx
is created and let it starts on any thread. In that case, the thread
affinity is set when the appctx is initialized. So, we must take cate to not
trigger the BUG_ON() in that case.

For now, we never hit the bug because the thread affinity is always set
during the appctx creation.

This patch must be backport as far as 2.8.

2 weeks agoMINOR: h3: remove unused outbuf in h3_resp_headers_send()
Amaury Denoyelle [Tue, 15 Jul 2025 16:17:14 +0000 (18:17 +0200)] 
MINOR: h3: remove unused outbuf in h3_resp_headers_send()

Cleanup h3_resp_headers_send() by removing outbuf buffer variable which
is not necessary anymore.

2 weeks agoBUG/MINOR: quic: Wrong source address use on FreeBSD
Frederic Lecaille [Fri, 11 Jul 2025 07:02:22 +0000 (09:02 +0200)] 
BUG/MINOR: quic: Wrong source address use on FreeBSD

The bug is a listener only one, and only occured on FreeBSD.

The FreeBSD issue has been reported here:
https://forums.freebsd.org/threads/quic-http-3-with-haproxy.98443/
where QUIC traces could reveal that sendmsg() calls lead to EINVAL
syscall errnos.

Such a similar issue could be reproduced from a FreeBSD 14-2 VM
with reg-tests/quic/retry.vtc as reg test.

As noted by Olivier, this issue could be fixed within the VM binding
the listener socket to INADDR_ANY.

That said, the symptoms are not exactly the same as the one reporte by the user.
What could be observed from such a VM is that if the first recvmsg() call
returns the datagram destination address, and if the listener
listening address is bound to a specific address, the calls to
sendmsg() fail because of the IP_SENDSRCADDR ip option value
set by cmsg_set_saddr(). According to the ip(4) freebsd manual
such an IP options must be used if the listening socket is
bound to a specific address. It is to be noted that into a VM
the first call to recvmsg() of the first connection does not return the datagram
destination address. This leads the first quic_conn to be initialized without
->local_addr value. This is this value which is used by IP_SENDSRCADDR
ip option. In this case, the sendmsg() calls (without IP_SENDSRCADDR)
never fail. The issue appears at the second condition.

This patch replaces the conditions to use IP_SENDSRCADDR to a call to
qc_may_use_saddr(). This latter also checks that the listener listening
address is not INADDR_ANY to allow the use of the source address.
It is generalized to all the OSes. Indeed, there is no reason to set the source
address when the listener is bound to a specific address.

Must be backported as far as 2.8.

2 weeks agoBUG/MINOR: h3: properly handle interim response on BE side
Amaury Denoyelle [Fri, 11 Jul 2025 14:06:51 +0000 (16:06 +0200)] 
BUG/MINOR: h3: properly handle interim response on BE side

On backend side, H3 layer is responsible to decode a HTTP/3 response
into an HTX message. Multiple responses may be received on a single
stream with interim status codes prior to the final one.

h3_resp_headers_to_htx() is the function used solely on backend side
responsible for H3 response to HTX transcoding. This patch extends it to
be able to properly support interim responses. When such a response is
received, the new flag H3_SF_RECV_INTERIM is set. This is converted to
QMUX qcs flag QC_SF_EOI_SUSPENDED.

The objective of this latter flag is to prevent stream EOI to be
reported during stream rcv_buf callback, even if HTX message contains
EOM and is empty. QC_SF_EOI_SUSPENDED will be cleared when the final
response is finally converted, which unblock stream EOI notification for
next rcv_buf invocations. Note however that HTX EOM is untouched : it is
always set for both interim and final response reception.

As a minor adjustment, HTX_SL_F_BODYLESS is always set for interim
responses.

Contrary to frontend interim response handling, a flag is necessary on
QMUX layer. This is because H3 to HTX transcoding and rcv_buf callback
are two distinct operations, called under different context (MUX vs
stream tasklet).

Also note that H3 layer has two distinct flags for interim response
handling, one only used as a server (FE side) and the other as a client
(BE side). It was preferred to used two distinct flags which is
considered less error-prone, contrary to a single unified flag which
would require to always set the proxy side to ensure it is relevant or
not.

No need to backport.

2 weeks agoBUG/MEDIUM: h3: handle interim response properly on FE side
Amaury Denoyelle [Fri, 11 Jul 2025 12:25:30 +0000 (14:25 +0200)] 
BUG/MEDIUM: h3: handle interim response properly on FE side

On frontend side, HTTP/3 layer is responsible to transcode an HTX
response message into HTTP/3 HEADERS frame. This operations is handled
via h3_resp_headers_send().

Prior to this patch, if HTX EOM was encountered in the HTX message after
response transcoding, <fin> was reported to the QMUX layer. This will in
turn cause FIN stream bit to be set when the response is emitted.
However, this is not correct as a single HTX response can be constitued
of several interim message, each delimited by EOM block.

Most of the time, this bug will cause the client to close the connection
as it is invalid to receive an interim response with FIN bit set.

Fixes this by now properly differentiate interim and final response.
During interim response transcoding, the new flag H3_SF_SENT_INTERIM
will be set, which will prevent <fin> to be reported. Thus, <fin> will
only be notified for the final response.

This must be backported up to 2.6. Note that it relies on the previous
patch which also must be taken.

2 weeks agoMINOR: qmux: change API for snd_buf FIN transmission
Amaury Denoyelle [Thu, 10 Jul 2025 13:27:23 +0000 (15:27 +0200)] 
MINOR: qmux: change API for snd_buf FIN transmission

Previous patches have fixes interim response encoding via
h3_resp_headers_send(). However, it is still necessary to adjust h3
layer state-machine so that several successive HTTP responses are
accepted for a single stream.

Prior to this, QMUX was responsible to decree that the final HTX message
was encoded so that FIN stream can be emitted. However, with interim
response, MUX is in fact unable to properly determine this. As such,
this is the responsibility of the application protocol layer. To reflect
this, app_ops snd_buf callback is modified so that a new output argument
<fin> is added to it.

Note that for now this commit does not bring any functional change.
However, it will be necessary for the following patch. As such, it
should be backported prior to it to every versions as necessary.