]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
5 weeks agoBUG/MEDIUM: hpack: correctly deal with too large decoded numbers
Willy Tarreau [Wed, 4 Mar 2026 10:37:12 +0000 (11:37 +0100)] 
BUG/MEDIUM: hpack: correctly deal with too large decoded numbers

The varint hpack decoder supports unbounded numbers but returns 32-bit
results. This means that possible truncation my happen on some field
lengths or indexes that would be emitted as quantities that do not fit
in a 32-bit number. The final value will also depend on how the left
shift operation behaves on the target architecture (e.g. whether bits
are lost or used modulo 31). This could lead to a desynchronization of
the HPACK stream decoding compared to what an external observer would
see (e.g. from a network traffic capture). However, there isn't any
impact between streams, HPACK is performed at the connection level,
not at the stream level, so no stream may try to leverage this
limitation to have any effect on another one.

For the fix, instead of adding checks everywhere in the loop and for
the final stage, let's rewrite the decoder to compare the read value
to a max value that is shifted by 7 bits for every 7 bits read. This
allows a sender to continue to emit zeroes for higher bits without
being blocked, while detecting that a received value would overflow.
The loop is now simpler as it deals both with values with the higher
bit set and the final ones, and stops once the final value was recorded.

A test on non-zero before performing the shift was added to please
ubsan, though in practice zero shifted by any quantity remains zero.
But the test is cheap so that's OK.

Thanks to Guillaume Meunier, Head of Vulnerability Operations Center
France at Orange Cyberdefense, for reporting this bug.

This should be backported to all stable versions.

5 weeks agoMINOR: quic: use server cache for ALPN on BE side
Amaury Denoyelle [Tue, 3 Mar 2026 09:02:39 +0000 (10:02 +0100)] 
MINOR: quic: use server cache for ALPN on BE side

On the backend side, QUIC MUX may be started preemptively before the
ALPN negotiation. This is useful notably for 0-RTT implementation.

However, this was a source of crashes. ALPN was expected to be retrieved
from the server cache, however QUIC MUX still used the ALPN from the
transport layer. This could cause a crash, especially when several
connections runs in parallel as the server cache is shared among
threads.

Thanks to the previous patch which reworks QUIC MUX init, this solution
can now be fixed. Indeed, if conn_get_alpn() is not successful, MUX can
look at the server cache again to use the expected value.

Note that this could still prevent the MUX to work as expected if the
server cache is resetted between connect_server() and MUX init. Thus,
the ultimate solution would be to copy the cached ALPN into the
connection. This problem is not specific to QUIC though, and must be
fixed in a separate patch.

5 weeks agoMEDIUM: quic/mux-quic: adjust app-ops install
Amaury Denoyelle [Tue, 3 Mar 2026 08:47:29 +0000 (09:47 +0100)] 
MEDIUM: quic/mux-quic: adjust app-ops install

This patch reworks the installation of app-ops layer by QUIC MUX.
Previously, app_ops field was stored directly into the quic_conn
structure. Then the MUX reused it directly during its qmux_init().

This patch removes app_ops field from quic_conn and replaces it with a
copy of the negotiated ALPN. By using quic_alpn_to_app_ops(), it ensures
it remains compatible with a known application layer.

On the MUX layer, qcc_install_app_ops() now uses the standard
conn_get_alpn() to retrieve the ALPN from the transport layer. This is
done via the newly defined <get_alpn> QUIC xprt callback.

This new architecture should be cleaner as it better highlights the
responsibility of each layers in the ALPN/app negotiation.

5 weeks agoMINOR: mux-quic: add function for ALPN to app-ops conversion
Amaury Denoyelle [Tue, 3 Mar 2026 08:45:22 +0000 (09:45 +0100)] 
MINOR: mux-quic: add function for ALPN to app-ops conversion

Extract the conversion from ALPN to qcc_app_ops type from quic_conn
source file into QUIC MUX. The newly created function is named
quic_alpn_to_app_ops(). This will serve as a central point to identify
which ALPNs are currently supported in our QUIC stack.

This patch is purely a small refactoring. It will be useful for the next
one which rework MUX app-ops layer init. The current cleanup allows
notably to remove H3/hq-interop headers from quic_conn source file.

5 weeks agoMINOR: quic/h3: reorganize stream reject after MUX closure
Amaury Denoyelle [Tue, 3 Mar 2026 08:41:26 +0000 (09:41 +0100)] 
MINOR: quic/h3: reorganize stream reject after MUX closure

The QUIC MUX layer is closed after its transport counterpart. This may
be necessary then to reject any new streams opened by the remote peer.
This operation is dependent however from the application protocol.

Previously, a function qc_h3_request_reject() was directly implemented
in quic_conn source file for use when HTTP/3 was previously negotiated.
However, this solution was not evolutive and broke layering.

This patch introduces a new proper separation with a <strm_reject>
callback defined in quic_conn structure. When set, it will be used to
preemptively close any new stream. QUIC MUX is responsible to set it
just before its closure.

No functional change. This patch is purely a refactoring with a better
architecture design. Especially, H3 specific code from transport layer
is now completely removed.

5 weeks agoMINOR: quic: use signed char type for ALPN manipulation
Amaury Denoyelle [Tue, 3 Mar 2026 08:02:44 +0000 (09:02 +0100)] 
MINOR: quic: use signed char type for ALPN manipulation

In most of haproxy code, ALPN is used as a signed char pointer. In QUIC
code instead, it is manipulated as unsigned.

Unifies this by using signed type in QUIC code. This allows to remove a
bunch of unnecessary casts.

5 weeks agoBUG/MEDIUM: stream: Handle TASK_WOKEN_RES as a stream event
Christopher Faulet [Tue, 3 Mar 2026 11:50:36 +0000 (12:50 +0100)] 
BUG/MEDIUM: stream: Handle TASK_WOKEN_RES as a stream event

The conversion of TASK_WOKEN_RES to a stream event was missing. Among other
things, this wakeup reason is used when a stream is dequeued. So it was
possible to skip the connection establishment if the stream was also woken
up for a timer reason. When this happened, the stream was blocked till the
queue timeout expiration.

Converting TASK_WOKEN_RES to STRM_EVT_RES fixes the issue.

This patch should fix the issue #3290. It must be backported as far as 3.2.

5 weeks agoBUG/MINOR: hlua: fix return with push nil on proxy check
Amaury Denoyelle [Tue, 3 Mar 2026 07:45:27 +0000 (08:45 +0100)] 
BUG/MINOR: hlua: fix return with push nil on proxy check

hlua_check_proxy() may now return NULL if the target proxy instance has
been flagged for deletion. Thus, proxies method have been adjusted and
may push nil to report such case.

This patch fixes these error paths. When nil is pushed, 1 must be
returned instead of 0. This represents the count of pushed values on the
stack which can be retrieved by the caller.

No need to backport.

5 weeks agoREGTESTS: complete "del backend" with unnamed defaults ref free
Amaury Denoyelle [Mon, 2 Mar 2026 07:51:46 +0000 (08:51 +0100)] 
REGTESTS: complete "del backend" with unnamed defaults ref free

Complete delete backend regtests by checking deletion of a proxy with a
reference on an unnamed defaults instance. This operation is sensible as
the defaults refcount is decremented, and when the last backend is
removed, the defaults is also freed.

5 weeks agoREGTESTS: add a test on "del backend"
Amaury Denoyelle [Fri, 27 Feb 2026 09:45:55 +0000 (10:45 +0100)] 
REGTESTS: add a test on "del backend"

Add a reg-tests to test "del backend" CLI command. First, checks are
performed to ensure a backend cannot be deleted if not in the expected
state.

Then, a "del backend" success is tested. Stats are dumped to ensure the
backend instance is indeed removed.

5 weeks agoMEDIUM: proxy: implement backend deletion
Amaury Denoyelle [Tue, 6 Jan 2026 14:26:13 +0000 (15:26 +0100)] 
MEDIUM: proxy: implement backend deletion

This patch finalizes "del backend" handler by implementing the proper
proxy deletion.

After ensuring backend deletion can be performed, several steps are
executed. First, any watcher elements are updated to point on the next
proxy instance. The backend is then removed from ID and name global
trees and is finally detached from proxies_list.

Once the backend instance is removed from proxies_list, the backend
cannot be found by new elements. Thread isolation is lifted and
proxy_drop() is called, which will purge the proxy if its refcount is
null. Thanks to recently introduced PROXIES_DEL_LOCK, proxy_drop() is
thread safe.

5 weeks agoMINOR: proxy: use atomic ops for default proxy refcount
Amaury Denoyelle [Mon, 2 Mar 2026 10:15:41 +0000 (11:15 +0100)] 
MINOR: proxy: use atomic ops for default proxy refcount

Default proxy refcount <def_ref> is used to comptabilize reference on a
default proxy instance by standard proxies. Currently, this is necessary
when a default proxy defines TCP/HTTP rules or a tcpcheck ruleset.

Transform every access on <def_ref> so that atomic operations are now
used. Currently, this is not strictly needed as default proxies
references are only manipulated at init or deinit in single thread mode.
However, when dynamic backends deletion will be implemented, <def_ref>
will be decremented at runtime also.

5 weeks agoMEDIUM: proxy: add lock for global accesses during default free
Amaury Denoyelle [Mon, 2 Mar 2026 08:05:19 +0000 (09:05 +0100)] 
MEDIUM: proxy: add lock for global accesses during default free

This patch is similar to the previous one, but this time it deals with
functions related to defaults proxies instances. Lock PROXIES_DEL_LOCK
is used to protect accesses on global collections.

This patch will be necessary to implement dynamic backend deletion, even
if defaults won't be use as direct target of a "del backend" CLI.
However, a backend may have a reference on a default instance. When the
backend is freed, this references is released, which can in turn cause
the freeing of the default proxy instance. All of this will occur at
runtime, outside of thread isolation.

5 weeks agoMEDIUM: proxy: add lock for global accesses during proxy free
Amaury Denoyelle [Mon, 2 Mar 2026 07:51:18 +0000 (08:51 +0100)] 
MEDIUM: proxy: add lock for global accesses during proxy free

Define a new lock with label PROXIES_DEL_LOCK. Its purpose is to protect
operations performed on global lists or trees while a proxy is freed.

Currently, this lock is unneeded as proxies are only freed on
single-thread init or deinit. However, with the incoming dynamic backend
deletion, this operation will be also performed at runtime, outside of
thread isolation.

5 weeks agoMINOR: proxy: add comment for defaults_px_ref/unref_all()
Amaury Denoyelle [Mon, 2 Mar 2026 07:52:20 +0000 (08:52 +0100)] 
MINOR: proxy: add comment for defaults_px_ref/unref_all()

Write documentation for functions related to default proxies instances.

5 weeks agoMINOR: cli: implement wait on be-removable
Amaury Denoyelle [Wed, 18 Feb 2026 13:00:08 +0000 (14:00 +0100)] 
MINOR: cli: implement wait on be-removable

Implement be-removable argument to CLI wait. This is implemented via
be_check_for_deletion() invokation, also used by "del backend" handler.

The objective is to test whether a backend instance can be removed. If
this is not the case, the command may returns immediately if the target
proxy is incompatible with dynamic removal or if a user action is
required. Else, the command will wait until the temporary restriction is
lifted.

5 weeks agoMINOR: server: mark backend removal as forbidden if QUIC was used
Amaury Denoyelle [Mon, 23 Feb 2026 11:01:39 +0000 (12:01 +0100)] 
MINOR: server: mark backend removal as forbidden if QUIC was used

Currenly, quic_conn on the backend side may access their parent proxy
instance during their lifetime. In particular, this is the case for
counters update, with <prx_counters> field directly referencing a proxy
memory zone.

As such, this prevents safe backend removal. One solution would be to
check if the upper connection instance is still alive, as a proxy cannot
be removed if connection are still active. However, this would
completely prevent proxy counters update via
quic_conn_prx_cntrs_update(), as this is performed on quic_conn release.

Another solution would be to use refcount, or a dedicated counter on the
which account for QUIC connections on a backend instance. However,
refcount is currently only used by short-term references, and it could
also have a negative impact on performance.

Thus, the simplest solution for now is to disable a backend removal if a
QUIC server is/was used in it. This is considered acceptable for now as
QUIC on the backend side is experimental.

5 weeks agoMINOR: proxy: prevent backend deletion if server still exists in it
Amaury Denoyelle [Mon, 12 Jan 2026 14:26:45 +0000 (15:26 +0100)] 
MINOR: proxy: prevent backend deletion if server still exists in it

Ensure a backend instance cannot be removed if there is still server in
it. This is checked via be_check_for_deletion() to ensure "del backend"
cannot be executed. The only solution is to use "del server" to remove
on the servers instances.

This check only covers servers not yet targetted via "del server". For
deleted servers not yet purged (due to their refcount), the proxy
refcount is incremented but this does not block "del backend"
invokation.

5 weeks agoMINOR: proxy: prevent deletion of backend referenced by config elements
Amaury Denoyelle [Tue, 6 Jan 2026 15:53:03 +0000 (16:53 +0100)] 
MINOR: proxy: prevent deletion of backend referenced by config elements

Define a new proxy flag PR_FL_NON_PURGEABLE. This is used to mark every
proxy instance explicitely referenced in the config. Such instances
cannot be deleted at runtime.

Static use_backend/default_backend rules are handled in
proxy_finalize(). Also, sample expression proxy references are protected
via smp_resolve_args().

Note that this last case also incidentally protects any proxies
referenced via a CLI "set var" expression. This should not be the case
as in this case variable value is instantly resolved so the proxy
reference is not needed anymore. This also affects dynamic servers.

5 weeks agoMINOR: proxy: prevent backend removal when unsupported
Amaury Denoyelle [Tue, 6 Jan 2026 15:38:05 +0000 (16:38 +0100)] 
MINOR: proxy: prevent backend removal when unsupported

Prevent removal of a backend which relies on features not compatible
with dynamic backends. This is the case if either dispatch or
transparent option is used, or if a stick-table is declared.

These limitations are similar to the "add backend" ones.

5 weeks agoMINOR: lua: handle proxy refcount
Amaury Denoyelle [Wed, 18 Feb 2026 08:55:13 +0000 (09:55 +0100)] 
MINOR: lua: handle proxy refcount

Implement proxy refcount for Lua proxy class. This is similar to the
server class.

In summary, proxy_take() is used to increment refcount when a Lua proxy
is instantiated. proxy_drop() is called via Lua garbage collector. To
ensure a deleted backend is released asap, hlua_check_proxy() now
returns NULL if PR_FL_DELETED is set.

This approach is directly dependable on Lua GC execution. As such, it
probably suffers from the same limitations as the ones already described
in the previous commit. With the current patch, "del backend" is not
directly impacted though. However, the final proxy deinit may happen
after a long period of time, which could cause memory pressure increase.

One final observations regarding deinit : it is necessary to delay a
BUG_ON() which checks that defaults proxies list is empty. Now this must
be executed after Lua deinit (called via post_deinit_list). This should
guarantee that all proxies and their defaults refcount are null.

5 weeks agoMINOR: server: take proxy refcount when deleting a server
Amaury Denoyelle [Tue, 6 Jan 2026 15:28:36 +0000 (16:28 +0100)] 
MINOR: server: take proxy refcount when deleting a server

When a server is deleted via "del server", increment refcount of its
parent backend. This is necessary as the server is not referenced
anymore in the backend, but can still access it via its own <proxy>
member. Thus, backend removal must not happen until the complete purge
of the server.

The proxy refcount is released in srv_drop() if the flag SRV_F_DELETED
is set, which indicates that "del server" was used. This operation is
performed after the complete release of the server instance to ensure no
access will be performed on the proxy via itself. The refcount must not
be decremented if a server is freed without "del server" invokation.

Another solution could be for servers to always increment the refcount.
However, for now in haproxy refcount usage is limited, so the current
approach is preferred. It should also ensure that if the refcount is
still incremented, it may indicate that some servers are not completely
purged themselves.

Note that this patch may cause issues if "del backend" are used in
parallel with LUA scripts referencing servers. Currently, any servers
referenced by LUA must be released by its garbage collector to ensure it
can be finally freed. However, it appeas that in some case the gc does
not run for several minutes. At least this has been observed with Lua
version 5.4.8. In the end, this will result in indefinitely blocking of
"del backend" commands.

5 weeks agoMINOR: proxy: rename default refcount to avoid confusion
Amaury Denoyelle [Fri, 27 Feb 2026 08:20:15 +0000 (09:20 +0100)] 
MINOR: proxy: rename default refcount to avoid confusion

Rename proxy conf <refcount> to <def_ref>. This field only serves for
defaults proxy instances. The objective is to avoid confusion with the
newly introduced <refcount> field used for dynamic backends.

As an optimization, it could be possible to remove <def_ref> and only
use <refcount> also for defaults proxies usage. However for now the
simplest solution is implemented.

This patch does not bring any functional change.

5 weeks agoMINOR: proxy: add refcount to proxies
Amaury Denoyelle [Fri, 13 Feb 2026 10:29:00 +0000 (11:29 +0100)] 
MINOR: proxy: add refcount to proxies

Implement refcount notion into proxy structure. The objective is to be
able to increment refcount on proxy to prevent its deletion temporarily.
This is similar to the server refcount : "del backend" is not blocked
and will remove the targetted instance from the global proxies_list.
However, the final free operation is delayed until the refcount is null.

As stated above, the API is similar to servers. Proxies are initialized
with a refcount of 1. Refcount can be incremented via proxy_take(). When
no longer useful, refcount is decremented via proxy_drop() which
replaces the older free_proxy(). Deinit is only performed once refcount
is null.

This commit also defines flag PR_FL_DELETED. It is set when a proxy
instance has been removed via a "del backend" CLI command. This should
serve as indication to modules which may still have a refcount on the
target proxy so that they can release it as soon as possible.

Note that this new refcount is completely ignored for a default proxy
instance. For them, proxy_take() is pure noop. Free is immediately
performed on first proxy_drop() invokation.

5 weeks agoMINOR: lua: use watcher for proxies iterator
Amaury Denoyelle [Tue, 24 Feb 2026 16:47:46 +0000 (17:47 +0100)] 
MINOR: lua: use watcher for proxies iterator

Ensures proxies iteration via lua functions is safe via a new watcher
member. The principle is similar to the one already used for servers
iteration.

6 weeks agoMINOR: promex: use watcher to iterate over backend instances
Amaury Denoyelle [Tue, 24 Feb 2026 15:22:12 +0000 (16:22 +0100)] 
MINOR: promex: use watcher to iterate over backend instances

Ensures proxies iteration in promex applet is safe via a new watcher
member. The principle is similar to the one already used for servers
iteration.

Note that ctx.p[0] is not updated anymore at the end of a function, as
this is automatically done via the watcher itself.

6 weeks agoMINOR: stats: protect proxy iteration via watcher
Amaury Denoyelle [Tue, 10 Feb 2026 10:20:12 +0000 (11:20 +0100)] 
MINOR: stats: protect proxy iteration via watcher

Define a new <px_watch> watcher member in stats applet context. It is
used to register the applet on a proxy when iterating over the proxies
list. <obj1> is automatically updated via the watcher interaction.
Watcher is first initialized prior to stats_dump_proxies() invocation.

This guarantees that stats dump is safe even if applet yields and a
backend is removed in parallel.

6 weeks agoMINOR: proxy: define proxy watcher member
Amaury Denoyelle [Tue, 10 Feb 2026 10:18:11 +0000 (11:18 +0100)] 
MINOR: proxy: define proxy watcher member

Define a new member watcher_list in proxy. It will be used to register
modules which iterate over the proxies list. This will ensure that the
operation is safe even if a backend is removed in parallel.

6 weeks agoMINOR: proxy: define a basic "del backend" CLI
Amaury Denoyelle [Tue, 6 Jan 2026 10:40:05 +0000 (11:40 +0100)] 
MINOR: proxy: define a basic "del backend" CLI

Add "del backend" handler which is restricted to admin level. Along with
it, a new function be_check_for_deletion() is used to test if the
backend is removable.

6 weeks agoMINOR: server: refactor srv_detach()
Amaury Denoyelle [Tue, 6 Jan 2026 15:36:44 +0000 (16:36 +0100)] 
MINOR: server: refactor srv_detach()

Correct documentation for srv_detach() which previously stated that this
function could be called for a server even if not stored in its proxy
list. In fact there is a BUG_ON() which detects this case.

6 weeks agoMINOR: proxy: convert proxy flags to uint
Amaury Denoyelle [Mon, 12 Jan 2026 09:53:57 +0000 (10:53 +0100)] 
MINOR: proxy: convert proxy flags to uint

Proxy flags member were of type char. This will soon enough not be
sufficient as new flags will be defined. As such, convert flags member
to unsigned int type.

6 weeks agoBUG/MINOR: proxy: add dynamic backend into ID tree
Amaury Denoyelle [Wed, 18 Feb 2026 13:00:22 +0000 (14:00 +0100)] 
BUG/MINOR: proxy: add dynamic backend into ID tree

Add missing proxy_index_id() call in "add backend" handler. This step is
responsible to store the newly created proxy instance in the
used_proxy_id global tree.

No need to backport.

6 weeks agoBUG/MINOR: promex: fix server iteration when last server is deleted
Amaury Denoyelle [Thu, 26 Feb 2026 10:18:43 +0000 (11:18 +0100)] 
BUG/MINOR: promex: fix server iteration when last server is deleted

Servers iteration via promex is now resilient to server runtime deletion
thanks to the watcher mechanism. However, the watcher was not correctly
initialized which could cause duplicate metrics reporting.

This issue happens when promex dump yielded when manipulating the last
server of a proxy. If this server is removed in parallel, <sv> pointer
will be set to NULL when promex resumes. Instead of switching to another
proxy, the code would reuse the same one and iterate again on the same
server list.

To fix this issue, <sv> pointer must not be reinitialized just after a
resumption point. Instead, this is now performed before
promex_dump_srv_metrics(), or just after switching to another proxy
instance. Thus, on resumption, if promex_dump_srv_metrics() is started
with <sv> as NULL, it means that the server was deleted and the end of
the current proxy list is reached, hence iteration is restarted on the
next proxy instance.

Note that ctx.p[1] does not need to be manually updated at the end of
promex_dump_srv_metrics() as srv_watch already does that.

This patch must be backported up to 3.0.

6 weeks agoMINOR: promex: test applet resume in stress mode
Amaury Denoyelle [Tue, 24 Feb 2026 16:05:37 +0000 (17:05 +0100)] 
MINOR: promex: test applet resume in stress mode

Implement a stress mode with force yield for promex applet each time a
metric is displayed. This is implemented by returning 0 in
promex_dump_ts() each time the output buffer is not empty.

To test this, haproxy must be compiled with DEBUG_STRESS and the
following configuration must be used :

  global
    stress-level 1

6 weeks agoBUG/MINOR: call EXTRA_COUNTERS_FREE() before srv_free_params() in srv_drop()
Willy Tarreau [Thu, 26 Feb 2026 16:18:41 +0000 (17:18 +0100)] 
BUG/MINOR: call EXTRA_COUNTERS_FREE() before srv_free_params() in srv_drop()

As seen with the last changes to counters allocation, the move of the
counters storage to the thread group as operated in commit 04a9f86a85
("MEDIUM: counters: add a dedicated storage for extra_counters in various
structs") causes some random errors when using ASAN, because the extra
counters are freed in srv_drop() after calling srv_free_params(), which
is responsible for freeing the per-thread group storage.

For the proxies however it's OK because free calls are made before the
call to deinit_proxy() which frees the per_tgrp area.

No backport is needed, this is purely 3.4-dev.

6 weeks agoMEDIUM: counters: make EXTRA_COUNTERS_GET() consider tgid
Willy Tarreau [Wed, 25 Feb 2026 08:58:08 +0000 (09:58 +0100)] 
MEDIUM: counters: make EXTRA_COUNTERS_GET() consider tgid

Now we store and retrieve only counters for the current tgid when more
than one is supported. This allows to significantly reduce contention
on shared stats. The haterm utility saw its performance increase from
4.9 to 5.8M req/s in H1, and 6.0 to 7.6M for H2, both with 5 groups of
16 threads, showing that we don't necessarily need insane amounts of
groups.

6 weeks agoMEDIUM: counters: return aggregate extra counters in ->fill_stats()
Willy Tarreau [Wed, 25 Feb 2026 17:38:55 +0000 (18:38 +0100)] 
MEDIUM: counters: return aggregate extra counters in ->fill_stats()

Now thanks to new macro EXTRA_COUNTERS_AGGR() we can iterate over all
thread groups storages when returning the data for a given metric. This
remains convenient and mostly transparent. The caller continues to pass
the pointer to the metric in the first group, and offsets are calculated
for all other groups and data summed. For now all groups except the
first one contain only zeroes but reported values are nevertheless
correct.

6 weeks agoMINOR: counters: add EXTRA_COUNTERS_BASE() to retrieve extra_counters base storage
Willy Tarreau [Wed, 25 Feb 2026 09:13:21 +0000 (10:13 +0100)] 
MINOR: counters: add EXTRA_COUNTERS_BASE() to retrieve extra_counters base storage

The goal is to always retrieve the storage address of the first thread
group for the given module. This will be used to iterate over all thread
groups. For now it returns the same value as EXTRA_COUNTERS_GET().

6 weeks agoMEDIUM: counters: store the number of thread groups accessing extra_counters
Willy Tarreau [Wed, 25 Feb 2026 15:06:21 +0000 (16:06 +0100)] 
MEDIUM: counters: store the number of thread groups accessing extra_counters

In order to be able to properly allocate all storage and retrieve data
from there, we'll need to know how many thread groups are supposed to
access it. Let's store the number of thread groups at init time. If the
tgrp_step is zero, there's always only one tg though.

Now EXTRA_COUNTERS_ALLOC() takes this number of thread groups in argument
and stores it in the structure. It also allocates as many areas as needed,
incrementing the datap pointer by the step for each of them.

EXTRA_COUNTERS_FREE() uses this info to free all allocated areas.

EXTRA_COUNTERS_INIT() initializes all allocated areas, this is used
elsewhere to clear/preset counters, e.g. in proxy_stats_clear_counters().
It involves a memcpy() call for each array, which is normally preset to
something empty but might also be used to preset certain non-scalar
fields such as an instance name.

6 weeks agoMINOR: counters: store a tgroup step for extra_counters to access multiple tgroups
Willy Tarreau [Wed, 25 Feb 2026 08:53:13 +0000 (09:53 +0100)] 
MINOR: counters: store a tgroup step for extra_counters to access multiple tgroups

We'll need to permit any user to update its own tgroup's extra counters
instead of the global ones. For this we now store the per-tgroup step
between two consecutive data storages, for when they're stored in a
tgroup array. When shared (e.g. resolvers or listeners), we just store
zero to indicate that it doesn't scale with tgroups. For now only the
registration was handled, it's not used yet.

6 weeks agoMEDIUM: counters: add a dedicated storage for extra_counters in various structs
Willy Tarreau [Tue, 24 Feb 2026 19:08:49 +0000 (20:08 +0100)] 
MEDIUM: counters: add a dedicated storage for extra_counters in various structs

Servers, proxies, listeners and resolvers all use extra_counters. We'll
need to move the storage to per-tgroup for those where it matters. Now
we're relying on an external storage, and the data member of the struct
was replaced with a pointer to that pointer to data called datap. When
the counters are registered, these datap are set to point to relevant
locations. In the case of proxies and servers, it points to the first
tgrp's storage. For listeners and resolvers, it points to a local
storage. The rationale here is that listeners are limited to a single
group anyway, and that resolvers have a low enough load so that we do
not care about contention there.

Nothing should change for the user at this point.

6 weeks agoCLEANUP: counters: only retrieve zeroes for unallocated extra_counters
Willy Tarreau [Wed, 25 Feb 2026 13:24:33 +0000 (14:24 +0100)] 
CLEANUP: counters: only retrieve zeroes for unallocated extra_counters

Since version 2.4 with commit 7f8f6cb926 ("BUG/MEDIUM: stats: prevent
crash if counters not alloc with dummy one") we can afford to always
update extra_counters because we know they're always either allocated
or linked to a dedicated trash. However, the ->fill_stats() callbacks
continue to access such values, making it technically possible to
retrieve random counters from this trash, which is not really clean.
Let's implement an explicit test in the ->fill_stats() functions to
only return 0 for the metric when not allocated like this. It's much
cleaner because it guarantees that we're returning an empty counter
in this case rather than random values.

The situation currently happens for dummy servers like the ones used
in Lua proxies as well as those used by rings (e.g. used for logging
or traces). Normally, none of the objects retrieved via stats or
Prometheus is concerned by this unallocated extra_counters situation,
so this is more about a cleanup than a real fix.

6 weeks agoMEDIUM: counters: change the fill_stats() API to pass the module and extra_counters
Willy Tarreau [Wed, 25 Feb 2026 10:44:48 +0000 (11:44 +0100)] 
MEDIUM: counters: change the fill_stats() API to pass the module and extra_counters

We'll soon need to iterate over thread groups in the fill_stats() functions,
so let's first pass the extra_counters and stats_module pointers to the
fill_stats functions. They now call EXTRA_COUNTERS_GET() themselves with
these elements in order to retrieve the required pointer. Nothing else
changed, and it's getting even a bit more transparent for callers.

This doesn't change anything visible however.

6 weeks agoCLEANUP: stats: drop stats.h / stats-t.h where not needed
Willy Tarreau [Tue, 24 Feb 2026 18:31:51 +0000 (19:31 +0100)] 
CLEANUP: stats: drop stats.h / stats-t.h where not needed

A number of C files include stats.h or stats-t.h, many of which were
just to access the counters. Now those which really need counters rely
on counters.h or counters-t.h, which already reduces the amount of
preprocessed code to be built (~3000 lines or about 0.05%).

6 weeks agoREORG: stats/counters: move extra_counters to counters not stats
Willy Tarreau [Tue, 24 Feb 2026 17:57:05 +0000 (18:57 +0100)] 
REORG: stats/counters: move extra_counters to counters not stats

It was always difficult to find extra_counters when the rest of the
counters are now in counters-t.h. Let's move the types to counters-t.h
and the macros to counters.h. Stats include them since they're used
there. But some users could be cleaned from the stats definitions now.

6 weeks agoCLEANUP: quic-stats: include counters from quic_stats
Willy Tarreau [Tue, 24 Feb 2026 17:50:30 +0000 (18:50 +0100)] 
CLEANUP: quic-stats: include counters from quic_stats

There's something a bit awkward in the way stats counters are inherited
through the QUIC modules: quic_conn-t includes quic_stats-t.h, which
declares quic_stats_module as extern from a type that's not known from
this file. And anyway externs should not be exported from type defintions
since they're not part of the ABI itself.

This commit moves the declaration to quic_stats.h which now takes care
to include stats-t.h to get the definition of struct stats_module. The
few users who used to learn it through quic_conn-t.h now include it
explicitly. As a bonus this reduces the number of preprocessed lines
by 5000 (~0.1%).

By the way, it looks like struct stats_module could benefit from being
moved off stats-t.h since it's only used at places where the rest of
the stats is not needed. Maybe something to consider for a future
cleanup.

6 weeks agoCLEANUP: tree-wide: drop a few useless null-checks before free()
Willy Tarreau [Wed, 25 Feb 2026 09:40:48 +0000 (10:40 +0100)] 
CLEANUP: tree-wide: drop a few useless null-checks before free()

We only support platforms where free(NULL) is a NOP so that
null checks are useless before free(). Let's drop them to keep
the code clean. There were a few in cfgparse-global, flt_trace,
ssl_sock and stats.

6 weeks agoBUG/MINOR: server: adjust initialization order for dynamic servers
Willy Tarreau [Tue, 24 Feb 2026 19:28:50 +0000 (20:28 +0100)] 
BUG/MINOR: server: adjust initialization order for dynamic servers

It appears that in cli_parse_add_server(), we're calling srv_alloc_lb()
and stats_allocate_proxy_counters_internal() before srv_preinit() which
allocates the thread groups. LB algos can make use of the per_tgrp part
which is initialized by srv_preinit(). Fortunately for now no algo uses
both tgrp and ->server_init() so this explains why this remained
unnoticed to date. Also, extra counters will soon require per_tgrp to
already be initialized. So let's move these between srv_preinit() and
srv_postinit(). It's possible that other parts will have to be moved
in between.

This could be backported to recent versions for the sake of safety but
it looks like the current code cannot tell the difference.

6 weeks agoBUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream
Willy Tarreau [Wed, 25 Feb 2026 23:18:44 +0000 (00:18 +0100)] 
BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream

Some stream parsing errors that do not affect the connection result in
the parsed block not being transferred from the rx buffer to the channel
and not being reported upstream in rcv_buf(), causing the stconn to time
out. Let's detect this condition, and propagate term flags anyway since
no more progress will be made otherwise.

This should be backported at least till 3.2, probably even 2.8.

6 weeks agoMINOR: mux-h2: add a new setting, "tune.h2.log-errors" to tweak error logging
Willy Tarreau [Wed, 25 Feb 2026 21:39:35 +0000 (22:39 +0100)] 
MINOR: mux-h2: add a new setting, "tune.h2.log-errors" to tweak error logging

The H2 mux currently logs whenever some decoding fails. Most of the errors
happen at the connection level, but some are even at the stream level,
meaning that multiple logs can be emitted for a given connection, which
can quickly use some resource for little value. This new setting allows
to tweak this and decide to only log errors that affect the connection,
or even none at all.

This should be backported at least as far as 3.2.

6 weeks agoMINOR: mux-h2: also count glitches on invalid trailers
Willy Tarreau [Wed, 25 Feb 2026 21:02:13 +0000 (22:02 +0100)] 
MINOR: mux-h2: also count glitches on invalid trailers

Two cases were not causing glitches to be incremented:
  - invalid trailers
  - trailers on closed streams

This patch addresses this. It could be backported, at least to 3.2.

6 weeks agoCLEANUP: ssl: remove outdated comments
Frederic Lecaille [Wed, 25 Feb 2026 10:25:05 +0000 (11:25 +0100)] 
CLEANUP: ssl: remove outdated comments

ssl_sock_srv_try_reuse_sess() was modified by this commit to no longer
fail (it now returns void), but the related comments remained:

  BUG/MINOR: quic: missing app ops init during backend 0-RTT sessions

This patch cleans them up.

6 weeks agoBUG/MINOR: quic: missing app ops init during backend 0-RTT sessions
Frederic Lecaille [Tue, 24 Feb 2026 18:22:50 +0000 (19:22 +0100)] 
BUG/MINOR: quic: missing app ops init during backend 0-RTT sessions

The QUIC mux requires "application operations" (app ops), which are a list
of callbacks associated with the application level (i.e., h3, h0.9) and
derived from the ALPN. For 0-RTT, when the session cache cannot be reused
before activation, the current code fails to reach the initialization of
these app ops, causing the mux to crash during its initialization.

To fix this, this patch restores the behavior of
ssl_sock_srv_try_reuse_sess(), whose purpose was to reuse sessions stored
in the session cache regardless of whether 0-RTT was enabled, prior to
this commit:

  MEDIUM: quic-be: modify ssl_sock_srv_try_reuse_sess() to reuse backend
  sessions (0-RTT)

With this patch, this function now does only one thing: attempt to reuse a
session, and that's it!

This patch allows ignoring whether a session was successfully reused from
the cache or not. This directly fixes the issue where app ops
initialization was skipped upon a session cache reuse failure. From a
functional standpoint, starting a mux without reusing the session cache
has no negative impact; the mux will start, but with no early data to
send.

Finally, there is the case where the ALPN is reset when the backend is
stopped. It is critical to continue locking read access to the ALPN to
secure shared access, which this patch does. It is indeed possible for the
server to be stopped between the call to connect_server() and
quic_reuse_srv_params(). But this cannot prevent the mux to start
without app ops. This is why a 'TODO' section was added, as a reminder that a
race condition regarding the ALPN reset still needs to be fixed.

Must be backported to 3.3

6 weeks agoBUG/MEDIUM: cpu-topo: Distribute CPUs fairly across groups
Olivier Houchard [Wed, 18 Feb 2026 10:22:04 +0000 (10:22 +0000)] 
BUG/MEDIUM: cpu-topo: Distribute CPUs fairly across groups

Make sure CPUs are distributed fairly across groups, in case the number
of groups to generate is not a divider of the number of CPUs, otherwise
we may end up with a few groups that will have no CPU bound to them.

This was introduced in 3.4-dev2 with commit 56fd0c1a5c ("MEDIUM: cpu-topo:
Add an optional directive for per-group affinity"). No backport is
needed unless this commit is backported.

6 weeks agoBUG/MINOR: haterm: cannot reset default "haterm" mode
Frederic Lecaille [Mon, 23 Feb 2026 16:10:56 +0000 (17:10 +0100)] 
BUG/MINOR: haterm: cannot reset default "haterm" mode

When "mode haterm" was set in a "defaults" section, it could not be
overridden in subsequent sections using the "mode" keyword. This is because
the proxy stream instantiation callback was not being reset to the
default stream_new() value.

This could break the stats URI with a configuration such as:

    defaults
        mode haterm
        # ...

    frontend stats
bind :8181
mode http
stats uri /

This patch ensures the ->stream_new_from_sc() proxy callback is reset
to stream_new() when the "mode" keyword is parsed for any mode other
than "haterm".

No need to backport.

6 weeks agoMINOR: quic: add a new metric for ncbuf failures
Maxime Henrion [Mon, 23 Feb 2026 16:25:53 +0000 (11:25 -0500)] 
MINOR: quic: add a new metric for ncbuf failures

This counts the number of times we failed to add data to the ncbuf
buffer because of the gap size limit.

6 weeks agoMINOR: proxy: improve code when checking server name conflicts
Amaury Denoyelle [Mon, 23 Feb 2026 09:10:05 +0000 (10:10 +0100)] 
MINOR: proxy: improve code when checking server name conflicts

During proxy_finalize(), a lookup is performed over the servers by name
tree to detect any collision. Only the first conflict for each server
instance is reported to avoid a combinatory explosion with too many
alerts shown.

Previously, this was written using a for loop without any iteration.
Replace this by a simple if statement as this is cleaner.

This should fix github issue #3276.

6 weeks agoMINOR: ncbmbuf: improve itbmap_next() code
Amaury Denoyelle [Mon, 23 Feb 2026 09:04:45 +0000 (10:04 +0100)] 
MINOR: ncbmbuf: improve itbmap_next() code

itbmap_next() advances an iterator over a ncbmbuf buffer storage. When
reaching the end of the buffer, <b> field is set to NULL, and the caller
is expected to stop working with the iterator.

Complete this part to ensure that itbmap type is fully initialized in
case null iterator value is returned. This is not strictly required
given the above description, but this is better to avoid any possible
future mistake.

This should fix coverity issue from github #3273.

This could be backported up to 2.8.

6 weeks agoMINOR: traces: always mark trace_source as thread-aligned
Willy Tarreau [Mon, 23 Feb 2026 15:19:48 +0000 (16:19 +0100)] 
MINOR: traces: always mark trace_source as thread-aligned

Some perf profiles occasionally show that reading the trace source's
state can take some time, which is not expected at all. It just happens
that the trace_source is not cache-aligned so depending on linkage, it
may share a cache line with a more active variable, thereby inducing a
slow down to all threads trying to read the variable.

Let's always mark it aligned to avoid this. For now the problem was not
observed again.

6 weeks agoBUG/MEDIUM: spoe: Acquire context buffer in applet before consuming a frame
Christopher Faulet [Mon, 23 Feb 2026 13:31:17 +0000 (14:31 +0100)] 
BUG/MEDIUM: spoe: Acquire context buffer in applet before consuming a frame

Changes brought to support large buffers revealed a bug in the SPOE applet
when a frame is copied in the SPOE context buffer. A b_xfer() was performed
without allocating the SPOE context buffer. It is not expected. As stated in
the function documentation, the caller is responsible for ensuring there is
enough space in the destination buffer. So first of all, it must ensure this
buffer was allocated.

With recent changes, we are able to hit a BUG_ON() because the swap is no
longer possible if source and destination buffers size are not the same.

This patch should fix the issue #3286. It could be backported as far as 3.1.

6 weeks agoCLENAUP: cfgparse: accept-invalid-http-* does not support "no"/"defaults"
Willy Tarreau [Mon, 23 Feb 2026 14:42:04 +0000 (15:42 +0100)] 
CLENAUP: cfgparse: accept-invalid-http-* does not support "no"/"defaults"

Some options do not support "no" nor "defaults" and they're placed after
the check for their absence. However, "accept-invalid-http-request" and
"accept-invalid-http-response" still used to check for the flags that
come with these prefixes, but Coverity noticed this was dead code in
github issue #3272. Let's just drop the test.

No backport needed as it's just dead code.

6 weeks agoCI: remove redundant "halog" compilation
Ilia Shipitsin [Sun, 22 Feb 2026 18:01:10 +0000 (19:01 +0100)] 
CI: remove redundant "halog" compilation

since 6499c0a0d5eb56ae640a50425f2fbbad3bc14f86 halog is being build
in vtest workflow, no need to build it two times

6 weeks agoCI: use the latest docker for QUIC Interop
Ilia Shipitsin [Sat, 21 Feb 2026 22:48:36 +0000 (23:48 +0100)] 
CI: use the latest docker for QUIC Interop

quic-interop runner is using features available in Docker v28.1
while Github runner includes v28.0

let's for sure setup the latest available

6 weeks agoCLEANUP: ssl: Remove a useless variable from ssl_gen_x509()
Frederic Lecaille [Mon, 23 Feb 2026 09:47:15 +0000 (10:47 +0100)] 
CLEANUP: ssl: Remove a useless variable from ssl_gen_x509()

This function was recently created by moving code from acme_gen_tmp_x509()
(in acme.c) to ssl_gencrt.c (ssl_gen_x509()). The <ctmp> variable was
initialized and then freed without ever being used. This was already the
case in the original acme_gen_tmp_x509() function.

This patch removes these useless statements.

Reported in GH #3284

6 weeks agoCLEANUP: haterm: avoid static analyzer warnings about rand() use
Frederic Lecaille [Mon, 23 Feb 2026 09:39:59 +0000 (10:39 +0100)] 
CLEANUP: haterm: avoid static analyzer warnings about rand() use

Avoid such a warnings from coverity:

CID 1645121: (#1 of 1): Calling risky function (DC.WEAK_CRYPTO)
dont_call: random should not be used for security-related applications,
because linear congruential algorithms are too easy to break.

Reported in GH #3283 and #3285

6 weeks agoCLEANUP: haterm: remove unreachable labels hstream_add_data()
Frederic Lecaille [Mon, 23 Feb 2026 09:13:25 +0000 (10:13 +0100)] 
CLEANUP: haterm: remove unreachable labels hstream_add_data()

This function does not return a status. It nevers fails.
Remove some useled dead code.

6 weeks agoBUG/MINOR: acme: fix incorrect number of arguments allowed in config
Mia Kanashi [Sun, 22 Feb 2026 23:06:13 +0000 (01:06 +0200)] 
BUG/MINOR: acme: fix incorrect number of arguments allowed in config

Fix incorrect number of arguments allowed in config for keywords
"chalenge" and "account-key".

6 weeks agoMINOR: ssl: clarify error reporting for unsupported keywords
Hyeonggeun Oh [Mon, 23 Feb 2026 03:49:37 +0000 (12:49 +0900)] 
MINOR: ssl: clarify error reporting for unsupported keywords

This patch changes the registration of the following keywords to be
unconditional:
  - ssl-dh-param-file
  - ssl-engine
  - ssl-propquery, ssl-provider, ssl-provider-path
  - ssl-default-bind-curves, ssl-default-server-curves
  - ssl-default-bind-sigalgs, ssl-default-server-sigalgs
  - ssl-default-bind-client-sigalgs, ssl-default-server-client-sigalgs

Instead of excluding them at compile time via #ifdef guards in the keyword
registration table, their parsing functions now check feature availability
at runtime and return a descriptive error when the feature is missing.

For features controlled by the SSL library (providers, curves, sigalgs,
DH), the error message includes the actual OpenSSL version string via
OpenSSL_version(OPENSSL_VERSION), so users can immediately identify which
library they are running rather than seeing cryptic internal macro names.

For ssl-dh-param-file, the message also includes "(no DH support)" as a
hint, since OPENSSL_NO_DH can be set either by an OpenSSL build or by
HAProxy itself in certain configurations.

For ssl-engine, which depends on a HAProxy build-time flag (USE_ENGINE),
the message retains the flag name as it is more actionable for the user.

This addresses issue https://github.com/haproxy/haproxy/issues/3246.

6 weeks agoBUG/MINOR: acme: wrong labels logic always memprintf errmsg
William Lallemand [Sat, 21 Feb 2026 15:24:22 +0000 (16:24 +0100)] 
BUG/MINOR: acme: wrong labels logic always memprintf errmsg

In acme_req_finalize(), acme_req_challenge(), acme_req_neworder(),
acme_req_account(), and acme_post_as_get(), the success path always
calls unconditionally memprintf(errmsg, ...).

This may result in a leak of errmsg.

Additionally, acme_res_chkorder(), acme_res_finalize(), acme_res_auth(),
and acme_res_neworder() had unused 'out:' labels that were removed.

Must be backported as far as 3.2.

6 weeks agoBUG/MINOR: acme: acme_ctx_destroy() leaks auth->dns
William Lallemand [Sat, 21 Feb 2026 15:03:17 +0000 (16:03 +0100)] 
BUG/MINOR: acme: acme_ctx_destroy() leaks auth->dns

365a696 ("MINOR: acme: emit a log for DNS-01 challenge response")
introduces the auth->dns member which is istdup(). But this member is
never free, instead auth->token was freed twice by mistake.

Must be backported to 3.2.

7 weeks agoBUG/MINOR: quic/h3: display QUIC/H3 backend module on HTML stats
Amaury Denoyelle [Fri, 20 Feb 2026 10:18:10 +0000 (11:18 +0100)] 
BUG/MINOR: quic/h3: display QUIC/H3 backend module on HTML stats

QUIC is now implemented on the backend side. Complete definitions for
QUIC/H3 stats module to add STATS_PX_CAP_BE capability.

This change is necessary to display QUIC/H3 counters on backend lines
for HTML stats page.

This should be backported up to 3.3.

7 weeks agoMINOR: quic: add BUG_ON() on half_open_conn counter access from BE
Amaury Denoyelle [Fri, 20 Feb 2026 10:05:40 +0000 (11:05 +0100)] 
MINOR: quic: add BUG_ON() on half_open_conn counter access from BE

half_open_conn is a proxy counter used to account for quic_conn in
half-open state : this represents a connection whose address is not yet
validated (handshake successful, or via token validation).

This counter only has sense for the frontend side. Currently, code is
safe as access is only performed if quic_conn is not yet flagged with
QUIC_FL_CONN_PEER_VALIDATED_ADDR, which is always set for backend
connections.

To better reflect this, add a BUG_ON() when half_open_conn is
incremented/decremented to ensure this never occurs for backend
connections.

7 weeks agoBUG/MINOR: quic: fix counters used on BE side
Amaury Denoyelle [Fri, 20 Feb 2026 10:05:20 +0000 (11:05 +0100)] 
BUG/MINOR: quic: fix counters used on BE side

quic_conn is initialized with a pointer to its proxy counters. These
counters are then updated during the connection lifetime.

Counters pointer was incorrect for backend quic_conn, as it always
referenced frontend counters. For pure backend, no stats would be
updated. For listen instances, this resulted in incorrect stats
reporting.

Fix this by correctly set proxy counters based on the connection side.

This must be backported up to 3.3.

7 weeks agoBUG/MINOR: haterm: missing allocation check in copy_argv()
Frederic Lecaille [Fri, 20 Feb 2026 11:12:10 +0000 (12:12 +0100)] 
BUG/MINOR: haterm: missing allocation check in copy_argv()

This is a very minor bug with a very low probability of occurring.
However, it could be flagged by a static analyzer or result in a small
contribution, which is always time-consuming for very little gain.

7 weeks agoMINOR: haterm: add long options for QUIC and TCP "bind" settings
Frederic Lecaille [Fri, 20 Feb 2026 11:00:34 +0000 (12:00 +0100)] 
MINOR: haterm: add long options for QUIC and TCP "bind" settings

Add the --quic-bind-opts and --tcp-bind-opts long options to append
settings to all QUIC and TCP bind lines. This requires modifying the argv
parser to first process these new options, ensuring they are available
during the second argv pass to be added to each relevant "bind" line.

7 weeks agoMINOR: haterm: provide -b and -c options (RSA key size, ECDSA curves)
Frederic Lecaille [Fri, 20 Feb 2026 09:40:04 +0000 (10:40 +0100)] 
MINOR: haterm: provide -b and -c options (RSA key size, ECDSA curves)

Add -b and -c options to the haterm argv parser. Use -b to specify the RSA
private key size (in bits) and -c to define the ECDSA certificate curves.
These self-signed certificates are required for haterm SSL bindings.

7 weeks agoBUG/MINOR: server: enable no-check-sni-auto for dynamic servers
Amaury Denoyelle [Thu, 19 Feb 2026 15:38:39 +0000 (16:38 +0100)] 
BUG/MINOR: server: enable no-check-sni-auto for dynamic servers

Allows server keyword "no-check-sni-auto" for dynamic servers. This may
be necessary to users who do not want to benefit from auto SNI for
checks.

Keyword "check-sni-auto" is still deactivated for dynamic servers, for
the same reason as "sni-auto" (cf the previous patch for a complete
explanation).

This must be backported up to 3.3.

7 weeks agoBUG/MINOR: server: set auto SNI for dynamic servers
Amaury Denoyelle [Thu, 19 Feb 2026 15:31:25 +0000 (16:31 +0100)] 
BUG/MINOR: server: set auto SNI for dynamic servers

Auto SNI configuration is configured during check config validity.
However, nothing was implemented for dynamic servers.

Fix this by implementing auto SNI configuration during "add server" CLI
handler. Auto SNI configuration code is moved in a dedicated function
srv_configure_auto_sni() called both for static and dynamic servers.

Along with this, allows the keyword "no-sni-auto" on dynamic servers, so
that this process can be deactivated if wanted. Note that "sni-auto"
remains unavailable as it only makes sense with default-servers which
are never used for dynamic server creation.

This must be backported up to 3.3.

7 weeks agoBUG/MINOR: proxy: detect strdup error on server auto SNI
Amaury Denoyelle [Thu, 19 Feb 2026 15:04:04 +0000 (16:04 +0100)] 
BUG/MINOR: proxy: detect strdup error on server auto SNI

There was no check on the result of strdup() used to setup auto SNI on a
server instance during check config validity. In case of failure, the
error would be silently ignored as the following server_parse_exprs()
does nothing when <sni_expr> server field is NULL. Hence, no SNI would
be used on the server, without any error nor warning reported.

Fix this by adding a check on strdup() return value. On error, ERR_ABORT
is reported along with an alert, parsing should be interrupted as soon
as possible.

This must be backported up to 3.3. Note that the related code in this
case is present in cfgparse.c source file.

7 weeks agoCLEANUP: acme: remove duplicate includes
William Lallemand [Thu, 19 Feb 2026 22:57:20 +0000 (23:57 +0100)] 
CLEANUP: acme: remove duplicate includes

Remove a bunch of duplicate includes in acme.c.

7 weeks ago[RELEASE] Released version 3.4-dev5 v3.4-dev5
Willy Tarreau [Thu, 19 Feb 2026 15:26:52 +0000 (16:26 +0100)] 
[RELEASE] Released version 3.4-dev5

Released version 3.4-dev5 with the following main changes :
    - DOC: internals: addd mworker V3 internals
    - BUG/MINOR: threads: Initialize maxthrpertgroup earlier.
    - BUG/MEDIUM: threads: Differ checking the max threads per group number
    - BUG/MINOR: startup: fix allocation error message of progname string
    - BUG/MINOR: startup: handle a possible strdup() failure
    - MINOR: cfgparse: validate defaults proxies separately
    - MINOR: cfgparse: move proxy post-init in a dedicated function
    - MINOR: proxy: refactor proxy inheritance of a defaults section
    - MINOR: proxy: refactor mode parsing
    - MINOR: backend: add function to check support for dynamic servers
    - MINOR: proxy: define "add backend" handler
    - MINOR: proxy: parse mode on dynamic backend creation
    - MINOR: proxy: parse guid on dynamic backend creation
    - MINOR: proxy: check default proxy compatibility on "add backend"
    - MEDIUM: proxy: implement dynamic backend creation
    - MINOR: proxy: assign dynamic proxy ID
    - REGTESTS: add dynamic backend creation test
    - BUG/MINOR: proxy: fix clang build error on "add backend" handler
    - BUG/MINOR: proxy: fix null dereference in "add backend" handler
    - MINOR: net_helper: extend the ip.fp output with an option presence mask
    - BUG/MINOR: proxy: fix default ALPN bind settings
    - CLEANUP: lb-chash: free lb_nodes from chash's deinit(), not global
    - BUG/MEDIUM: lb-chash: always properly initialize lb_nodes with dynamic servers
    - CLEANUP: haproxy: fix bad line wrapping in run_poll_loop()
    - MINOR: activity: support setting/clearing lock/memory watching for task profiling
    - MEDIUM: activity: apply and use new finegrained task profiling settings
    - MINOR: activity: allow to switch per-task lock/memory profiling at runtime
    - MINOR: startup: Add the SSL lib verify directory in haproxy -vv
    - BUG/MINOR: ssl: SSL_CERT_DIR environment variable doesn't affect haproxy
    - CLEANUP: initcall: adjust comments to INITCALL{0,1} macros
    - DOC: proxy-proto: underline the packed attribute for struct pp2_tlv_ssl
    - MINOR: queues: Check minconn first in srv_dynamic_maxconn()
    - MINOR: servers: Call process_srv_queue() without lock when possible
    - BUG/MINOR: quic: ensure handshake speed up is only run once per conn
    - BUG/MAJOR: quic: reject invalid token
    - BUG/MAJOR: quic: fix parsing frame type
    - MINOR: ssl: Missing '\n' in error message
    - MINOR: jwt: Convert an RSA JWK into an EVP_PKEY
    - MINOR: jwt: Add new jwt_decrypt_jwk converter
    - REGTESTS: jwt: Add new "jwt_decrypt_jwk" tests
    - MINOR: startup: Add HAVE_WORKING_TCP_MD5SIG in haproxy -vv
    - MINOR: startup: sort the feature list in haproxy -vv
    - MINOR: startup: show the list of detected features at runtime with haproxy -vv
    - SCRIPTS: build-vtest: allow to set a TMPDIR and a DESTDIR
    - MINOR: filters: rework RESUME_FILTER_* macros as inline functions
    - MINOR: filters: rework filter iteration for channel related callback functions
    - MEDIUM: filters: use per-channel filter list when relevant
    - DEV: gdb: add a utility to find the post-mortem address from a core
    - BUG/MINOR: deviceatlas: add missing return on error in config parsers
    - BUG/MINOR: deviceatlas: add NULL checks on strdup() results in config parsers
    - BUG/MEDIUM: deviceatlas: fix resource leaks on init error paths
    - BUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()
    - BUG/MINOR: deviceatlas: fix cookie vlen using wrong length after extraction
    - BUG/MINOR: deviceatlas: fix double-checked locking race in checkinst
    - BUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure
    - BUG/MINOR: deviceatlas: fix deinit to only finalize when initialized
    - BUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance
    - MINOR: deviceatlas: check getproptype return and remove pprop indirection
    - MINOR: deviceatlas: increase DA_MAX_HEADERS and header buffer sizes
    - MINOR: deviceatlas: define header_evidence_entry in dummy library header
    - MINOR: deviceatlas: precompute maxhdrlen to skip oversized headers early
    - CLEANUP: deviceatlas: add unlikely hints and minor code tidying
    - DEV: gdb: use unsigned longs to display pools memory usage
    - BUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration
    - BUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser
    - BUG/MINOR: ssl: fix leak in ssl-f-use parser upon error
    - BUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing
    - BUG/MINOR: ssl: error with ssl-f-use when no "crt"
    - MEDIUM: backend: make "balance random" consider tg local req rate when loads are equal
    - BUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally closed QCS"
    - BUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented
    - MINOR: mux-quic: add BUG_ON_STRESS() when draining data on closed stream
    - REGTESTS: fix quoting in feature cmd which prevents test execution
    - BUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is closed
    - BUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states
    - BUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)
    - DEV: term-events: Fix hanshake events decoding
    - BUG/MINOR: flt-trace: Properly compute length of the first DATA block
    - MINOR: flt-trace: Add an option to limit the amount of data forwarded
    - CLEANUP: compression: Remove unused static buffers
    - BUG/MEDIUM: shctx: Use the next block when data exactly filled a block
    - BUG/MINOR: http-ana: Stop to wait for body on client error/abort
    - MINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags
    - REORG: stconn: Move functions related to channel buffers to sc_strm.h
    - BUG/MEDIUM: jwe: fix timing side-channel and dead code in JWE decryption
    - MINOR: tree-wide: Use the buffer size instead of global setting when possible
    - MINOR: buffers: Swap buffers of same size only
    - BUG/MINOR: config: Check buffer pool creation for failures
    - MEDIUM: cache: Don't rely on a chunk to store messages payload
    - MEDIUM: stream: Limit number of synchronous send per stream wakeup
    - MEDIUM: compression: Be sure to never compress more than a chunk at once
    - MEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size
    - MEDIUM: applet: Disable 0-copy for buffers of different size
    - MINOR: h1-htx: Disable 0-copy for buffers of different size
    - MEDIUM: stream: Offer buffers of default size only
    - BUG/MEDIUM: htx: Fix function used to change part of a block value when defrag
    - MEDIUM: htx: Refactor transfer of htx blocks to merge DATA blocks if possible
    - MEDIUM: htx: Refactor htx defragmentation to merge data blocks
    - MEDIUM: htx: Improve detection of fragmented/unordered HTX messages
    - MINOR: http-ana: Do a defrag on unaligned HTX message when waiting for payload
    - MINOR: http-fetch: Use pointer to HTX DATA block when retrieving HTX body
    - MEDIUM: dynbuf: Add a pool for large buffers with a configurable size
    - MEDIUM: chunk: Add support for large chunks
    - MEDIUM: stconn: Properly handle large buffers during a receive
    - MEDIUM: sample: Get chunks with a size dependent on input data when necessary
    - MEDIUM: http-fetch: Be able to use large chunks when necessary
    - MINPR: htx: Get large chunk if necessary to perform a defrag
    - MEDIUM: http-ana: Use a large buffer if necessary when waiting for body
    - MINOR: dynbuf: Add helpers to know if a buffer is a default or a large buffer
    - MINOR: config: reject configs using HTTP with large bufsize >= 256 MB
    - CI: do not use ghcr.io for Quic Interop workflows
    - BUG/MEDIUM: ssl: SSL backend sessions used after free
    - CI: vtest: move the vtest2 URL to vinyl-cache.org
    - CI: github: disable windows.yml by default on unofficials repo
    - MEDIUM: Add connect/queue/tarpit timeouts to set-timeout
    - CLEANUP: mux-h1: Remove unneeded null check
    - DOC: remove openssl no-deprecated CI image
    - BUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails
    - BUG/MINOR: backend: check delay MUX before conn_prepare()
    - OPTIM: backend: reduce contention when checking MUX init with ALPN
    - DOC: configuration: add the ACME wiki page link
    - MINOR: ssl/ckch: Move EVP_PKEY and cert code generation from acme
    - MINOR: ssl/ckch: certificates generation from "load" "crt-store" directive
    - MINOR: trace: add definitions for haterm streams
    - MINOR: init: allow a fileless init mode
    - MEDIUM: init: allow the redefinition of argv[] parsing function
    - MINOR: stconn: stream instantiation from proxy callback
    - MINOR: haterm: add haterm HTTP server
    - MINOR: haterm: new "haterm" utility
    - MINOR: haterm: increase thread-local pool size
    - BUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full
    - BUG/MINOR: stats-file: manipulate shm-stats-file heartbeat using unsigned int
    - BUG/MEDIUM: stats-file: detect and fix inconsistent shared clock when resuming from shm-stats-file
    - CI: github: only enable OS X on development branches

7 weeks agoCI: github: only enable OS X on development branches
William Lallemand [Thu, 19 Feb 2026 13:51:05 +0000 (14:51 +0100)] 
CI: github: only enable OS X on development branches

Don't use the macOS job on maintenance branches, it's mainly use for
development and checking portability, but we don't support actively
macOS on stable branches.

7 weeks agoBUG/MEDIUM: stats-file: detect and fix inconsistent shared clock when resuming from...
Aurelien DARRAGON [Thu, 19 Feb 2026 12:53:11 +0000 (13:53 +0100)] 
BUG/MEDIUM: stats-file: detect and fix inconsistent shared clock when resuming from shm-stats-file

When leveraging shm-stats-file, global_now_ms and global_now_ns are stored
(and thus shared) inside the shared map, so that all co-processes share
the same clock source.

Since the global_now_{ns,ms} clocks are derived from now_ns, and given
that now_ns is a monotonic clock (hence inconsistent from one host to
another or reset after reboot) special care must be taken to detect
situations where the clock stored in the shared map is inconsistent
with the one from the local process during startup, and cannot be
relied upon anymore. A common situation where the current implementation
fails is resuming from a shared file after reboot: the global_now_ns stored
in the shm-stats-file will be greater than the local now_ns after reboot,
and applying the shared offset doesn't help since it was only relevant to
processes prior to rebooting. Haproxy's clock code doesn't expect that
(once the now offset is applied) global_now_ns > now_ns, and it creates
ambiguous situation where the clock computations (both haproxy oriented
and shm-stats-file oriented) are broken.

To fix the issue, when we detect that the clock stored in the shm is
off by more than SHM_STATS_FILE_HEARTBEAT_TIMEOUT (60s) from the
local now_ns, since this situation is not supposed to happen in normal
environment on the host, we assume that the shm file was previously used
on a different system (or that the current host rebooted).

In this case, we perform a manually adjustment of the now offset so that
the monotonic clock from the current host is consistent again with the
global_now_ns stored in the file. Doing so we can ensure that clock-
dependent objects (such as freq_counters) stored within the map will keep
working as if we just (re)started where we left off when the last process
stopped updating the map.

Normally it is not expected that we update the now offset stored in the
map once the map was already created (because of concurrent accesses to
the file when multiple processes are attached to it), but in this specific
case, we know we are the first process on this host to start working
(again) on the file, thus we update the offset as if we created the
file ourself, while keeping existing content.

It should be backported in 3.3

7 weeks agoBUG/MINOR: stats-file: manipulate shm-stats-file heartbeat using unsigned int
Aurelien DARRAGON [Thu, 19 Feb 2026 13:59:52 +0000 (14:59 +0100)] 
BUG/MINOR: stats-file: manipulate shm-stats-file heartbeat using unsigned int

shm-stats-file heartbeat is derived from now_ms with an extra time added
to it, thus it should be handled using the same time as now_ms is.

Until now, we used to handle heartbeat using signed integer. This was not
found to cause severe harm but it could result in improper handling due
to early wrapping because of signedness for instance, so let's better fix
that before it becomes a real issue.

It should be backported in 3.3

7 weeks agoBUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full
Aurelien DARRAGON [Wed, 18 Feb 2026 16:04:03 +0000 (17:04 +0100)] 
BUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full

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

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

haproxy would segfault right after during clock update operation.

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

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

It should be backported in 3.3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Add the ACME page link to the HAProxy github wiki.

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

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

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

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

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

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

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

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

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

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

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

This must be backported up to 3.3.

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

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

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

Must be backported as far as 3.3.

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

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

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

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

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