]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 months agoBUG/MAJOR: leastconn: never reuse the node after dropping the lock
Willy Tarreau [Mon, 19 May 2025 13:57:03 +0000 (15:57 +0200)] 
BUG/MAJOR: leastconn: never reuse the node after dropping the lock

On ARM with 80 cores and a single server, it's sometimes possible to see
a segfault in fwlc_get_next_server() around 600-700k RPS. It seldom
happens as well on x86 with 128 threads with the same config around 1M
rps. It turns out that in fwlc_get_next_server(), before calling
fwlc_srv_reposition(), we have to drop the lock and that one takes it
back again.

The problem is that anything can happen to our node during this time,
and it can be freed. Then when continuing our work, we later iterate
over it and its next to find a node with an acceptable key, and by
doing so we can visit either uninitialized memory or simply nodes that
are no longer in the tree.

A first attempt at fixing this consisted in artificially incrementing
the elements count before dropping the lock, but that turned out to be
even worse because other threads could loop forever on such an element
looking for an entry that does not exist. Maintaining a separate
refcount didn't work well either, and it required to deal with the
memory release while dropping it, which is really not convenient.

Here we're taking a different approach consisting in simply not
trusting this node anymore and going back to the beginning of the
loop, as is done at a few other places as well. This way we can
safely ignore the possibly released node, and the test runs reliably
both on the arm and the x86 platforms mentioned above. No performance
regression was observed either, likely because this operation is quite
rare.

No backport is needed since this appeared with the leastconn rework
in 3.2.

2 months agoBUG/MINOR: quic: fix crash on quic_conn alloc failure
Amaury Denoyelle [Mon, 19 May 2025 09:02:46 +0000 (11:02 +0200)] 
BUG/MINOR: quic: fix crash on quic_conn alloc failure

If there is an alloc failure during qc_new_conn(), cleaning is done via
quic_conn_release(). However, since the below commit, an unchecked
dereferencing of <qc.path> is performed in the latter.

  e841164a4402118bd7b2e2dc2b5068f21de5d9d2
  MINOR: quic: account for global congestion window

To fix this, simply check <qc.path> before dereferencing it in
quic_conn_release(). This is safe as it is properly initialized to NULL
on qc_new_conn() first stage.

This does not need to be backported.

2 months agoBUG/MAJOR: queue: properly keep count of the queue length
Willy Tarreau [Sat, 17 May 2025 08:28:50 +0000 (10:28 +0200)] 
BUG/MAJOR: queue: properly keep count of the queue length

The queue length was moved to its own variable in commit 583303c48
("MINOR: proxies/servers: Calculate queueslength and use it."), however a
few places were missed in pendconn_unlink() and assign_server_and_queue()
resulting in never decreasing counts on aborted streams. This was
reproduced when injecting more connections than the total backend
could stand in TCP mode and letting some of them time out in the
queue. No backport is needed, this is only 3.2.

2 months agoBUG/MAJOR: leastconn: do not loop forever when facing saturated servers
Willy Tarreau [Sat, 17 May 2025 07:54:49 +0000 (09:54 +0200)] 
BUG/MAJOR: leastconn: do not loop forever when facing saturated servers

Since commit 9fe72bba3 ("MAJOR: leastconn; Revamp the way servers are
ordered."), there's no way to escape the loop visiting the mt_list heads
in fwlc_get_next_server if all servers in the list are saturated,
resulting in a watchdog panic. It can be reproduced with this config
and injecting with more than 2 concurrent conns:

    balance leastconn
    server s1 127.0.0.1:8000 maxconn 1
    server s2 127.0.0.1:8000 maxconn 1

Here we count the number of saturated servers that were encountered, and
escape the loop once the number of remaining servers exceeds the number
of saturated ones. No backport is needed since this arrived in 3.2.

2 months agoIMPORT: slz: silence a build warning on non-x86 non-arm
Willy Tarreau [Fri, 16 May 2025 14:19:04 +0000 (16:19 +0200)] 
IMPORT: slz: silence a build warning on non-x86 non-arm

Building with clang 16 on MIPS64 yields this warning:

  src/slz.c:931:24: warning: unused function 'crc32_uint32' [-Wunused-function]
  static inline uint32_t crc32_uint32(uint32_t data)
                         ^

Let's guard it using UNALIGNED_LE_OK which is the only case where it's
used. This saves us from introducing a possibly non-portable attribute.

This is libslz upstream commit f5727531dba8906842cb91a75c1ffa85685a6421.

2 months agoIMPORT: slz: fix header used for empty zlib message
Willy Tarreau [Mon, 26 Jun 2023 16:00:39 +0000 (18:00 +0200)] 
IMPORT: slz: fix header used for empty zlib message

Calling slz_rfc1950_finish() without emitting any data would result in
incorrectly emitting a gzip header (rfc1952) instead of a zlib header
(rfc1950) due to a copy-paste between the two wrappers. The impact is
almost inexistent since the zlib format is almost never used in this
context, and compressing totally empty messages is quite rare as well.
Let's take this opportunity for fixing another mistake on an RFC number
in a comment.

This is slz upstream commit 7f3fce4f33e8c2f5e1051a32a6bca58e32d4f818.

2 months agoIMPORT: slz: use a better hash for machines with a fast multiply
Willy Tarreau [Sun, 9 Apr 2023 09:50:15 +0000 (11:50 +0200)] 
IMPORT: slz: use a better hash for machines with a fast multiply

The current hash involves 3 simple shifts and additions so that it can
be mapped to a multiply on architecures having a fast multiply. This is
indeed what the compiler does on x86_64. A large range of values was
scanned to try to find more optimal factors on machines supporting such
a fast multiply, and it turned out that new factor 0x1af42f resulted in
smoother hashes that provided on average 0.4% better compression on both
the Silesia corpus and an mbox file composed of very compressible emails
and uncompressible attachments. It's even slightly better than CRC32C
while being faster on Skylake. This patch enables this factor on archs
with a fast multiply.

This is slz upstream commit 82ad1e75c13245a835c1c09764c89f2f6e8e2a40.

2 months agoIMPORT: slz: support crc32c for lookup hash on sse4 but only if requested
Willy Tarreau [Sun, 9 Apr 2023 09:35:19 +0000 (11:35 +0200)] 
IMPORT: slz: support crc32c for lookup hash on sse4 but only if requested

If building for sse4 and USE_CRC32C_HASH is defined, then we can use
crc32c to calculate the lookup hash. By default we don't do it because
even on skylake it's slower than the current hash, which only involves
a short multiply (~5% slower). But the gains are marginal (0.3%).

This is slz upstream commit 44ae4f3f85eb275adba5844d067d281e727d8850.

Note: this is not used by default and only merged in order to avoid
divergence between the code bases.

2 months agoIMPORT: slz: avoid multiple shifts on 64-bits
Willy Tarreau [Sun, 9 Apr 2023 08:23:18 +0000 (10:23 +0200)] 
IMPORT: slz: avoid multiple shifts on 64-bits

On 64-bit platforms, disassembling the code shows that send_huff() performs
a left shift followed by a right one, which are the result of integer
truncation and zero-extension caused solely by using different types at
different levels in the call chain. By making encode24() take a 64-bit
int on input and send_huff() take one optionally, we can remove one shift
in the hot path and gain 1% performance without affecting other platforms.

This is slz upstream commit fd165b36c4621579c5305cf3bb3a7f5410d3720b.

2 months agoBUILD: debug: mark ha_crash_now() as attribute(noreturn)
Willy Tarreau [Fri, 16 May 2025 14:12:12 +0000 (16:12 +0200)] 
BUILD: debug: mark ha_crash_now() as attribute(noreturn)

Building on MIPS64 with clang16 incorrectly reports some uninitialized
value warnings in stats-proxy.c due to some calls to ABORT_NOW() where
the compiler didn't know the code wouldn't return. Let's properly mark
the function as noreturn, and take this opportunity for also marking it
unused to avoid possible warnings depending on the build options (if
ABORT_NOW is not used). No backport needed though it will not harm.

2 months agoDOC: management: change reference to configuration manual
William Lallemand [Fri, 16 May 2025 13:57:13 +0000 (15:57 +0200)] 
DOC: management: change reference to configuration manual

Since e24b77e7 ('DOC: config: move the extraneous sections out of the
"global" definition') the ACME section of the configuration manual was
move from 3.13 to 12.8.

Change the reference to that section in "acme renew".

2 months agoDOC: config: properly index "table and "stick-table" in their section
Willy Tarreau [Fri, 16 May 2025 13:37:03 +0000 (15:37 +0200)] 
DOC: config: properly index "table and "stick-table" in their section

Tim reported in issue #2953 that "stick-table" and "table" were not
indexed as keywords. The issue was the indent level. Also let's make
sure to put a box around the "store" arguments as well.

2 months 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.

2 months agoBUG/MINOR: h3: don't insert more than one Host header
Willy Tarreau [Fri, 16 May 2025 12:51:13 +0000 (14:51 +0200)] 
BUG/MINOR: h3: don't insert more than one Host header

Let's make sure we drop extraneous Host headers after having compared
them. That also works when :authority was already present. This way,
like for h1 and h2, we only keep one copy of it, while still making
sure that Host matches :authority. This way, if a request has both
:authority and Host, only one Host header will be produced (from
:authority). Note that due to the different organization of the code
and wording along the evolving RFCs, here we also check that all
duplicates are identical, while h2 ignores them as per RFC7540, but
this will be re-unified later.

This should be backported to stable versions, at least 2.8, though
thanks to the existing checks the impact is probably nul.

2 months agoBUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload
Christopher Faulet [Fri, 16 May 2025 12:19:52 +0000 (14:19 +0200)] 
BUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload

It is especially a problem with Lua filters, but it is important to disable
the 0-copy forwarding if a filter alters the payload, or at least to be able
to disable it. While the filter is registered on the data filtering, it is
not an issue (and it is the common case) because, there is now way to
fast-forward data at all. But it may be an issue if a filter decides to
alter the payload and to unregister from data filtering. In that case, the
0-copy forwarding can be re-enabled in a hardly precdictable state.

To fix the issue, a SC flags was added to do so. The HTTP compression filter
set it and lua filters too if the body length is changed (via
HTTPMessage.set_body_len()).

Note that it is an issue because of a bad design about the HTX. Many info
about the message are stored in the HTX structure itself. It must be
refactored to move several info to the stream-endpoint descriptor. This
should ease modifications at the stream level, from filter or a TCP/HTTP
rules.

This should be backported as far as 3.0. If necessary, it may be backported
on lower versions, as far as 2.6. In that case, it must be reviewed and
adapted.

2 months agoMEDIUM: hlua: Add function to change the body length of an HTTP Message
Christopher Faulet [Fri, 16 May 2025 12:10:31 +0000 (14:10 +0200)] 
MEDIUM: hlua: Add function to change the body length of an HTTP Message

There was no function for a lua filter to change the body length of an HTTP
Message. But it is mandatory to be able to alter the message payload. It is
not possible update to directly update the message headers because the
internal state of the message must also be updated accordingly.

It is the purpose of HTTPMessage.set_body_len() function. The new body
length myst be passed as argument. If it is an integer, the right
"Content-Length" header is set. If the "chunked" string is used, it forces
the message to be chunked-encoded and in that case the "Transfer-Encoding"
header.

This patch should fix the issue #2837. It could be backported as far as 2.6.

2 months agoBUG/MEDIUM: peers: also limit the number of incoming updates
Willy Tarreau [Thu, 15 May 2025 13:41:50 +0000 (15:41 +0200)] 
BUG/MEDIUM: peers: also limit the number of incoming updates

There's a configurable limit to the number of messages sent to a
peer (tune.peers.max-updates-at-once), but this one is not applied to
the receive side. While it can usually be OK with default settings,
setups involving a large tune.bufsize (1MB and above) regularly
experience high latencies and even watchdogs during reloads because
the full learning process sends a lot of data that manages to fill
the entire buffer, and due to the compactness of the protocol, 1MB
of buffer can contain more than 100k updates, meaning taking locks
etc during this time, which is not workable.

Let's make sure the receiving side also respects the max-updates-at-once
setting. For this it counts incoming updates, and refrains from
continuing once the limit is reached. It's a bit tricky to do because
after receiving updates we still have to send ours (and possibly some
ACKs) so we cannot just leave the loop.

This issue was reported on 3.1 but it should progressively be backported
to all versions having the max-updates-at-once option available.

2 months agoBUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers
Aurelien DARRAGON [Thu, 15 May 2025 13:54:13 +0000 (15:54 +0200)] 
BUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers

using "send-proxy" or "send-proxy-v2" option on a ring server is not
relevant nor supported. Worse, on 2.4 it causes haproxy process to
crash as reported in GH #2965.

Let's be more explicit about the fact that this keyword is not supported
under "ring" context by ignoring the option and emitting a warning message
to inform the user about that.

Ideally, we should do the same for peers and log servers. The proper way
would be to check servers options during postparsing but we currently lack
proper cross-type server postparsing hooks. This will come later and thus
will give us a chance to perform the compatibilty checks for server
options depending on proxy type. But for now let's simply fix the "ring"
case since it is the only one that's known to cause a crash.

It may be backported to all stable versions.

2 months agoDOC: configuration: explicit multi-choice on bind shards option
Basha Mougamadou [Wed, 14 May 2025 15:50:47 +0000 (15:50 +0000)] 
DOC: configuration: explicit multi-choice on bind shards option

From the documentation, this wasn't clear enough that shards should
be followed by one of the options number / by-thread / by-group.
Align it with existing options in documentation so that it becomes
more explicit.

2 months ago[RELEASE] Released version 3.2-dev16 v3.2-dev16
Willy Tarreau [Wed, 14 May 2025 15:01:46 +0000 (17:01 +0200)] 
[RELEASE] Released version 3.2-dev16

Released version 3.2-dev16 with the following main changes :
    - BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
    - DEBUG: pool: permit per-pool UAF configuration
    - MINOR: acme: add the global option 'acme.scheduler'
    - DEBUG: pools: add a new integrity mode "backup" to copy the released area
    - MEDIUM: sock-inet: re-check IPv6 connectivity every 30s
    - BUG/MINOR: ssl: doesn't fill conf->crt with first arg
    - BUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line
    - BUG/MINOR: ssl/ckch: always free() the previous entry during parsing
    - MINOR: tools: ha_freearray() frees an array of string
    - BUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing
    - MINOR: ssl/ckch: warn when the same keyword was used twice
    - BUG/MINOR: threads: fix soft-stop without multithreading support
    - BUG/MINOR: tools: improve parse_line()'s robustness against empty args
    - BUG/MINOR: cfgparse: improve the empty arg position report's robustness
    - BUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()
    - BUG/MINOR: server: perform lbprm deinit for dynamic servers
    - MINOR: http: add a function to validate characters of :authority
    - BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly
    - MINOR: quic: account Tx data per stream
    - MINOR: mux-quic: account Rx data per stream
    - MINOR: quic: add stream format for "show quic"
    - MINOR: quic: display QCS info on "show quic stream"
    - MINOR: quic: display stream age
    - BUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters
    - MINOR: cpu-topo: add a new "group-by-ccx" CPU policy
    - MINOR: cpu-topo: provide a function to sort clusters by average capacity
    - MEDIUM: cpu-topo: change "performance" to consider per-core capacity
    - MEDIUM: cpu-topo: change "efficiency" to consider per-core capacity
    - MEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"
    - MEDIUM: config: change default limits to 1024 threads and 32 groups
    - BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation
    - DOC: config: Fix a typo in the "term_events" definition
    - BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state
    - BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received
    - BUG/MINOR: mux-spop: Make the demux stream ID a signed integer
    - BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
    - MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
    - BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
    - BUG/MEDIUM: mux-spop: Properly handle CLOSING state
    - BUG/MEDIUM: spop-conn: Report short read for partial frames payload
    - BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error
    - BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data
    - DEBUG: mux-spop: Review some trace messages to adjust the message or the level
    - DOC: config: move address formats definition to section 2
    - DOC: config: move stick-tables and peers to their own section
    - DOC: config: move the extraneous sections out of the "global" definition
    - CI: AWS-LC(fips): enable unit tests
    - CI: AWS-LC: enable unit tests
    - CI: compliance: limit run on forks only to manual + cleanup
    - CI: musl: enable unit tests
    - CI: QuicTLS (weekly): limit run on forks only to manual dispatch
    - CI: WolfSSL: enable unit tests

2 months agoCI: WolfSSL: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:38:45 +0000 (20:38 +0200)] 
CI: WolfSSL: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: QuicTLS (weekly): limit run on forks only to manual dispatch
Ilia Shipitsin [Tue, 13 May 2025 18:38:10 +0000 (20:38 +0200)] 
CI: QuicTLS (weekly): limit run on forks only to manual dispatch

2 months agoCI: musl: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:37:35 +0000 (20:37 +0200)] 
CI: musl: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: compliance: limit run on forks only to manual + cleanup
Ilia Shipitsin [Tue, 13 May 2025 18:36:41 +0000 (20:36 +0200)] 
CI: compliance: limit run on forks only to manual + cleanup

2 months agoCI: AWS-LC: enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:36:17 +0000 (20:36 +0200)] 
CI: AWS-LC: enable unit tests

Run the new make unit-tests on the CI.

2 months agoCI: AWS-LC(fips): enable unit tests
Ilia Shipitsin [Tue, 13 May 2025 18:35:29 +0000 (20:35 +0200)] 
CI: AWS-LC(fips): enable unit tests

Run the new make unit-tests on the CI.

2 months agoDOC: config: move the extraneous sections out of the "global" definition
Willy Tarreau [Wed, 14 May 2025 13:54:58 +0000 (15:54 +0200)] 
DOC: config: move the extraneous sections out of the "global" definition

Due to some historic mistakes that have spread to newly added sections,
a number of of recently added small sections found themselves described
under section 3 "global parameters" which is specific to "global" section
keywords. This is highly confusing, especially given that sections 3.1,
3.2, 3.3 and 3.10 directly start with keywords valid in the global section,
while others start with keywords that describe a new section.

Let's just create a new chapter "12. other sections" and move them all
there. 3.10 "HTTPclient tuning" however was moved to 3.4 as it's really
a definition of the global options assigned to the HTTP client. The
"programs" that are going away in 3.3 were moved at the end to avoid a
renumbering later.

Another nice benefit is that it moves a lot of text that was previously
keeping the global and proxies sections apart.

2 months agoDOC: config: move stick-tables and peers to their own section
Willy Tarreau [Wed, 14 May 2025 12:26:38 +0000 (14:26 +0200)] 
DOC: config: move stick-tables and peers to their own section

As suggested by Tim in issue #2953, stick-tables really deserve their own
section to explain the configuration. And peers have to move there as well
since they're totally dedicated to stick-tables.

Now we introduce a new section "Stick-tables and Peers", explaining the
concepts, and under which there is one subsection for stick-tables
configuration and one for the peers (which mostly keeps the existing
peers section).

2 months agoDOC: config: move address formats definition to section 2
Willy Tarreau [Wed, 14 May 2025 13:39:15 +0000 (15:39 +0200)] 
DOC: config: move address formats definition to section 2

Section 2 describes the config file format, variables naming etc, so
there's no reason why the address format used in this file should be
in a separate section, let's bring it into section 2 as well.

2 months agoDEBUG: mux-spop: Review some trace messages to adjust the message or the level
Christopher Faulet [Wed, 14 May 2025 07:39:03 +0000 (09:39 +0200)] 
DEBUG: mux-spop: Review some trace messages to adjust the message or the level

Some trace messages were not really accurrate, reporting a CLOSED connection
while only an error was reported on it. In addition, an TRACE_ERROR() was
used to report a short read on HELLO/DISCONNECT frames header. But it is not
an error. a TRACE_DEVEL() should be used instead.

This patch could be backported to 3.1 to ease future backports.

2 months agoBUG/MEDIUM: mux-spop; Don't report a read error if there are pending data
Christopher Faulet [Wed, 14 May 2025 07:33:46 +0000 (09:33 +0200)] 
BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data

When an read error is detected, no error must be reported on the SPOP
connection is there are still some data to parse. It is important to be sure
to process all data before reporting the error and be sure to not truncate
received frames. However, we must also take care to handle short read case
to not wait data that will never be received.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error
Christopher Faulet [Wed, 14 May 2025 07:22:45 +0000 (09:22 +0200)] 
BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error

There was no test in the demux part to detect truncated frames and to report
an error at the connection level. The SPOP streams were properly switch to
half-closed state. But waiting the associated SPOE applets were woken up and
released, the SPOP connection could be woken up several times for nothing. I
never triggered the watchdog in that case, but it is not excluded.

Now, at the end of the demux function, if a specific test was added to
detect truncated frames to report an error and close the connection.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: spop-conn: Report short read for partial frames payload
Christopher Faulet [Wed, 14 May 2025 07:20:08 +0000 (09:20 +0200)] 
BUG/MEDIUM: spop-conn: Report short read for partial frames payload

When a frame was not fully received, a short read must be reported on the
SPOP connection to help the demux to handle truncated frames. This was
performed for frames truncated on the header part but not on the payload
part. It is now properly detected.

This patch must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Properly handle CLOSING state
Christopher Faulet [Tue, 13 May 2025 17:04:01 +0000 (19:04 +0200)] 
BUG/MEDIUM: mux-spop: Properly handle CLOSING state

The CLOSING state was not handled at all by the SPOP multiplexer while it is
mandatory when a DISCONNECT frame was sent and the mux should wait for the
DISCONNECT frame in reply from the agent. Thanks to this patch, it should be
fixed.

In addition, if an error occurres during the AGENT HELLO frame parsing, the
SPOP connection is no longer switched to CLOSED state and remains in ERROR
state instead. It is important to be able to send the DISCONNECT frame to
the agent instead of closing the TCP connection immediately.

This patch depends on following commits:

  * BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
  * MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
  * BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
  * BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

All the series must be backported to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
Christopher Faulet [Tue, 13 May 2025 16:55:32 +0000 (18:55 +0200)] 
BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state

SPOP_CS_FRAME_H and SPOP_CS_FRAME_P states, that were used to handle frame
parsing, were removed. The demux process now relies on the demux stream ID
to know if it is waiting for the frame header or the frame
payload. Concretly, when the demux stream ID is not set (dsi == -1), the
demuxer is waiting for the next frame header. Otherwise (dsi >= 0), it is
waiting for the frame payload. It is especially important to be able to
properly handle DISCONNECT frames sent by the agents.

SPOP_CS_RUNNING state is introduced to know the hello handshake was finished
and the SPOP connection is able to open SPOP streams and exchange NOTIFY/ACK
frames with the agents.

It depends on the following fixes:

  * MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
  * BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

This change will be mandatory for the next fix. It must be backported to 3.1
with the commits above.

2 months agoMINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
Christopher Faulet [Tue, 13 May 2025 16:41:09 +0000 (18:41 +0200)] 
MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing

After the ACK frame was parsed, it is useless to set the SPOP connection
state to SPOP_CS_FRAME_H state because this will be automatically handled by
the demux function. If it is not an issue, but this will simplify changes
for the next commit.

2 months agoBUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
Christopher Faulet [Tue, 13 May 2025 16:35:29 +0000 (18:35 +0200)] 
BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error

Till now, only SPOP connections fully closed or those with a TCP connection on
error were concerned. But available streams could be reported for SPOP
connections in error or closing state. But in these states, no NOTIFY frames
will be sent and no ACK frames will be parsed. So, no new SPOP streams should be
opened.

This patch should be backported to 3.1.

2 months agoBUG/MINOR: mux-spop: Make the demux stream ID a signed integer
Christopher Faulet [Tue, 13 May 2025 16:26:25 +0000 (18:26 +0200)] 
BUG/MINOR: mux-spop: Make the demux stream ID a signed integer

The demux stream ID of a SPOP connection, used when received frames are
parsed, must be a signed integer because it is set to -1 when the SPOP
connection is initialized. It will be important for the next fix.

This patch must be backported to 3.1.

2 months agoBUG/MINOR: mux-spop: Don't report error for stream if ACK was already received
Christopher Faulet [Tue, 13 May 2025 16:05:26 +0000 (18:05 +0200)] 
BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received

When a SPOP connection was closed or was in error, an error was
systematically reported on all its SPOP streams. However, SPOP streams that
already received their ACK frame must be excluded. Otherwise if an agent
sends a ACK and close immediately, the ACK will be ignored because the SPOP
stream will handle the error first.

This patch must be backported to 3.1.

2 months agoBUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state
Christopher Faulet [Tue, 13 May 2025 15:45:18 +0000 (17:45 +0200)] 
BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state

When the SPOE applet was released, if a SPOE filter context was still
attached to it, an error was reported to the filter. However, there is no
reason to report an error if the ACK message was already received. Because
of this bug, if the ACK message is received and the SPOE connection is
immediately closed, this prevents the ACK message to be processed.

This patch should be backported to 3.1.

2 months agoDOC: config: Fix a typo in the "term_events" definition
Christopher Faulet [Tue, 13 May 2025 12:26:37 +0000 (14:26 +0200)] 
DOC: config: Fix a typo in the "term_events" definition

A space was missing before the colon.

2 months agoBUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation
Christopher Faulet [Mon, 12 May 2025 14:12:13 +0000 (16:12 +0200)] 
BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation

When the channel API was revisted, the both functions above was added. An
offset can be passed as argument. However, this parameter could be reported
to be out of range if there was not enough input data was received yet. It
is an issue, especially with a tcp rule, because more data could be
received. If an error is reported too early, this prevent the rule to be
reevaluated later. In fact, an error should only be reported if the offset
is part of the output data.

Another issue is about the conditions to report 'nil' instead of an empty
string. 'nil' was reported when no data was found. But it is not aligned
with the documentation. 'nil' must only be returned if no more data cannot
be received and there is no input data at all.

This patch should fix the issue #2716. It should be backported as far as 2.6.

2 months agoMEDIUM: config: change default limits to 1024 threads and 32 groups
Willy Tarreau [Tue, 13 May 2025 15:58:28 +0000 (17:58 +0200)] 
MEDIUM: config: change default limits to 1024 threads and 32 groups

A test run on a dual-socket EPYC 9845 (2x160 cores) showed that we'll
be facing new limits during the lifetime of 3.2 with our current 16
groups and 256 threads max:

  $ cat test.cfg
  global
      cpu-policy perforamnce

  $ ./haproxy -dc -c -f test.cfg
  ...
  Thread CPU Bindings:
    Tgrp/Thr  Tid        CPU set
    1/1-32    1-32       32: 0-15,320-335
    2/1-32    33-64      32: 16-31,336-351
    3/1-32    65-96      32: 32-47,352-367
    4/1-32    97-128     32: 48-63,368-383
    5/1-32    129-160    32: 64-79,384-399
    6/1-32    161-192    32: 80-95,400-415
    7/1-32    193-224    32: 96-111,416-431
    8/1-32    225-256    32: 112-127,432-447

Raising the default limit to 1024 threads and 32 groups is sufficient
to buy us enough margin for a long time (hopefully, please don't laugh,
you, reader from the future):

  $ ./haproxy -dc -c -f test.cfg
  ...
  Thread CPU Bindings:
    Tgrp/Thr  Tid        CPU set
    1/1-32    1-32       32: 0-15,320-335
    2/1-32    33-64      32: 16-31,336-351
    3/1-32    65-96      32: 32-47,352-367
    4/1-32    97-128     32: 48-63,368-383
    5/1-32    129-160    32: 64-79,384-399
    6/1-32    161-192    32: 80-95,400-415
    7/1-32    193-224    32: 96-111,416-431
    8/1-32    225-256    32: 112-127,432-447
    9/1-32    257-288    32: 128-143,448-463
    10/1-32   289-320    32: 144-159,464-479
    11/1-32   321-352    32: 160-175,480-495
    12/1-32   353-384    32: 176-191,496-511
    13/1-32   385-416    32: 192-207,512-527
    14/1-32   417-448    32: 208-223,528-543
    15/1-32   449-480    32: 224-239,544-559
    16/1-32   481-512    32: 240-255,560-575
    17/1-32   513-544    32: 256-271,576-591
    18/1-32   545-576    32: 272-287,592-607
    19/1-32   577-608    32: 288-303,608-623
    20/1-32   609-640    32: 304-319,624-639

We can change this default now because it has no functional effect
without any configured cpu-policy, so this will only be an opt-in
and it's better to do it now than to have an effect during the
maintenance phase. A tiny effect is a doubling of the number of
pool buckets and stick-table shards internally, which means that
aside slightly reducing contention in these areas, a dump of tables
can enumerate keys in a different order (hence the adjustment in the
vtc).

The only really visible effect is a slightly higher static memory
consumption (29->35 MB on a small config), but that difference
remains even with 50k servers so that's pretty much acceptable.

Thanks to Erwan Velu for the quick tests and the insights!

2 months agoMEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"
Willy Tarreau [Tue, 13 May 2025 14:20:53 +0000 (16:20 +0200)] 
MEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"

Most of the time, machines made of multiple CPU types use the same L3
for them, and grouping CPUs by frequencies to form groups doesn't bring
any value and on the opposite can impair the incoming connection balancing.
This choice of grouping by cluster was made in order to constitute a good
choice on homogenous machines as well, so better rely on the per-CCX
grouping than the per-cluster one in this case. This will create less
clusters on machines where it counts without affecting other ones.

It doesn't seem necessary to change anything for the "resource" policy
since it selects a single cluster.

2 months agoMEDIUM: cpu-topo: change "efficiency" to consider per-core capacity
Willy Tarreau [Tue, 13 May 2025 14:18:25 +0000 (16:18 +0200)] 
MEDIUM: cpu-topo: change "efficiency" to consider per-core capacity

This is similar to the previous change to the "performance" policy but
it applies to the "efficiency" one. Here we're changing the sorting
method to sort CPU clusters by average per-CPU capacity, and we evict
clusters whose per-CPU capacity is above 125% of the previous one.
Per-core capacity allows to detect discrepancies between CPU cores,
and to continue to focus on efficient ones as a priority.

2 months agoMEDIUM: cpu-topo: change "performance" to consider per-core capacity
Willy Tarreau [Tue, 13 May 2025 14:12:52 +0000 (16:12 +0200)] 
MEDIUM: cpu-topo: change "performance" to consider per-core capacity

Running the "performance" policy on highly heterogenous systems yields
bad choices when there are sufficiently more small than big cores,
and/or when there are multiple cluster types, because on such setups,
the higher the frequency, the lower the number of cores, despite small
differences in frequencies. In such cases, we quickly end up with
"performance" only choosing the small or the medium cores, which is
contrary to the original intent, which was to select performance cores.
This is what happens on boards like the Orion O6 for example where only
the 4 medium cores and 2 big cores are choosen, evicting the 2 biggest
cores and the 4 smallest ones.

Here we're changing the sorting method to sort CPU clusters by average
per-CPU capacity, and we evict clusters whose per-CPU capacity falls
below 80% of the previous one. Per-core capacity allows to detect
discrepancies between CPU cores, and to continue to focus on high
performance ones as a priority.

2 months agoMINOR: cpu-topo: provide a function to sort clusters by average capacity
Willy Tarreau [Tue, 13 May 2025 14:00:23 +0000 (16:00 +0200)] 
MINOR: cpu-topo: provide a function to sort clusters by average capacity

The current per-capacity sorting function acts on a whole cluster, but
in some setups having many small cores and few big ones, it becomes
easy to observe an inversion of metrics where the many small cores show
a globally higher total capacity than the few big ones. This does not
necessarily fit all use cases. Let's add new a function to sort clusters
by their per-cpu average capacity to cover more use cases.

2 months agoMINOR: cpu-topo: add a new "group-by-ccx" CPU policy
Willy Tarreau [Tue, 13 May 2025 13:39:35 +0000 (15:39 +0200)] 
MINOR: cpu-topo: add a new "group-by-ccx" CPU policy

This cpu-policy will only consider CCX and not clusters. This makes
a difference on machines with heterogenous CPUs that generally share
the same L3 cache, where it's not desirable to create multiple groups
based on the CPU types, but instead create one with the different CPU
types. The variants "group-by-2/3/4-ccx" have also been added.

Let's also add some text explaining the difference between cluster
and CCX.

2 months agoBUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters
Willy Tarreau [Tue, 13 May 2025 09:40:44 +0000 (11:40 +0200)] 
BUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters

Some (rare) boards have their clusters in an erratic order. This is
the case for the Radxa Orion O6 where one of the big cores appears as
CPU0 due to booting from it, then followed by the small cores, then the
medium cores, then the remaining big cores. This results in clusters
appearing this order: 0,2,1,0.

The core in cpu_policy_group_by_cluster() expected ordered clusters,
and performs ordered comparisons to decide whether a CPU's cluster has
already been taken care of. On the board above this doesn't work, only
clusters 0 and 2 appear and 1 is skipped.

Let's replace the cluster number comparison with a cpuset to record
which clusters have been taken care of. Now the groups properly appear
like this:

  Tgrp/Thr  Tid        CPU set
  1/1-2     1-2        2: 0,11
  2/1-4     3-6        4: 1-4
  3/1-6     7-12       6: 5-10

No backport is needed, this is purely 3.2.

2 months agoMINOR: quic: display stream age
Amaury Denoyelle [Fri, 9 May 2025 15:30:27 +0000 (17:30 +0200)] 
MINOR: quic: display stream age

Add a field to save the creation date of qc_stream_desc instance. This
is useful to display QUIC stream age in "show quic stream" output.

2 months agoMINOR: quic: display QCS info on "show quic stream"
Amaury Denoyelle [Wed, 7 May 2025 15:38:15 +0000 (17:38 +0200)] 
MINOR: quic: display QCS info on "show quic stream"

Complete stream output for "show quic" by displaying information from
its upper QCS. Note that QCS may be NULL if already released, so a
default output is also provided.

2 months agoMINOR: quic: add stream format for "show quic"
Amaury Denoyelle [Wed, 7 May 2025 14:28:39 +0000 (16:28 +0200)] 
MINOR: quic: add stream format for "show quic"

Add a new format for "show quic" command labelled as "stream". This is
an equivalent of "show sess", dedicated to the QUIC stack. Each active
QUIC streams are listed on a line with their related infos.

The main objective of this command is to ensure there is no freeze
streams remaining after a transfer.

2 months agoMINOR: mux-quic: account Rx data per stream
Amaury Denoyelle [Mon, 24 Mar 2025 10:27:27 +0000 (11:27 +0100)] 
MINOR: mux-quic: account Rx data per stream

Add counters to measure Rx buffers usage per QCS. This reused the newly
defined bdata_ctr type already used for Tx accounting.

Note that for now, <tot> value of bdata_ctr is not used. This is because
it is not easy to account for data accross contiguous buffers.

These values are displayed both on log/traces and "show quic" output.

2 months agoMINOR: quic: account Tx data per stream
Amaury Denoyelle [Wed, 7 May 2025 15:32:46 +0000 (17:32 +0200)] 
MINOR: quic: account Tx data per stream

Add accounting at qc_stream_desc level to be able to report the number
of allocated Tx buffers and the sum of their data. This represents data
ready for emission or already emitted and waiting on ACK.

To simplify this accounting, a new counter type bdata_ctr is defined in
quic_utils.h. This regroups both buffers and data counter, plus a
maximum on the buffer value.

These values are now displayed on QCS info used both on logline and
traces, and also on "show quic" output.

2 months 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.

2 months 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.

2 months agoBUG/MINOR: server: perform lbprm deinit for dynamic servers
Aurelien DARRAGON [Mon, 12 May 2025 14:27:43 +0000 (16:27 +0200)] 
BUG/MINOR: server: perform lbprm deinit for dynamic servers

Last commit 7361515 ("BUG/MINOR: server: dont depend on proxy for server
cleanup in srv_drop()") introduced a regression because the lbprm
server_deinit is not evaluated anymore with dynamic servers, possibly
resulting in a memory leak.

To fix the issue, in addition to free_proxy(), the server deinit check
should be manually performed in cli_parse_delete_server() as well.

No backport needed.

2 months agoBUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()
Aurelien DARRAGON [Mon, 12 May 2025 14:09:15 +0000 (16:09 +0200)] 
BUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()

In commit b5ee8bebfc ("MINOR: server: always call ssl->destroy_srv when
available"), we made it so srv_drop() doesn't depend on proxy to perform
server cleanup.

It turns out this is now mandatory, because during deinit, free_proxy()
can occur before the final srv_drop(). This is the case when using Lua
scripts for instance.

In 2a9436f96 ("MINOR: lbprm: Add method to deinit server and proxy") we
added a freeing check under srv_drop() that depends on the proxy.
Because of that UAF may occur during deinit when using a Lua script that
manipulate server objects.

To fix the issue, let's perform the lbprm server deinit logic under
free_proxy() directly, where the DEINIT server hooks are evaluated.

Also, to prevent similar bugs in the future, let's explicitly document
in srv_drop() that server cleanups should assume that the proxy may
already be freed.

No backport needed unless 2a9436f96 is.

2 months agoBUG/MINOR: cfgparse: improve the empty arg position report's robustness
Willy Tarreau [Mon, 12 May 2025 14:06:28 +0000 (16:06 +0200)] 
BUG/MINOR: cfgparse: improve the empty arg position report's robustness

OSS Fuzz found that the previous fix ebb19fb367 ("BUG/MINOR: cfgparse:
consider the special case of empty arg caused by \x00") was incomplete,
as the output can sometimes be larger than the input (due to variables
expansion) in which case the work around to try to report a bad arg will
fail. While the parse_line() function has been made more robust now in
order to avoid this condition, let's fix the handling of this special
case anyway by just pointing to the beginning of the line if the supposed
error location is out of the line's buffer.

All details here:
   https://oss-fuzz.com/testcase-detail/5202563081502720

No backport is needed unless the fix above is backported.

2 months agoBUG/MINOR: tools: improve parse_line()'s robustness against empty args
Willy Tarreau [Mon, 12 May 2025 14:01:27 +0000 (16:01 +0200)] 
BUG/MINOR: tools: improve parse_line()'s robustness against empty args

The fix in 10e6d0bd57 ("BUG/MINOR: tools: only fill first empty arg when
not out of range") was not that good. It focused on protecting against
<arg> becoming out of range to detect we haven't emitted anything, but
it's not the right way to detect this. We're always maintaining arg_start
as a copy of outpos, and that later one is incremented when emitting a
char, so instead of testing args[arg] against out+arg_start, we should
instead check outpos against arg_start, thereby eliminating the <out>
offset and the need to access args[]. This way we now always know if
we've emitted an empty arg without dereferencing args[].

There's no need to backport this unless the fix above is also backported.

2 months agoBUG/MINOR: threads: fix soft-stop without multithreading support
Aurelien DARRAGON [Mon, 12 May 2025 09:57:39 +0000 (11:57 +0200)] 
BUG/MINOR: threads: fix soft-stop without multithreading support

When thread support is disabled ("USE_THREAD=" or "USE_THREAD=0" when
building), soft-stop doesn't work as haproxy never ends after stopping
the proxies.

This used to work fine in the past but suddenly stopped working with
ef422ced91 ("MEDIUM: thread: make stopping_threads per-group and add
stopping_tgroups") because the "break;" instruction under the stopping
condition is never executed when support for multithreading is disabled.

To fix the issue, let's add an "else" block to run the "break;"
instruction when USE_THREAD is not defined.

It should be backported up to 2.8

2 months agoMINOR: ssl/ckch: warn when the same keyword was used twice
William Lallemand [Fri, 9 May 2025 17:18:38 +0000 (19:18 +0200)] 
MINOR: ssl/ckch: warn when the same keyword was used twice

When using a crt-list or a crt-store, keywords mentionned twice on the
same line overwritte the previous value.

This patch emits a warning when the same keyword is found another time
on the same line.

2 months agoBUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing
William Lallemand [Fri, 9 May 2025 17:16:02 +0000 (19:16 +0200)] 
BUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing

The ckch_conf_parse() function is the generic function which parses
crt-store keywords from the crt-store section, and also from a
crt-list.

When having multiple time the same keyword, a leak of the previous
value happens. This patch ensure that the previous value is always
freed before overwriting it.

This is the same problem as the previous "BUG/MINOR: ssl/ckch: always
free() the previous entry during parsing" patch, however this one
applies on PARSE_TYPE_ARRAY_SUBSTR.

No backport needed.

2 months agoMINOR: tools: ha_freearray() frees an array of string
William Lallemand [Fri, 9 May 2025 17:09:12 +0000 (19:09 +0200)] 
MINOR: tools: ha_freearray() frees an array of string

ha_freearray() is a new function which free() an array of strings
terminated by a NULL entry.

The pointer to the array will be free and set to NULL.

2 months agoBUG/MINOR: ssl/ckch: always free() the previous entry during parsing
William Lallemand [Fri, 9 May 2025 17:01:28 +0000 (19:01 +0200)] 
BUG/MINOR: ssl/ckch: always free() the previous entry during parsing

The ckch_conf_parse() function is the generic function which parses
crt-store keywords from the crt-store section, and also from a crt-list.

When having multiple time the same keyword, a leak of the previous value
happens. This patch ensure that the previous value is always freed
before overwriting it.

This patch should be backported as far as 3.0.

2 months agoBUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line
William Lallemand [Fri, 9 May 2025 16:52:09 +0000 (18:52 +0200)] 
BUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line

The 'ssl-f-use' implementation doesn't prevent to have multiple time the
'crt' keyword, which overwrite the previous value. Letting users think
that is it possible to use multiple certificates on the same line, which
is not the case.

This patch emits an alert when setting the 'crt' keyword multiple times
on the same ssl-f-use line.

Should fix issue #2966.

No backport needed.

2 months agoBUG/MINOR: ssl: doesn't fill conf->crt with first arg
William Lallemand [Fri, 9 May 2025 16:23:06 +0000 (18:23 +0200)] 
BUG/MINOR: ssl: doesn't fill conf->crt with first arg

Commit c7f29afc ("MEDIUM: ssl: replace "crt" lines by "ssl-f-use"
lines") forgot to remove an the allocation of the crt field which was
done with the first argument.

Since ssl-f-use takes keywords, this would put the first keyword in
"crt" instead of the certificate name.

2 months agoMEDIUM: sock-inet: re-check IPv6 connectivity every 30s
Willy Tarreau [Fri, 9 May 2025 13:23:10 +0000 (15:23 +0200)] 
MEDIUM: sock-inet: re-check IPv6 connectivity every 30s

IPv6 connectivity might start off (e.g. network not fully up when
haproxy starts), so for features like resolvers, it would be nice to
periodically recheck.

With this change, instead of having the resolvers code rely on a variable
indicating connectivity, it will now call a function that will check for
how long a connectivity check hasn't been run, and will perform a new one
if needed. The age was set to 30s which seems reasonable considering that
the DNS will cache results anyway. There's no saving in spacing it more
since the syscall is very check (just a connect() without any packet being
emitted).

The variables remain exported so that we could present them in show info
or anywhere else.

This way, "dns-accept-family auto" will now stay up to date. Warning
though, it does perform some caching so even with a refreshed IPv6
connectivity, an older record may be returned anyway.

2 months agoDEBUG: pools: add a new integrity mode "backup" to copy the released area
Willy Tarreau [Thu, 8 May 2025 13:28:18 +0000 (15:28 +0200)] 
DEBUG: pools: add a new integrity mode "backup" to copy the released area

This way we can preserve the entire contents of the released area for
later inspection. This automatically enables comparison at reallocation
time as well (like "integrity" does). If used in combination with
integrity, the comparison is disabled but the check of non-corruption
of the area mangled by integrity is still operated.

2 months agoMINOR: acme: add the global option 'acme.scheduler'
William Lallemand [Fri, 9 May 2025 11:45:48 +0000 (13:45 +0200)] 
MINOR: acme: add the global option 'acme.scheduler'

The automatic scheduler is useful but sometimes you don't want to use,
or schedule manually.

This patch adds an 'acme.scheduler' option in the global section, which
can be set to either 'auto' or 'off'. (auto is the default value)

This also change the ouput of the 'acme status' command so it does not
shows scheduled values. The state will be 'Stopped' instead of
'Scheduled'.

2 months agoDEBUG: pool: permit per-pool UAF configuration
Willy Tarreau [Thu, 8 May 2025 17:52:16 +0000 (19:52 +0200)] 
DEBUG: pool: permit per-pool UAF configuration

The new MEM_F_UAF flag can be set just after a pool's creation to make
this pool UAF for debugging purposes. This allows to maintain a better
overall performance required to reproduce issues while still having a
chance to catch UAF. It will only be used by developers who will manually
add it to areas worth being inspected, though.

2 months agoBUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
Amaury Denoyelle [Fri, 9 May 2025 08:54:40 +0000 (10:54 +0200)] 
BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference

Emission of flow-control frames have been recently modified. Now, each
frame is sent one by one, via a single entry list. If a failure occurs,
emission is interrupted and frame is reinserted into the original
<qcc.lfctl.frms> list.

This code is incorrect as it only checks if qcc_send_frames() returns an
error code to perform the reinsert operation. However, an error here
does not always mean that the frame was not properly emitted by lower
quic-conn layer. As such, an extra test LIST_ISEMPTY() must be performed
prior to reinsert the frame.

This bug would cause a heap overflow. Indeed, the reinsert frame would
be a random value. A crash would occur as soon as it would be
dereferenced via <qcc.lfctl.frms> list.

This was reproduced by issuing a POST with a big file and interrupt it
after just a few seconds. This results in a crash in about a third of
the tests. Here is an example command using ngtcp2 :

 $ ngtcp2-client -q --no-quic-dump --no-http-dump \
   -m POST -d ~/infra/html/1g 127.0.0.1 20443 "http://127.0.0.1:20443/post"

Heap overflow was detected via a BUG_ON() statement from qc_frm_free()
via qcc_release() caller :

  FATAL: bug condition "!((&((*frm)->reflist))->n == (&((*frm)->reflist)))" matched at src/quic_frame.c:1270

This does not need to be backported.

2 months ago[RELEASE] Released version 3.2-dev15 v3.2-dev15
Willy Tarreau [Fri, 9 May 2025 08:51:30 +0000 (10:51 +0200)] 
[RELEASE] Released version 3.2-dev15

Released version 3.2-dev15 with the following main changes :
    - BUG/MEDIUM: stktable: fix sc_*(<ctr>) BUG_ON() regression with ctx > 9
    - BUG/MINOR: acme/cli: don't output error on success
    - BUG/MINOR: tools: do not create an empty arg from trailing spaces
    - MEDIUM: config: warn about the consequences of empty arguments on a config line
    - MINOR: tools: make parse_line() provide hints about empty args
    - MINOR: cfgparse: visually show the input line on empty args
    - BUG/MINOR: tools: always terminate empty lines
    - BUG/MINOR: tools: make parseline report the required space for the trailing 0
    - DEBUG: threads: don't keep lock label "OTHER" in the per-thread history
    - DEBUG: threads: merge successive idempotent lock operations in history
    - DEBUG: threads: display held locks in threads dumps
    - BUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends
    - Revert "BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame"
    - MINOR: acme/cli: 'acme status' show the status acme-configured certificates
    - MEDIUM: acme/ssl: remove 'acme ps' in favor of 'acme status'
    - DOC: configuration: add "acme" section to the keywords list
    - DOC: configuration: add the "crt-store" keyword
    - BUG/MAJOR: queue: lock around the call to pendconn_process_next_strm()
    - MINOR: ssl: add filename and linenum for ssl-f-use errors
    - BUG/MINOR: ssl: can't use crt-store some certificates in ssl-f-use
    - BUG/MINOR: tools: only fill first empty arg when not out of range
    - MINOR: debug: bump the dump buffer to 8kB
    - MINOR: stick-tables: add "ipv4" as an alias for the "ip" type
    - MINOR: quic: extend return value during TP parsing
    - BUG/MINOR: quic: use proper error code on missing CID in TPs
    - BUG/MINOR: quic: use proper error code on invalid server TP
    - BUG/MINOR: quic: reject retry_source_cid TP on server side
    - BUG/MINOR: quic: use proper error code on invalid received TP value
    - BUG/MINOR: quic: fix TP reject on invalid max-ack-delay
    - BUG/MINOR: quic: reject invalid max_udp_payload size
    - BUG/MEDIUM: peers: hold the refcnt until updating ts->seen
    - BUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()
    - BUG/MINOR: cli: fix too many args detection for commands
    - MINOR: server: ensure server postparse tasks are run for dynamic servers
    - BUG/MEDIUM: stick-table: always remove update before adding a new one
    - BUG/MEDIUM: quic: free stream_desc on all data acked
    - BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
    - DOC: config: recommend disabling libc-based resolution with resolvers

2 months agoDOC: config: recommend disabling libc-based resolution with resolvers
Willy Tarreau [Fri, 9 May 2025 08:30:30 +0000 (10:30 +0200)] 
DOC: config: recommend disabling libc-based resolution with resolvers

Using both libc and haproxy resolvers can lead to hard to diagnose issues
when their bevahiour diverges; recommend using only one type of resolver.

Should be backported to stable versions.

Link: https://www.mail-archive.com/haproxy@formilux.org/msg45663.html
Co-authored-by: Lukas Tribus <lukas@ltri.eu>
2 months agoBUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
Willy Tarreau [Fri, 9 May 2025 07:55:39 +0000 (09:55 +0200)] 
BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00

The reporting of the empty arg location added with commit 08d3caf30
("MINOR: cfgparse: visually show the input line on empty args") falls
victim of a special case detected by OSS Fuzz:

     https://issues.oss-fuzz.com/issues/415850462

In short, making an argument start with "\x00" doesn't make it empty for
the parser, but still emits an empty string which is detected and
displayed. Unfortunately in this case the error pointer is not set so
the sanitization function crashes.

What we're doing in this case is that we fall back to the position of
the output argument as an estimate of where it was located in the input.
It's clearly inexact (quoting etc) but will still help the user locate
the problem.

No backport is needed unless the commit above is backported.

2 months agoBUG/MEDIUM: quic: free stream_desc on all data acked
Amaury Denoyelle [Wed, 7 May 2025 15:08:42 +0000 (17:08 +0200)] 
BUG/MEDIUM: quic: free stream_desc on all data acked

The following patch simplifies qc_stream_desc_ack(). The qc_stream_desc
instance is not freed anymore, even if all data were acknowledged. As
implies by the commit message, the caller is responsible to perform this
cleaning operation.
  f4a83fbb14bdd14ed94752a2280a2f40c1b690d2
  MINOR: quic: do not remove qc_stream_desc automatically on ACK handling

However, despite the commit instruction, qc_stream_desc_free()
invokation was not moved in the caller. This commit fixes this by adding
it after stream ACK handling. This is performed only when a transfer is
completed : all data is acknowledged and qc_stream_desc has been
released by its MUX stream instance counterpart.

This bug may cause a significant increase in memory usage when dealing
with long running connection. However, there is no memory leak, as every
qc_stream_desc attached to a connection are finally freed when quic_conn
instance is released.

This must be backported up to 3.1.

2 months agoBUG/MEDIUM: stick-table: always remove update before adding a new one
Willy Tarreau [Thu, 8 May 2025 21:21:25 +0000 (23:21 +0200)] 
BUG/MEDIUM: stick-table: always remove update before adding a new one

Since commit 388539faa ("MEDIUM: stick-tables: defer adding updates to a
tasklet"), between the entry creation and its arrival in the updates tree,
there is time for scheduling, and it now becomes possible for an stksess
entry to be requeued into the list while it's still in the tree as a remote
one. Only local updates were removed prior to being inserted. In this case
we would re-insert the entry, causing it to appear as the parent of two
distinct nodes or leaves, and to be visited from the first leaf during a
delete() after having already been removed and freed, causing a crash,
as Christian reported in issue #2959.

There's no reason to backport this as this appeared with the commit above
in 3.2-dev13.

2 months agoMINOR: server: ensure server postparse tasks are run for dynamic servers
Aurelien DARRAGON [Wed, 7 May 2025 21:50:46 +0000 (23:50 +0200)] 
MINOR: server: ensure server postparse tasks are run for dynamic servers

commit 29b76cae4 ("BUG/MEDIUM: server/log: "mode log" after server
keyword causes crash") introduced some postparsing checks/tasks for
server

Initially they were mainly meant for "mode log" servers postparsing, but
we already have a check dedicated to "tcp/http" servers (ie: only tcp
proto supported)

However when dynamic servers are added they bypass _srv_postparse() since
the REGISTER_POST_SERVER_CHECK() is only executed for servers defined in
the configuration.

To ensure consistency between dynamic and static servers, and ensure no
post-check init routine is missed, let's manually invoke _srv_postparse()
after creating a dynamic server added via the cli.

2 months agoBUG/MINOR: cli: fix too many args detection for commands
Aurelien DARRAGON [Wed, 7 May 2025 23:01:28 +0000 (01:01 +0200)] 
BUG/MINOR: cli: fix too many args detection for commands

d3f928944 ("BUG/MINOR: cli: Issue an error when too many args are passed
for a command") added a new check to prevent the command to run when
too many arguments are provided. In this case an error is reported.

However it turns out this check (despite marked for backports) was
ineffective prior to 20ec1de21 ("MAJOR: cli: Refacor parsing and
execution of pipelined commands") as 'p' pointer was reset to the end of
the buffer before the check was executed.

Now since 20ec1de21, the check works, but we have another issue: we may
read past initialized bytes in the buffer because 'p' pointer is always
incremented in a while loop without checking if we increment it past 'end'
(This was detected using valgrind)

To fix the issue introduced by 20ec1de21, let's only increment 'p' pointer
if p < end.

For 3.2 this is it, now for older versions, since d3f928944 was marked for
backport, a sligthly different approach is needed:

 - conditional p increment must be done in the loop (as in this patch)
 - max arg check must moved above "fill unused slots" comment where p is
   assigned to the end of the buffer

This patch should be backported with d3f928944.

2 months agoBUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()
Willy Tarreau [Wed, 7 May 2025 16:43:57 +0000 (18:43 +0200)] 
BUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()

It might be possible not to see the element in the tree, then not to
see it in the update list, thus not to take the lock before deleting.
But an element in the list could have moved to the tree during the
check, and be removed later without the updt_lock.

Let's delete prior to checking the presence in the tree to avoid
this situation. No backport is needed since this arrived in -dev13
with the update list.

2 months agoBUG/MEDIUM: peers: hold the refcnt until updating ts->seen
Willy Tarreau [Tue, 6 May 2025 09:32:34 +0000 (11:32 +0200)] 
BUG/MEDIUM: peers: hold the refcnt until updating ts->seen

In peer_treat_updatemsg(), we call stktable_touch_remote() after
releasing the write lock on the TS, asking it to decrement the
refcnt, then we update ts->seen. Unfortunately this is racy and
causes the issue that Christian reported in issue #2959.

The sequence of events is very hard to trigger manually, but what happens
is the following:

 T1.  stktable_touch_remote(table, ts, 1);
      -> at this point the entry is in the mt_list, and the refcnt is zero.

      T2.  stktable_trash_oldest() or process_table_expire()
           -> these can run, because the refcnt is now zero.
              The entry is cleanly deleted and freed.

 T1.  HA_ATOMIC_STORE(&ts->seen, 1)
      -> we dereference freed memory.

A first attempt at a fix was made by keeping the refcnt held during
all the time the entry is in the mt_list, but this is expensive as
such entries cannot be purged, causing lots of skips during
trash_oldest_data(). This managed to trigger watchdogs, and was only
hiding the real cause of the problem.

The correct approach clearly is to maintain the ref_cnt until we
touch ->seen. That's what this patch does. It does not decrement
the refcnt, while calling stktable_touch_remote(), and does it
manually after touching ->seen. With this the problem is gone.

Note that a reproducer involves the following:
  - a config with 10 stick-ctr tracking the same table with a
    random key between 10M and 100M depending on the machine.
  - the expiration should be between 10 and 20s. http_req_cnt
    is stored and shared with the peers.
  - 4 total processes with such a config on the local machine,
    each corresponding to a different peer. 3 of the peers are
    bound to half of the cores (all threads) and share the same
    threads; the last process is bound to the other half with
    its own threads.
  - injecting at full load, ~256 conn, on the shared listening
    port. After ~2x expiration time to 1 minute the lone process
    should segfault in pools code due to a corrupted by_lru list.

This problem already exists in earlier versions but the race looks
narrower. Given how difficult it is to trigger on a given machine
in its current form, it's likely that it only happens once in a
while on stable branches. The fix must be backported wherever the
code is similar, and there's no hope to reproduce it to validate
the backport.

Thanks again to Christian for his amazing help!

2 months agoBUG/MINOR: quic: reject invalid max_udp_payload size
Amaury Denoyelle [Tue, 6 May 2025 16:01:32 +0000 (18:01 +0200)] 
BUG/MINOR: quic: reject invalid max_udp_payload size

Add a checks on received max_udp_payload transport parameters. As
defined per RFC 9000, values below 1200 are invalid, and thus the
connection must be closed with TRANSPORT_PARAMETER_ERROR code.

Prior to this patch, an invalid value was silently ignored.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoBUG/MINOR: quic: fix TP reject on invalid max-ack-delay
Amaury Denoyelle [Tue, 6 May 2025 16:01:09 +0000 (18:01 +0200)] 
BUG/MINOR: quic: fix TP reject on invalid max-ack-delay

Checks are implemented on some received transport parameter values,
to reject invalid ones defined per RFC 9000. This is the case for
max_ack_delay parameter.

The check was not properly implemented as it only reject values strictly
greater than the limit set to 2^14. Fix this by rejecting values of 2^14
and above. Also, the proper error code TRANSPORT_PARAMETER_ERROR is now
set.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoBUG/MINOR: quic: use proper error code on invalid received TP value
Amaury Denoyelle [Tue, 6 May 2025 16:00:43 +0000 (18:00 +0200)] 
BUG/MINOR: quic: use proper error code on invalid received TP value

As per RFC 9000, checks must be implemented to reject invalid values for
received transport parameters. Such values are dependent on the
parameter type.

Checks were already implemented for ack_delay_exponent and
active_connection_id_limit, accordingly with the QUIC specification.
However, the connection was closed with an incorrect error code. Fix
this to ensure that TRANSPORT_PARAMETER_ERROR code is used as expected.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoBUG/MINOR: quic: reject retry_source_cid TP on server side
Amaury Denoyelle [Tue, 6 May 2025 15:59:37 +0000 (17:59 +0200)] 
BUG/MINOR: quic: reject retry_source_cid TP on server side

Close the connection on error if retry_source_connection_id transport
parameter is received. This is specified by RFC 9000 as this parameter
must not be emitted by a client. Previously, it was silently ignored.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoBUG/MINOR: quic: use proper error code on invalid server TP
Amaury Denoyelle [Tue, 6 May 2025 15:59:21 +0000 (17:59 +0200)] 
BUG/MINOR: quic: use proper error code on invalid server TP

This commit is similar to the previous one. It fixes the error code
reported when dealing with invalid received transport parameters. This
time, it handles reception of original_destination_connection_id,
preferred_address and stateless_reset_token which must not be emitted by
the client.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoBUG/MINOR: quic: use proper error code on missing CID in TPs
Amaury Denoyelle [Tue, 6 May 2025 14:45:23 +0000 (16:45 +0200)] 
BUG/MINOR: quic: use proper error code on missing CID in TPs

Handle missing received transport parameter value
initial_source_connection_id / original_destination_connection_id.
Previously, such case would result in an error reported via
quic_transport_params_store(), which triggers a TLS alert converted as
expected as a CONNECTION_CLOSE. The issue is that the error code
reported in the frame was incorrect.

Fix this by returning QUIC_TP_DEC_ERR_INVAL for such conditions. This is
directly handled via quic_transport_params_store() which set the proper
TRANSPORT_PARAMETER_ERROR code for the CONNECTION_CLOSE. However, no
error is reported so the SSL handshake is properly terminated without a
TLS alert. This is enough to ensure that the CONNECTION_CLOSE frame will
be emitted as expected.

This should be backported up to 2.6. Note that is relies on previous
patch "MINOR: quic: extend return value on TP parsing".

2 months agoMINOR: quic: extend return value during TP parsing
Amaury Denoyelle [Tue, 6 May 2025 16:10:27 +0000 (18:10 +0200)] 
MINOR: quic: extend return value during TP parsing

Extend API used for QUIC transport parameter decoding. This is done via
the introduction of a dedicated enum to report the various error
condition detected. No functional change should occur with this patch,
as the only returned code is QUIC_TP_DEC_ERR_TRUNC, which results in the
connection closure via a TLS alert.

This patch will be necessary to properly reject transport parameters
with the proper CONNECTION_CLOSE error code. As such, it should be
backported up to 2.6 with the following series.

2 months agoMINOR: stick-tables: add "ipv4" as an alias for the "ip" type
Willy Tarreau [Tue, 6 May 2025 08:54:48 +0000 (10:54 +0200)] 
MINOR: stick-tables: add "ipv4" as an alias for the "ip" type

However the doc purposely says the opposite, to encourage migrating away
from "ip". The goal is that in the future we change "ip" to mean "ipv6",
which seems to be what most users naturally expect. But we cannot break
configurations in the LTS version so for now "ipv4" is the alias.

The reason for not changing it in the table is that the type name is
used at a few places (look for "].kw"):
  - dumps
  - promex

We'd rather not change that output for 3.2, but only do it in 3.3.
This way, 3.2 can be made future-proof by using "ipv4" in the config
without any other side effect.

Please see github issue #2962 for updates on this transition.

2 months agoMINOR: debug: bump the dump buffer to 8kB
Willy Tarreau [Wed, 7 May 2025 08:00:08 +0000 (10:00 +0200)] 
MINOR: debug: bump the dump buffer to 8kB

Now with the improved backtraces, the lock history and details in the
mux layers, some dumps appear truncated or with some chars alone at
the beginning of the line. The issue is in fact caused by the limited
dump buffer size (2kB for stderr, 4kB for warning), that cannot hold
a complete trace anymore.

Let's jump bump them to 8kB, this will be plenty for a long time.

2 months agoBUG/MINOR: tools: only fill first empty arg when not out of range
Willy Tarreau [Wed, 7 May 2025 05:22:24 +0000 (07:22 +0200)] 
BUG/MINOR: tools: only fill first empty arg when not out of range

In commit 3f2c8af313 ("MINOR: tools: make parse_line() provide hints
about empty args") we've added the ability to record the position of
the first empty arg in parse_line(), but that check requires to
access the args[] array for the current arg, which is not valid in
case we stopped on too large an argument count. Let's just check the
arg's validity before doing so.

This was reported by OSS Fuzz:
  https://issues.oss-fuzz.com/issues/415850462

No backport is needed since this was in the latest dev branch.

2 months agoBUG/MINOR: ssl: can't use crt-store some certificates in ssl-f-use
William Lallemand [Tue, 6 May 2025 19:16:20 +0000 (21:16 +0200)] 
BUG/MINOR: ssl: can't use crt-store some certificates in ssl-f-use

When declaring a certificate via the crt-store section, this certificate
can then be used 2 ways in a crt-list:
- only by using its name, without any crt-store options
- or by using the exact set of crt-list option that was defined in the
  crt-store

Since ssl-f-use is generating a crt-list, this is suppose to behave the
same. To achieve this, ckch_conf_parse() will parse the keywords related
to the ckch_conf on the ssl-f-use line and use ckch_conf_cmp() to
compare it to the previous declaration from the crt-store. This
comparaison is only done when any ckch_conf keyword are present.

However, ckch_conf_parse() was done for the crt-list, and the crt-list
does not use the "crt" parameter to declare the name of the certificate,
since it's the first element of the line. So when used with ssl-f-use,
ckch_conf_parse() will always see a "crt" keyword which is a ckch_conf
one, and consider that it will always need to have the exact same set of
paremeters when using the same crt in a crt-store and an ssl-f-use line.

So a simple configuration like this:

   crt-store web
     load crt "foo.com.crt" key "foo.com.key" alias "foo"

   frontend mysite
     bind :443 ssl
     ssl-f-use crt "@web/foo" ssl-min-ver TLSv1.2

Would lead to an error like this:

    config : '@web/foo' in crt-list '(null)' line 0, is already defined with incompatible parameters:
    - different parameter 'key' : previously 'foo.com.key' vs '(null)'

In order to fix the issue, this patch parses the "crt" parameter itself
for ssl-f-use instead of using ckch_conf_parse(), so the keyword would
never be considered as a ckch_conf keyword to compare.

This patch also take care of setting the CKCH_CONF_SET_CRTLIST flag only
if a ckch_conf keyword was found. This flag is used by ckch_conf_cmp()
to know if it has to compare or not.

No backport needed.

2 months agoMINOR: ssl: add filename and linenum for ssl-f-use errors
William Lallemand [Tue, 6 May 2025 18:13:15 +0000 (20:13 +0200)] 
MINOR: ssl: add filename and linenum for ssl-f-use errors

Fill cfg_crt_node with a filename and linenum so the post_section
callback can use it to emit errors.

This way the errors are emitted with the right filename and linenum
where ssl-f-use is used instead of (null):0

2 months agoBUG/MAJOR: queue: lock around the call to pendconn_process_next_strm()
Willy Tarreau [Tue, 6 May 2025 16:55:04 +0000 (18:55 +0200)] 
BUG/MAJOR: queue: lock around the call to pendconn_process_next_strm()

The extra call to pendconn_process_next_strm() made in commit cda7275ef5
("MEDIUM: queue: Handle the race condition between queue and dequeue
differently") was performed after releasing the server queue's lock,
which is incompatible with the calling convention for this function.
The result is random corruption of the server's streams list likely
due to picking old or incorrect pendconns from the queue, and in the
end infinitely looping on apparently already locked mt_list objects.
Just adding the lock fixes the problem.

It's very difficult to reproduce, it requires low maxconn values on
servers, stickiness on the servers (cookie), a long enough slowstart
(e.g. 10s), and regularly flipping servers up/down to re-trigger the
slowstart.

No backport is needed as this was only in 3.2.

2 months agoDOC: configuration: add the "crt-store" keyword
William Lallemand [Tue, 6 May 2025 14:07:29 +0000 (16:07 +0200)] 
DOC: configuration: add the "crt-store" keyword

Add the "crt-store" keyword with its argument in the "3.12" section, so
this could be detected by haproxy-dconv has a keyword and put in the
keywords list.

Must be backported as far as 3.0

2 months agoDOC: configuration: add "acme" section to the keywords list
William Lallemand [Tue, 6 May 2025 13:34:39 +0000 (15:34 +0200)] 
DOC: configuration: add "acme" section to the keywords list

Add the "acme" keyword with its argument in the "3.13" section, so this
could be detected by haproxy-dconv has a keyword and put in the keywords
list.

2 months agoMEDIUM: acme/ssl: remove 'acme ps' in favor of 'acme status'
William Lallemand [Tue, 6 May 2025 13:20:05 +0000 (15:20 +0200)] 
MEDIUM: acme/ssl: remove 'acme ps' in favor of 'acme status'

Remove the 'acme ps' command which does not seem useful anymore with the
'acme status' command.

The big difference with the 'acme status' command is that it was only
displaying the running tasks instead of the status of all certificate.

2 months agoMINOR: acme/cli: 'acme status' show the status acme-configured certificates
William Lallemand [Tue, 6 May 2025 12:56:38 +0000 (14:56 +0200)] 
MINOR: acme/cli: 'acme status' show the status acme-configured certificates

The "acme status" command, shows the status of every certificates
configured with ACME, not only the running task like "acme ps".

The IO handler loops on the ckch_store tree and outputs a line for each
ckch_store which has an acme section set. This is still done under the
ckch_store lock and doesn't support resuming when the buffer is full,
but we need to change that in the future.

2 months agoRevert "BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT...
Christopher Faulet [Tue, 6 May 2025 11:43:59 +0000 (13:43 +0200)] 
Revert "BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame"

This reverts commit 53c3046898633e56f74f7f05fb38cabeea1c87a1.

This patch introduced a regression leading to a loop on the frames
demultiplexing because a frame may be ignore but not consumed.

But outside this regression that can be fixed, there is a design issue that
was not totally fixed by the patch above. The SPOP connection state is mixed
with the status of the frames demultiplexer and this needlessly complexify
the connection management. Instead of fixing the fix, a better solution is
to revert it to work a a proper solution.

For the record, the idea is to deal with the spop connection state onlu
using 'state' field and to introduce a new field to handle the frames
demultiplexer state. This should ease the closing state management.

Another issue that must be fixed. We must take care to not abort a SPOP
stream when an error is detected on a SPOP connection or when the connection
is closed, if the ACK frame was already received for this stream. It is not
a common case, but it can be solved by saving the last known stream ID that
recieved a ACK.

This patch must be backported if the commit above is backported.

2 months agoBUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends
Aurelien DARRAGON [Fri, 2 May 2025 17:06:44 +0000 (19:06 +0200)] 
BUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends

proxy_inc_fe_cum_sess_ver_ctr() was implemented in 9969adbc
("MINOR: stats: add by HTTP version cumulated number of sessions and
requests")

As its name suggests, it is meant to be called for frontends, not backends

Also, in 9969adbc, when used under h1_init(), a precaution is taken to
ensure that the function is only called with frontends.

However, this precaution was not applied in h2_init() and qc_init().

Due to this, it remains possible to have proxy_inc_fe_cum_sess_ver_ctr()
being called with a backend proxy as parameter. While it did not cause
known issues so far, it is not expected and could result in bugs in the
future. Better fix this by ensuring the function is only called with
frontends.

It may be backported up to 2.8