]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 weeks agoMEDIUM: sched: do not run a same task multiple times in series
Willy Tarreau [Sat, 21 Mar 2026 14:47:09 +0000 (14:47 +0000)] 
MEDIUM: sched: do not run a same task multiple times in series

There's always a risk that some tasks run multiple times if they wake
each other up. Now we include the loop counter in the task struct and
stop processing the queue it's in when meeting a task that has already
run. We only pick 16 bits since that's only what remains free in the
task common part, so from time to time (once every 65536) it will be
possible to wrongly match a task as having already run and stop evaluating
its queue, but it's rare enough that we don't care, because this will
be OK on the next iteration.

2 weeks agoBUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding
Frederic Lecaille [Fri, 20 Mar 2026 18:30:35 +0000 (19:30 +0100)] 
BUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding

This patch improves the robustness of the QPACK varint decoder and fixes
potential 1-byte out-of-bounds reads in qpack_decode_fs().

In qpack_decode_fs(), two 1-byte OOB reads were possible on truncated
streams between two varint decoding. These occurred when trying to read
the byte containing the Huffman bit <h> and the Value Length prefix
immediately following an Index or a Name Length.

Note that these OOB are limited to a single byte because
qpack_get_varint() already ensures that its input length is non-zero
before consuming any data.

The fixes in qpack_decode_fs() are:
- When decoding an index, we now verify that at least one byte remains
  to safely access the following <h> bit and value length.
- When decoding a literal, we now check len < name_len + 1 to ensure
  the byte starting the header value is reachable.

In qpack_get_varint(), the maximum value is now strictly capped at 2^62-1
as per RFC. This is enforced using a budget-based check:

   (v & 127) > (limit - ret) >> shift

This prevents values from  overflowing into the 63rd or 64th bits, which
would otherwise break subsequent signed comparisons (e.g., if (len < name_len))
by interpreting the length as a negative value, leading to false positive
tests.

Thank you to @jming912 for having reported this issue in GH #3302.

Must be backported as far as 2.6

3 weeks agoBUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM
Egor Shestakov [Wed, 25 Feb 2026 16:52:33 +0000 (16:52 +0000)] 
BUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM

In the ENFILE and ENOMEM cases, when accept() fails, an irrelevant
global.maxsock value was printed that doesn't reflect system limits.
Now the actconn is printed that gives a hint about the failure reasons.

Should be backported in all stable branches.

3 weeks agoMINOR: log: support optional 'profile <log_profile_name>' argument to do-log action
Aurelien DARRAGON [Thu, 19 Mar 2026 11:43:00 +0000 (12:43 +0100)] 
MINOR: log: support optional 'profile <log_profile_name>' argument to do-log action

We anticipated that the do-log action should be expanded with optional
arguments at some point. Now that we heard of multiple use-cases
that could be achieved with do-log action, but that are limitated by the
fact that all do-log statements inherit from the implicit log-profile
defined on the logger, we need to provide a way for the user to specify
that custom log-profile that could be used per do-log actions individually

This is what we try to achieve in this commit, by leveraging the
prerequisite work performed by the last 2 commits.

3 weeks agoMINOR: log: provide a way to override logger->profile from process_send_log_ctx
Aurelien DARRAGON [Thu, 19 Mar 2026 11:53:43 +0000 (12:53 +0100)] 
MINOR: log: provide a way to override logger->profile from process_send_log_ctx

In process_send_log(), now also consider the ctx if ctx->profile != NULL

In that case, we do as if logger->prof was set, but we consider
ctx->profile in priority over the logger one. What this means is that
it will become possible to pass ctx.profile to a profile that will be
used no matter what to generate the log payload.

This is a pre-requisite to implement optional "profile" argument for
do-log action

3 weeks agoMINOR: log: split do_log() in do_log() + do_log_ctx()
Aurelien DARRAGON [Thu, 19 Mar 2026 11:54:23 +0000 (12:54 +0100)] 
MINOR: log: split do_log() in do_log() + do_log_ctx()

do_log() is just a wrapper to use do_log_ctx() with pre-filled ctx, but
we now have the low-level do_log_ctx() variant which can be used to
pass specific ctx parameters instead.

3 weeks ago[RELEASE] Released version 3.4-dev7 v3.4-dev7
Willy Tarreau [Fri, 20 Mar 2026 09:14:59 +0000 (10:14 +0100)] 
[RELEASE] Released version 3.4-dev7

Released version 3.4-dev7 with the following main changes :
    - BUG/MINOR: stconn: Increase SC bytes_out value in se_done_ff()
    - BUG/MINOR: ssl-sample: Fix sample_conv_sha2() by checking EVP_Digest* failures
    - BUG/MINOR: backend: Don't get proto to use for webscoket if there is no server
    - BUG/MINOR: jwt: Missing 'jwt_tokenize' return value check
    - MINOR: flt_http_comp: define and use proxy_get_comp() helper function
    - MEDIUM: flt_http_comp: split "compression" filter in 2 distinct filters
    - CLEANUP: flt_http_comp: comp_state doesn't bother about the direction anymore
    - BUG/MINOR: admin: haproxy-reload use explicit socat address type
    - MEDIUM: admin: haproxy-reload conversion to POSIX sh
    - BUG/MINOR: admin: haproxy-reload rename -vv long option
    - SCRIPTS: git-show-backports: hide the common ancestor warning in quiet mode
    - SCRIPTS: git-show-backports: add a restart-from-last option
    - MINOR: mworker: add a BUG_ON() on mproxy_li in _send_status
    - BUG/MINOR: mworker: don't set the PROC_O_LEAVING flag on master process
    - Revert "BUG/MINOR: jwt: Missing 'jwt_tokenize' return value check"
    - MINOR: jwt: Improve 'jwt_tokenize' function
    - MINOR: jwt: Convert EC JWK to EVP_PKEY
    - MINOR: jwt: Parse ec-specific fields in jose header
    - MINOR: jwt: Manage ECDH-ES algorithm in jwt_decrypt_jwk function
    - MINOR: jwt: Add ecdh-es+axxxkw support in jwt_decrypt_jwk converter
    - MINOR: jwt: Manage ec certificates in jwt_decrypt_cert
    - DOC: jwt: Add ECDH support in jwt_decrypt converters
    - MINOR: stconn: Call sc_conn_process from the I/O callback if TASK_WOKEN_MSG state was set
    - MINOR: mux-h2: Rely on h2s_notify_send() when resuming h2s for sending
    - MINOR: mux-spop: Rely on spop_strm_notify_send() when resuming streams for sending
    - MINOR: muxes: Wakup the data layer from a mux stream with TASK_WOKEN_IO state
    - MAJOR: muxes: No longer use app_ops .wake() callback function from muxes
    - MINOR: applet: Call sc_applet_process() instead of .wake() callback function
    - MINOR: connection: Call sc_conn_process() instead of .wake() callback function
    - MEDIUM: stconn: Remove .wake() callback function from app_ops
    - MINOR: check: Remove wake_srv_chk() function
    - MINOR: haterm: Remove hstream_wake() function
    - MINOR: stconn: Wakup the SC with TASK_WOKEN_IO state from opposite side
    - MEDIUM: stconn: Merge all .chk_rcv() callback functions in sc_chk_rcv()
    - MINOR: stconn: Remove .chk_rcv() callback functions
    - MEDIUM: stconn: Merge all .chk_snd() callback functions in sc_chk_snd()
    - MINOR: stconn: Remove .chk_snd() callback functions
    - MEDIUM: stconn: Merge all .abort() callback functions in sc_abort()
    - MINOR: stconn: Remove .abort() callback functions
    - MEDIUM: stconn: Merge all .shutdown() callback functions in sc_shutdown()
    - MINOR: stconn: Remove .shutdown() callback functions
    - MINOR: stconn: Totally app_ops from the stconns
    - MINOR: stconn: Simplify sc_abort/sc_shutdown by merging calls to se_shutdown
    - DEBUG: stconn: Add a CHECK_IF() when I/O are performed on a orphan SC
    - MEDIUM: mworker: exiting when couldn't find the master mworker_proc element
    - BUILD: ssl: use ASN1_STRING accessors for OpenSSL 4.0 compatibility
    - BUILD: ssl: make X509_NAME usage OpenSSL 4.0 ready
    - BUG/MINOR: tcpcheck: Fix typo in error error message for `http-check expect`
    - BUG/MINOR: jws: fix memory leak in jws_b64_signature
    - DOC: configuration: http-check expect example typo
    - DOC/CLEANUP: config: update mentions of the old "Global parameters" section
    - BUG/MEDIUM: ssl: Handle receiving early data with BoringSSL/AWS-LC
    - BUG/MINOR: mworker: always stop the receiving listener
    - BUG/MEDIUM: ssl: Don't report read data as early data with AWS-LC
    - BUILD: makefile: fix range build without test command
    - BUG/MINOR: memprof: avoid a small memory leak in "show profiling"
    - BUG/MINOR: proxy: do not forget to validate quic-initial rules
    - MINOR: activity: use dynamic allocation for "show profiling" entries
    - MINOR: tools: extend the pointer hashing code to ease manipulations
    - MINOR: tools: add a new pointer hash function that also takes an argument
    - MINOR: memprof: attempt different retry slots for different hashes on collision
    - MINOR: tinfo: start to add basic thread_exec_ctx
    - MINOR: memprof: prepare to consider exec_ctx in reporting
    - MINOR: memprof: also permit to sort output by calling context
    - MINOR: tools: add a function to write a thread execution context.
    - MINOR: debug: report the execution context on thread dumps
    - MINOR: memprof: report the execution context on profiling output
    - MINOR: initcall: record the file and line declaration of an INITCALL
    - MINOR: tools: decode execution context TH_EX_CTX_INITCALL
    - MINOR: tools: support decoding ha_caller type exec context
    - MINOR: sample: store location for fetch/conv via initcalls
    - MINOR: sample: also report contexts registered directly
    - MINOR: tools: support an execution context that is just a function
    - MINOR: actions: store the location of keywords registered via initcalls
    - MINOR: actions: also report execution contexts registered directly
    - MINOR: filters: set the exec context to the current filter config
    - MINOR: ssl: set the thread execution context during message callbacks
    - MINOR: connection: track mux calls to report their allocation context
    - MINOR: task: set execution context on task/tasklet calls
    - MINOR: applet: set execution context on applet calls
    - MINOR: cli: keep the info of the current keyword being processed in the appctx
    - MINOR: cli: keep track of the initcall context since kw registration
    - MINOR: cli: implement execution context for manually registered keywords
    - MINOR: activity: support aggregating by caller also for memprofile
    - MINOR: activity: raise the default number of memprofile buckets to 4k
    - DOC: internals: short explanation on how thread_exec_ctx works
    - BUG/MINOR: mworker: only match worker processes when looking for unspawned proc
    - MINOR: traces: defer processing of "-dt" options
    - BUG/MINOR: mworker: fix typo &= instead of & in proc list serialization
    - BUG/MINOR: mworker: set a timeout on the worker socketpair read at startup
    - BUG/MINOR: mworker: avoid passing NULL version in proc list serialization
    - BUG/MINOR: sockpair: set FD_CLOEXEC on fd received via SCM_RIGHTS
    - BUG/MEDIUM: stconn: Don't forget to wakeup applets on shutdown
    - BUG/MINOR: spoe: Properly switch SPOE filter to WAITING_ACK state
    - BUG/MEDIUM: spoe: Properly abort processing on client abort
    - BUG/MEDIUM: stconn: Fix abort on close when a large buffer is used
    - BUG/MEDIUM: stconn: Don't perform L7 retries with large buffer
    - BUG/MINOR: h2/h3: Only test number of trailers inserted in HTX message
    - MINOR: htx: Add function to truncate all blocks after a specific block
    - BUG/MINOR: h2/h3: Never insert partial headers/trailers in an HTX message
    - BUG/MINOR: http-ana: Swap L7 buffer with request buffer by hand
    - BUG/MINOR: stream: Fix crash in stream dump if the current rule has no keyword
    - BUG/MINOR: mjson: make mystrtod() length-aware to prevent out-of-bounds reads
    - MEDIUM: stats-file/clock: automatically update now_offset based on shared clock
    - MINOR: promex: export "haproxy_sticktable_local_updates" metric
    - BUG/MINOR: spoe: Fix condition to abort processing on client abort
    - BUILD: spoe: Remove unsused variable
    - MINOR: tools: add a function to create a tar file header
    - MINOR: tools: add a function to load a file into a tar archive
    - MINOR: config: support explicit "on" and "off" for "set-dumpable"
    - MINOR: debug: read all libs in memory when set-dumpable=libs
    - DEV: gdb: add a new utility to extract libs from a core dump: libs-from-core
    - MINOR: debug: copy debug symbols from /usr/lib/debug when present
    - MINOR: debug: opportunistically load libthread_db.so.1 with set-dumpable=libs
    - BUG/MINOR: mworker: don't try to access an initializing process
    - BUG/MEDIUM: peers: enforce check on incoming table key type
    - BUG/MINOR: mux-h2: properly ignore R bit in GOAWAY stream ID
    - BUG/MINOR: mux-h2: properly ignore R bit in WINDOW_UPDATE increments
    - OPTIM: haterm: use chunk builders for generated response headers
    - BUG/MAJOR: h3: check body size with content-length on empty FIN
    - BUG/MEDIUM: h3: reject unaligned frames except DATA
    - BUG/MINOR: mworker/cli: fix show proc pagination losing entries on resume
    - CI: github: treat vX.Y.Z release tags as stable like haproxy-* branches
    - MINOR: freq_ctr: add a function to add values with a peak
    - MINOR: task: maintain a per-thread indicator of the peak run-queue size
    - MINOR: mux-h2: store the concurrent streams hard limit in the h2c
    - MINOR: mux-h2: permit to moderate the advertised streams limit depending on load
    - MINOR: mux-h2: permit to fix a minimum value for the advertised streams limit
    - BUG/MINOR: mworker: fix sort order of mworker_proc in 'show proc'
    - CLEANUP: mworker: fix tab/space mess in mworker_env_to_proc_list()

3 weeks agoCLEANUP: mworker: fix tab/space mess in mworker_env_to_proc_list()
William Lallemand [Thu, 19 Mar 2026 17:01:06 +0000 (18:01 +0100)] 
CLEANUP: mworker: fix tab/space mess in mworker_env_to_proc_list()

The previous patch messed up with the indentation in
mworker_env_to_proc_list()

3 weeks agoBUG/MINOR: mworker: fix sort order of mworker_proc in 'show proc'
William Lallemand [Thu, 19 Mar 2026 15:59:23 +0000 (16:59 +0100)] 
BUG/MINOR: mworker: fix sort order of mworker_proc in 'show proc'

Since version 3.1, the display order of old workers in 'show proc' was
accidentally reversed. The oldest worker was shown first and the newest
last, which was not the intended behavior. This regression was introduced
during the master-worker rework.

Fix this by sorting the list during deserialization in
mworker_env_to_proc_list().

An alternative fix would have been to iterate the list in reverse order
in the show proc function, but that approach risks introducing
inconsistencies when backporting to older versions.

Must be backported to 3.1 and later.

3 weeks agoMINOR: mux-h2: permit to fix a minimum value for the advertised streams limit
Willy Tarreau [Thu, 19 Mar 2026 15:00:05 +0000 (16:00 +0100)] 
MINOR: mux-h2: permit to fix a minimum value for the advertised streams limit

When using rq-load on tune.h2.fe.max-concurrent-streams, it's easy to
reach a situation where only one stream is allowed. There's nothing
wrong with this but it turns out that slightly higher values do not
necessarily cause significantly higher loads and will improve the user
experience. For this reason the keyword now also supports "min" to
specify a value. Experimentation shows that values from 5 to 15 remain
very effective at protecting the run queue while allowing a great level
of parallelism that keeps a site fluid.

3 weeks agoMINOR: mux-h2: permit to moderate the advertised streams limit depending on load
Willy Tarreau [Wed, 18 Mar 2026 21:32:05 +0000 (22:32 +0100)] 
MINOR: mux-h2: permit to moderate the advertised streams limit depending on load

Global setting tune.h2.fe.max-concurrent-streams now supports an optional
"rq-load" option to pass either a target load, or a keyword among "auto"
and "ignore". These are used to quadratically reduce the advertised streams
limit when the thread's run queue size goes beyong the configured value,
and automatically reduce the load on the process from new connections.
With "auto", instead of taking an explicit value, it uses as a target the
"tune.runqueue-depth" setting (which might be automatic). Tests have shown
that values between 50 and 100 are already very effective at reducing the
loads during attacks from 100000 to around 1500. By default, "ignore"
is in effect, which means that the dynamic tuning is not enabled.

3 weeks agoMINOR: mux-h2: store the concurrent streams hard limit in the h2c
Willy Tarreau [Thu, 19 Mar 2026 07:16:30 +0000 (08:16 +0100)] 
MINOR: mux-h2: store the concurrent streams hard limit in the h2c

The hard limit on the number of concurrent streams is currently
determined only by configuration and returned by
h2c_max_concurrent_streams(). However this doesn't permit to
change such settings on the fly without risking to break connections,
and it doesn't allow a connection to pick a different value, which
could be desirable for example to try to slow abuse down.

Let's store a copy of h2c_max_concurrent_streams() at connection
creation time into the h2c as streams_hard_limit. This inflates
the h2c size from 1324 to 1328 (0.3%) which is acceptable for the
expected benefits.

3 weeks agoMINOR: task: maintain a per-thread indicator of the peak run-queue size
Willy Tarreau [Thu, 19 Mar 2026 14:18:32 +0000 (15:18 +0100)] 
MINOR: task: maintain a per-thread indicator of the peak run-queue size

The new field th_ctx->rq_tot_peak contains the computed peak run queue
length averaged over the last 512 calls. This is computed when entering
process_runnable_tasks. It will not take into account new tasks that are
created or woken up during this round nor those which are evicted, which
is the reason why we're using a peak measurement to increase chances to
observe transient high values. Tests have shown that 512 samples are good
to provide a relatively smooth average measurement while still fading
away in a matter of milliseconds at high loads. Since this value is
only updated once per round, it cannot be used as a statistic and
shouldn't be exposed, it's only for internal use (self-regulation).

3 weeks agoMINOR: freq_ctr: add a function to add values with a peak
Willy Tarreau [Thu, 19 Mar 2026 14:08:29 +0000 (15:08 +0100)] 
MINOR: freq_ctr: add a function to add values with a peak

Sometimes it's desirable to observe fading away peak values, where a new
value that is higher than the historical one instantly replaces it,
otherwise contributes to it. It is convenient when trying to observe
certain phenomenons like peak queue sizes. The new function
swrate_add_peak_local() does that to a private variable (no atomic ops
involved as it's not worth the cost since such use cases are typically
local).

3 weeks agoCI: github: treat vX.Y.Z release tags as stable like haproxy-* branches
William Lallemand [Thu, 19 Mar 2026 14:55:58 +0000 (15:55 +0100)] 
CI: github: treat vX.Y.Z release tags as stable like haproxy-* branches

Add detection of release tags matching the vX.Y.Z pattern so they use
the same stable CI configuration as haproxy-* branches, rather than the
development one.

It prevents stable tag to trigger the CI with docker images and SSL
libraries only used for development.

Must be backported in stable releases.

3 weeks agoBUG/MINOR: mworker/cli: fix show proc pagination losing entries on resume
Alexander Stephan [Thu, 19 Feb 2026 11:31:45 +0000 (11:31 +0000)] 
BUG/MINOR: mworker/cli: fix show proc pagination losing entries on resume

After commit 594408cd612b5 ("BUG/MINOR: mworker/cli: fix show proc
pagination using reload counter"), the old-workers pagination stores
ctx->next_reload = child->reloads on flush failure, then skips entries
with child->reloads >= ctx->next_reload on resume.

The >= comparison is direction-dependent: it assumes the list is in
descending reload order (newest first). On current master, proc_list
is in ascending order (oldest first) because mworker_env_to_proc_list()
appends deserialized entries before mworker_prepare_master() appends
the new worker. This means the skip logic is inverted and can miss
entries or loop incorrectly depending on the version.

We fix this by renaming the context field to resume_reload and changing its
semantics: it now tracks the reload count of the last *successfully
flushed* row rather than the failed one. On flush failure, resume_reload
is left unchanged so the failed row is replayed on the next call. On
resume, entries are skipped by walking the list until the marker entry is
found (exact == match), which works regardless of list direction.

Additionally, we have to handle the unlikely case where the marker entry
is deleted from proc_list between handler calls (e.g. the process exits and
SIGCHLD processing removes it). Detect this by tracking the previous
LEAVING entry's reload count during the skip phase: if two consecutive
entries straddle the skip value (one > skip, the other < skip), the
deleted entry's former position has been crossed, so skipping stops and
the current entry is emitted.

This should be backported to all stable branches. On branches where
proc_list is in descending order (2.9, 3.0), the fix applies the
same way since the skip logic is now direction-agnostic.

3 weeks agoBUG/MEDIUM: h3: reject unaligned frames except DATA
Amaury Denoyelle [Tue, 17 Mar 2026 16:33:00 +0000 (17:33 +0100)] 
BUG/MEDIUM: h3: reject unaligned frames except DATA

HTTP/3 parser cannot deal with unaligned frames, except for DATA. As it
was expected that such case would not occur, a simple BUG_ON() was
written to protect HEADERS parsing.

First, this BUG_ON() was incorrectly written due an incorrect operator
'>=' vs '>' when checking if data wraps. Thus this patch correct it.

However this correction is not sufficient as it still possible to handle
a large unaligned HEADERS frame, which would trigger this BUG_ON(). This
is very unlikely as HEADERS is the first received frame on a request
stream, but not completely impossible. As HTTP/3 frame header (type +
length) is parsed first and removed, this leaves a small gap at the
buffer beginning. If this small gap is then filled with the remaining
frame payload, it would result in unaligned data. Also, trailers are
also sensitive here as in this case a HEADERS frame is handled after
other frames.

The objective of this patch is to ensure that an unaligned frame is now
handled in a safe way. This is extend to all HTTP/3 frames (except DATA)
and not only to HEADERS type. Parsing is interrupted if frame payload is
wrapping in the buffer. This should never happen except maybe with some
weird clients, so the connection is closed with H3_EXCESSIVE_LOAD error.

This approach is considered the safest one, in particular for backport
purpose. In the future, realign operation via copy may be implemented
instead if considered as useful.

This must be backported up to 2.6.

3 weeks agoBUG/MAJOR: h3: check body size with content-length on empty FIN
Amaury Denoyelle [Wed, 18 Mar 2026 08:24:32 +0000 (09:24 +0100)] 
BUG/MAJOR: h3: check body size with content-length on empty FIN

In QUIC, a STREAM frame may be received with no data but with FIN bit
set. This situation is tedious to handle and haproxy parsing code has
changed several times to deal with this situation. Now, H3 and H09
layers parsing code are skipped in favor of the shared function
qcs_http_handle_standalone_fin() used to handle the HTX EOM emission.

However, this shortcut bypasses an important HTTP/3 validation check on
the received body size vs the announced content-length header. Under
some conditions, this could cause a desynchronization with the backend
server which could be exploited for request smuggling.

Fix HTTP/3 parsing code by adding a call to h3_check_body_size() prior
to qcs_http_handle_standalone_fin() if content-length header has been
found. If the body size is incorrect, the stream is immediately resetted
with H3_MESSAGE_ERROR code and the error is forwarded to the stream
layer.

Thanks to Martino Spagnuolo for his detailed report on this issue and
for having contacting us about it via the security mailing list.

This must be backported up to 2.6.

3 weeks agoOPTIM: haterm: use chunk builders for generated response headers
Aleksandar Lazic [Sun, 15 Mar 2026 13:37:57 +0000 (14:37 +0100)] 
OPTIM: haterm: use chunk builders for generated response headers

hstream_build_http_resp() currently uses snprintf() to build the
status code and the generated X-req/X-rsp header values.

These strings are short and are fully derived from already parsed request
state, so they can be assembled directly in the HAProxy trash buffer using
`chunk_strcat()` and `ultoa_o()`.

This keeps the generated output unchanged while removing the remaining
`snprintf()` calls from the response-building path.

No functional change is expected.

Signed-off-by: Aleksandar Lazic <al-haproxy@none.at>
3 weeks agoBUG/MINOR: mux-h2: properly ignore R bit in WINDOW_UPDATE increments
Willy Tarreau [Thu, 19 Mar 2026 06:21:47 +0000 (07:21 +0100)] 
BUG/MINOR: mux-h2: properly ignore R bit in WINDOW_UPDATE increments

The window size increments are 31 bits and the topmost bit is reserved
and should be ignored, however it was not masked, so a peer sending it
set would emit a negative value which could actually reduce the current
window instead of increasing it. Note that the window cannot reach zero
as there's already a test for this, but transfers could slow down to
the same speed as if an initial window of just a few bytes had been
advertised. Let's just mask the reserved bit before processing.

This should be backported to all stable versions.

3 weeks agoBUG/MINOR: mux-h2: properly ignore R bit in GOAWAY stream ID
Willy Tarreau [Thu, 19 Mar 2026 06:11:54 +0000 (07:11 +0100)] 
BUG/MINOR: mux-h2: properly ignore R bit in GOAWAY stream ID

The stream ID indicated in GOAWAY frames must have its bit 31 (R) ignored
and this wasn't the case. The effect is that if this bit was present, the
GOAWAY frame would mark the last acceptable stream as negative, which is
the default situation (unlimited), thus would basically result in this
GOAWAY frame to be ignored since it would replace a negative last_sid
with another negative one. The impact is thus basically that if a peer
would emit anything non-zero in the R bit, the GOAWAY frame would be
ignored and new streams would still be initiated on the backend, before
being rejected by the server.

Thanks to Haruto Kimura (Stella) for finding and reporting this bug.

This fix needs to be backported to all stable versions.

3 weeks agoBUG/MEDIUM: peers: enforce check on incoming table key type
Willy Tarreau [Thu, 19 Mar 2026 05:58:14 +0000 (06:58 +0100)] 
BUG/MEDIUM: peers: enforce check on incoming table key type

The key type received over the peers protocol is not checked for
validity and as a result can crash the process when passed through
peer_int_key_type[] in peer_treat_definemsg(). The risk remains
very low since only trusted peers may exchange tables, however it
represents a risk the day haproxy supports new key types, because
mixing old and new versions could then cause the old ones to crash.
Let's add the required check in peer_treat_definemsg().

It is also worth noting that in this function a few protocol identifiers
of type int read directly from a var_int via intdecode() and that some
protocol aliasing may occur (e.g. table_id, table_id_len etc). This is
not supposed to be a problem but it could hide implementation bugs and
cause interoperability issues once fixed, so these should be addressed
in a future commit that will not be marked for backporting.

Thanks to Haruto Kimura (Stella) for finding and reporting this bug.

This fix needs to be backported to all stable versions.

3 weeks agoBUG/MINOR: mworker: don't try to access an initializing process
William Lallemand [Wed, 18 Mar 2026 15:53:43 +0000 (16:53 +0100)] 
BUG/MINOR: mworker: don't try to access an initializing process

In pcli_prefix_to_pid(), when resolving a worker by absolute pid
(@!<pid>) or by relative pid (@1), a worker that still has PROC_O_INIT
set (i.e. not yet ready, still initializing) could be returned as a
valid target.

During a reload, if a client connects to the master CLI and sends a
command targeting a worker (e.g. @@1 or @@!<pid>), the master resolves
the target pid and attempts to forward the command by transferring a fd
over the worker's sockpair. If the worker is still initializing and has
not yet sent its READY signal, its end of the sockpair is not usable,
causing send_fd_uxst() to fail with EPIPE. This results in the
following alert being repeated in a loop:

  [ALERT] (550032) : socketpair: Cannot transfer the fd 13 over sockpair@5. Giving up.

The situation is even worse if the initializing worker has already
exited (e.g. due to a bind failure) but has not yet been removed from
the process list: in that case the sockpair's remote end is already
closed, making the failure immediate and unrecoverable until the dead
worker is cleaned up.

This was not possible before 3.1 because the master's polling loop only
started once all workers were fully ready, making it impossible to
receive CLI connections while a worker was still initializing.

Fix this by skipping workers with PROC_O_INIT set in both the absolute
and relative pid resolution paths of pcli_prefix_to_pid(), so that
only fully initialized workers can be targeted.

Must be backported to 3.1 and later.

3 weeks agoMINOR: debug: opportunistically load libthread_db.so.1 with set-dumpable=libs
Willy Tarreau [Wed, 18 Mar 2026 10:17:22 +0000 (11:17 +0100)] 
MINOR: debug: opportunistically load libthread_db.so.1 with set-dumpable=libs

When loading libs into the core dump, let's also try to load
libthread_db.so.1 that gdb usually requires. It can significantly help
decoding the threads for systems which require it, and the file is quite
small. It can appear at a few different locations and is generally next
to libpthread.so, or alternately libc, so we first look where we found
them, and fall back to a few other common places. The file is really
small, a few tens of kB usually.

3 weeks agoMINOR: debug: copy debug symbols from /usr/lib/debug when present
Willy Tarreau [Wed, 18 Mar 2026 12:39:23 +0000 (13:39 +0100)] 
MINOR: debug: copy debug symbols from /usr/lib/debug when present

When set-dumpable=libs, let's also pick the debug symbols for the libs
we're loading. For now we only try /usr/lib/debug/<path>, which is quite
common and easy to guess. Build IDs could also be used but are more
complex to deal with, so let's stay simple for now.

3 weeks agoDEV: gdb: add a new utility to extract libs from a core dump: libs-from-core
Willy Tarreau [Wed, 18 Mar 2026 13:40:13 +0000 (14:40 +0100)] 
DEV: gdb: add a new utility to extract libs from a core dump: libs-from-core

This utility takes in argument the path to a core dump, and it looks
for the archive signature of libraries embedded with "set-dumpable libs",
and either emits the offset and size of stdout, or directly dumps the
contents so that the tar file can be extracted directly by piping the
output to tar xf.

3 weeks agoMINOR: debug: read all libs in memory when set-dumpable=libs
Willy Tarreau [Wed, 18 Mar 2026 09:47:16 +0000 (10:47 +0100)] 
MINOR: debug: read all libs in memory when set-dumpable=libs

When "set-dumpable" is set to "libs", in addition to marking the process
dumpable, haproxy also reads the binary and shared objects into memory as
a tar archive in a page-aligned location so that these files are easily
extractable from a future core dump. The goal here is to always have
access to the exact same binary and libs as those which caused the core
to happen. It's indeed very frequent to miss some of these, or to get
mismatching files due to a local update that didn't experience a reload,
or to get those of a host system instead of the container.

The in-memory tar file presents everything under a directory called
"core-%d" where %d corresponds to the PID of the worker process. In
order to ease the finding of these data in the core dump, the memory
area is contiguous and surrounded by PROT_NONE pages so that it appears
in its own segment in the core file. The total size used by this is a
few tens of MB, which is not a problem on large systems.

3 weeks agoMINOR: config: support explicit "on" and "off" for "set-dumpable"
Willy Tarreau [Wed, 18 Mar 2026 09:39:30 +0000 (10:39 +0100)] 
MINOR: config: support explicit "on" and "off" for "set-dumpable"

The global "set-dumpable" keyword currently is only positional. Let's
extend its syntax to support arguments. For now we support both "on"
and "off" to explicitly enable or disable it.

3 weeks agoMINOR: tools: add a function to load a file into a tar archive
Willy Tarreau [Wed, 18 Mar 2026 09:28:16 +0000 (10:28 +0100)] 
MINOR: tools: add a function to load a file into a tar archive

New function load_file_into_tar() concatenates a file into an in-memory
tar archive and grows its size. Only the base name and a provided prefix
are used to name the faile. If the file cannot be loaded, it's added as
size zero and permissions 0 to show that it failed to load. This will
be used to load post-mortem information so it needs to remain simple.

3 weeks agoMINOR: tools: add a function to create a tar file header
Willy Tarreau [Wed, 18 Mar 2026 07:24:43 +0000 (08:24 +0100)] 
MINOR: tools: add a function to create a tar file header

The purpose here is to create a tar file header in memory from a known
file name, prefix, size and mode. It will be used to prepare archives
of libs in use for improved debugging, but may probably be useful for
other purposes due to its simplicity.

3 weeks agoBUILD: spoe: Remove unsused variable
Christopher Faulet [Wed, 18 Mar 2026 10:26:46 +0000 (11:26 +0100)] 
BUILD: spoe: Remove unsused variable

Since 7a1382da7 ("BUG/MINOR: spoe: Fix condition to abort processing on
client abort"), the chn variable is no longer used in
spoe_process_event(). Let's remove it

This patch must be backported with the commit above, as far as 3.1.

3 weeks agoBUG/MINOR: spoe: Fix condition to abort processing on client abort
Christopher Faulet [Wed, 18 Mar 2026 09:53:13 +0000 (10:53 +0100)] 
BUG/MINOR: spoe: Fix condition to abort processing on client abort

The test to detect client aborts in the SPOE, introduced by commit b3be3b94a
("BUG/MEDIUM: spoe: Properly abort processing on client abort"), was no
correct. Producer flags must not be tested. Only the frontend SC must be
tested when the abortonclose option is set.

Because of this bug, when a client aborted, the SPOE processing was aborted
too, regardless the abortonclose option.

This patch must be backpoeted with the commit above, so as far as 3.1.

3 weeks agoMINOR: promex: export "haproxy_sticktable_local_updates" metric
Aurelien DARRAGON [Wed, 18 Mar 2026 10:08:25 +0000 (11:08 +0100)] 
MINOR: promex: export "haproxy_sticktable_local_updates" metric

haproxy_sticktable_local_updates corresponds to the table->localupdate
counter, which is used internally by the peers protocol to identify
update messages in order to send and ack them among peers.

Here we decide to expose this information, as it is already the case in
"show peers" output, because it turns out that this value, which is
cumulative and grows in sync with the number of updates triggered on the
table due to changes initiated by the current process, can be used to
compute the update rate of the table. Computing the update rate of the
table (from the process point of view, ie: updates sent by the process and
not those received by the process), can be a great load indicator in order
to properly scale the infrastructure that is intended to handle the
table updates.

Note that there is a pitfall, which is that the value will eventually
wrap since it is stored using unsigned 32bits integer. Scripts or system
making use of this value must take wrapping into account between two
readings to properly compute the effective number of updates that were
performed between two readings. Also, they must ensure that the "polling"
rate between readings is small enough so that the value cannot wrap behind
their back.

3 weeks agoMEDIUM: stats-file/clock: automatically update now_offset based on shared clock
Aurelien DARRAGON [Fri, 20 Feb 2026 21:45:11 +0000 (22:45 +0100)] 
MEDIUM: stats-file/clock: automatically update now_offset based on shared clock

We no longer rely on now_offset stored in the shm-stats-file. Instead
haproxy automatically computes the now_offset relative to the monotonic
clock and the shared global clock.

Indeed, the previous model based on static now_offset when monotonic
clock is available proved to be insufficient when used in
combination with shm-stats-file (that is when monotonic clock is shared
between multiple co-processes). In ideal situation co-processes would
correctly apply the offset to their local monotonic clock and end up
with consistent now_ns. But when restarting from an existing
shm-stats-file from a previous session (ie: prior to reboot), then the
local monotonic clock would no longer be consistent with the one used
to update the file previously, so applying a static offset would fail
to restore clock consistency.

For this specific issue, a workaround was brought by 09bf116
("BUG/MEDIUM: stats-file: detect and fix inconsistent shared clock when resuming from shm-stats-file")
but the solution implemented there was deemed too fragile, because there
is a 60sec window where the fix would fail to detect inconsistent clock
and would leave haproxy with a broken clock ranging from 0 to 60 seconds,
which can be huge..

By simply recomputing the now_offset each time we learn from another
process (through the shared map by reading global_now_ns), we simply
recompute our local offset (difference between OUR monotonic clock
and the SHARED one). Also, in clock_update_global_date(), we make
sure we always recompute the now_offset as now_ms may have been
updated from shared clock if shared clock was ahead of us.

Thanks to that new logic, interrupted processes, resumed processes,
processed started with shm-stats-file from previous session now
correctly recover from those various situations and multiple
co-processes with diverting clocks on startup end up converging to
the same values.

Since it is no longer relevant to save now_offset in the map, it was
removed but to prevent shm-stats-file incompatibility with previous
versions, 8-byte hole was forced, and we didn't bump the shm-stats-file
version on purpose.

This patch may be backported in 3.3 after a solid period of observation
to ensure we didn't break things.

3 weeks agoBUG/MINOR: mjson: make mystrtod() length-aware to prevent out-of-bounds reads
William Lallemand [Tue, 17 Mar 2026 11:24:28 +0000 (12:24 +0100)] 
BUG/MINOR: mjson: make mystrtod() length-aware to prevent out-of-bounds reads

mystrtod() was not length-aware and relied on null-termination or a
non-numeric character to stop. The fix adds a length parameter as a
strict upper bound for all pointer accesses.

The practical impact in haproxy is essentially null: all callers embed
the JSON payload inside a large haproxy buffer, so the speculative read
past the last digit lands on memory that is still within the same
allocation. ASAN cannot detect it in a normal haproxy run for the same
reason â€” the overread never escapes the enclosing buffer. Triggering a
detectable fault requires placing the JSON payload at the exact end of
an allocation.

Note: the 'path' buffer was using a null-terminated string so the result
of strlen is passed to it, this part was not at risk.

Thanks to Kamil Frankowicz for the original bug report.

This patch must be backported to all maintained versions.

3 weeks agoBUG/MINOR: stream: Fix crash in stream dump if the current rule has no keyword
Christopher Faulet [Tue, 17 Mar 2026 07:31:31 +0000 (08:31 +0100)] 
BUG/MINOR: stream: Fix crash in stream dump if the current rule has no keyword

The commit 9f1e9ee0e ("DEBUG: stream: Display the currently running rule in
stream dump") revealed a bug. When a stream is dumped, if it is blocked on a
rule, we must take care the rule has a keyword to display its name.

Indeed, some action parsings are inlined with the rule parser. In that case,
there is no keyword attached to the rule.

Because of this bug, crashes can be experienced when a stream is
dumped. Now, when there is no keyword, "?" is display instead.

This patch must be backported as far as 2.6.

3 weeks agoBUG/MINOR: http-ana: Swap L7 buffer with request buffer by hand
Christopher Faulet [Thu, 12 Mar 2026 20:42:10 +0000 (21:42 +0100)] 
BUG/MINOR: http-ana: Swap L7 buffer with request buffer by hand

When a L7 retry is performed, we should not rely on b_xfer() to swap the L7
buffer with the request buffer. When it is performed the request buffer is
not allocated. b_xfer() must not be called with an unallocated destination
buffer. The swap remains an optim. For instance, It is not performed on
buffers of different size. So the caller is responsible to provide an
allocated destination buffer with enough free space to transfer data.

However, when a L7 retry is performed, we cannot allocate a request buffer,
because we cannot yield. An error was reported, if we wait for a buffer, the
error will be handled by process_stream(). But we can swap the buffers by
hand. At this stage, we know there is no request buffer, so we can easily
swap it with the L7 buffer.

Note there is no real bug for now.

This patch could be backported to all stable versions.

3 weeks agoBUG/MINOR: h2/h3: Never insert partial headers/trailers in an HTX message
Christopher Faulet [Thu, 12 Mar 2026 13:57:24 +0000 (14:57 +0100)] 
BUG/MINOR: h2/h3: Never insert partial headers/trailers in an HTX message

In HTX, headers and trailers parts must always be complete. It is unexpected
to found header blocks without the EOH block or trailer blocks without the
EOT block. So, during H2/H3 message parsing, we must take care to remove any
HEADER/TRAILER block inserted when an error is encountered. It is mandatory
to be sure to properly report parsing error to upper layer.x

It is now performed by calling htx_truncat_blk() function on the error
path. The tail block is saved before converting any HEADERS/TRAILERS frame
to HTX. It is used to remove all inserted block on error.

This patch rely on the following one:

  "MINOR: htx: Add function to truncate all blocks after a specific block"

It should be backported with the commit above to all stable versions for
the H2 part and as far as 2.8 for h3 one.

3 weeks agoMINOR: htx: Add function to truncate all blocks after a specific block
Christopher Faulet [Thu, 12 Mar 2026 13:54:20 +0000 (14:54 +0100)] 
MINOR: htx: Add function to truncate all blocks after a specific block

htx_truncated_blk() function does the same than htx_trunctate(), except data
are truncated relatively to a block in the message instead of an offset.

3 weeks agoBUG/MINOR: h2/h3: Only test number of trailers inserted in HTX message
Christopher Faulet [Thu, 12 Mar 2026 10:21:34 +0000 (11:21 +0100)] 
BUG/MINOR: h2/h3: Only test number of trailers inserted in HTX message

When H2 or H3 trailers are inserted in an HTX message, we must take care to
not exceed the maximum number of trailers allowed in a message (same than
the maximum number of headers, i.e tune.http.maxhdr). However, all HTX
blocks in the HTX message were considered. Only TRAILERS HTX blocks must be
considered.

To fix the issue, in h2_make_htx_trailers(), we rely on the "idx" variable
at the end of the for loop. In h3_trailers_to_htx(), we rely on the
"hdr_idx" variable.

This patch must be backported to all stables versions for the H2 part and as
far as 2.8 for the H3 one.

pouet

3 weeks agoBUG/MEDIUM: stconn: Don't perform L7 retries with large buffer
Christopher Faulet [Thu, 12 Mar 2026 20:41:31 +0000 (21:41 +0100)] 
BUG/MEDIUM: stconn: Don't perform L7 retries with large buffer

L7 retries are buggy when a large buffer is used on the request channel. A
memcpy is used to copy data from the request buffer into the L7 buffer. The
L7 buffer is for now always a standard buffer. So if a larger buffer is
used, this leads to a buffer overflow and crash the process.

The Best way to fix the issue is to disable L7 retries when a large buffer
was allocated for the request channel. In that case, we don't want to
allocate an extra large buffer.

No backport needed.

3 weeks agoBUG/MEDIUM: stconn: Fix abort on close when a large buffer is used
Christopher Faulet [Fri, 13 Mar 2026 08:06:43 +0000 (09:06 +0100)] 
BUG/MEDIUM: stconn: Fix abort on close when a large buffer is used

When a large buffer is used on a channel, once we've started to send data to
the opposite side, receives are blocked temporarily to be sure to flush the
large buffer ASAP to be able to fall back on regular buffers. This was
performed by skipping call to the endpoint (connection or applet). Howerver,
doing so, this broken the abortonclose and more generally this masked any
shut or error events reported by the lower layer.

To fix the issue, instead of skipping receives, we now try a receive but
with a requested size set to 0.

No backport needed

3 weeks agoBUG/MEDIUM: spoe: Properly abort processing on client abort
Christopher Faulet [Mon, 16 Mar 2026 06:59:24 +0000 (07:59 +0100)] 
BUG/MEDIUM: spoe: Properly abort processing on client abort

Client abort when abortonclose is configured was ignored when messges were
sent on event while it works properly when messages are sent via an
"send-spoe-group" action.

To fix the issue, when the SPOE filter is waiting for the SPOE applet
response, it must check if a client abort was reported and if so, must
interrupt its processing.

This patch should be backported as far as 3.1.

3 weeks agoBUG/MINOR: spoe: Properly switch SPOE filter to WAITING_ACK state
Christopher Faulet [Mon, 16 Mar 2026 06:46:30 +0000 (07:46 +0100)] 
BUG/MINOR: spoe: Properly switch SPOE filter to WAITING_ACK state

When the SPOE applet is created, the SPOE filter is set in SENDING_MSGS
state. When the applet has transferred data, it should switch the filter to
WAITING_ACK state. Concretly, there is no bug. At best, it could save some
useless applet wakeups.

This patch should be backported as far as 3.1

3 weeks agoBUG/MEDIUM: stconn: Don't forget to wakeup applets on shutdown
Christopher Faulet [Tue, 17 Mar 2026 06:33:21 +0000 (07:33 +0100)] 
BUG/MEDIUM: stconn: Don't forget to wakeup applets on shutdown

When SC's shudown callback functions were merged, a regression was
introduced. The applet was no longer woken up. Because of this bug, an
applet could remain blocked, waiting for an I/O event or a timeout.

This patch should fix the issue #3301.

No backport needed.

3 weeks agoBUG/MINOR: sockpair: set FD_CLOEXEC on fd received via SCM_RIGHTS
William Lallemand [Mon, 16 Mar 2026 15:08:45 +0000 (16:08 +0100)] 
BUG/MINOR: sockpair: set FD_CLOEXEC on fd received via SCM_RIGHTS

FDs received through recv_fd_uxst() do not have FD_CLOEXEC set.
The equivalent sock_accept_conn() already handles this correctly:
any FD accepted or received in the master must be marked close-on-exec
to avoid leaking it across the execvp() performed on soft-reload.

This is currently triggering a leak in the master since 3.1: the worker
sends a socketpair fd to the master  to issue the _send_status CLI
command, and recv_fd_uxst() receive it without setting FD_CLOEXEC.  If a
re-exec is emitted before the master had the chance to close that fd, it
survives execvp() and appears as an untracked unnamed AF_UNIX socket in
the new master generation.

This must be backported to all maintained branches.

3 weeks agoBUG/MINOR: mworker: avoid passing NULL version in proc list serialization
William Lallemand [Fri, 13 Mar 2026 19:24:37 +0000 (20:24 +0100)] 
BUG/MINOR: mworker: avoid passing NULL version in proc list serialization

Add a NULL guard for the version field. This has no functional impact
since the master process never uses this field for its own mworker_proc
element, and should be the only one impacted. This avoid seeing "(null)"
in the version field when debugging.

Must be backported to 3.1 and later.

3 weeks agoBUG/MINOR: mworker: set a timeout on the worker socketpair read at startup
William Lallemand [Fri, 13 Mar 2026 17:41:05 +0000 (18:41 +0100)] 
BUG/MINOR: mworker: set a timeout on the worker socketpair read at startup

During a soft reload, a starting worker sends sock_pair[0] to the master
via send_fd_uxst(), then reads on sock_pair[1] waiting for the master to
acknowledge receipt. Because of a documented macOS sendmsg(2) bug, the
worker must keep sock_pair[0] open until the master confirms the fd was
received by the CLI applet. This means the read() on sock_pair[1] will
never return 0 (EOF), since the worker itself still holds a reference to
sock_pair[0]. The worker can only unblock when the master actively sends
a byte back. If the master crashes before doing so, the worker blocks
indefinitely in read().

Fix this by setting a 2-second SO_RCVTIMEO on sock_pair[1] before the
read(), so the worker can unblock and continue regardless of the master's
state.

This was introduced by d7f6819161c ("BUG/MEDIUM: mworker: fix startup
and reload on macOS").

This should be backported to 3.1 and later.

3 weeks agoBUG/MINOR: mworker: fix typo &= instead of & in proc list serialization
William Lallemand [Fri, 13 Mar 2026 16:43:19 +0000 (17:43 +0100)] 
BUG/MINOR: mworker: fix typo &= instead of & in proc list serialization

In mworker_proc_list_to_env(), a typo used '&=' instead of '&' when
checking PROC_O_TYPE_WORKER in child->options. This would corrupt the
options field by clearing all bits except PROC_O_TYPE_WORKER, but since
the function is called right before the master re-execs itself during a
reload, the corruption has no actual effect: the in-memory proc_list is
discarded by the exec, and the options field is not serialized to the
environment anyway.

This should be backported to all maintained versions.

4 weeks agoMINOR: traces: defer processing of "-dt" options
Maxime Henrion [Thu, 12 Mar 2026 15:29:38 +0000 (11:29 -0400)] 
MINOR: traces: defer processing of "-dt" options

We defer processing of the "-dt" options until after the configuration
file has been read. This will be useful if we ever allow trace sources
to be registered later, for instance with LUA.

No backport needed.

4 weeks agoBUG/MINOR: mworker: only match worker processes when looking for unspawned proc
William Lallemand [Thu, 12 Mar 2026 16:38:40 +0000 (17:38 +0100)] 
BUG/MINOR: mworker: only match worker processes when looking for unspawned proc

In master-worker mode, when a freshly forked worker looks up its own
entry in proc_list to send its "READY" status to the master, the loop
was breaking on the first process with pid == -1 regardless of its
type. If a non-worker process (e.g. a master or program) also had
pid == -1, the wrong entry could be selected, causing send_fd_uxst()
to use an invalid ipc_fd.

Fix this by adding a PROC_O_TYPE_WORKER check to the loop condition,
and add a BUG_ON() assertion to catch any case where the loop exits
without finding a valid worker entry.

Must be backported to 3.1.

4 weeks agoDOC: internals: short explanation on how thread_exec_ctx works
Willy Tarreau [Thu, 12 Mar 2026 17:23:01 +0000 (18:23 +0100)] 
DOC: internals: short explanation on how thread_exec_ctx works

The goal is to have enough info to be able to automatically enable the
feature on future rulesets or subsystems.

4 weeks agoMINOR: activity: raise the default number of memprofile buckets to 4k
Willy Tarreau [Thu, 12 Mar 2026 09:52:27 +0000 (10:52 +0100)] 
MINOR: activity: raise the default number of memprofile buckets to 4k

It was set to 1k by default but with the refinement of exec_ctx it's
becoming short, so let's raise it now.

4 weeks agoMINOR: activity: support aggregating by caller also for memprofile
Willy Tarreau [Wed, 11 Mar 2026 17:03:26 +0000 (18:03 +0100)] 
MINOR: activity: support aggregating by caller also for memprofile

"show profiling" supports "aggr" for tasks but it was ignored for
memory. Now that we're having many more entries, it makes sense to
have it to ignore the call path and merge similar operations.

4 weeks agoMINOR: cli: implement execution context for manually registered keywords
Willy Tarreau [Thu, 12 Mar 2026 08:37:15 +0000 (09:37 +0100)] 
MINOR: cli: implement execution context for manually registered keywords

Keywords registered out of an initcall will have a TH_EX_CTX_CLI_KWL
execution context pointing to the keyword list. The report will indicate
the 5 first words of the first command of the list, e.g.:

     exec_ctx: cli kwl starting with 'debug counters   '

This should also work for CLI keywords registered in Lua.

4 weeks agoMINOR: cli: keep track of the initcall context since kw registration
Willy Tarreau [Thu, 12 Mar 2026 08:35:16 +0000 (09:35 +0100)] 
MINOR: cli: keep track of the initcall context since kw registration

Now CLI keywords registered via an initcall will be tracked during
execution, by keeping a link to their initcall location. "show threads"
now shows "exec_ctx: kw registered at @debug.c:3093" which indeed
corresponds to the initcall for the debugging commands.

4 weeks agoMINOR: cli: keep the info of the current keyword being processed in the appctx
Willy Tarreau [Thu, 12 Mar 2026 08:32:26 +0000 (09:32 +0100)] 
MINOR: cli: keep the info of the current keyword being processed in the appctx

Till now the CLI didn't know what keyword was being processed after it
was parsed. In order to report the execution context, we'll need to
store it. And this may even help for post-mortem analysis to know the
exact keyword being processed, so let's store the pointer in the cli_ctx
part of the appctx.

4 weeks agoMINOR: applet: set execution context on applet calls
Willy Tarreau [Thu, 12 Mar 2026 08:05:14 +0000 (09:05 +0100)] 
MINOR: applet: set execution context on applet calls

It allows to know when a thread is currnetly running inside an applet.
For example now "show threads" will show "applet '<CLI>'" for the thread
issuing this command.

4 weeks agoMINOR: task: set execution context on task/tasklet calls
Willy Tarreau [Wed, 11 Mar 2026 08:33:28 +0000 (09:33 +0100)] 
MINOR: task: set execution context on task/tasklet calls

It now appears almost everywhere due to callbacks (e.g. ssl_sock_io_cb).
Muxes also become visible now on memory profiling. A small test on h1+ssl
yields 838 lines of statistics. The number of buckets should definitely
be increased, and more grouping criteria should be added.

A performance test was conducted to observe the possible effect of
setting the execution context on each task switch, and it didn't change
at all, remaining at about 1.01 billion ctxsw/s on a 128-thread EPYC.

4 weeks agoMINOR: connection: track mux calls to report their allocation context
Willy Tarreau [Wed, 11 Mar 2026 09:28:25 +0000 (10:28 +0100)] 
MINOR: connection: track mux calls to report their allocation context

Most calls to mux ops were instrumented with a CALL_MUX_WITH_RET() or
CALL_MUX_NO_RET() macro in order to make the current thread's context
point to the called mux and be able to track its allocations. Only
a bunch of harmless mux_ctl() and ->subscribe/unsubscribe calls were
left untouched since useless. But destroy/detach/shut/init/snd_buf
and rcv_buf are now tracked.

It will not show allocations performed in IO callback via tasklet
wakeups however.

In order to ease reading of the output, cmp_memprof_ctx() knows about
muxes and sorts based on the .subscribe function address instead of
the mux_ops address so as to keep various callers grouped.

4 weeks agoMINOR: ssl: set the thread execution context during message callbacks
Willy Tarreau [Wed, 11 Mar 2026 08:00:24 +0000 (09:00 +0100)] 
MINOR: ssl: set the thread execution context during message callbacks

In order to be able to track memory allocation performed from message
callbacks, let's set the thread execution context to a generic function
pointing to them during their call. This allows for example to observe
the share of SSL allocations caused by ssl_sock_parse_clienthello() when
SSL captures are enabled.

The release calls are automatic from the SSL library for these, and are
registered directly via SSL_get_ex_new_index(). Maybe we should improve
the internal API to wrap that function and systematically track free
calls as well. In this case, maybe even registering the message callback
registration could take both the callback and the release function.
There are few such users however, essentially capture and keylog.

4 weeks agoMINOR: filters: set the exec context to the current filter config
Willy Tarreau [Fri, 6 Mar 2026 19:22:18 +0000 (20:22 +0100)] 
MINOR: filters: set the exec context to the current filter config

Doing this allows to report the allocations/releases performed by filters
when running with memory profiling enabled. The flt_conf pointer is kept
and the report shows the filter name.

4 weeks agoMINOR: actions: also report execution contexts registered directly
Willy Tarreau [Fri, 6 Mar 2026 16:02:16 +0000 (17:02 +0100)] 
MINOR: actions: also report execution contexts registered directly

This now reports directly registered actions using new type
TH_EX_CTX_ACTION which will report the first keyword of the
list.

4 weeks agoMINOR: actions: store the location of keywords registered via initcalls
Willy Tarreau [Fri, 6 Mar 2026 13:32:51 +0000 (14:32 +0100)] 
MINOR: actions: store the location of keywords registered via initcalls

A bit similar to what was done for sample fetch functions and converters,
we now store with each action keyword the location of the initcall when
they're registered this way. Since there are many functions only calling
a LIST_APPEND() (one per ruleset), we now implement a dedicated function
to store the context in all keywords before doing the append.

However that's not sufficient, because keywords are not mandatory for
actions, so we cannot safely rely on rule->kw. Thus we then set the
exec_ctx per rule when they are all scanned in check_action_rules(),
based on the keyword if it exists, otherwise we make a context from
the action_ptr function if it is set (it should).

Finally at all call points we now check rule->exec_ctx.

4 weeks agoMINOR: tools: support an execution context that is just a function
Willy Tarreau [Wed, 11 Mar 2026 07:53:37 +0000 (08:53 +0100)] 
MINOR: tools: support an execution context that is just a function

The purpose here is to be able to spot certain callbacks, such as the
SSL message callbacks, which are difficult to associate to anything.
Thus we introduce a new context type, TH_EX_CTX_FUNC, for which the
context is just the function pointed to by the void *pointer. One
difficulty with callbacks is that the allocation and release contexts
will likely be different, so the code should be properly structured
to allow proper tracking, either by instrumenting all calls, or by
making sure that the free calls are easy to spot in a report.

4 weeks agoMINOR: sample: also report contexts registered directly
Willy Tarreau [Fri, 6 Mar 2026 09:59:18 +0000 (10:59 +0100)] 
MINOR: sample: also report contexts registered directly

With the two new context types TH_EX_CTX_SMPF/CONV, we can now also
report contexts corresponding to direct calls to sample_register_fetches()
and sample_register_convs(). In this case, the first word of the keyword
list is reported.

4 weeks agoMINOR: sample: store location for fetch/conv via initcalls
Willy Tarreau [Fri, 6 Mar 2026 09:49:46 +0000 (10:49 +0100)] 
MINOR: sample: store location for fetch/conv via initcalls

Now keywords are registered with an exec_ctx and this one is passed
when calling ->process. The ctx is of type INITCALL when passed via
an initcall where we know the file name and line number.

This was tested with and extra "malloc(15)" added in smp_fetch_path()
which shows that it works:

  $ socat /tmp/sock1 - <<< "show profiling memory"|grep via
           Calls         |         Tot Bytes           |       Caller and method  [via]
      1893399           0       60592592              0|         0x78b2ec task_run_applet+0x3339c malloc(32) [via initcall @http_fetch.c:2416]

4 weeks agoMINOR: tools: support decoding ha_caller type exec context
Willy Tarreau [Thu, 12 Mar 2026 16:44:50 +0000 (17:44 +0100)] 
MINOR: tools: support decoding ha_caller type exec context

The TH_EX_CTX_CALLER type takes an ha_caller pointer which allows a
caller to mark its caller's location using MK_CALLER().

4 weeks agoMINOR: tools: decode execution context TH_EX_CTX_INITCALL
Willy Tarreau [Fri, 6 Mar 2026 09:41:35 +0000 (10:41 +0100)] 
MINOR: tools: decode execution context TH_EX_CTX_INITCALL

When the execution context is set to TH_EX_CTX_INITCALL, the pointer
points to a valid initcall, and the decoder will show "kw registered
at %s:%d" with file and line number of the initcall declaration. It's
up to the caller to make the initcall pointer point to the one that was
set during the initcall. The purpose here is to be able to preserve and
pass that knowledge of an initcall down the chain so that future calls
to functions registered via the initcall are still assigned to it.

4 weeks agoMINOR: initcall: record the file and line declaration of an INITCALL
Willy Tarreau [Tue, 3 Mar 2026 09:08:19 +0000 (10:08 +0100)] 
MINOR: initcall: record the file and line declaration of an INITCALL

The INITCALL macros will now store the file and line number where they
are declared into the initcall struct, and RUN_INITCALLS() will assign
them to the global caller_file and caller_line variables, and will even
set caller_initcall to the current initall so that at any instant such
functions know where their caller declared them. This will help with
error messages and traces where a bit of context will be welcome.

4 weeks agoMINOR: memprof: report the execution context on profiling output
Willy Tarreau [Tue, 3 Mar 2026 16:35:09 +0000 (17:35 +0100)] 
MINOR: memprof: report the execution context on profiling output

This leads to the context pointer being reported in "show profiling
memory" when known, as "[via other ctx XXX]" for example.

4 weeks agoMINOR: debug: report the execution context on thread dumps
Willy Tarreau [Thu, 12 Mar 2026 07:55:04 +0000 (08:55 +0100)] 
MINOR: debug: report the execution context on thread dumps

Now we have one extra line saying "exec_ctx: something" in thread dumps
when it's known. It may help with warnings and panics to figure what
is ongoing.

4 weeks agoMINOR: tools: add a function to write a thread execution context.
Willy Tarreau [Thu, 12 Mar 2026 06:48:14 +0000 (07:48 +0100)] 
MINOR: tools: add a function to write a thread execution context.

The new function chunk_append_thread_ctx() appends to a buffer the given
execution context based on its type and pointer. The goal is to easily
use it in profiling output and thread dumps. For now it only handles
TH_EX_CTX_NONE (which prints nothing) and TH_EX_CTX_OTHER (which indicates
"other ctx" followed by the pointer). It will be extended by new types as
they arrive.

4 weeks agoMINOR: memprof: also permit to sort output by calling context
Willy Tarreau [Fri, 6 Mar 2026 18:51:08 +0000 (19:51 +0100)] 
MINOR: memprof: also permit to sort output by calling context

By passing "byctx" to "show profiling memory", it's possible to sort by
the calling context first, which could help group certain calls by
subsystem and ease the interpretation of the output.

4 weeks agoMINOR: memprof: prepare to consider exec_ctx in reporting
Willy Tarreau [Tue, 3 Mar 2026 13:02:38 +0000 (14:02 +0100)] 
MINOR: memprof: prepare to consider exec_ctx in reporting

This now allows to report the same function in multiple bins based on the
th_ctx's exec_ctx discriminant. It's also worth noting that the context is
not atomically committed, but this shouldn't be a problem since a single
entry can get it. In the worst case, a second thread trying to create the
same context in parallel would create a different bin just for this call,
which is harmless. The same situation already exists with the caller
pointer.

4 weeks agoMINOR: tinfo: start to add basic thread_exec_ctx
Willy Tarreau [Tue, 3 Mar 2026 08:37:10 +0000 (09:37 +0100)] 
MINOR: tinfo: start to add basic thread_exec_ctx

We have the struct made of a type and a pointer in the th_ctx and a
function to switch it for the current thread. Two macros are provided
to enclose a callee within a temporary context. For now only type OTHER
is supported (only a generic pointer).

4 weeks agoMINOR: memprof: attempt different retry slots for different hashes on collision
Willy Tarreau [Wed, 11 Mar 2026 15:33:33 +0000 (16:33 +0100)] 
MINOR: memprof: attempt different retry slots for different hashes on collision

When two pointer hash to the same memprofile bin, we currently try again
with the same bin until we find a spare one or we reach the limit of 16.
Olivier suggested to try with a different step for different pointers so
as to limit the number of bins to visit in such a case, so let's split
the pointer hash calculation so that we keep the raw hash before reduction
and use its lowest bits as the retry step. We force lowest bit to 1 to
avoid integral multiples that would oscillate between only a few positions.

Quick tests with h1+h2 requests show that for ~744 distinct entries, we
used to have 1.17 retries per lookup before and 0.6 now so we're halving
the cost of hash collisions. A heavier workload that used to produce 920
entries with 2.01 retries per lookup now reaches 966 entries (94.3% usage
vs 89.8% before) with only 1.44 retries per lookup.

This should be safe to backport, but depends on this previous commit:

    MINOR: tools: extend the pointer hashing code to ease manipulations

4 weeks agoMINOR: tools: add a new pointer hash function that also takes an argument
Willy Tarreau [Fri, 6 Mar 2026 18:14:06 +0000 (19:14 +0100)] 
MINOR: tools: add a new pointer hash function that also takes an argument

The purpose here is to combine two pointers and a long argument instead
of having the caller perform the mixing. Also it's cleaner and more
efficient this was as the arg is mixed after the multiplications, and
modern processors are efficient at multiplying then adding.

4 weeks agoMINOR: tools: extend the pointer hashing code to ease manipulations
Willy Tarreau [Wed, 11 Mar 2026 15:20:23 +0000 (16:20 +0100)] 
MINOR: tools: extend the pointer hashing code to ease manipulations

We'll need to further extend the pointer hashing code to pass extra
parameters and to retrieve the dropped bits, so let's first split the
part that hashes the pointer from the part that reduces the hash to
the desired size.

4 weeks agoMINOR: activity: use dynamic allocation for "show profiling" entries
Willy Tarreau [Wed, 11 Mar 2026 14:22:24 +0000 (15:22 +0100)] 
MINOR: activity: use dynamic allocation for "show profiling" entries

Historically, the data manipulated by "show profiling" were copied
onto the stack for sorting and aggregating, but not only this limits
the number of entries we can keep, but it also has an impact on CPU
usage (having to redo the whole copy+sort upon each resume) and the
output accuracy (if sorting changes lines, resume may happen from an
incorrect one).

Instead, let's dynamically allocate the work buffer and place it into
the service context. We only allocate it immediately before needing it
and release it immediately afterwards so that it doesn't stay long. It
also requires a release handler to release those allocates by interrupted
dumps, but that's all. The overall result is now much cleaner, more
accurate, faster and safer.

This patch may be backported to older LTS releases.

4 weeks agoBUG/MINOR: proxy: do not forget to validate quic-initial rules
Willy Tarreau [Thu, 12 Mar 2026 15:35:29 +0000 (16:35 +0100)] 
BUG/MINOR: proxy: do not forget to validate quic-initial rules

In check_config_validity() and proxy_finalize() we check the consistency
of all rule sets, but the quic_initial rules were not placed there. This
currently has little to no impact, however we're going to use that to
also finalize certain debugging info so better call the function. This
can be backported to 3.1 (proxy_finalize is 3.4-only).

4 weeks agoBUG/MINOR: memprof: avoid a small memory leak in "show profiling"
Willy Tarreau [Wed, 11 Mar 2026 14:14:43 +0000 (15:14 +0100)] 
BUG/MINOR: memprof: avoid a small memory leak in "show profiling"

In 3.1, per-DSO statistics were added to the memprofile output by
commit 401fb0e87a ("MINOR: activity/memprofile: show per-DSO stats").
However an strdup() is performed there on the .info field, that is
never freed when leaving the function. Let's do it each time we leave
it. Ironically, this was found thanks to "show profiling" showing
itself as an unbalanced caller of strdup().

This needs to be backported to 3.0 since that commit was backported
there.

4 weeks agoBUILD: makefile: fix range build without test command
Willy Tarreau [Thu, 12 Mar 2026 07:30:30 +0000 (08:30 +0100)] 
BUILD: makefile: fix range build without test command

In 3.3, the "make range" target adopted a test command via the TEST_CMD
variable, with commit 90b70b61b1 ("BUILD: makefile: implement support
for running a command in range"). However now it breaks the script when
TEST_CMD is not set due to the shell expansion leaving two '||' operators
side by side. Let's fix this by passing the contents of the makefile
variable in positional arguments before executing them.

4 weeks agoBUG/MEDIUM: ssl: Don't report read data as early data with AWS-LC
Olivier Houchard [Thu, 12 Mar 2026 16:31:43 +0000 (17:31 +0100)] 
BUG/MEDIUM: ssl: Don't report read data as early data with AWS-LC

To read early data with AWS-LC (and BoringSSL), we have to use
SSL_read(). But SSL_read() will also try to do the handshake if it
hasn't been done yet, and at some point will do the handshake and will
return data that are actually not early data. So use SSL_in_early_data()
to make sure that the data we received are actually early data, and only
if so add the CO_FL_EARLY_DATA flag. Otherwise any data first received will be
considered early, and a Early-data header will be added.
As this bug was introduced by 76ba026548975a6d1bc23d1344807c64d994bf1e,
it should be backported with it.

4 weeks agoBUG/MINOR: mworker: always stop the receiving listener
William Lallemand [Thu, 12 Mar 2026 15:49:32 +0000 (16:49 +0100)] 
BUG/MINOR: mworker: always stop the receiving listener

Upon _send_status, always stop the listener from which the request
was received, rather than looking it up from the proc_list entry via
fdtab[proc->ipc_fd[0]].owner.

A BUG_ON is added to verify that the listener which received the
request is the one expected for the reported PID.

This means it is no longer possible to send "_send_status READY XXX"
manually through the master CLI for testing, as that would trigger
the BUG_ON.

Must be backported as far as 3.1.

4 weeks agoBUG/MEDIUM: ssl: Handle receiving early data with BoringSSL/AWS-LC
Olivier Houchard [Fri, 6 Mar 2026 12:34:37 +0000 (13:34 +0100)] 
BUG/MEDIUM: ssl: Handle receiving early data with BoringSSL/AWS-LC

The API for early data is a bit different with BoringSSL and AWS-LC than
it is for OpenSSL. As it was implemented, early data would be accepted,
but would not be processed until the handshake is done. Change that by
doing something similar to what OpenSSL does, and, if 0RTT has been
enabled on the listener, use SSL_read() to try to get early data before
starting the handshake, and if there's any, provide them to the mux the
same way it is done for OpenSSL.
That replaces a bunch of #ifdef SSL_READ_EARLY_DATA_SUCCESS by
something specific to OpenSSL has to be done.
This should be backported to 3.3.

4 weeks agoDOC/CLEANUP: config: update mentions of the old "Global parameters" section
Egor Shestakov [Wed, 25 Feb 2026 19:04:34 +0000 (19:04 +0000)] 
DOC/CLEANUP: config: update mentions of the old "Global parameters" section

The name of "Global section" was changed only in the summary, not in the
text itself. The names of some related refs were also updated.

Should be backported as far as 3.2.

4 weeks agoDOC: configuration: http-check expect example typo
Tom Braarup [Thu, 26 Feb 2026 12:30:21 +0000 (12:30 +0000)] 
DOC: configuration: http-check expect example typo

On the http-check expect example
(https://docs.haproxy.org/dev/configuration.html#4.2-http-check%20expect)
there is a typo

-http-check expect header name "set-cookie" value -m beg "sessid="
+http-check expect hdr name "set-cookie" value -m beg "sessid="

4 weeks agoBUG/MINOR: jws: fix memory leak in jws_b64_signature
Mia Kanashi [Thu, 5 Mar 2026 16:08:32 +0000 (18:08 +0200)] 
BUG/MINOR: jws: fix memory leak in jws_b64_signature

EVP_MD_CTX is allocated using EVP_MD_CTX_new() but was never freed.
ctx should be initialized to NULL otherwise EVP_MD_CTX_free(ctx) could
segfault.

Must be backported as far as 3.2.

4 weeks agoBUG/MINOR: tcpcheck: Fix typo in error error message for `http-check expect`
Tim Duesterhus [Fri, 20 Feb 2026 11:20:05 +0000 (12:20 +0100)] 
BUG/MINOR: tcpcheck: Fix typo in error error message for `http-check expect`

With a config:

    backend bk_app
     http-check expect status 200 string "status: ok"

This now correctly emits the error:

    config : parsing [./patch.cfg:2] : 'http-check expect' : only one pattern expected.

This line containing the typo is unchanged since at least HAProxy 2.2, the
patch should be backported into all supported branches.

4 weeks agoBUILD: ssl: make X509_NAME usage OpenSSL 4.0 ready
William Lallemand [Wed, 11 Mar 2026 14:03:36 +0000 (15:03 +0100)] 
BUILD: ssl: make X509_NAME usage OpenSSL 4.0 ready

Starting with OpenSSL 4.0, X509_get_subject_name(), X509_get_issuer_name(),
and X509_CRL_get_issuer() return a const-qualified X509_NAME pointer.
Similarly, X509_NAME_get_entry() returns a const X509_NAME_ENTRY *, and
X509_NAME_ENTRY_get_data() returns a const ASN1_STRING *.

Introduce the __X509_NAME_CONST__ macro (defined to 'const' for OpenSSL
>= 4.0.0, empty for WolfSSL and older OpenSSL version which lacks const
on these APIs) and use it to qualify X509_NAME * variables and the
parameters of the three DN helper functions ssl_sock_get_dn_entry(),
ssl_sock_get_dn_formatted(), and ssl_sock_get_dn_oneline(). This avoids
both const-qualifier warnings on OpenSSL 4.0 and discarded-qualifier
warnings on WolfSSL, without needing explicit casts at call sites.

In ssl_sock.c (ssl_get_client_ca_file) and ssl_gencert.c
(ssl_sock_do_create_cert), a __X509_NAME_CONST__ X509_NAME * variable was
being reused to store the result of X509_NAME_dup() and then passed to
mutating functions (X509_NAME_add_entry_by_txt, X509_NAME_free). Introduce
separate X509_NAME * variables (xn_dup, subject) to hold the mutable
duplicate.

Original patch from Alexandr Nedvedicky <sashan@openssl.org>:
https://www.mail-archive.com/haproxy@formilux.org/msg46696.html

4 weeks agoBUILD: ssl: use ASN1_STRING accessors for OpenSSL 4.0 compatibility
William Lallemand [Wed, 11 Mar 2026 09:53:00 +0000 (10:53 +0100)] 
BUILD: ssl: use ASN1_STRING accessors for OpenSSL 4.0 compatibility

In OpenSSL 4.0, the ASN1_STRING struct was made opaque and direct access
to its members (->data, ->length, ->type) no longer compiles. Replace
these accesses in ssl_sock_get_serial(), ssl_sock_get_time(), and
asn1_generalizedtime_to_epoch() with the proper accessor functions
ASN1_STRING_get0_data(), ASN1_STRING_length(), and ASN1_STRING_type().

The old direct access is preserved under USE_OPENSSL_WOLFSSL since
WolfSSL does not provide these accessor functions.

Original patch from Alexandr Nedvedicky <sashan@openssl.org>:
https://www.mail-archive.com/haproxy@formilux.org/msg46696.html

4 weeks agoMEDIUM: mworker: exiting when couldn't find the master mworker_proc element
William Lallemand [Tue, 10 Mar 2026 14:45:23 +0000 (15:45 +0100)] 
MEDIUM: mworker: exiting when couldn't find the master mworker_proc element

When a master process is reloading, the HAPROXY_PROCESSES variable is
deserialized. In older version of the master-worker (< 1.9), no master
element was existing in this variable.

This is not suppose to happen anymore, and could have provoked problems
in the master anyway.

This patch changes the behavior by exiting the master with an alert if
mp master element was found in this variable.

4 weeks agoDEBUG: stconn: Add a CHECK_IF() when I/O are performed on a orphan SC
Christopher Faulet [Mon, 9 Mar 2026 17:43:59 +0000 (18:43 +0100)] 
DEBUG: stconn: Add a CHECK_IF() when I/O are performed on a orphan SC

When no endpoint is attached to a SC, it is unexpected to have I/O (receive
or send). But we honestly don't know if it happens or not. So a CHECK_IF()
is added to be able to track such calls.

4 weeks agoMINOR: stconn: Simplify sc_abort/sc_shutdown by merging calls to se_shutdown
Christopher Faulet [Mon, 9 Mar 2026 17:40:39 +0000 (18:40 +0100)] 
MINOR: stconn: Simplify sc_abort/sc_shutdown by merging calls to se_shutdown

Calls to se_shutdown were no the same between applets and mux endpoints.
Only the SHUTW flag was not the same. However, on the multiplexers are
sensitive to the true SHUTW flag. The applets handle all of them the same
way. So calls to se_shutdown() from sc_abort() and sc_shutdown() can be
merged to always use the multiplexer version.

4 weeks agoMINOR: stconn: Totally app_ops from the stconns
Christopher Faulet [Thu, 5 Mar 2026 20:06:37 +0000 (21:06 +0100)] 
MINOR: stconn: Totally app_ops from the stconns

The stconn app_ops structure is now empty and can be safely removed. So let's do
so.

4 weeks agoMINOR: stconn: Remove .shutdown() callback functions
Christopher Faulet [Thu, 5 Mar 2026 20:02:42 +0000 (21:02 +0100)] 
MINOR: stconn: Remove .shutdown() callback functions

These callback functions are no longer used, so they can safely be
removed. In addition, the field was removed from the app_ops structure.

4 weeks agoMEDIUM: stconn: Merge all .shutdown() callback functions in sc_shutdown()
Christopher Faulet [Thu, 5 Mar 2026 19:59:40 +0000 (20:59 +0100)] 
MEDIUM: stconn: Merge all .shutdown() callback functions in sc_shutdown()

sc_shutdown() is no longer relying on .shutdown() callback functions.
Everything was merged in sc_shutdown() with a test on the app type.

4 weeks agoMINOR: stconn: Remove .abort() callback functions
Christopher Faulet [Thu, 5 Mar 2026 17:33:05 +0000 (18:33 +0100)] 
MINOR: stconn: Remove .abort() callback functions

These callback functions are no longer used, so they can safely be
removed. In addition, the field was removed from the app_ops structure.

4 weeks agoMEDIUM: stconn: Merge all .abort() callback functions in sc_abort()
Christopher Faulet [Thu, 5 Mar 2026 17:31:02 +0000 (18:31 +0100)] 
MEDIUM: stconn: Merge all .abort() callback functions in sc_abort()

sc_abort() is no longer relying on .abort() callback functions.  Everything
was merged in abort() with a test on the app type.