haproxy-3.0.git
2 weeks agoREGTESTS: explicitly use "balance roundrobin" where RR is needed
Willy Tarreau [Thu, 4 Sep 2025 06:18:53 +0000 (08:18 +0200)]
REGTESTS: explicitly use "balance roundrobin" where RR is needed

A few tests explicitly rely on the server ordering granted by
"balance roundrobin", but didn't specify the balance algorithm.
As it will change soon, let's explicit it.

(cherry picked from commit 60931ceae9bd52db27dde002af2fe3232cd2b811)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 7f5293656fa3963cf4cee6376b20eb8a15703901)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0cc80c44505dfa528fecc68c3a460ab15e28d6ed)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: quic: Add more information about RX packets
Frederic Lecaille [Tue, 2 Sep 2025 08:48:33 +0000 (10:48 +0200)]
MINOR: quic: Add more information about RX packets

This patch is very useful to debug issues at RX packet processing level.

Should be easily backported as far as 2.6 (for debug purposes).

(cherry picked from commit 58b153b8824a12493ac9808403883db35496517a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit df2c048d089454f6d1426df0a5a0e43c79615a36)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit f93e6193ae69072931ec8dd3add4cc488f18eb51)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUILD: acl: silence a possible null deref warning in parse_acl_expr()
Willy Tarreau [Tue, 2 Sep 2025 15:41:51 +0000 (17:41 +0200)]
BUILD: acl: silence a possible null deref warning in parse_acl_expr()

The fix in commit 441cd614f9 ("BUG/MINOR: acl: set arg_list->kw to
aclkw->kw string literal if aclkw is found") involves an unchecked
access to "al" after that one is tested for possibly being NULL. This
rightfully upsets Coverity (GH #3095) and might also trigger warnings
depending on the compilers. However, no known caller to date passes
a NULL arg list here so there's no way to trigger this theoretical
bug.

This should be backported along with the fix above to avoid emitting
warnings, possibly as far as 2.6 since that fix was tagged as such.

(cherry picked from commit 4902195313f16eeca44507bfbc9e5b3b8016a61f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 137dccf2c7c0e066ed5008ebc2b6ac66bd143752)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit eb39181b955a677651e29eb2a276715d0be36b53)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: haproxy: be sure not to quit too early on soft stop
Willy Tarreau [Tue, 2 Sep 2025 09:26:50 +0000 (11:26 +0200)]
BUG/MINOR: haproxy: be sure not to quit too early on soft stop

The fix in 4a9e3e102e ("BUG/MINOR: haproxy: only tid 0 must not sleep
if got signal") had the nasty side effect of breaking the graceful
reload operations: threads whose id is non-zero could quit too early and
not process incoming traffic, which is visible with broken connections
during reloads. They just need to ignore the the stopping condition
until the signal queue is empty. In any case, it's the thread in charge
of the signal queue which will notify them once it receives the signal.

It was verified that connections are no longer broken with this fix,
and that the issue that required it (#2537, looping threads on reload)
does not re-appear with the reproducer, while it still did without the
fix above. Since the fix above was backported to every stable version,
this one will also have to.

(cherry picked from commit c128887b8ef1a9b010b5de6cef2879f1d8bc204c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 9462ca9ba5e0c24cd426c8e2611c38e35277a4cd)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit a8ce27cc8fcef0b7b49b031c4735bc8b4118c4df)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: fix padding issue on INITIAL retransmit
Amaury Denoyelle [Fri, 29 Aug 2025 12:07:47 +0000 (14:07 +0200)]
BUG/MINOR: quic: fix padding issue on INITIAL retransmit

On loss detection timer expiration, qc_dgrams_retransmit() is used to
reemit lost packets. Different code paths are present depending on the
active encryption level.

If Initial level is still initialized, retransmit is performed both for
Initial and Handshake spaces, by first retrieving the list of lost
frames for each of them.

Prior to this patch, Handshake level was always registered for emission
after Initial, even if it dit not have any frame to reemit. In this
case, most of the time it would result in a datagram containing Initial
reemitted frames packet coalesced with a Handshake packet consisting
only of a PADDING frame. This is because padding is only added for the
last registered QEL.

For QUIC backend support, this may cause issues. This is because
contrary to QUIC server side, Initial and Handshake levels keys are not
derived simultaneously for a QUIC client. Thus, if the latter keys are
unavailable, Handshake packet cannot be encoded in sending, leaving a
single Initial packet. However, this is now too late to add PADDING.
Thus the resulting datagram is invalid : this triggers the BUG_ON()
assert failure located on qc_txb_store().

This patch fixes this by amending qc_dgrams_retransmit(). Now, Handshake
level is only registered for emission if there is frame to retransmit,
which implies that Handshake keys are already available. Thus, PADDING
will now either be added at Initial or Handshake level as expected.

Note that this issue should not be present on QUIC frontend, due to
Initial and Handshake keys derivation almost simultaneously. However,
this should still be backported up to 3.0.

(cherry picked from commit e9b78e3fb17d91cb7502ed481e2fdfec5ad2a174)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit c7c033642e068c81c662e5a249e0c2dafe645873)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 61b5731dd90c58282c0f605d5117ef23ac0ca15f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: fix room check if padding requested
Amaury Denoyelle [Fri, 29 Aug 2025 12:17:44 +0000 (14:17 +0200)]
BUG/MINOR: quic: fix room check if padding requested

qc_prep_pkts() activates padding when building an Initial packet. This
ensures that resulting datagram will always be at least 1.200 bytes,
which is mandatory to prevent deadlock over anti-amplication.

Prior to padding activation, a check is performed to ensure that output
buffer is big enough for a padded datagram. However, this did not take
into account previously built packets which would be coalesced in the
same datagram. Thus this patch fixes this comparison check.

In theory, prior to this patch, in some cases Initial packets could not
be built despite a datagram of the proper size. Currently, this probably
never happens as Initial packet is always the first encoded in a
datagram, thus there is no coalesced packet prior to it. However, there
is no hard requirement on this, so it's better to reflect this in the
code.

This should be backported up to 2.6.

(cherry picked from commit 34d5bfd23c30e08228d7939ba94a839b03716489)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0ecea5e96a3322c74b8eb2478f45d286bf43a6f9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ffe81c3628e64800156d276c6716077d18f327e4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: ignore AGAIN ncbuf err when parsing CRYPTO frames
Frederic Lecaille [Mon, 1 Sep 2025 12:35:14 +0000 (14:35 +0200)]
BUG/MINOR: quic: ignore AGAIN ncbuf err when parsing CRYPTO frames

This fix follows this previous one:

    BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets

which is not sufficient when a client fragments and mixes its CRYPTO frames AND
leaveswith holes by packets. ngtcp2 (and perhaps chrome) splits theire CRYPTO
frames but without hole by packet. In such a case, the CRYPTO parsing leads to
QUIC_RX_RET_FRM_AGAIN errors which cannot be fixed when the peer resends its packets.
Indeed, even if the peer resends its frames in a different order, this does not
help because since the previous commit, the CRYPTO frames are ordered on haproxy side.

This issue was detected thanks to the interopt tests with quic-go as client. This
client fragments its CRYPTO frames, mixes them, and generate holes, and most of
the times with the retry test.

To fix this, when a QUIC_RX_RET_FRM_AGAIN error is encountered, the CRYPTO frames
parsing is not stop. This leaves chances to the next CRYPTO frames to be parsed.

Must be backported as far as 2.6 as the commit mentioned above.

(cherry picked from commit fba80c7fe84707afe134a5b240a2842a0a51f78f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 02d7f2b30df2c6dd4de371c31eab423e9e7bce1f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 47a60d8c8e446456cc3406ac5540fbc4180d9ff5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: tools: Add OOM check for malloc() in indent_msg()
Alexander Stephan [Mon, 1 Sep 2025 10:01:50 +0000 (10:01 +0000)]
BUG/MINOR: tools: Add OOM check for malloc() in indent_msg()

This patch adds a missing out-of-memory (OOM) check after
the call to `malloc()` in `indent_msg()`. If memory
allocation fails, the function returns NULL to prevent
undefined behavior.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit 26776c7b8f963299585300472a2b29ad39e47943)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 35c11b9b05b1adbfc75338a08660460458507e6f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ffbcd48e5af6bcfd25a14ab8bb0553e2954ff0e6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: compression: Add OOM check for calloc() in parse_compression_options()
Alexander Stephan [Mon, 1 Sep 2025 09:57:51 +0000 (09:57 +0000)]
BUG/MINOR: compression: Add OOM check for calloc() in parse_compression_options()

This patch adds a missing out-of-memory (OOM) check after
the call to `calloc()` in `parse_compression_options()`. If
memory allocation fails, an error message is set, the function
returns -1, and parsing is aborted to ensure safe handling
of low-memory conditions.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit aa20905ac9e45c6caa8929f4686020708209e2bf)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e39edf65b0076a106a4475d73e3496df809f44ef)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 077efc51806cf6b65b26371fcb972ef8dff60869)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: cfgparse: Add OOM check for calloc() in cfg_parse_listen()
Alexander Stephan [Mon, 1 Sep 2025 09:51:19 +0000 (09:51 +0000)]
BUG/MINOR: cfgparse: Add OOM check for calloc() in cfg_parse_listen()

This commit adds a missing out-of-memory (OOM) check
after the call to `calloc()` in `cfg_parse_listen()`.
If memory allocation fails, an alert is logged, error
codes are set, and parsing is aborted to prevent
undefined behavior.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit 73f9a75894c660dd034439e0bc343aa00489dbc9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8a4bc5b7fc474e1b7178f8cf25428077c3fb7c34)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e9065b50776baca3c6d475539b89b2e7ab994b7c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: acl: Add OOM check for calloc() in smp_fetch_acl_parse()
Alexander Stephan [Mon, 1 Sep 2025 09:47:30 +0000 (09:47 +0000)]
BUG/MINOR: acl: Add OOM check for calloc() in smp_fetch_acl_parse()

This patch adds a missing out-of-memory (OOM) check after
the call to `calloc()` in `smp_fetch_acl_parse()`. If
memory allocation fails, an error message is set and
the function returns 0, improving robustness in
low-memory situations.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit c3e69cf065c59acbe01db5452f29b7ac199354d5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 1801fc6dd7041cc567a0fd38e5cf18963ea3cd69)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 68f494f900443f5e630e554031308c93b366425c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: log: Add OOM checks for calloc() and malloc() in logformat parser and...
Alexander Stephan [Mon, 1 Sep 2025 09:36:07 +0000 (09:36 +0000)]
BUG/MINOR: log: Add OOM checks for calloc() and malloc() in logformat parser and dup_logger()

This patch adds missing out-of-memory (OOM) checks after calls
to `calloc()` and `malloc()` in the logformat parser and the
`dup_logger()` function. If memory allocation fails, an error
is reported or NULL is returned, preventing undefined behavior
in low-memory conditions.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit 22ac1f5ee9889eb7273201de0d92449d9fc5e3fa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0fd91432f06ee6a7b427664be127b02c854e34ab)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit de370ed1e1925fa54778ae021f92c97f96ca1a03)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: halog: Add OOM checks for calloc() in filter_count_srv_status() and filter...
Alexander Stephan [Mon, 1 Sep 2025 09:32:04 +0000 (09:32 +0000)]
BUG/MINOR: halog: Add OOM checks for calloc() in filter_count_srv_status() and filter_count_url()

This patch adds missing out-of-memory (OOM) checks after calls to
calloc() in the functions `filter_count_srv_status()` and `filter_count_url()`.
If memory allocation fails, an error message is printed to stderr
and the process exits with status 1. This improves robustness
and prevents undefined behavior in low-memory situations.

Co-authored-by: Christian Norbert Menges <christian.norbert.menges@sap.com>
(cherry picked from commit fbd0fb20a22a77f85ca2ec0e41cc5df51de3d30a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3e7e85cd7bee9aea13505a19096fa35e7652a967)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 670df778d8acfe77a6d259c217a490dccc00509b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: server: Duplicate healthcheck's alpn inherited from default server
Christopher Faulet [Mon, 1 Sep 2025 13:04:18 +0000 (15:04 +0200)]
BUG/MEDIUM: server: Duplicate healthcheck's alpn inherited from default server

When "check-alpn" parameter is inherited from the default server, the value
is not duplicated, the pointer of the default server is used. However, when
this parameter is overridden, the old value is released. So the "check-alpn"
value of the default server is released. So it is possible to have a UAF if
if another server inherit from the same the default server.

To fix the issue, the "check-alpn" parameter must be handled the same way
the "alpn" is. The default value is duplicated. So it could be safely
released if it is forced on the server line.

This patch should fix the issue #3096. It must be backported to all stable
versions.

(cherry picked from commit f7a04b428a47edeabfe40bf1a48a85b03c105633)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 361ae50063941df0d7269489646fc4e5978ea97f)
[cf: ctx adjt]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 015732185bee1f75a3160a8a99369511a29c7aa4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoREG-TESTS: map_redirect: Don't use hdr_dom in ACLs with "-m end" matching method
Christopher Faulet [Mon, 1 Sep 2025 13:37:50 +0000 (15:37 +0200)]
REG-TESTS: map_redirect: Don't use hdr_dom in ACLs with "-m end" matching method

hdr_dom() is a alias of "hdr() -m dom". So using it with another explicit
matching method does not work because the matching on the domain will never
be performed. Only the last matching method is used. The scripts was working
by chance because no port was set on host header values.

The script was fixed by using "host_only" converter. In addition, host
header values were changed to have a port now.

(cherry picked from commit d09d7676d024f12a92390d7589895a2c4bae8e2b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ec64dcd295b0aaae77a8dcc840978266256edad4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 5ff7dde86be5c759976c79c98710890e59c666c7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MAJOR: mux-quic: fix crash on reload during emission
Amaury Denoyelle [Mon, 1 Sep 2025 13:07:53 +0000 (15:07 +0200)]
BUG/MAJOR: mux-quic: fix crash on reload during emission

MUX QUIC restricts buffer allocation per connection based on the
underlying congestion window. If a QCS instance cannot allocate a new
buffer, it is put in a buf_wait list. Typically, this will cause stream
upper layer to subscribe for sending.

A BUG_ON() was present on snd_buf and nego_ff callback prologue to
ensure that these functions were not called if QCS is already in
buf_wait list. The objective was to guarantee that there is no wake up
on a stream if it cannot allocate a buffer.

However, this BUG_ON() is not correct, as it can be fired legitimely.
Indeed, stream layer can retry emission even if no wake up occured. This
case can happen on reload. Thus, BUG_ON() will cause an unexpected
crash.

Fix this by removing these BUG_ON(). Instead, snd_buf/nego_ff callbacks
ensure that QCS is not subscribed in buf_wait list. If this is the case,
a nul value will be returned, which is sufficient for the stream layer
to pause emission and subscribe if necessary.

Occurences for this crash have been reported on the mailing list. It is
also the subject of github issue #3080, which should be fixed with this
patch.

This must be backported up to 3.0.

(cherry picked from commit dcf22616123432e3230c0a084cf13c5adc57b851)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 49fd57fe90939f15e7f75040a968266d7fa0112a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 54115fc2205ffbfe19a36212178cd861a210883f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: quic: CRYPTO frame freeing without eb_delete()
Frederic Lecaille [Mon, 1 Sep 2025 08:39:00 +0000 (10:39 +0200)]
BUG/MEDIUM: quic: CRYPTO frame freeing without eb_delete()

Since this commit:

BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets

when they are parsed, the CRYPTO frames are ordered by their offsets into an ebtree.
Then their data are provided to the ncbufs.

But in case of error, when qc_handle_crypto_frm() returns QUIC_RX_RET_FRM_FATAL
or QUIC_RX_RET_FRM_AGAIN), they remain attached to their tree. Then
from <err> label, they are deteleted and deleted (with a while(node) { eb_delete();
qc_frm_free();} loop). But before this loop, these statements directly
free the frame without deleting it from its tree, if this is a CRYPTO frame,
leading to a use after free when running the loop:

     if (frm)
    qc_frm_free(qc, &frm);

This issue was detected by the interop tests, with quic-go as client. Weirdly, this
client sends CRYPTO frames by packet with holes.
Must be backported as far as 2.6 as the commit mentioned above.

(cherry picked from commit 800ba73a9ca39dc0e0c33230c87ececd540f5541)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ed1b2dc1f8ec5a68dbf3e075d4bffd5bc738bf2b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e3b7cd5d61b6ea1c1b42ddcd5539e1fdf9cfe542)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoCLEANUP: quic: remove a useless CRYPTO frame variable assignment
Frederic Lecaille [Mon, 1 Sep 2025 07:29:16 +0000 (09:29 +0200)]
CLEANUP: quic: remove a useless CRYPTO frame variable assignment

This modification should have arrived with this commit:

MINOR: quic: remove ->offset qf_crypto struct field

Since this commit, the CRYPTO offset node key assignment is done at parsing time
when calling qc_parse_frm() from qc_parse_pkt_frms().

This useless assigment has been reported in GH #3095 by coverity.

This patch should be easily backported as far as 2.6 as the one mentioned above
to ease any further backport to come.

(cherry picked from commit 90126ec9b733694d4c5ad0f20c221cff639db95f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit daf26577556f36c208a8eb0b06cbc5bb1ffe74e2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit c410e74be38562a4f9a244c2025823e35e8e0f65)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: doc: add missing statistics column
Amaury Denoyelle [Thu, 28 Aug 2025 16:34:54 +0000 (18:34 +0200)]
MINOR: doc: add missing statistics column

Complete documentation with missing description of newly added columns.

This must be backported up to 2.8.

(cherry picked from commit fb43343f6fba7333b7138992841a7536e601166a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit da07f7325fdf5a8e7d7da579c0eeeb6644824837)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 80447b35feaaa5224fd2106ddc54c8d96f191cf3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: doc: add missing statistics column
Amaury Denoyelle [Thu, 28 Aug 2025 16:27:26 +0000 (18:27 +0200)]
MINOR: doc: add missing statistics column

Complete documentation with missing description of newly added columns.

This should be backported up to 2.4

(cherry picked from commit f0710a1fbcf054bb7da843670fc68cf69f5f9705)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 09135aecf62234d16206521b7ff3277801969876)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 91fccab6782a117bea4cb6bc523d5f48aa9aaa62)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: configuration: confuse "strict-mode" with "zero-warning"
William Lallemand [Thu, 28 Aug 2025 15:31:27 +0000 (17:31 +0200)]
DOC: configuration: confuse "strict-mode" with "zero-warning"

4b10302fd8 ("MINOR: cfgparse: implement a simple if/elif/else/endif
macro block handler") introduces a confusion between "strict-mode" and
"zero-warning".

This patch fixes the issue by changing "strict-mode" by "zero-warning"
in section 2.4. Conditional blocks.

Must be backported as far as 2.4.

(cherry picked from commit e0ec01849fc6eff6a6e9ac67e23dea03d779fe70)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 98d4d720e11ef808e849bba76e902fee7f6419d1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 46cf247231358866b5c6c03e0176f7e5290a2492)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: unreliable sockpair@ on macOS
William Lallemand [Thu, 28 Aug 2025 13:23:02 +0000 (15:23 +0200)]
DOC: unreliable sockpair@ on macOS

We discovered that the sockpair@ protocol is unreliable in macOS, this
is the same problem that we fixed in d7f6819. But it's not possible to
implement a acknowledgment once the socket are in non-blocking mode.

The problem was discovered in issue #3045.

Must be backported in every stable versions.

(cherry picked from commit 8a456399dba70c9880394a7e85f9523feb1505c5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0746af209c3600a908b141f213c8ba7bb807840a)
[cf: ctx adjt]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 16ab3761721b11803d6b5df38a487a8bf48a8b49)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: server: decrement session idle_conns on del server
Amaury Denoyelle [Tue, 19 Aug 2025 13:41:43 +0000 (15:41 +0200)]
BUG/MINOR: server: decrement session idle_conns on del server

When a server is deleted, each of its idle connections are removed. This
is also performed for every private connections stored on sessions which
referenced the target server.

As mentionned above, these private connections are idle, guaranteed by
srv_check_for_deletion(). A BUG_ON() on CO_FL_SESS_IDLE is already
present to guarantee this. Thus, these connections are accounted on the
session to enforce max-session-srv-conns limit.

However, this counter is not decremented during private conns cleanup on
"del server" handler. This patch fixes this by adding a decrement for
every private connections removed via "del server".

This should be backported up to 3.0.

(cherry picked from commit 0be225f341485a46d17bc17ccc7906613bfbc3d0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 15805ddc6ddfcde5e0b777f295f2fce1bef2d01a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit f8d6215a9e4a1442ece0b7fcef10ab24c6f83973)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: connection: remove extra session_unown_conn() on reverse
Amaury Denoyelle [Thu, 21 Aug 2025 15:30:10 +0000 (17:30 +0200)]
BUG/MINOR: connection: remove extra session_unown_conn() on reverse

When a connection is reversed via rhttp protocol on the edge endpoint,
it migrates from frontend to backend side. This operation is performed
by conn_reverse(). During this transition, the conn owning session is
freed as it becomes unneeded.

Prior to this patch, session_unown_conn() was also called during
frontend to backend migration. However, this is unnecessary as this
function is only used for backend connection reuse. As such, this patch
removes this unnecessary call.

This does not cause any harm to the process as session_unown_conn() can
handle a connection not inserted yet. However, for clarity purpose it's
better to backport this patch up to 3.0.

(cherry picked from commit 04f05f188058e8931f203efc44f72a009bc85c0f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d04278827974e55f1e29746b23e5a030876aeeb5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit bdd74840c89b9eb0791f3ab8e2a08d0ee8054705)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: connection: rearrange union list members
Amaury Denoyelle [Wed, 27 Aug 2025 12:58:59 +0000 (14:58 +0200)]
BUG/MINOR: connection: rearrange union list members

A connection can be stored in several lists, thus there is several
attach points in struct connection. Depending on its proxy side, either
frontend or backend, a single connection will only access some of them
during its lifetime.

As an optimization, these attach points are organized in a union.
However, this repartition was not correctly achieved along
frontend/backend side delimitation.

Furthermore, reverse HTTP has recently been introduced. With this
feature, a connection can migrate from frontend to backend side or vice
versa. As such, it becomes even more tedious to ensure that these
members are always accessed in a safe way.

This commit rearrange these fields. First, union is now clearly splitted
between frontend and backend only elements. Next, backend elements are
initialized with conn_backend_init(), which is already used during
connection reversal on an edge endpoint. A new function
conn_frontend_init() serves to initialize the other members, called both
on connection first instantiation and on reversal on a dialer endpoint.

This model is much cleaner and should prevent any access to fields from
the wrong side.

Currently, there is no known case of wrong access in the existing code
base. However, this cleanup is considered an improvement which must be
backported up to 3.0 to remove any possible undefined behavior.

(cherry picked from commit a96f1286a75246fef6db3e615fabdef1de927d83)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit efed852704238d4a523a1154c061e47ca704b951)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 284a60cbbd00409a98e8b2f238ab6667748f0cd1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: acl: set arg_list->kw to aclkw->kw string literal if aclkw is found
Valentine Krasnobaeva [Tue, 26 Aug 2025 22:33:48 +0000 (00:33 +0200)]
BUG/MINOR: acl: set arg_list->kw to aclkw->kw string literal if aclkw is found

During configuration parsing *args can contain different addresses, it is
changing from line to line. smp_resolve_args() is called after the
configuration parsing, it uses arg_list->kw to create an error message, if a
userlist referenced in some ACL is absent. This leads to wrong keyword names
reported in such message or some garbage is printed.

It does not happen in the case of sample fetches. In this case arg_list->kw is
assigned to a string literal from the sample_fetch struct returned by
find_sample_fetch(). Let's do the same in parse_acl_expr(), when find_acl_kw()
lookup returns a corresponding acl_keyword structure.

This fixes the issue #3088 at GitHub.
This should be backported in all stable versions since 2.6 including 2.6.

(cherry picked from commit 441cd614f92bd3d7d66003e509ae71bcb779b0f5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 802fc568c81c67af3461d3b58a324a4d8aef5508)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 789c30fc9b6f3ed1fcb9e12b8133db7e2ea36393)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: mux-quic: trace with non initialized qcc
Frederic Lecaille [Thu, 28 Aug 2025 05:58:00 +0000 (07:58 +0200)]
BUG/MINOR: mux-quic: trace with non initialized qcc

This issue leads to crashes when the QUIC mux traces are enabled and could be
reproduced with -dMfail. When the qcc allocation fails (qcc_init()) haproxy
crashes into qmux_dump_qcc_info() because ->conn qcc member is initialized:

Program terminated with signal SIGSEGV, Segmentation fault.
    at src/qmux_trace.c:146
146             const struct quic_conn *qc = qcc->conn->handle.qc;
[Current thread is 1 (LWP 1448960)]
(gdb) p qcc
$1 = (const struct qcc *) 0x7f9c63719fa0
(gdb) p qcc->conn
$2 = (struct connection *) 0x155550508
(gdb)

This patch simply fixes the TRACE() call concerned to avoid <qcc> object
dereferencing when it is NULL.

Must be backported as far as 3.0.

(cherry picked from commit ffa926ead3f17cd8da773daa137184619bfc1a0a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 46a8238ca06f28a057658c2dade22ac894c571cf)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit cc3c9a786f8eeba582342838014c2c2e29c3b4da)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: quic: remove ->offset qf_crypto struct field
Frederic Lecaille [Wed, 27 Aug 2025 14:28:04 +0000 (16:28 +0200)]
MINOR: quic: remove ->offset qf_crypto struct field

This patch follows this previous bug fix:

    BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets

where a ebtree node has been added to qf_crypto struct. It has the same
meaning and type as ->offset_node.key field with ->offset_node an eb64tree node.
This patch simply removes ->offset which is no more useful.

This patch should be easily backported as far as 2.6 as the one mentioned above
to ease any further backport to come.

(cherry picked from commit 31c17ad837195c70fb6d4e427845ded1c6acffaa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4a1a08be4f34feafb637115a1d8536ad70a2df33)
[cf: Some changes were made inlined in quic_tx.c because some functions does
 not exist in 3.2 and lower]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 565d73a3b1d6fa562408392bb55340a5e7b8b967)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets
Frederic Lecaille [Wed, 27 Aug 2025 12:18:25 +0000 (14:18 +0200)]
BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets

This issue impacts the QUIC listeners. It is the same as the one fixed by this
commit:

BUG/MINOR: quic: repeat packet parsing to deal with fragmented CRYPTO

As chrome, ngtcp2 client decided to fragment its CRYPTO frames but in a much
more agressive way. This could be fixed with a list local to qc_parse_pkt_frms()
to please chrome thanks to the commit above. But this is not sufficient for
ngtcp2 which often splits its ClientHello message into more than 10 fragments
with very small ones. This leads the packet parser to interrupt the CRYPTO frames
parsing due to the ncbuf gap size limit.

To fix this, this patch approximatively proceeds the same way but with an
ebtree to reorder the CRYPTO by their offsets. These frames are directly
inserted into a local ebtree. Then this ebtree is reused to provide the
reordered CRYPTO data to the underlying ncbuf (non contiguous buffer). This way
there are very few less chances for the ncbufs used to store CRYPTO data
to reach a too much fragmented state.

Must be backported as far as 2.6.

(cherry picked from commit d753f24096dafdef227fe66621513086c2c663c1)
[cf: ctx adjt]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 9146b06962565992724ec12e35b3b77bb3274805)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b673c57a165614598919f3b7ccfe1344bc7e3d97)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

(cherry picked from commit d9855102cf303948ffc842e8c0f7939e67a29bd9)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 72ca5e5e8f3fcbc2f2ef6ed312e424a22235730d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 99039c8e6ece475b5e19b1df4d0c7a9702bd6dc2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

(cherry picked from commit 41a40680ce1c513d49a40d5e9f3c80a8a70a369f)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit ed3273f771c778527a19f85bd646b7c4a21ce0d9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 22210bb66f77d87cd8004105e029ef3f893ed3d7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: quic: centralize padding for HP sampling on packet building
Amaury Denoyelle [Tue, 12 Aug 2025 08:40:06 +0000 (10:40 +0200)]
MINOR: quic: centralize padding for HP sampling on packet building

The below patch has simplified INITIAL padding on emission. Now,
qc_prep_pkts() is responsible to activate padding for this case, and
there is no more special case in qc_do_build_pkt() needed.

  commit 8bc339a6ad4702f2c39b2a78aaaff665d85c762b
  BUG/MAJOR: quic: fix INITIAL padding with probing packet only

However, qc_do_build_pkt() may still activate padding on its own, to
ensure that a packet is big enough so that header protection decryption
can be performed by the peer. HP decryption is performed by extracting a
sample from the ciphered packet, starting 4 bytes after PN offset.
Sample length is 16 bytes as defined by TLS algos used by QUIC. Thus, a
QUIC sender must ensures that length of packet number plus payload
fields to be at least 4 bytes long. This is enough given that each
packet is completed by a 16 bytes AEAD tag which can be part of the HP
sample.

This patch simplifies qc_do_build_pkt() by centralizing padding for this
case in a single location. This is performed at the end of the function
after payload is completed. The code is thus simpler.

This is not a bug. However, it may be interesting to backport this patch
up to 2.6, as qc_do_build_pkt() is a tedious function, in particular
when dealing with padding generation, thus it may benefit greatly from
simplification.

(cherry picked from commit 1529ec1a25cc216f7613517e5e8c936852d18007)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6dfdf20e00b491f6fc4708917024a51620850a09)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4a2a5ee5dde65c8f3cfb2ce6765e93b9ae728388)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MAJOR: quic: fix INITIAL padding with probing packet only
Amaury Denoyelle [Mon, 11 Aug 2025 15:54:39 +0000 (17:54 +0200)]
BUG/MAJOR: quic: fix INITIAL padding with probing packet only

A QUIC datagram that contains an INITIAL packet must be padded to 1.200
bytes to prevent any deadlock due to anti-amplification protection. This
is implemented by encoding a PADDING frame on the last packet of the
datagram if necessary.

Previously, qc_prep_pkts() was responsible to activate padding when
calling qc_do_build_pkt(), as it knows which packet is the last to
encode. However, this has the side-effect of preventing PING emission
for probing with no data as this case was handled in an else-if branch
after padding. This was fixed by the below commit

  217e467e89d15f3c22e11fe144458afbf718c8a8
  BUG/MINOR: quic: fix malformed probing packet building

Above logic was altered to fix the PING case : padding was set to false
explicitely in qc_prep_pkts(). Padding was then added in a specific
block dedicated to the PING case in qc_do_build_pkt() itself for INITIAL
packets.

However, the fix is incorrect if the last QEL used to built a packet is
not the initial one and probing is used with PING frame only. In this
case, specific block in qc_do_build_pkt() does not add padding. This
causes a BUG_ON() crash in qc_txb_store() which catches these packets as
irregularly formed.

To fix this while also properly handling PING emission, revert to the
original padding logic : qc_prep_pkts() is responsible to activate
INITIAL padding. To not interfere with PING emission, qc_do_build_pkt()
body is adjusted so that PING block is moved up in the function and
detached from the padding condition.

The main benefit from this patch is that INITIAL padding decision in
qc_prep_pkts() is clearer now.

Note that padding can also be activated by qc_do_build_pkt(), as packets
should be big enough for header protection decipher. However, this case
is different from INITIAL padding, so it is not covered by this patch.

This should be backported up to 2.6.

(cherry picked from commit 8bc339a6ad4702f2c39b2a78aaaff665d85c762b)
[cf: context adjustment]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 613457413b4edb5dc21c9a8b8b741556b019f129)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d6365e5197bea8ee8dee8beaf0bcb10de687ee0a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: do not emit probe data if CONNECTION_CLOSE requested
Amaury Denoyelle [Tue, 12 Aug 2025 09:30:03 +0000 (11:30 +0200)]
BUG/MINOR: quic: do not emit probe data if CONNECTION_CLOSE requested

If connection closing is activated, qc_prep_pkts() can only built a
datagram with a single packet. This is because we consider that only a
single CONNECTION_CLOSE frame is relevant at this stage.

This is handled both by qc_prep_pkts() which ensure that only a single
packet datagram is built and also qc_do_build_pkt() which prevents the
invokation of qc_build_frms() if <cc> is set.

However, there is an incoherency for probing. First, qc_prep_pkts()
deactivates it if connection closing is requested. But qc_do_build_pkt()
may still emit probing frame as it does not check its <probe> argument
but rather <pto_probe> QEL field directly. This can results in a packet
mixing a PING and a CONNECTION close frames, which is useless.

Fix this by adjusting qc_do_build_pkt() : closing argument is also
checked on PING probing emission. Note that there is still shaky code
here as qc_do_build_pkt() should rely only on <probe> argument to ensure
this.

This should be backported up to 2.6.

(cherry picked from commit 0376e66112f17d79cfd1824ae75d7288eb383059)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6d0cdabc754d94c1e5036ca4ce4b01085afcdfa1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0937c7e85bc541a15ec0d51e2397a9799bdbcf33)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: mux-h1: fix wrong lock label
Amaury Denoyelle [Fri, 8 Aug 2025 13:12:59 +0000 (15:12 +0200)]
BUG/MINOR: mux-h1: fix wrong lock label

Wrong lock label is used when manipulating idle lock on h1_timeout_task.
Fix this by replacing OTHER_LOCK by IDLE_CONNS_LOCK.

This only concerns thread debugging statistics.

This must be backported up to 2.4.

(cherry picked from commit 8ac54cafcda749a5b50532b3a10d39a5a37ce9b3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8969387e94cb5ac0562b1bfe8d01cc0131b9652e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 50a5aa77a1811fde4787fed552126f329eb1e744)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Test HTX_FL_EOM flag before commiting the HTX buffer
Christopher Faulet [Tue, 8 Jul 2025 06:24:45 +0000 (08:24 +0200)]
BUG/MEDIUM: http-client: Test HTX_FL_EOM flag before commiting the HTX buffer

when htx_to_buf() function is called, if the HTX message is empty, the
buffer is reset. So HTX flags must not be tested after because the info may
be lost.

So now, we take care to test HTX_FL_EOM flag before calling htx_to_buf().

This patch must be backported as far as 2.8.

(cherry picked from commit 4bdb2e5a26587120101234c8f73cbc40d1777656)
[wla: API does not emit HTX in response for 3.2, some adjutements were
made to better match the 3.3 behavior]
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit d01fa873acdd5ac40819d311923a28159e01040b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 03d4267efa7d815efd97366e9db5f9770f804370)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: config: recommend single quoting passwords
Lukas Tribus [Tue, 12 Aug 2025 16:28:55 +0000 (16:28 +0000)]
DOC: config: recommend single quoting passwords

Suggests single quoting passwords and update examples to avoid unexpected
behaviors due to special characters.

Should be backported to stable versions.

Link: https://discourse.haproxy.org/t/enhance-documentation-for-insecure-passwords-and-invald-characters/11959
(cherry picked from commit 9432e7d6887ade0db69947f343c5b5535a33e303)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 456d7dc170fd4a3e6541cc5816810f398efe2d07)
[cf: context adjustment]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 99dc78982db90181de548a9051e21069628ec6c5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: management: fix typo in commit f4f93c56
Lukas Tribus [Tue, 12 Aug 2025 16:28:22 +0000 (16:28 +0000)]
DOC: management: fix typo in commit f4f93c56

Fixes a small typo in commit f4f93c56 ("DOC: management: clarify usage
of -V with -c").

Must be backported as far as 2.8 along commit f4f93c56.

(cherry picked from commit faacc6c0842d2409abaf655d1967330af1790048)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit e4bc87caaa08b3c8fbe46bd8c988aa486b571425)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 33bb9f423f8c14aaf3753724a2d0a492fc8b7c39)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: init: Initialize random seed earlier in the init process
Remi Tricot-Le Breton [Mon, 11 Aug 2025 13:55:35 +0000 (15:55 +0200)]
BUG/MINOR: init: Initialize random seed earlier in the init process

The random seed used in ha_random functions needs to be first
initialized by calling ha_random_boot. This function was called rather
late in the init process, after the init functions (INITCALLS) are
called and after the configuration parsing for instance which means that
any ha_random call in an init function would return 0. This was the case
in 'vars_init' and 'cache_init' which tried to build seeds for specific
hash calculations but ended up not being seeded.

This patch can be backported on all stable branches.

(cherry picked from commit 15ee49e8222be2b34663fac838aa74e62f6c82ea)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit f7fbb55f0dcbbb44f6d20950bc1c0835699c85b6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0429f236a3adae23ca173cf11b74ccfd8099168f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: ssl: fix build with AWS-LC
Olivier Houchard [Fri, 8 Aug 2025 18:17:55 +0000 (20:17 +0200)]
BUG/MEDIUM: ssl: fix build with AWS-LC

AWS-LC doesn't provide SSL_in_before(), and doesn't provide an easy way
to know if we already started the handshake or not. So instead, just add
a new field in ssl_sock_ctx, "can_write_early_data", that will be
initialized to 1, and will be set to 0 as soon as we start the
handshake.

This should be backported up to 2.8 with
13aa5616c9f99dbca0711fd18f716bd6f48eb2ae.

(cherry picked from commit b6702d53427a22725c125425552074c622c2f25d)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 5ff41e99b8f68eb674231d99e546783b27c7e562)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3fff6803385f325c6a87d00405978ab7a2b280e6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: ssl: Fix 0rtt to the server
Olivier Houchard [Fri, 8 Aug 2025 16:26:29 +0000 (18:26 +0200)]
BUG/MEDIUM: ssl: Fix 0rtt to the server

In order to send early data, we have to make sure no handshake has been
initiated at all. To do that, we remove the CO_FL_SSL_WAIT_HS flag, so
that we won't attempt to start a handshake. However, by removing those
flags, we allow ssl_sock_to_buf() to call SSL_read(), as it's no longer
aware that no handshake has been done, and SSL_read() will begin the
handshake, thus preventing us from sending early data.
The fix is to just call SSL_in_before() to check if no handshake has
been done yet, in addition to checking CO_FL_SSL_WAIT_HS (both are
needed, as CO_FL_SSL_WAIT_HS may come back in case of renegociation).
In ssl_sock_from_buf(), fix the check to see if we may attempt to send
early data. Use SSL_in_before() instead of SSL_is_init_finished(), as
SSL_is_init_finished() will return 1 if the handshake has been started,
but not terminated, and if the handshake has been started, we can no
longer send early data.
This fixes errors when attempting to send early data (as well as
actually sending early data).

This should be backported up to 2.8.

(cherry picked from commit 13aa5616c9f99dbca0711fd18f716bd6f48eb2ae)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 1a54596e40d8599e3cc4b4e98ac69a90bf15f071)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0f60a540425b123e2ae93b9e90bef25ba6680690)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: stick-table: cap sticky counter idx with tune.nb_stk_ctr instead of MAX_SE...
Valentine Krasnobaeva [Thu, 7 Aug 2025 09:54:58 +0000 (11:54 +0200)]
BUG/MINOR: stick-table: cap sticky counter idx with tune.nb_stk_ctr instead of MAX_SESS_STKCTR

Cap sticky counter index with tune.nb_stk_ctr instead of MAX_SESS_STKCTR for
sc-add-gpc. Same logic is already implemented for sc-inc-gpc and sc-set-gpt
keywords. So, it seems missed for sc-add-gpc.

This fixes the issue #3061 reported at GitHub. Thanks to @ma311 for
reporting their analysis of the issue.
This should be backported in all versions until 2.8, included 2.8.

(cherry picked from commit 21d5f43aa6e9513d11dff2d80a2a332d92c0a857)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 4b71a4c528876a37fee996ac1326b03622c90bc7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6ff65b14cc06550b10560d3bf6fc8d7eee9a4868)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUILD: compat: always set _POSIX_VERSION to ease comparisons
Willy Tarreau [Tue, 5 Aug 2025 13:59:11 +0000 (15:59 +0200)]
BUILD: compat: always set _POSIX_VERSION to ease comparisons

Sometimes we need to compare it to known versions, let's make sure it's
always defined. We set it to zero if undefined so that it cannot match
any comparison.

(cherry picked from commit e921fe894f6b992414e595be9450a9092f4df48e)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit a04c2d7ac5e4071da95230b128911d5b78bc996a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 319077ed41e46975cbcb3f9e2d3b8af5623d42ce)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUILD: compat: provide relaxed versions of the MIN/MAX macros
Willy Tarreau [Wed, 6 Aug 2025 17:05:29 +0000 (19:05 +0200)]
BUILD: compat: provide relaxed versions of the MIN/MAX macros

In 3.0 the MIN/MAX macros were converted to compound expressions with
commit 0999e3d959 ("CLEANUP: compat: make the MIN/MAX macros more
reliable"). However with older compilers these are not supported out
of code blocks (e.g. to initialize variables or struct members). This
is the case on Solaris 10 with gcc-5.5 when QUIC doesn't compile
anymore with the future pool registration:

  In file included from include/haproxy/quic_tx.h:26:0,
                   from src/quic_tx.c:15:
  include/haproxy/compat.h:106:19: error: braced-group within expression allowed only inside a function
   #define MAX(a, b) ({    \
                     ^
  include/haproxy/pool.h:41:11: note: in definition of macro '__REGISTER_POOL'
     .size = _size,           \
             ^
  ...
  include/haproxy/quic_tx-t.h:6:29: note: in expansion of macro 'MAX'
   #define QUIC_MAX_CC_BUFSIZE MAX(QUIC_INITIAL_IPV6_MTU, QUIC_INITIAL_IPV4_MTU)

Let's provide the old relaxed versions as _MIN/_MAX for use with constants
like such cases where it's certain that there is no risk. A previous attempt
using __builtin_constant_p() to switch between the variants did not work,
and it's really not worth the hassle of going this far.

(cherry picked from commit cf8871ae40ae85f86b0d396b6af1eb657134ffc1)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit a245298b3c05826834d0c5925a1eb74fe22d4392)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 2ae6edb59f8acf7fe0342c08e1d939c691004cf2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

Complete list of global keywords with missing QUIC entries.

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

(cherry picked from commit 7fa812a1ac2721d9290900b3467fd80110f15cc7)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 0b4d823b3e6056a7a8465c744b7ad69537245871)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 282d1f28261ff9477ca5952fe1ef259453886b87)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

This should fix Github issue #3035

This should be backported up to 2.8.

(cherry picked from commit f8e9545f700a4e3799bbac4cd1c94989b9c1fb61)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 0d87b8343f8780c1c677dd282dc7648cf038a00a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ba9ee8147702b5cc5c400b7521afc2f13659eb2c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

(cherry picked from commit 254e4d59f75784c237e0c51596c6e0ca8730e717)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit dd276c752d5edfe26778ded9006dea40d5e33d23)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8fc62dbff10a674cdd673d319b61a6aa0ab01b4a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

This patch must be backport as far as 2.8.

(cherry picked from commit 4f7c26cbb33fac44b255c714610191ffad2ec653)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit be0148c5ccbe5711c201020b1eba2af297acacf6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0b854dfaf028a8836e3e460738370ef7210f1854)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

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

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

Must be backported as far as 2.8.

(cherry picked from commit 1c33756f7803247c81354f55678322b636279089)
[ad: replace <target> by <li> qc member]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 6c237bb64b9d19cc927ed72aee360d8e22138969)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 34f540f57240b3ebab0c225c9c2820c927ed8d67)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Notify applet has more data to deliver until the EOM
Christopher Faulet [Wed, 9 Jul 2025 13:20:41 +0000 (15:20 +0200)]
BUG/MEDIUM: http-client: Notify applet has more data to deliver until the EOM

When we leave the I/O handler with an unfinished request, we must report the
applet has more data to deliver. Otherwise, when the channel request buffer
is emptied, the http-client applet is not always woken up to forward the
remaining request data.

This issue was probably revealed by commit "BUG/MEDIUM: http-client: Don't
wake http-client applet if nothing was xferred". It is only an issue with
large POSTs, when the payload is streamed.

This patch must be backported as far as 2.6 with the commit above. But on
older versions, the applet API may differ. So be careful.

(cherry picked from commit 0b97bf36fad6fbced8077ac416a1399c05806c7d)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit dd3ba78fc13a99e79052496d1851cff65c24f73c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 91f19003114ad4afcb189233d0784c6f7ce923f4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Drain the request if an early response is received
Christopher Faulet [Tue, 8 Jul 2025 06:45:10 +0000 (08:45 +0200)]
BUG/MEDIUM: http-client: Drain the request if an early response is received

When a large request is sent, it is possible to have a response before the
end of the request. It is valid from HTTP perspective but it is an issue
with the current design of the http-client. Indded, the request and the
response are handled sequentially. So the response will be blocked, waiting
for the end of the request. Most of time, it is not an issue, except when
the request transfer is blocked. In that case, the applet is blocked.

With the current API, it is not possible to handle early response and
continue the request transfer. So, this case cannot be handle. In that case,
it seems reasonnable to drain the request if a response is received. This
way, the request transfer, from the caller point of view, is never blocked
and the response can be properly processed.

To do so, the action flag HTTPCLIENT_FA_DRAIN_REQ is added to the
http-client. When it is set, the request payload is just dropped. In that
case, we take care to not report the end of input to properly report the
request was truncated, especially in logs.

It is only an issue with large POSTs, when the payload is streamed.

This patch must be backported as far as 2.6.

(cherry picked from commit 25b0625d5c27a209c38dcac6a81c58495e5360af)
[ad: context adjustement due to missing HTTPCLIENT_O_RES_HTX in 3.2]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit eadb777452f8470ddaeb0ffdb59c130ce1621823)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit fff555a50b229a32341931e7928d19fc7b023789)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: http-client: Reject any 101-switching-protocols response
Christopher Faulet [Tue, 8 Jul 2025 06:57:16 +0000 (08:57 +0200)]
BUG/MINOR: http-client: Reject any 101-switching-protocols response

Protocol updages are not supported by the http-client. So report an error is
a 101-switching-protocols response is received. Of course, it is unexpected
because the API is not designed to support upgrades. But it is better to
properly handle this case.

This patch could be backported as far as 2.6. It depends on the commit
"BUG/MINOR: http-client: Ignore 1XX interim responses in non-HTX mode".

(cherry picked from commit 8ba754108d70d25d796e3dc166155503aab180b2)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 0bfaef56d630a355d85fcdf2b733e479fee8595b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 31ff75c23d25eb6b10dbe9f1af09e63083428df2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: http-client: Ignore 1XX interim responses in non-HTX mode
Christopher Faulet [Tue, 8 Jul 2025 06:38:31 +0000 (08:38 +0200)]
BUG/MINOR: http-client: Ignore 1XX interim responses in non-HTX mode

When the response is re-formatted in raw message, the 1XX interim responses
must be skipped. Otherwise, information of the first interim response will
be saved (status line and headers) and those from the final response will be
dropped.

Note that for now, in HTX-mode, the interim messages are removed.

This patch must be backported as far as 2.6.

(cherry picked from commit 9d10be33aebb08058c37d7dcd15874e42be74a29)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 8abebc8d061c29dcdf511efba2321cf2a6df00d6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 39b319f6c9d615c546631ea918daff11684c7b1b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Ask for more room when request data cannot be xferred
Christopher Faulet [Tue, 8 Jul 2025 06:17:49 +0000 (08:17 +0200)]
BUG/MEDIUM: http-client: Ask for more room when request data cannot be xferred

When the request payload cannot be xferred to the channel because its buffer
is full, we must request for more room by calling sc_need_room(). It is
important to be sure the httpclient applet will not be woken up in loop to
push more data while it is not possible.

It is only an issue with large POSTs, when the payload is streamed.

This patch must be backported as far as 2.6. Note that on 2.6,
sc_need_room() only takes one argument.

(cherry picked from commit e4a0d40c62594b4504fd7443158731fef54e040a)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 5377ea587fba88b56e5249008be153cb529f066b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e1aa83ce71f826ed446b763a16e19114f4e15e83)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Properly inc input data when HTX blocks are xferred
Christopher Faulet [Tue, 8 Jul 2025 06:04:01 +0000 (08:04 +0200)]
BUG/MEDIUM: http-client: Properly inc input data when HTX blocks are xferred

When HTX blocks from the requests are transferred into the channel buffer,
the return value of htx_xfer_blks() function must not be used to increment
the channel input value because meta data are counted here while they are
not part of input data. Because of this bug, it is possible to forward more
data than these present in the channel buffer.

Instead, we look at the input data before and after the transfer and the
difference is added.

It is only an issue with large POSTs, when the payload is streamed.

This patch must be backported as far as 2.6.

(cherry picked from commit d9ca8f6b71cd17bae0718f0b1e9da919fc00264d)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 208ef1d7aebc11133e8c64966be475a521da5409)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 90167928a38f05680852fd0943b86ef66496ee18)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: http-client: Don't wake http-client applet if nothing was xferred
Christopher Faulet [Tue, 8 Jul 2025 05:46:26 +0000 (07:46 +0200)]
BUG/MEDIUM: http-client: Don't wake http-client applet if nothing was xferred

When data are transferred to or from the htt-pclient, the applet is
systematically woken up, even when no data are transferred. This could lead
to needlessly wakeups. When called from a lua script, if data are blocked
for a while, this leads to a wakeup ping-pong loop where the http-client
applet is woken up by the lua script which wakes back the script.

To fix the issue, in httpclient_req_xfer() and httpclient_res_xfer()
functions, we now take care to not wake the http-client applet up when no
data are transferred.

This patch must be backported as far as 2.6.

(cherry picked from commit fffdac42df4848420028f89b14c2a90c12dbf9ab)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit b35b0aaf82d625c8f78f734fb5b4c0deebd1697a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 9dab53c6b7ba9928b61d68e5243930b1f72431f3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: listener: really assign distinct IDs to shards
Willy Tarreau [Wed, 9 Jul 2025 13:52:33 +0000 (15:52 +0200)]
BUG/MINOR: listener: really assign distinct IDs to shards

A fix was made in 3.0 for the case where sharded listeners were using
a same ID with commit 0db8b6034d ("BUG/MINOR: listener: always assign
distinct IDs to shards"). However, the fix is incorrect. By checking the
ID of temporary node instead of the kept one in bind_complete_thread_setup()
it ends up never inserting the used nodes at this point, thus not reserving
them. The side effect is that assigning too close IDs to subsequent
listeners results in the same ID still being assigned twice since not
reserved. Example:

   global
       nbthread 20

   frontend foo
       bind :8000 shards by-thread id 10
       bind :8010 shards by-thread id 20

The first one will start a series from 10 to 29 and the second one a
series from 20 to 39. But 20 not being inserted when creating the shards,
it will remain available for the post-parsing phase that assigns all
unassigned IDs by filling holes, and two listeners will have ID 20.

By checking the correct node, the problem disappears. The patch above
was marked for backporting to 2.6, so this fix should be backported that
far as well.

(cherry picked from commit dd49f1ee6230eaf608f3afa880ef0a6d2b84456e)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit c12e3b66be1eec8e5ccf6ca25871df77864c2b79)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 68c664f407bbc6d602f832344953e3c132da7217)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMEDIUM: ssl/cli: relax crt insertion in crt-list of type directory
William Lallemand [Mon, 11 Aug 2025 15:24:11 +0000 (17:24 +0200)]
MEDIUM: ssl/cli: relax crt insertion in crt-list of type directory

In previous versions of haproxy, insertions of certificates in a
crt-list from the CLI would require to have the path of the directory,
in the path of the certificate. This would help avoiding that the
certificate wasn't loaded upon a reload because it is not at the right
place.

However, since version 3.0 and crt-store, the name stored in the tree
could be an alias and not a path, so that does not make sense anymore.
Even though path would be right, the check is not right anymore in this
case.

The tool or user inserting the certificate must now check itself that
the certificate was placed at the right spot on the filesystem.

Reported in issue #3053.

Could be backported as far as haproxy 3.0.

(cherry picked from commit 55d561042c81f8853364a62b4d5eaba2555c2673)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit 780f1e8a3301b49d74d336c2dbf3400a2d8d1cfb)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4e364f2a6dd6fba914dcc3c53976ea6a037fc7aa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: management: clarify usage of -V with -c
William Lallemand [Mon, 11 Aug 2025 14:19:17 +0000 (16:19 +0200)]
DOC: management: clarify usage of -V with -c

In ticket #3065 an user complained that no success message is printed
anymore when using -c. The message does not appear by default since
version 2.9. This patch clarify the documentation.

Must be backported as far as 2.8.

(cherry picked from commit f4f93c56c17165e7098dc98cecf49e656e57afff)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit d650878491600e281bf1ea15b378237d28e50b69)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 1c67ac3c0a579f335a0a7c581e409d4be1122e8e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

Thanks to GH user @zhanhb for having reported the issue

It may be backported to all stable versions.

(cherry picked from commit 2ffe515d97a80318f1f3a84f8e18015500b8ef01)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit ac1be87c8359abad1c1a55f5ea6822d4362706db)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0ea8c5bd38ef8b85f7efaa2ae3e4543127bee4e4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

It should be backported in 3.0 with ccc43412.

(cherry picked from commit 31adfb6c15df075967bffe909509cb49583dd0d1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit ce6822eade1b4a1677c621b3d1f67422679f2285)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 151a7c53d893618f6648577ec3c349601ac3c2bf)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

(cherry picked from commit 765f14e0e34054cd805b9974f531145d3e796967)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 4f820213ea0fbcbb13ecb26567d1f9ee5b8aa116)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit eacc3ffc583db7e393c820ded6e81d6162b96102)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

(cherry picked from commit 7e96ff6b84b7d7e0805a9a4e87a0a85b6b976df8)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 839755b1d401928df89b4fd8b146a20a17e28a3d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 503d60bac653237d618ecb21c468d65855473484)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

(cherry picked from commit 21e45a61d134786f42b046666aacced7a6ce3cc0)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 4e09e4d9d024c2e71027e7df43ed7db6c99a714f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 60e98e90233ebceb2d9e199cd100273c65b73e15)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

So now, we take care to silently remove headers.

This patch must be backported to all stable versions.

(cherry picked from commit 5b5ecf848dbe7467afb67ea70951b4e56f39dab5)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 8daaeb14e8e89c936a82a4ddff9c54dc1c93b92b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0c62785f34fd14d612985e0a8b01d57540b136f2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: deviceatlas build clarifications
David Carlier [Wed, 2 Jul 2025 13:11:30 +0000 (14:11 +0100)]
DOC: deviceatlas build clarifications

Update accordingly the related documentation, removing/clarifying confusing
parts as it was more complicated than it needed to be.

(cherry picked from commit e7c59a7a8435fa58377400aa88c241bfa111409e)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 2d6d7f335091a36f278f31a24ad2661ab66d9090)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8f01f82423f1da7a47f06a51bff54d185572c16a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUILD/MEDIUM: deviceatlas: fix when installed in custom locations.
David Carlier [Wed, 2 Jul 2025 13:00:07 +0000 (14:00 +0100)]
BUILD/MEDIUM: deviceatlas: fix when installed in custom locations.

We are reusing DEVICEATLAS_INC/DEVICEATLAS_LIB when the DeviceAtlas
library had been compiled and installed with cmake and make install targets.
Works fine except when ldconfig is unaware of the path, thus adding
cflags/ldflags into the mix.

Ideally, to be backported down to the lowest stable branch.

(cherry picked from commit 0e8e20a83f4dd789443b9176cd93573bcfa75c20)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit 770ad55db942bc69d436939bfdf1a7072d5572f9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit f1dcfdd56cb24260b5c1884941f037a29edc83cb)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: httpclient: wrongly named httpproxy flag
William Lallemand [Fri, 24 Jan 2025 16:53:04 +0000 (17:53 +0100)]
BUG/MINOR: httpclient: wrongly named httpproxy flag

The HC_F_HTTPPROXY flag was wrongly named and does not use the correct
value, indeed this flag was meant to be used for the httpclient API, not
the httpclient CLI.

This patch fixes the problem by introducing HTTPCLIENT_FO_HTTPPROXY
which has must be set in hc->flags.

Also add a member 'options' in the httpclient structure, because the
member flags is reinitialized when starting.

Must be backported as far as 3.0.

(cherry picked from commit 519abefb57da1ae21fc557213cae8b21cdaa2797)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 008045a03eeca63712546e030a4549671d00ffc1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit cba2b004accf766a3c6e6aac35852e27cd74cf07)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: Fix 'jwt_verify' converter doc
Remi Tricot-Le Breton [Mon, 30 Jun 2025 14:56:23 +0000 (16:56 +0200)]
DOC: Fix 'jwt_verify' converter doc

Contrary to what the doc says, the jwt_verify converter only works with
a public key and not a full certificate for certificate based protocols
(everything but HMAC).

This patch should be backported up to 2.8.

(cherry picked from commit 5c3d0a554b3db024aef62826b67821ca6a1383ee)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit a1845360477633ee572d2ef071dba0fd12512223)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 48de20ff93df34eef0b152a3701d84fb412079cf)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: jwt: Copy input and parameters in dedicated buffers in jwt_verify converter
Remi Tricot-Le Breton [Mon, 30 Jun 2025 14:56:22 +0000 (16:56 +0200)]
BUG/MINOR: jwt: Copy input and parameters in dedicated buffers in jwt_verify converter

When resolving variable values the temporary trash chunks are used so
when calling the 'jwt_verify' converter with two variable parameters
like in the following line, the input would be overwritten by the value
of the second parameter :
    var(txn.bearer),jwt_verify(txn.jwt_alg,txn.cert)
Copying the values into dedicated alloc'ed buffers prevents any new call
to get_trash_chunk from erasing the data we need in the converter.

This patch can be backported up to 2.8.

(cherry picked from commit 3465f88f8ab9c3f163d73938765f741c2b7e6a67)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 33eb0792afff79fa9cd596e87e4796f6d518d2c7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 47a40f66d72d3be619b2db6c2639f584a4e861b1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: mux-h2: Properly handle connection error during preface sending
Christopher Faulet [Mon, 30 Jun 2025 14:23:39 +0000 (16:23 +0200)]
BUG/MEDIUM: mux-h2: Properly handle connection error during preface sending

On backend side, an error at connection level during the preface sending was
not properly handled and could lead to a spinning loop on process_stream()
when the h2 stream on client side was blocked, for instance because of h2
flow control.

It appeared that no transition was perfromed from the PREFACE state to an
ERROR state on the H2 connection when an error occurred on the underlying
connection. In that case, the H2 connection was woken up in loop to try to
receive data, waking up the upper stream at the same time.

To fix the issue, an H2C error must be reported. Most state transitions are
handled by the demux function. So it is the right place to do so. First, in
PREFACE state and on server side, if an error occurred on the TCP
connection, an error is now reported on the H2 connection. REFUSED_STREAM
error code is used in that case. In addition, in that case, we also take
care to properly handle the connection shutdown.

This patch should fix the issue #3020. It must be backported to all stable
versions.

(cherry picked from commit 5ba0a2d5270f2ba52a3022578e52fb5709bff3cb)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 0232f26d8862229c079188a5e0141904d7db3dc1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit dfe831816c990b488d1e4316eca7bfbfe4e76bd0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MEDIUM: hlua: Forbid any L6/L7 sample fetche functions from lua services
Christopher Faulet [Tue, 24 Jun 2025 06:26:14 +0000 (08:26 +0200)]
BUG/MEDIUM: hlua: Forbid any L6/L7 sample fetche functions from lua services

It was already forbidden to use HTTP sample fetch functions from lua
services. An error is triggered if it happens. However, the error must be
extended to any L6/L7 sample fetch functions.

Indeed, a lua service is an applet. It totally unexepected for an applet to
access to input data in a channel's buffer. These data have not been
analyzed yet and are still subject to any change. An applet, lua or not,
must never access to "not forwarded" data. Only output data are
available. For now, if a lua applet relies on any L6/L7 sampel fetch
functions, the behavior is undefined and not consistent.

So to fix the issue, hlua flag HLUA_F_MAY_USE_HTTP is renamed to
HLUA_F_MAY_USE_CHANNELS_DATA. This flag is used to prevent any lua applet to
use L6/L7 sample fetch functions.

This patch could be backported to all stable versions.

(cherry picked from commit a2a142bf40c76114cf85dfe1f48d7b14ec70ad5f)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 236a6faff2a8abd7221b13fac1746488d335868e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit db837984a6bba5846f4157cacd675f3685a93afe)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoSCRIPTS: drop the HTML generation from announce-release
Willy Tarreau [Thu, 26 Jun 2025 16:01:02 +0000 (18:01 +0200)]
SCRIPTS: drop the HTML generation from announce-release

It has not been used over the last 5 years or so and systematically
requires manual removal. Let's just stop producing it. Also take
this opportunity to add the missing link to /discussions.

(cherry picked from commit 27baa3f9ff7f50f3751aa541daaa22a4ca577b5a)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit eae27fc288eb2d33fea53d60cbc5362d3eaffc01)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b66643125323412a64bcfe978edb617cca4c15ce)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoMINOR: quic: Useless TX buffer size reduction in closing state
Frederic Lecaille [Wed, 25 Jun 2025 08:15:50 +0000 (10:15 +0200)]
MINOR: quic: Useless TX buffer size reduction in closing state

There is no need to limit the size of the TX buffer to QUIC_MIN_CC_PKTSIZE bytes
when the connection is in closing state. There is already a test which limits the
number of bytes to be used from this TX buffer after this useless test removed.
It limits this number of bytes to the size of the TX buffer itself:

    if (end > (unsigned char *)b_wrap(buf))
    end = (unsigned char *)b_wrap(buf);

This is exactly what is needed when the connection is in closing state. Indeed,
the size of the TX buffers are limited to reduce the memory usage. The connection
only needs to send short datagrams with at most 2 packets with a CONNECTION_CLOSE*
frames. They are built only one time and backed up into small TX buffer allocated
from a dedicated pool.
The size of this TX buffer is QUIC_MAX_CC_BUFSIZE which depends on QUIC_MIN_CC_PKTSIZE:

 #define QUIC_MIN_CC_PKTSIZE  128
 #define QUIC_MAX_CC_BUFSIZE (2 * (QUIC_MIN_CC_PKTSIZE + QUIC_DGRAM_HEADLEN))

This size is smaller than an MTU.

This patch should be backported as far as 2.9 to ease further backports to come.

(cherry picked from commit c898b29e6486ec17442555b2df4929c77684298f)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 1699cc9df385cbb3abe23547553fee2b47da490f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 9fe465256cbcaed3fc41c30c6b2b9df93376d639)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding
Frederic Lecaille [Mon, 23 Jun 2025 14:52:09 +0000 (16:52 +0200)]
BUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding

This is an old bug which was there since this commit:

     MINOR: quic: Avoid zeroing frame structures

It seems QUIC_FT_CONNECTION_CLOSE was confused with QUIC_FT_CONNECTION_CLOSE_APP
which does not include a "frame type" field. This field was not initialized
(so with a random value) which prevent the packet to be built because the
packet builder supposes the packet with such frames are very short.

Must be backported as far as 2.6.

(cherry picked from commit 1e6d8f199c9943eca13dec48e8676377356c81d0)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 1f73ddeb5c49ad6e742efb7deca305798dc43896)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3f6e0d887d30b9a2815d379d5fbf15470854aa65)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: configuration: add details on prefer-client-ciphers
William Lallemand [Wed, 25 Jun 2025 12:41:45 +0000 (14:41 +0200)]
DOC: configuration: add details on prefer-client-ciphers

prefer-client-ciphers does not work exactly the same way when used with
a dual algorithm stack (ECDSA + RSA). This patch details its behavior.

This patch must be backported in every maintained version.

Problem was discovered in #2988.

(cherry picked from commit 370a8cea4a2680cf27d5be61163bada27d541347)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 5000d32a2488a47cf817bebcf023312510d0cddc)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit faa6c12a5ceea61b904847a6b481d2efb2ba421b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: log: Be able to use %ID alias at anytime of the stream's evaluation
Christopher Faulet [Mon, 23 Jun 2025 05:50:01 +0000 (07:50 +0200)]
BUG/MINOR: log: Be able to use %ID alias at anytime of the stream's evaluation

In a log-format string, using "%[unique-id]" or "%ID" should be equivalent.
However, for the first one, the unique ID is generated when the sample fetch
function is called. For the alias, it is not true. It that case, the
stream's unique ID is generated when the log message is emitted. Otherwise,
by default, the unique id is automatically generated at the end of the HTTP
request analysis.

So, if the alias "%ID" is use in a log-format string anywhere before the end
of the request analysis, the evaluation failed and the ID is considered as
empty. It is not consistent and in contradiction with the "%ID"
documentation.

To fix the issue, instead of evaluating the unique ID when the log message
is emitted, it is now performed on demand when "%ID" format is evaluated.

This patch should fix the issue #3016. It should be backported to all stable
versions. It relies on the following commit:

  * BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself

(cherry picked from commit 20a82027ceb7a46ce2a0cbe05e40c63d132601f7)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 609d9447e2ecfe6bc4854aa2c3ee9154a97b2710)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b07ee7114ded568f80fb1de115e11bc355916774)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself
Christopher Faulet [Mon, 23 Jun 2025 05:33:06 +0000 (07:33 +0200)]
BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself

There is nothing that prevent a "unique-id-format" to reference itself,
using '%ID' or '%[unique-id]'. If the sample fetch function is used, it
leads to an infinite loop, calling recursively the function responsible to
generate the unique ID.

One solution is to detect it during the configuration parsing to trigger an
error. With this patch, we just inhibit recursive calls by considering the
unique-id as empty during its evaluation. So "id-%[unique-id]" lf string
will be evaluated as "id-".

This patch must be backported to all stable versions.

(cherry picked from commit fb7b5c8a53cb4f19a223abd20660d47162aa8708)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit dfbb00ac1410af65d2befe3e94afb6cfc137b220)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b9968b4d131918075c00708fd6ad5b51fc3146c5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoBUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream
Amaury Denoyelle [Wed, 18 Jun 2025 13:12:31 +0000 (15:12 +0200)]
BUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream

Previously, no check on peer flow-control was implemented prior to open
a local QUIC stream. This was a small problem for frontend
implementation, as in this case haproxy as a server never opens
bidirectional streams.

On frontend, the only stream opened by haproxy in this case is for
HTTP/3 control unidirectional data. If the peer uses an initial value
for max uni streams set to 0, it would violate its flow control, and the
peer will probably close the connection. Note however that RFC 9114
mandates that each peer defines minimal initial value so that at least
the control stream can be created.

This commit improves the situation of too low initial max uni streams
value. Now, on HTTP/3 layer initialization, haproxy preemptively checks
flow control limit on streams via a new function
qcc_fctl_avail_streams(). If credit is already expired due to a too
small initial value, haproxy preemptively closes the connection using
H3_ERR_GENERAL_PROTOCOL_ERROR. This behavior is better as haproxy is now
the initiator of the connection closure.

This should be backported up to 2.8.

(cherry picked from commit 805a070ab920d14b22a6b7beac3b0648e684b2d2)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 47a4954c3974b85fc1b30ea723bf1d809e66e630)
[cf: context adjustment]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 541d2c9a9b124cb19f4346a8c2fff3ada354380a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

2 weeks agoDOC: config: prefer-last-server: add notes for non-deterministic algorithms
Valentine Krasnobaeva [Tue, 17 Jun 2025 13:33:12 +0000 (13:33 +0000)]
DOC: config: prefer-last-server: add notes for non-deterministic algorithms

Add some notes which load-balancing algorithm can be considered as
deterministic or non-deterministic and add some examples for each type.
This was asked via mailing list to clarify the usage of
prefer-last-server option.

This can be backported to all stable versions.

(cherry picked from commit cdb2f8d780a27778cc23669693a9910e07135e8a)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit d6ca14b764039ed1c5d21d2fa83706996fd0a717)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit db39526525ec1124f8742410c573a621311c0ce3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

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

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

(cherry picked from commit df00164fdd98d15e832daad34fb23249083bfb9c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 38ef948e754e4cab938f219349642c89cf0a79e6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

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

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

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

(cherry picked from commit 9a05c1f57490ba3adb378ad8e6e26830425514e7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 479befa356966c12a0a0ead74971750de4ac4499)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

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

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

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

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

The code was made usable both for H2 and H3.

(cherry picked from commit ebab479cdf34255cd6162d2e843645f88b95327f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit dcb963f9d777af39926e83f20e0a3c65c54f3bc0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

5 weeks agoMINOR: compiler: add __nonstring macro
Valentine Krasnobaeva [Mon, 31 Mar 2025 09:47:45 +0000 (11:47 +0200)]
MINOR: compiler: add __nonstring macro

GCC 15 throws the following warning on fixed-size char arrays if they do not
contain terminated NUL:

src/tools.c:2041:25: error: initializer-string for array of 'char' truncates NUL terminator but destination lacks 'nonstring' attribute (17 chars into 16 available) [-Werror=unterminated-string-initialization]
 2041 | const char hextab[16] = "0123456789ABCDEF";

We are using a couple of such definitions for some constants. Converting them
to flexible arrays, like: hextab[] = "0123456789ABCDEF" may have consequences,
as enlarged arrays won't fit anymore where they were possibly located due to
the memory alignement constraints.

GCC adds 'nonstring' variable attribute for such char arrays, but clang and
other compilers don't have it. Let's wrap 'nonstring' with our
__nonstring macro, which will test if the compiler supports this attribute.

This fixes the issue #2910.

(cherry picked from commit b3038614696fee43b6eaa826f47f273a8619690d)
[wla: should be backported to every stable branches]
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit d4234b3c32b79b8dffd70f22c1eb3ba39541acb3)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>

2 months agoBUG/MEDIUM: hlua_fcn: ensure systematic watcher cleanup for server list iterator
Aurelien DARRAGON [Fri, 1 Aug 2025 13:33:56 +0000 (15:33 +0200)]
BUG/MEDIUM: hlua_fcn: ensure systematic watcher cleanup for server list iterator

In 358166a ("BUG/MINOR: hlua_fcn: restore server pairs iterator pointer
consistency"), I wrongly assumed that because the iterator was a temporary
object, no specific cleanup was needed for the watcher.

In fact watcher_detach() is not only relevant for the watcher itself, but
especially for its parent list to remove the current watcher from it.

As iterators are temporary objects, failing to remove their watchers from
the server watcher list causes the server watcher list to be corrupted.

On a normal iteration sequence, the last watcher_next() receives NULL
as target so it successfully detaches the last watcher from the list.
However the corner case here is with interrupted iterators: users are
free to break away from the iteration loop when a specific condition is
met for instance from the lua script, when this happens
hlua_listable_servers_pairs_iterator() doesn't get a chance to detach the
last iterator.

Also, Lua doesn't tell us that the loop was interrupted,
so to fix the issue we rely on the garbage collector to force a last
detach right before the object is freed. To achieve that, watcher_detach()
was slightly modified so that it becomes possible to call it without
knowing if the watcher is already detached or not, if watcher_detach() is
called on a detached watcher, the function does nothing. This way it saves
the caller from having to track the watcher state and makes the API a
little more convenient to use. This way we now systematically call
watcher_detach() for server iterators right before they are garbage
collected.

This was first reported in GH #3055. It can be observed when the server
list is browsed one than more time when it was already browsed from Lua
for a given proxy and the iteration was interrupted before the end. As the
watcher list is corrupted, the common symptom is watcher_attach() or
watcher_next() not ending due to the internal mt_list call looping
forever.

Thanks to GH users @sabretus and @sabretus for their precious help.

It should be backported everywhere 358166a was.

(cherry picked from commit aeff2a3b2a87ae5572e73944eb56e732bb98295f)
Signed-off-by: Aurelien DARRAGON <adarragon@haproxy.com>
(cherry picked from commit 97bb595f25b56bc6d8b68d75a6251a53fa86c4e1)
Signed-off-by: Aurelien DARRAGON <adarragon@haproxy.com>
(cherry picked from commit 051f51fe8417e072bdc949a050e0b5377073adca)
Signed-off-by: Aurelien DARRAGON <adarragon@haproxy.com>

2 months agoBUG/MINOR: hlua_fcn: restore server pairs iterator pointer consistency
Aurelien DARRAGON [Wed, 11 Dec 2024 09:42:11 +0000 (10:42 +0100)]
BUG/MINOR: hlua_fcn: restore server pairs iterator pointer consistency

Since 9c91b30 ("MINOR: server: remove prev_deleted server list"), hlua
server pair iterator may use and return invalid (stale) server pointer
if multiple servers were deleted between two iterations.

Indeed, the server refcount mechanism (using srv_take()) is no longer
sufficient as the prev_deleted mitigation was removed.

To ensure server pointer consistency between two yields, the new watcher
mechanism must be used (as it already the case for stats dumping).

Thus in this patch we slightly change the server iteration logic:
hlua_server_list_iterator_context struct now stores the next valid server
pointer, and a watcher is added to ensure this pointer is never stale.

Then in hlua_listable_servers_pairs_iterator(), this next pointer is used
to create the Lua server object, and the next valid pointer is obtained by
leveraging watcher_next().

No backport needed unless 9c91b30 ("MINOR: server: remove prev_deleted
server list") is. Please note that dynamic servers were not supported in
Lua prior to 2.8, so it doesn't make sense to backport this patch further
than 2.8.

(cherry picked from commit 358166ae6a3e98d36b378c7eeab1673cc8b4a4dd)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit d3fd2a825b4520cc76584709123bdc6b781ab93f)
Signed-off-by: Aurelien DARRAGON <adarragon@haproxy.com>

2 months agoBUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers
William Lallemand [Thu, 12 Jun 2025 14:50:08 +0000 (16:50 +0200)]
BUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers

Patch 23093c72 ("BUG/MINOR: ssl: suboptimal certificate selection with TLSv1.3
and dual ECDSA/RSA") introduced a problem when prioritizing the ECDSA
with TLSv1.3.

Indeed, when a client with TLSv1.3 capabilities announce a list of
ECDSA sigalgs, a list of TLSv1.3 ciphersuites compatible with ECDSA,
but only RSA ciphers for TLSv1.2, and haproxy is configured to a
ssl-max-ver TLSv1.2, then haproxy would use the ECDSA keypair, but the
client wouldn't be able to process it because TLSv1.2 was negociated.

HAProxy would be configured like that:

  ssl-default-bind-options ssl-max-ver TLSv1.2

And a client could be used this way:

  openssl s_client -connect localhost:8443 -cipher ECDHE-ECDSA-AES128-GCM-SHA256 \
          -ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

This patch fixes the issue by checking if TLSv1.3 was configured before
allowing ECDSA is an TLSv1.3 ciphersuite is in the list.

This could be backported where 23093c72 ("BUG/MINOR: ssl: suboptimal
certificate selection with TLSv1.3 and dual ECDSA/RSA") was backported.
However this is quite sensible and we should wait a bit before the
backport.

This should fix issue #2988

(cherry picked from commit 4a298c6c5c64ecbbc8df1351df4b410216f95828)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit b552780290616a66ed9eb4247250c7239d159a90)
Signed-off-by: William Lallemand <wlallemand@haproxy.com>
(cherry picked from commit 4c91018f1b50bc121b683b4dd83bdae90ad8f698)
[wla: ssl_clienthello.c didn't exist in <= 3.0, changes were made in
ssl_sock.c instead]
Signed-off-by: William Lallemand <wlallemand@haproxy.com>

4 months agoBUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported
Christopher Faulet [Mon, 16 Jun 2025 14:33:04 +0000 (16:33 +0200)]
BUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported

When a connection error is reported, we try to collect as much information
as possible on the connection status and the server status is adjusted
accordingly. However, the function does nothing if there is no connection
error and if the healthcheck is not expired yet. It is a problem when an
internal error occurred. It may happen at many places and it is hard to be
sure an error is reported on the connection. And in fact, it is already a
problem when the multiplexer allocation fails. In that case, the healthcheck
is not interrupted as it should be. Concretely, it could only happen when a
connection is established.

It is hard to predict the effects of this bug. It may be unimportant. But it
could probably lead to a crash. To avoid any issue, a SOCKERR status is now
set by default when a connection error is reported. There is no reason to
report a connection error for nothing. So a healthcheck failure must be
reported. There is no "internal error" status. So a socket error is
reported.

This patch must be backport to all stable versions.

(cherry picked from commit 54d74259e9860c7017903221f27525be89983a75)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 18542f3a8b2c42598ca1e5061507c8393bc3ce2d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 806f245ea838066ca32a6a2bb1118f90c17f1597)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoMINOR: cli: handle EOS/ERROR first
Christopher Faulet [Mon, 16 Jun 2025 14:29:07 +0000 (16:29 +0200)]
MINOR: cli: handle EOS/ERROR first

It is not especially a bug fixed. But APPCTX_FL_EOS and APPCTX_FL_ERROR
flags must be handled first. These flags are set by the applet itself and
should mark the end of all processing. So there is not reason to get the
output buffer in first place.

This patch could be backported as far as 3.0.

(cherry picked from commit fb7665552668df368bbc85ef56beca11c356f53a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 9a874dc54c3a6eb061f19d0a65e882d17d4b1a3e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit a1246d92eeeb50f6b10349fb6848e9cead969c0e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MEDIUM: cli: Don't consume data if outbuf is full or not available
Christopher Faulet [Mon, 16 Jun 2025 13:48:04 +0000 (15:48 +0200)]
BUG/MEDIUM: cli: Don't consume data if outbuf is full or not available

The output buffer must be available to process a command, at least to be
able to emit error messages. When this buffer is full or cannot be
allocated, we must wait. In that case, we must take care to notify the SE
will not consume input data. It is important to avoid wakeup in loop,
especially when the client aborts.

When the output buffer is available again and no longer full, and the CLI
applet is waiting for a command line, it must notify it will consume input
data.

This patch must be backported as far as 3.0.

(cherry picked from commit 396f0252bf3a400c9dbfdaf730e994bb44f198dd)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit de668f5eb86f0370357042badc07a90e5d565576)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6072496521b2feb0ffcae5b72b95adff10291b7b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MINOR: config/server: reject QUIC addresses
Amaury Denoyelle [Wed, 11 Jun 2025 16:26:10 +0000 (18:26 +0200)]
BUG/MINOR: config/server: reject QUIC addresses

QUIC is not implemented on the backend side. To prevent any issue, it is
better to reject any server configured which uses it. This is done via
_srv_parse_init() which is used both for static and dynamic servers.

This should be backported up to all stable versions.

(cherry picked from commit 1ecf2e9babe9d2505cebfc9e0f64454be66c2905)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4b2ae7c9c644b5b27af732dc15df3d2fc7558693)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit dac40233379db32ba92c8fc0a8265a1fba2ddee7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MINIR: h1: Fix doc of 'accept-unsafe-...-request' about URI parsing
Christopher Faulet [Tue, 10 Jun 2025 17:03:44 +0000 (19:03 +0200)]
BUG/MINIR: h1: Fix doc of 'accept-unsafe-...-request' about URI parsing

The description of tests performed on the URI in H1 when
'accept-unsafe-violations-in-http-request' option is wrong. It states that
only characters below 32 and 127 are blocked when this option is set,
suggesting that otherwise, when it is not set, all invalid characters in the
URI, according to the RFC3986, are blocked.

But in fact, it is not true. By default all character below 32 and above 127
are blocked. And when 'accept-unsafe-violations-in-http-request' option is
set, characters above 127 (excluded) are accepted. But characters in
(33..126) are never checked, independently of this option.

This patch should fix the issue #2906. It should be backported as far as
3.0. For older versions, the docuementation could also be clarified because
this part is not really clear.

Note the request URI validation is still under discution because invalid
characters in (33.126) are never checked and some users request a stricter
parsing.

(cherry picked from commit b2f64af3413e623aff2f2413cbbef6ac27f44f21)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3b01e537edd2b50c449ede6cb312caa45786ca35)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit eeb21041a1fab3022d905cfbfe9fad683c52b623)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MEDIUM: fd: Use the provided tgid in fd_insert() to get tgroup_info
Olivier Houchard [Tue, 10 Jun 2025 12:39:22 +0000 (12:39 +0000)]
BUG/MEDIUM: fd: Use the provided tgid in fd_insert() to get tgroup_info

In fd_insert(), use the provided tgid to ghet the thread group info,
instead of using the one of the current thread, as we may call
fd_insert() from a thread of another thread group, that will happen at
least when binding the listeners. Otherwise we'd end up accessing the
thread mask containing enabled thread of the wrong thread group, which
can lead to crashes if we're binding on threads not present in the
thread group.
This should fix Github issue #2991.

This should be backported up to 2.8.

(cherry picked from commit 6993981cd6e81448cd6a21ca32f21f2b548aa1b3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 12989a221bdf829a36f73d25ac947e95af7af59a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 67455c2e293fe0af1dfaf12c031de04bff958930)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MINOR: quic: Missing SSL session object freeing
Frederic Lecaille [Wed, 4 Jun 2025 09:49:14 +0000 (11:49 +0200)]
BUG/MINOR: quic: Missing SSL session object freeing

qc_alloc_ssl_sock_ctx() allocates an SSL_CTX object for each connection. It also
allocates an SSL object. When this function failed, it freed only the SSL_CTX object.
The correct way to free both of them is to call qc_free_ssl_sock_ctx().

Must be backported as far as 2.6.

(cherry picked from commit 6b746330692380f7e88fc757b7124b5a9c88ebd8)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit aaef9e0000fb2fc6011d9a95e6e7f5241863db8f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3ba302684fcc346ed02c3892335f5ab9e8bceeb8)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MEDIUM: check: Requeue healthchecks on I/O events to handle check timeout
Christopher Faulet [Tue, 3 Jun 2025 12:50:38 +0000 (14:50 +0200)]
BUG/MEDIUM: check: Requeue healthchecks on I/O events to handle check timeout

When a healthchecks is processed, once the first wakeup passed to start the
check, and as long as the expiration timer is not reached, only I/O events
are able to wake it up. It is an issue when there is a check timeout
defined.  Especially if the connect timeout is high and the check timeout is
low. In that case, the healthcheck's task is never requeue to handle any
timeout update. When the connection is established, the check timeout is set
to replace the connect timeout. It is thus possible to report a success
while a timeout should be reported.

So, now, when an I/O event is handled, the healthcheck is requeue, except if
an success or an abort is reported.

Thanks to Thierry Fournier for report and the reproducer.

This patch must be backported to all stable versions.

(cherry picked from commit 7c788f0984623f727a71ae4aee9917ddeac1b59d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 73b733e2e0bf6d6e9914c3b58a632f2b4dcb2d8d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 2341a3c06afd1ec3a92d0df5766daf30360374d6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoDOC: config: Fix a typo in 2.7 (Name format for maps and ACLs)
Christopher Faulet [Mon, 2 Jun 2025 07:18:08 +0000 (09:18 +0200)]
DOC: config: Fix a typo in 2.7 (Name format for maps and ACLs)

"identified" was used instead of "identifier". May be backported as far as
3.0

(cherry picked from commit 8e8cdf114b1961b008fd108dbe6b6c4aa0ce2b68)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 81e566388907ca03c56ee30ad745ddd93ce04a97)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 1a6a3e5d958e2a42246c221369b96d18715112b1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUILD: tools: properly define ha_dump_backtrace() to avoid a build warning
Willy Tarreau [Fri, 30 May 2025 15:13:21 +0000 (17:13 +0200)]
BUILD: tools: properly define ha_dump_backtrace() to avoid a build warning

In resolve_sym_name() we declare a few symbols that we want to be able
to resolve. ha_dump_backtrace() was declared with a struct buffer instead
of a pointer to such a struct, which has no effect since we only want to
get the function's pointer, but produces a build warning with LTO, so
let's fix it.

This can be backported to 3.0.

(cherry picked from commit b88164d9c0eb1540c9b787478162c254ac947e8d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6330c20026e79f54a6ead77d6c9573945a074744)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 30e59abd95cf22d755791fcd167c6e80d0b2d805)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

4 months agoBUG/MINOR: quic: ensure cwnd limits are always enforced
Amaury Denoyelle [Mon, 20 Jan 2025 15:24:21 +0000 (16:24 +0100)]
BUG/MINOR: quic: ensure cwnd limits are always enforced

Congestion window is limit by a minimal and maximum values which can
never be exceeded. Min value is hardcoded to 2 datagrams as recommended
by the specification. Max value is specified via haproxy configuration.

These values must be respected each time the congestion window size is
adjusted. However, in some rare occasions, limit were not always
enforced. Fix this by implementing wrappers to set or increment the
congestion window. These functions ensure limits are always applied
after the operation.

Additionnally, wrappers also ensure that if window reached a new maximum
value, it is saved in <cwnd_last_max> field.

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

(cherry picked from commit 7bad88c35c7547d52ac170ed9f89f29cccd6c46c)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 355a3225302d1714792781f2dbee7d2ccfdc2a62)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>

4 months agoMINOR: quic: rename min/max fields for congestion window algo
Amaury Denoyelle [Thu, 23 Jan 2025 09:47:57 +0000 (10:47 +0100)]
MINOR: quic: rename min/max fields for congestion window algo

There was some possible confusion between fields related to congestion
window size min and max limit which cannot be exceeded, and the maximum
value previously reached by the window.

Fix this by adopting a new naming scheme. Enforced limit are now renamed
<limit_max>/<limit_min>, while the previously reached max value is
renamed <cwnd_last_max>.

This should be backported up to 3.1.

(cherry picked from commit 2eb1b0cd96f663b9260ee48921612566417b3b8d)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 13c3baf545c93994688c3abd4895e6aede05211a)
 [ad: pick to ease next backport]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>

4 months agoBUG/MINOR: mux-quic: do not decode if conn in error
Amaury Denoyelle [Wed, 23 Apr 2025 15:06:22 +0000 (17:06 +0200)]
BUG/MINOR: mux-quic: do not decode if conn in error

Add an early return to qcc_decode_qcs() if QCC instance is flagged on
error and connection is scheduled for immediate closure.

The main objective is to ensure to not trigger BUG_ON() from
qcc_set_error() : if a stream decoding has set the connection error, do
not try to process decoding on other streams as they may also encounter
an error. Thus, the connection is closed asap with the first encountered
error case.

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

(cherry picked from commit 6c5030f703e29bfd8deeace111bcedc6835c7065)
[ad: context adjustement, due to multiple Rx bufs not available in 3.1]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 52235aed6248ff32832a24530ca8593610c76903)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>