]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 months agoBUG/MINOR: cli: Issue an error when too many args are passed for a command
Christopher Faulet [Wed, 23 Apr 2025 13:29:00 +0000 (15:29 +0200)] 
BUG/MINOR: cli: Issue an error when too many args are passed for a command

When a command is parsed to split it in an array of arguments, by default,
at most 64 arguments are supported. But no warning was emitted when there
were too many arguments. Instead, the arguments above the limit were
silently ignored. It could be an issue for some commands, like "add server",
because there was no way to know some arguments were ignored.

Now an error is issued when too many arguments are passed and the command is
not executed.

This patch should be backported to all stable versions.

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

2 months agoBUG/MINOR: mux-quic: fix possible infinite loop during decoding
Amaury Denoyelle [Wed, 23 Apr 2025 15:27:24 +0000 (17:27 +0200)] 
BUG/MINOR: mux-quic: fix possible infinite loop during decoding

With the support of multiple Rx buffers per QCS instance, stream
decoding in qcc_io_recv() has been reworked for the next haproxy
release. An issue appears in a double while loop : a break statement is
used in the inner loop, which is not sufficient as it should instead
exit from the outer one.

Fix this by replacing break with a goto statement.

No need to backport this.

2 months agoMINOR: h3: simplify h3_rcv_buf return path
Amaury Denoyelle [Wed, 23 Apr 2025 14:57:42 +0000 (16:57 +0200)] 
MINOR: h3: simplify h3_rcv_buf return path

Remove return statement in h3_rcv_buf() in case of stream/connection
error. Instead, reuse already existing label err. This simplifies the
code path. It also fixes the missing leave trace for these cases.

2 months agoMINOR: stick-table: use a separate lock label for updates
Willy Tarreau [Thu, 24 Apr 2025 12:01:13 +0000 (14:01 +0200)] 
MINOR: stick-table: use a separate lock label for updates

Too many locks were sharing STK_TABLE_LOCK making it hard to analyze.
Let's split the already heavily used update lock.

2 months agoMEDIUM: acme: rename "account" into "account-key"
William Lallemand [Thu, 24 Apr 2025 09:06:39 +0000 (11:06 +0200)] 
MEDIUM: acme: rename "account" into "account-key"

Rename the "account" option of the acme section into "account-key".

2 months agoMEDIUM: acme: rename "uri" into "directory"
William Lallemand [Thu, 24 Apr 2025 08:51:41 +0000 (10:51 +0200)] 
MEDIUM: acme: rename "uri" into "directory"

Rename the "uri" option of the acme section into "directory".

2 months agoMEDIUM: acme: use a customized proxy
William Lallemand [Wed, 23 Apr 2025 13:37:57 +0000 (15:37 +0200)] 
MEDIUM: acme: use a customized proxy

Use a customized proxy for the ACME client.

The proxy is initialized at the first acme section parsed.

The proxy uses the httpsclient log format as ACME CA use HTTPS.

2 months agoMINOR: httpclient: add an "https" log-format
William Lallemand [Wed, 23 Apr 2025 13:32:46 +0000 (15:32 +0200)] 
MINOR: httpclient: add an "https" log-format

Add an experimental "https" log-format for the httpclient, it is not
used by the httpclient by default, but could be define in a customized
proxy.

The string is basically a httpslog, with some of the fields replaced by
their backend equivalent or - when not available:

"%ci:%cp [%tr] %ft -/- %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %[bc_err]/%[ssl_bc_err,hex]/-/-/%[ssl_bc_is_resumed] -/-/-"

2 months agoMINOR: acme/cli: add the 'acme renew' command to the help message
William Lallemand [Wed, 23 Apr 2025 11:59:27 +0000 (13:59 +0200)] 
MINOR: acme/cli: add the 'acme renew' command to the help message

Add the 'acme renew' command to the 'help' command of the CLI.

2 months agoMINOR: http-act: Add 'pause' action to temporarily suspend the message analysis
Christopher Faulet [Tue, 22 Apr 2025 14:08:50 +0000 (16:08 +0200)] 
MINOR: http-act: Add 'pause' action to temporarily suspend the message analysis

The 'pause' HTTP action can now be used to suspend for a moment the message
analysis. A timeout, expressed in milliseconds using a time-format
parameter, or an expression can be used. If an expression is used, errors
and invalid values are ignored.

Internally, the action will set the analysis expiration date on the
corresponding channel to the configured value and it will yield while it is
not expired.

The 'pause' action is available for 'http-request' and 'http-response'
rules.

2 months agoBUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames
Christopher Faulet [Tue, 22 Apr 2025 13:27:12 +0000 (15:27 +0200)] 
BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames

When a SPOP connection is opened, the maximum size for frames is negociated.
This negociated size is properly used when a frame is received and if a too
big frame is detected, an error is triggered. However, the same was not
performed on the sending path. No check was performed on frames sent to the
agent. So it was possible to send frames bigger than the maximum size
supported by the the SPOE agent.

Now, the size of NOTIFY and DISCONNECT frames is checked before sending them
to the agent.

Thanks to Miroslav to have reported the issue.

This patch must be backported to 3.1.

2 months agoCLEANUP: h1: Remove now useless h1_parse_cont_len_header() function
Christopher Faulet [Tue, 15 Apr 2025 17:17:21 +0000 (19:17 +0200)] 
CLEANUP: h1: Remove now useless h1_parse_cont_len_header() function

Since the commit "MINOR: hlua/h1: Use http_parse_cont_len_header() to parse
content-length value", this function is no longer used. So it can be safely
removed.

2 months agoMINOR: hlua/h1: Use http_parse_cont_len_header() to parse content-length value
Christopher Faulet [Tue, 15 Apr 2025 17:14:31 +0000 (19:14 +0200)] 
MINOR: hlua/h1: Use http_parse_cont_len_header() to parse content-length value

Till now, h1_parse_cont_len_header() was used during the H1 message parsing and
by the lua HTTP applets to parse the content-length header value. But a more
generic function was added some years ago doing exactly the same operations. So
let's use it instead.

2 months agoMINOR: mux-h1: Keep custom "Content-Length: 0" header in 1xx and 204 messages
Christopher Faulet [Tue, 15 Apr 2025 17:04:42 +0000 (19:04 +0200)] 
MINOR: mux-h1: Keep custom "Content-Length: 0" header in 1xx and 204 messages

Thanks to the commit "MINOR: mux-h1: Don't remove custom "Content-Length: 0"
header in 1xx and 204 messages", we are now sure that 1xx and 204 responses
were sanitized during the parsing. So, if one of these headers are found in
such responses when sent to the client, it means it was added by hand, via a
"set-header" action for instance. In this context, we are able to make an
exception for the "Content-Length: 0" header, and only this one with this
value, to not break leagacy applications.

So now, a user can force the "Content-Length: 0" header to appear in 1xx and
204 responses by adding the right action in hist configuration.
"Transfer-Encoding" headers are still dropped as "Content-Length" headers
with another value than 0. Note, that in practice, only 101 and 204 are
concerned because other 1xx message are not subject to HTTP analysis.

This patch should fix the issue #2888. There is no reason to backport
it. But if we do so, the patch above must be backported too.

2 months agoMINOR: h1-htx: Skip C-L and T-E headers for 1xx and 204 messages during parsing
Christopher Faulet [Tue, 15 Apr 2025 16:56:18 +0000 (18:56 +0200)] 
MINOR: h1-htx: Skip C-L and T-E headers for 1xx and 204 messages during parsing

According to the RFC9110 and RFC9112, a server must not add 'Content-Length'
or 'Transfer-Encoding' headers into 1xx and 204 responses. So till now,
these headers were dropped from the response when it is sent to the client.

However, it seems more logical to remove it during the message parsing. In
addition to sanitize messages as early as possible, this will allow us to
apply some exception in some cases (This will be the subject of another
patch).

In this patch, 'Content-Length' and 'Transfer-Encoding' headers are removed
from 1xx and 204 responses during the parsing but the same is still
performed during the formatting stage.

2 months agoMINOR: proxy: Add options to drop HTTP trailers during message forwarding
Christopher Faulet [Tue, 15 Apr 2025 13:36:19 +0000 (15:36 +0200)] 
MINOR: proxy: Add options to drop HTTP trailers during message forwarding

In RFC9110, it is stated that trailers could be merged with the
headers. While it should be performed with a speicial care, it may be a
problem for some applications. To avoid any trouble with such applications,
two new options were added to drop trailers during the message forwarding.

On the backend, "http-drop-request-trailers" option can be enabled to drop
trailers from the requests before sending them to the server. And on the
frontend, "http-drop-response-trailers" option can be enabled to drop
trailers from the responses before sending them to the client. The options
can be defined in defaults sections and disabled with "no" keyword.

This patch should fix the issue #2930.

2 months agoCLEANUP: Slightly reorder some proxy option flags to free slots
Christopher Faulet [Tue, 15 Apr 2025 06:40:49 +0000 (08:40 +0200)] 
CLEANUP: Slightly reorder some proxy option flags to free slots

PR_O_TCPCHK_SSL and PR_O_CONTSTATS was shifted to free a slot. The idea is
to have 2 contiguous slots to be able to insert two new options.

2 months agoCLEANUP: proxy: detach the name node in proxy_free_common() instead
Willy Tarreau [Sat, 19 Apr 2025 08:21:19 +0000 (10:21 +0200)] 
CLEANUP: proxy: detach the name node in proxy_free_common() instead

This changes commit d2a9149f0 ("BUG/MINOR: proxy: always detach a proxy
from the names tree on free()") to be cleaner. AurĂ©lien spotted that
the free(p->id) was indeed already done in proxy_free_common(), which is
called before we delete the node. That's still a bit ugly and it only
works because ebpt_delete() does not dereference the key during the
operation. Better play safe and delete the entry before freeing it,
that's more future-proof.

2 months agoBUG/MINOR: proxy: always detach a proxy from the names tree on free()
Willy Tarreau [Fri, 18 Apr 2025 21:50:13 +0000 (23:50 +0200)] 
BUG/MINOR: proxy: always detach a proxy from the names tree on free()

Stephen Farrell reported in issue #2942 that recent haproxy versions
crash if there's no resolv.conf. A quick bisect with his reproducer
showed that it started with commit 4194f75 ("MEDIUM: tree-wide: avoid
manually initializing proxies") which reorders the proxies initialization
sequence a bit. The crash shows a corrupted tree, typically indicating a
use-after-free. With the help of ASAN it was possible to find that a
resolver proxy had been destroyed and freed before the name insertion
that causes the crash, very likely caused by the absence of the needed
resolv.conf:

    #0 0x7ffff72a82f7 in free (/usr/local/lib64/libasan.so.5+0x1062f7)
    #1 0x94c1fd in free_proxy src/proxy.c:436
    #2 0x9355d1 in resolvers_destroy src/resolvers.c:2604
    #3 0x93e899 in resolvers_create_default src/resolvers.c:3892
    #4 0xc6ed29 in httpclient_resolve_init src/http_client.c:1170
    #5 0xc6fbcf in httpclient_create_proxy src/http_client.c:1310
    #6 0x4ae9da in ssl_ocsp_update_precheck src/ssl_ocsp.c:1452
    #7 0xa1b03f in step_init_2 src/haproxy.c:2050

But free_proxy() doesn't delete the ebpt_node that carries the name,
which perfectly explains the situation. This patch simply deletes the
name node and Stephen confirmed that it fixed the problem for him as
well. Let's also free it since the key points to p->id which is never
freed either in this function!

No backport is needed since the patch above was first merged into
3.2-dev10.

2 months agoBUG/MINOR: quic: do not crash on CRYPTO ncbuf alloc failure
Amaury Denoyelle [Fri, 18 Apr 2025 16:02:48 +0000 (18:02 +0200)] 
BUG/MINOR: quic: do not crash on CRYPTO ncbuf alloc failure

To handle out-of-order received CRYPTO frames, a ncbuf instance is
allocated. This is done via the helper quic_get_ncbuf().

Buffer allocation was improperly checked. In case b_alloc() fails, it
crashes due to a BUG_ON(). Fix this by removing it. The function now
returns NULL on allocation failure, which is already properly handled in
its caller qc_handle_crypto_frm().

This should fix the last reported crash from github issue #2935.

This must be backported up to 2.6.

2 months ago[RELEASE] Released version 3.2-dev11 v3.2-dev11
Willy Tarreau [Fri, 18 Apr 2025 12:19:47 +0000 (14:19 +0200)] 
[RELEASE] Released version 3.2-dev11

Released version 3.2-dev11 with the following main changes :
    - CI: enable weekly QuicTLS build
    - DOC: management: slightly clarify the prefix role of the '@' command
    - DOC: management: add a paragraph about the limitations of the '@' prefix
    - MINOR: master/cli: support bidirectional communications with workers
    - MEDIUM: ssl/ckch: add filename and linenum argument to crt-store parsing
    - MINOR: acme: add the acme section in the configuration parser
    - MINOR: acme: add configuration for the crt-store
    - MINOR: acme: add private key configuration
    - MINOR: acme/cli: add the 'acme renew' command
    - MINOR: acme: the acme section is experimental
    - MINOR: acme: get the ACME directory
    - MINOR: acme: handle the nonce
    - MINOR: acme: check if the account exist
    - MINOR: acme: generate new account
    - MINOR: acme: newOrder request retrieve authorizations URLs
    - MINOR: acme: allow empty payload in acme_jws_payload()
    - MINOR: acme: get the challenges object from the Auth URL
    - MINOR: acme: send the request for challenge ready
    - MINOR: acme: implement a check on the challenge status
    - MINOR: acme: generate the CSR in a X509_REQ
    - MINOR: acme: finalize by sending the CSR
    - MINOR: acme: verify the order status once finalized
    - MINOR: acme: implement retrieval of the certificate
    - BUG/MINOR: acme: ckch_conf_acme_init() when no filename
    - MINOR: ssl/ckch: handle ckch_conf in ckchs_dup() and ckch_conf_clean()
    - MINOR: acme: copy the original ckch_store
    - MEDIUM: acme: replace the previous ckch instance with new ones
    - MINOR: acme: schedule retries with a timer
    - BUILD: acme: enable the ACME feature when JWS is present
    - BUG/MINOR: cpu-topo: check the correct variable for NULL after malloc()
    - BUG/MINOR: acme: key not restored upon error in acme_res_certificate()
    - BUG/MINOR: thread: protect thread_cpus_enabled_at_boot with USE_THREAD
    - MINOR: acme: default to 2048bits for RSA
    - DOC: acme: explain how to configure and run ACME
    - BUG/MINOR: debug: remove the trailing \n from BUG_ON() statements
    - DOC: config: add the missing "profiling.memory" to the global kw index
    - DOC: config: add the missing "force-cfg-parser-pause" to the global kw index
    - DEBUG: init: report invalid characters in debug description strings
    - DEBUG: rename DEBUG_GLITCHES to DEBUG_COUNTERS and enable it by default
    - DEBUG: counters: make COUNT_IF() only appear at DEBUG_COUNTERS>=1
    - DEBUG: counters: add the ability to enable/disable updating the COUNT_IF counters
    - MINOR: tools: let dump_addr_and_bytes() support dumping before the offset
    - MINOR: debug: in call traces, dump the 8 bytes before the return address, not after
    - MINOR: debug: detect call instructions and show the branch target in backtraces
    - BUG/MINOR: acme: fix possible NULL deref
    - CLEANUP: acme: stored value is overwritten before it can be used
    - BUILD: incompatible pointer type suspected with -DDEBUG_UNIT
    - BUG/MINOR: http-ana: Properly detect client abort when forwarding the response
    - BUG/MEDIUM: http-ana: Report 502 from req analyzer only during rsp forwarding
    - CI: fedora rawhide: enable unit tests
    - DOC: configuration: fix a typo in ACME documentation
    - MEDIUM: sink: add a new dpapi ring buffer
    - Revert "BUG/MINOR: acme: key not restored upon error in acme_res_certificate()"
    - BUG/MINOR: acme: key not restored upon error in acme_res_certificate() V2
    - BUG/MINOR: acme: fix the exponential backoff of retries
    - DOC: configuration: specify limitations of ACME for 3.2
    - MINOR: acme: emit logs instead of ha_notice
    - MINOR: acme: add a success message to the logs
    - BUG/MINOR: acme/cli: fix certificate name in error message
    - MINOR: acme: register the task in the ckch_store
    - MINOR: acme: free acme_ctx once the task is done
    - BUG/MEDIUM: h3: trim whitespaces when parsing headers value
    - BUG/MEDIUM: h3: trim whitespaces in header value prior to QPACK encoding
    - BUG/MINOR: h3: filter upgrade connection header
    - BUG/MINOR: h3: reject invalid :path in request
    - BUG/MINOR: h3: reject request URI with invalid characters
    - MEDIUM: h3: use absolute URI form with :authority
    - BUG/MEDIUM: hlua: fix hlua_applet_{http,tcp}_fct() yield regression (lost data)
    - BUG/MINOR: mux-h2: prevent past scheduling with idle connections
    - BUG/MINOR: rhttp: fix reconnect if timeout connect unset
    - BUG/MINOR: rhttp: ensure GOAWAY can be emitted after reversal
    - BUG/MINOR: mux-h2: do not apply timer on idle backend connection
    - MINOR: mux-h2: refactor idle timeout calculation
    - MINOR: mux-h2: prepare to support PING emission
    - MEDIUM: server/mux-h2: implement idle-ping on backend side
    - MEDIUM: listener/mux-h2: implement idle-ping on frontend side
    - MINOR: mux-h2: do not emit GOAWAY on idle ping expiration
    - MINOR: mux-h2: handle idle-ping on conn reverse
    - BUILD: makefile: enable backtrace by default on musl
    - BUG/MINOR: threads: set threads_idle and threads_harmless even with no threads
    - BUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill()
    - BUG/MINOR: wdt/debug: avoid signal re-entrance between debugger and watchdog
    - BUG/MINOR: debug: detect and prevent re-entrance in ha_thread_dump_fill()
    - MINOR: debug: do not statify a few debugging functions often used with wdt/dbg
    - MINOR: tools: also protect the library name resolution against concurrent accesses
    - MINOR: tools: protect dladdr() against reentrant calls from the debug handler
    - MINOR: debug: protect ha_dump_backtrace() against risks of re-entrance
    - MINOR: tinfo: keep a copy of the pointer to the thread dump buffer
    - MINOR: debug: always reset the dump pointer when done
    - MINOR: debug: remove unused case of thr!=tid in ha_thread_dump_one()
    - MINOR: pass a valid buffer pointer to ha_thread_dump_one()
    - MEDIUM: wdt: always make the faulty thread report its own warnings
    - MINOR: debug: make ha_stuck_warning() only work for the current thread
    - MINOR: debug: make ha_stuck_warning() print the whole message at once
    - CLEANUP: debug: no longer set nor use TH_FL_DUMPING_OTHERS
    - MINOR: sched: add a new function is_sched_alive() to report scheduler's health
    - MINOR: wdt: use is_sched_alive() instead of keeping a local ctxsw copy
    - MINOR: sample: add 4 new sample fetches for clienthello parsing
    - REGTEST: add new reg-test for the 4 new clienthello fetches
    - MINOR: servers: Move the per-thread server initialization earlier
    - MINOR: proxies: Initialize the per-thread structure earlier.
    - MINOR: servers: Provide a pointer to the server in srv_per_tgroup.
    - MINOR: lb_fwrr: Move the next weight out of fwrr_group.
    - MINOR: proxies: Add a per-thread group lbprm struct.
    - MEDIUM: lb_fwrr: Use one ebtree per thread group.
    - MEDIUM: lb_fwrr: Don't start all thread groups on the same server.
    - MINOR: proxies: Do stage2 initialization for sinks too

2 months agoMINOR: proxies: Do stage2 initialization for sinks too
Olivier Houchard [Thu, 17 Apr 2025 15:16:44 +0000 (17:16 +0200)] 
MINOR: proxies: Do stage2 initialization for sinks too

In check_config_validity(), we initialize the proxy in several stages.
We do so for the sink list for stage1, but not for stage2. It may not be
needed right now, but it may become needed in the future, so do it
anyway.

2 months agoMEDIUM: lb_fwrr: Don't start all thread groups on the same server.
Olivier Houchard [Thu, 17 Apr 2025 14:45:29 +0000 (16:45 +0200)] 
MEDIUM: lb_fwrr: Don't start all thread groups on the same server.

Now that all there is one tree per thread group, all thread groups will
start on the same server. To prevent that, just insert the servers in a
different order for each thread group.

2 months agoMEDIUM: lb_fwrr: Use one ebtree per thread group.
Olivier Houchard [Thu, 17 Apr 2025 14:31:44 +0000 (16:31 +0200)] 
MEDIUM: lb_fwrr: Use one ebtree per thread group.

When using the round-robin load balancer, the major source of contention
is the lbprm lock, that has to be held every time we pick a server.
To mitigate that, make it so there are one tree per thread-group, and
one lock per thread-group. That means we now have a lb_fwrr_per_tgrp
structure that will contain the two lb_fwrr_groups (active and backup) as well
as the lock to protect them in the per-thread lbprm struct, and all
fields in the struct server are now moved to the per-thread structure
too.
Those changes are mostly mechanical, and brings good performances
improvment, on a 64-cores AMD CPU, with 64 servers configured, we could
process about 620000 requests par second, and we now can process around
1400000 requests per second.

2 months agoMINOR: proxies: Add a per-thread group lbprm struct.
Olivier Houchard [Thu, 17 Apr 2025 14:10:48 +0000 (16:10 +0200)] 
MINOR: proxies: Add a per-thread group lbprm struct.

Add a new structure in the per-thread groups proxy structure, that will
contain whatever is per-thread group in lbprm.
It will be accessed as p->per_tgrp[tgid].lbprm.

2 months agoMINOR: lb_fwrr: Move the next weight out of fwrr_group.
Olivier Houchard [Thu, 17 Apr 2025 13:50:33 +0000 (15:50 +0200)] 
MINOR: lb_fwrr: Move the next weight out of fwrr_group.

Move the "next_weight" outside of fwrr_group, and inside struct lb_fwrr
directly, one for the active servers, one for the backup servers.
We will soon have one fwrr_group per thread group, but next_weight will
be global to all of them.

2 months agoMINOR: servers: Provide a pointer to the server in srv_per_tgroup.
Olivier Houchard [Thu, 17 Apr 2025 09:20:24 +0000 (11:20 +0200)] 
MINOR: servers: Provide a pointer to the server in srv_per_tgroup.

Add a pointer to the server into the struct srv_per_tgroup, so that if
we only have access to that srv_per_tgroup, we can come back to the
corresponding server.

2 months agoMINOR: proxies: Initialize the per-thread structure earlier.
Olivier Houchard [Thu, 17 Apr 2025 15:05:07 +0000 (17:05 +0200)] 
MINOR: proxies: Initialize the per-thread structure earlier.

Move the call to initialize the proxy's per-thread structure earlier
than currently done, so that they are usable when we're initializing the
load balancers.

2 months agoMINOR: servers: Move the per-thread server initialization earlier
Olivier Houchard [Thu, 17 Apr 2025 08:42:25 +0000 (10:42 +0200)] 
MINOR: servers: Move the per-thread server initialization earlier

Move the code responsible for calling per-thread server initialization
earlier than it was done, so that per-thread structures are available a
bit later, when we initialize load-balancing.

2 months agoREGTEST: add new reg-test for the 4 new clienthello fetches
Mariam John [Wed, 16 Apr 2025 13:36:08 +0000 (08:36 -0500)] 
REGTEST: add new reg-test for the 4 new clienthello fetches

Add a reg-test which uses the 4 fetches:

- req.ssl_cipherlist
- req.ssl_sigalgs
- req.ssl_keyshare_groups
- req.ssl_supported_groups

2 months agoMINOR: sample: add 4 new sample fetches for clienthello parsing
Mariam John [Wed, 16 Apr 2025 13:36:07 +0000 (08:36 -0500)] 
MINOR: sample: add 4 new sample fetches for clienthello parsing

This patch contains this 4 new fetches and doc changes for the new fetches:

- req.ssl_cipherlist
- req.ssl_sigalgs
- req.ssl_keyshare_groups
- req.ssl_supported_groups

Towards:#2532

2 months agoMINOR: wdt: use is_sched_alive() instead of keeping a local ctxsw copy
Willy Tarreau [Thu, 17 Apr 2025 13:26:30 +0000 (15:26 +0200)] 
MINOR: wdt: use is_sched_alive() instead of keeping a local ctxsw copy

Now we can simply call is_sched_alive() on the local thread to verify
that the scheduler is still ticking instead of having to keep a copy of
the ctxsw and comparing it. It's cleaner, doesn't require to maintain
a local copy, doesn't rely on activity[] (whose purpose is mainly for
observation and debugging), and shows how this could be extended later
to cover other use cases. Practically speaking this doesn't change
anything however, the algorithm is still the same.

2 months agoMINOR: sched: add a new function is_sched_alive() to report scheduler's health
Willy Tarreau [Thu, 17 Apr 2025 13:24:08 +0000 (15:24 +0200)] 
MINOR: sched: add a new function is_sched_alive() to report scheduler's health

This verifies that the scheduler is still ticking without having to
access the activity[] array nor keeping local copies of the ctxsw
counter. It just tests and sets a flag that is reset after each
return from a ->process() function.

2 months agoCLEANUP: debug: no longer set nor use TH_FL_DUMPING_OTHERS
Willy Tarreau [Thu, 17 Apr 2025 13:35:50 +0000 (15:35 +0200)] 
CLEANUP: debug: no longer set nor use TH_FL_DUMPING_OTHERS

TH_FL_DUMPING_OTHERS was being used to try to perform exclusion between
threads running "show threads" and those producing warnings. Now that it
is much more cleanly handled, we don't need that type of protection
anymore, which was adding to the complexity of the solution. Let's just
get rid of it.

2 months agoMINOR: debug: make ha_stuck_warning() print the whole message at once
Willy Tarreau [Thu, 17 Apr 2025 06:59:45 +0000 (08:59 +0200)] 
MINOR: debug: make ha_stuck_warning() print the whole message at once

It has been noticed quite a few times during troubleshooting and even
testing that warnings can happen in avalanches from multiple threads
at the same time, and that their reporting it interleaved bacause the
output is produced in small chunks. Originally, this code inspired by
the panic code aimed at making sure to log whatever could be emitted
in case it would crash later. But this approach was wrong since writes
are atomic, and performing 5 writes in sequence in each dumping thread
also means that the outputs can be mixed up at 5 different locations
between multiple threads. The output of warnings is never very long,
and the stack-based buffer is 4kB so let's just concatenate everything
in the buffer and emit it at once using a single write(). Now there's
no longer this confusion on the output.

2 months agoMINOR: debug: make ha_stuck_warning() only work for the current thread
Willy Tarreau [Thu, 17 Apr 2025 06:54:43 +0000 (08:54 +0200)] 
MINOR: debug: make ha_stuck_warning() only work for the current thread

Since we no longer call it with a foreign thread, let's simplify its code
and get rid of the special cases that were relying on ha_thread_dump_fill()
and synchronization with a remote thread. We're not only dumping the
current thread so ha_thread_dump_one() is sufficient.

2 months agoMEDIUM: wdt: always make the faulty thread report its own warnings
Willy Tarreau [Thu, 17 Apr 2025 06:42:36 +0000 (08:42 +0200)] 
MEDIUM: wdt: always make the faulty thread report its own warnings

Warnings remain tricky to deal with, especially for other threads as
they require some inter-thread synchronization that doesn't cope very
well with other parallel activities such as "show threads" for example.

However there is nothing that forces us to handle them this way. The
panic for example is already handled by bouncing the WDT signal to the
faulty thread.

This commit rearranges the WDT handler to make a better used of this
existing signal bouncing feature of the WDT handler so that it's no
longer limited to panics but can also deal with warnings. In order not
to bounce on all wakeups, we only bounce when there is a suspicion,
that is, when the warning timer has been crossed. We'll let the target
thread verify the stuck flag and context switch count by itself to
decide whether or not to panic, warn, or just do nothing and update
the counters.

As a bonus, now all warning traces look the same regardless of the
reporting thread:

   call trace(16):
   |       0x6bc733 <01 00 00 e8 6d e6 de ff]: ha_dump_backtrace+0x73/0x309 > main-0x2570
   |       0x6bd37a <00 00 00 e8 d6 fb ff ff]: ha_thread_dump_fill+0xda/0x104 > ha_thread_dump_one
   |       0x6bd625 <00 00 00 e8 7b fc ff ff]: ha_stuck_warning+0xc5/0x19e > ha_thread_dump_fill
   |       0x7b2b60 <64 8b 3b e8 00 aa f0 ff]: wdt_handler+0x1f0/0x212 > ha_stuck_warning
   | 0x7fd7e2cef3a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
   | 0x7ffc6af9e634 <85 a6 00 00 00 0f 01 f9]: linux-vdso:__vdso_gettimeofday+0x34/0x2b0
   |       0x6bad74 <7c 24 10 e8 9c 01 df ff]: sc_conn_io_cb+0x9fa4 > main-0x2400
   |       0x67c457 <89 f2 4c 89 e6 41 ff d0]: main+0x1cf147
   |       0x67d401 <48 89 df e8 8f ed ff ff]: cli_io_handler+0x191/0xb38 > main+0x1cee80
   |       0x6dd605 <40 48 8b 45 60 ff 50 18]: task_process_applet+0x275/0xce9

2 months agoMINOR: pass a valid buffer pointer to ha_thread_dump_one()
Willy Tarreau [Wed, 16 Apr 2025 14:48:13 +0000 (16:48 +0200)] 
MINOR: pass a valid buffer pointer to ha_thread_dump_one()

The goal is to let the caller deal with the pointer so that the function
only has to fill that buffer without worrying about locking. This way,
synchronous dumps from "show threads" are produced and emitted directly
without causing undesired locking of the buffer nor risking causing
confusion about thread_dump_buffer containing bits from an interrupted
dump in progress.

It's only the caller that's responsible for notifying the requester of
the end of the dump by setting bit 0 of the pointer if needed (i.e. it's
only done in the debug handler).

2 months agoMINOR: debug: remove unused case of thr!=tid in ha_thread_dump_one()
Willy Tarreau [Thu, 10 Apr 2025 07:03:05 +0000 (09:03 +0200)] 
MINOR: debug: remove unused case of thr!=tid in ha_thread_dump_one()

This function was initially designed to dump any threadd into the presented
buffer, but the way it currently works is that it's always called for the
current thread, and uses the distinction between coming from a sighandler
or being called directly to detect which thread is the caller.

Let's simplify all this by replacing thr with tid everywhere, and using
the thread-local pointers where it makes sense (e.g. th_ctx, th_ctx etc).
The confusing "from_signal" argument is now replaced with "is_caller"
which clearly states whether or not the caller declares being the one
asking for the dump (the logic is inverted, but there are only two call
places with a constant).

2 months agoMINOR: debug: always reset the dump pointer when done
Willy Tarreau [Thu, 10 Apr 2025 11:55:52 +0000 (13:55 +0200)] 
MINOR: debug: always reset the dump pointer when done

We don't need to copy the old dump pointer to the thread_dump_pointer
area anymore to indicate a dump is collected. It used to be done as an
artificial way to keep the pointer for the post-mortem analysis but
since we now have this pointer stored separately, that's no longer
needed and it simplifies the mechanim to reset it.

2 months agoMINOR: tinfo: keep a copy of the pointer to the thread dump buffer
Willy Tarreau [Thu, 10 Apr 2025 06:29:39 +0000 (08:29 +0200)] 
MINOR: tinfo: keep a copy of the pointer to the thread dump buffer

Instead of using the thread dump buffer for post-mortem analysis, we'll
keep a copy of the assigned pointer whenever it's used, even for warnings
or "show threads". This will offer more opportunities to figure from a
core what happened, and will give us more freedom regarding the value of
the thread_dump_buffer itself. For example, even at the end of the dump
when the pointer is reset, the last used buffer is now preserved.

2 months agoMINOR: debug: protect ha_dump_backtrace() against risks of re-entrance
Willy Tarreau [Fri, 4 Apr 2025 16:11:23 +0000 (18:11 +0200)] 
MINOR: debug: protect ha_dump_backtrace() against risks of re-entrance

If a thread is dumping itself (warning, show thread etc) and another one
wants to dump the state of all threads (e.g. panic), it may interrupt the
first one during backtrace() and re-enter it from the signal handler,
possibly triggering a deadlock in the underlying libc. Let's postpone
the debug signal delivery at this point until the call ends in order to
avoid this.

2 months agoMINOR: tools: protect dladdr() against reentrant calls from the debug handler
Willy Tarreau [Fri, 4 Apr 2025 16:08:45 +0000 (18:08 +0200)] 
MINOR: tools: protect dladdr() against reentrant calls from the debug handler

If a thread is currently resolving a symbol while another thread triggers
a thread dump, the current thread may enter the debug handler and call
resolve_sym_addr() again, possibly deadlocking if the underlying libc
uses locking. Let's postpone the debug signal delivery in this area
during the call. This will slow the resolution a little bit but we don't
care, it's not supposed to happen often and it must remain rock-solid.

2 months agoMINOR: tools: also protect the library name resolution against concurrent accesses
Willy Tarreau [Fri, 4 Apr 2025 14:56:44 +0000 (16:56 +0200)] 
MINOR: tools: also protect the library name resolution against concurrent accesses

This is an extension of eb41d768f ("MINOR: tools: use only opportunistic
symbols resolution"). It also makes sure we're not calling dladddr() in
parallel to dladdr_and_size(), as a preventive measure against some
potential deadlocks in the inner layers of the libc.

2 months agoMINOR: debug: do not statify a few debugging functions often used with wdt/dbg
Willy Tarreau [Tue, 15 Apr 2025 07:25:27 +0000 (09:25 +0200)] 
MINOR: debug: do not statify a few debugging functions often used with wdt/dbg

A few functions are used when debugging debug signals and watchdog, but
being static, they're not resolved and are hard to spot in dumps, and
they appear as any random other function plus an offset. Let's just not
mark them static anymore, it only hurts:
  - cli_io_handler_show_threads()
  - debug_run_cli_deadlock()
  - debug_parse_cli_loop()
  - debug_parse_cli_panic()

2 months agoBUG/MINOR: debug: detect and prevent re-entrance in ha_thread_dump_fill()
Willy Tarreau [Fri, 4 Apr 2025 16:27:42 +0000 (18:27 +0200)] 
BUG/MINOR: debug: detect and prevent re-entrance in ha_thread_dump_fill()

In the following trace trying to abuse the watchdog from the CLI's
"debug dev loop" command running in parallel to "show threads" loops,
it's clear that some re-entrance may happen in ha_thread_dump_fill().

A first minimal fix consists in using a test-and-set on the flag
indicating that the function is currently dumping threads, so that
the one from the signal just returns. However the caller should be
made more reliable to serialize all of this, that's for future
work.

Here's an example capture of 7 threads stuck waiting for each other:
  (gdb) bt
  #0  0x00007fe78d78e147 in sched_yield () from /lib64/libc.so.6
  #1  0x0000000000674a05 in ha_thread_relax () at src/thread.c:356
  #2  0x00000000005ba4f5 in ha_thread_dump_fill (thr=2, buf=0x7ffdd8e08ab0) at src/debug.c:402
  #3  ha_thread_dump_fill (buf=0x7ffdd8e08ab0, thr=<optimized out>) at src/debug.c:384
  #4  0x00000000005baac4 in ha_stuck_warning (thr=thr@entry=2) at src/debug.c:840
  #5  0x00000000006a360d in wdt_handler (sig=<optimized out>, si=<optimized out>, arg=<optimized out>) at src/wdt.c:156
  #6  <signal handler called>
  #7  0x00007fe78d78e147 in sched_yield () from /lib64/libc.so.6
  #8  0x0000000000674a05 in ha_thread_relax () at src/thread.c:356
  #9  0x00000000005ba4c2 in ha_thread_dump_fill (thr=2, buf=0x7fe78f2d6420) at src/debug.c:426
  #10 ha_thread_dump_fill (buf=0x7fe78f2d6420, thr=2) at src/debug.c:384
  #11 0x00000000005ba7c6 in cli_io_handler_show_threads (appctx=0x2a89ab0) at src/debug.c:548
  #12 0x000000000057ea43 in cli_io_handler (appctx=0x2a89ab0) at src/cli.c:1176
  #13 0x00000000005d7885 in task_process_applet (t=0x2a82730, context=0x2a89ab0, state=<optimized out>) at src/applet.c:920
  #14 0x0000000000659002 in run_tasks_from_lists (budgets=budgets@entry=0x7ffdd8e0a5c0) at src/task.c:644
  #15 0x0000000000659bd7 in process_runnable_tasks () at src/task.c:886
  #16 0x00000000005cdcc9 in run_poll_loop () at src/haproxy.c:2858
  #17 0x00000000005ce457 in run_thread_poll_loop (data=<optimized out>) at src/haproxy.c:3075
  #18 0x0000000000430628 in main (argc=<optimized out>, argv=<optimized out>) at src/haproxy.c:3665

2 months agoBUG/MINOR: wdt/debug: avoid signal re-entrance between debugger and watchdog
Willy Tarreau [Fri, 4 Apr 2025 15:20:25 +0000 (17:20 +0200)] 
BUG/MINOR: wdt/debug: avoid signal re-entrance between debugger and watchdog

As seen in issue #2860, there are some situations where a watchdog could
trigger during the debug signal handler, and where similarly the debug
signal handler may trigger during the wdt handler. This is really bad
because it could trigger some deadlocks inside inner libc code such as
dladdr() or backtrace() since the code will not protect against re-
entrance but only against concurrent accesses.

A first attempt was made using ha_sigmask() but that's not always very
convenient because the second handler is called immediately after
unblocking the signal and before returning, leaving signal cascades in
backtrace. Instead, let's mark which signals to block at registration
time. Here we're blocking wdt/dbg for both signals, and optionally
SIGRTMAX if DEBUG_DEV is used as that one may also be used in this case.

This should be backported at least to 3.1.

2 months agoBUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill()
Willy Tarreau [Thu, 17 Apr 2025 08:28:37 +0000 (10:28 +0200)] 
BUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill()

The function must make sure to return NULL for foreign threads and
the local buffer for the current thread in this case, otherwise panics
(and sometimes even warnings) will segfault when USE_THREAD_DUMP is
disabled. Let's slightly re-arrange the function to reduce the #if/else
since we have to specifically handle the case of !USE_THREAD_DUMP anyway.

This needs to be backported wherever b8adef065d ("MEDIUM: debug: on
panic, make the target thread automatically allocate its buf") was
backported (at least 2.8).

2 months agoBUG/MINOR: threads: set threads_idle and threads_harmless even with no threads
Willy Tarreau [Tue, 15 Apr 2025 07:03:35 +0000 (09:03 +0200)] 
BUG/MINOR: threads: set threads_idle and threads_harmless even with no threads

Some signal handlers rely on these to decide about the level of detail to
provide in dumps, so let's properly fill the info about entering/leaving
idle. Note that for consistency with other tests we're using bitops with
t->ltid_bit, while we could simply assign 0/1 to the fields. But it makes
the code more readable and the whole difference is only 88 bytes on a 3MB
executable.

This bug is not important, and while older versions are likely affected
as well, it's not worth taking the risk to backport this in case it would
wake up an obscure bug.

2 months agoBUILD: makefile: enable backtrace by default on musl
Willy Tarreau [Thu, 17 Apr 2025 14:11:14 +0000 (16:11 +0200)] 
BUILD: makefile: enable backtrace by default on musl

The reason musl builds was not producing exploitable backtraces was
that the toolchain used appears to automatically omit the frame pointer
at -O2 but leaves it at -O0. This patch just makes sure to always append
-fno-omit-frame-pointer to the BACKTRACE cflags and enables the option
with musl where it now works. This will allow us to finally get
exploitable traces from docker images where core dumps are not always
available.

2 months agoMINOR: mux-h2: handle idle-ping on conn reverse
Amaury Denoyelle [Tue, 8 Apr 2025 09:52:41 +0000 (11:52 +0200)] 
MINOR: mux-h2: handle idle-ping on conn reverse

This commit extends MUX H2 connection reversal step to properly take
into account the new idle-ping feature. It first ensures that h2c task
is properly instantiated/freed depending now on both timers and
idle-ping configuration. Also, h2c_update_timeout() is now called
instead of manually requeuing the task, which ensures the proper timer
value is selected depending on the new connection side.

2 months agoMINOR: mux-h2: do not emit GOAWAY on idle ping expiration
Amaury Denoyelle [Thu, 17 Apr 2025 09:14:10 +0000 (11:14 +0200)] 
MINOR: mux-h2: do not emit GOAWAY on idle ping expiration

If idle-ping is activated and h2c task is expired due to missing PING
ACK, consider that the peer is away and the connection can be closed
immediately. GOAWAY emission is thus skipped.

A new test is necessary in h2c_update_timeout() when PING ACK is
currently expected, but the next timer expiration selected is not
idle-ping. This may happen if http-keep-alive/http-request timers are
selected first. In this case, H2_CF_IDL_PING_SENT flag is resetted. This
is necessary to not prevent GOAWAY emission on expiration.

2 months agoMEDIUM: listener/mux-h2: implement idle-ping on frontend side
Amaury Denoyelle [Tue, 8 Apr 2025 14:08:17 +0000 (16:08 +0200)] 
MEDIUM: listener/mux-h2: implement idle-ping on frontend side

This commit is the counterpart of the previous one, adapted on the
frontend side. "idle-ping" is added as keyword to bind lines, to be able
to refresh client timeout of idle frontend connections.

H2 MUX behavior remains similar as the previous patch. The only
significant change is in h2c_update_timeout(), as idle-ping is now taken
into account also for frontend connection. The calculated value is
compared with http-request/http-keep-alive timeout value. The shorter
delay is then used as expired date. As hr/ka timeout are based on
idle_start, this allows to run them in parallel with an idle-ping timer.

2 months agoMEDIUM: server/mux-h2: implement idle-ping on backend side
Amaury Denoyelle [Tue, 8 Apr 2025 09:09:06 +0000 (11:09 +0200)] 
MEDIUM: server/mux-h2: implement idle-ping on backend side

This commit implements support for idle-ping on the backend side. First,
a new server keyword "idle-ping" is defined in configuration parsing. It
is used to set the corresponding new server member.

The second part of this commit implements idle-ping support on H2 MUX. A
new inlined function conn_idle_ping() is defined to access connection
idle-ping value. Two new connection flags are defined H2_CF_IDL_PING and
H2_CF_IDL_PING_SENT. The first one is set for idle connections via
h2c_update_timeout().

On h2_timeout_task() handler, if first flag is set, instead of releasing
the connection as before, the second flag is set and tasklet is
scheduled. As both flags are now set, h2_process_mux() will proceed to
PING emission. The timer has also been rearmed to the idle-ping value.
If a PING ACK is received before next timeout, connection timer is
refreshed. Else, the connection is released, as with timer expiration.

Also of importance, special care is needed when a backend connection is
going to idle. In this case, idle-ping timer must be rearmed. Thus a new
invokation of h2c_update_timeout() is performed on h2_detach().

2 months agoMINOR: mux-h2: prepare to support PING emission
Amaury Denoyelle [Tue, 8 Apr 2025 09:49:37 +0000 (11:49 +0200)] 
MINOR: mux-h2: prepare to support PING emission

Adapt the already existing function h2c_ack_ping(). The objective is to
be able to emit a PING request. First, it is renamed as h2c_send_ping().
A new boolean argument <ack> is used to emit either a PING request or
ack.

2 months agoMINOR: mux-h2: refactor idle timeout calculation
Amaury Denoyelle [Thu, 10 Apr 2025 09:51:05 +0000 (11:51 +0200)] 
MINOR: mux-h2: refactor idle timeout calculation

Reorganize code for timeout calculation in case the connection is idle.
The objective is to better reflect the relations between each timeouts
as follow :

* if GOAWAY already emitted, use shut-timeout, or if unset fallback to
  client/server one. However, an already set timeout is never erased.

* else, for frontend connection, http-request or keep-alive timeout is
  applied depending on the current demux state. If the selected value is
  unset, fallback to client timeout

* for backend connection, no timeout is set to perform http-reuse

This commit is pure refactoring, so no functional change should occur.

2 months agoBUG/MINOR: mux-h2: do not apply timer on idle backend connection
Amaury Denoyelle [Tue, 15 Apr 2025 16:06:54 +0000 (18:06 +0200)] 
BUG/MINOR: mux-h2: do not apply timer on idle backend connection

Since the following commit, MUX H2 timeout function has been slightly
exetended.

  d38d8c6ccb189e7bc813b3693fec3093c9be55f1
  BUG/MEDIUM: mux-h2: make sure control frames do not refresh the idle timeout

A side-effect of this patch is that now backend idle connection expire
timer is not reset if already defined. This means that if a timer was
registered prior to the connection transition to idle, the connection
would be destroyed on its timeout. If this happens for enough
connection, this may have an impact on the reuse rate.

In practice, this case should be rare, as h2c timer is set to
TICK_ETERNITY while there is active streams. The timer is not refreshed
most of the time before going the transition to idle, so the connection
won't be deleted on expiration.

The only case where it could occur is if there is still pending data
blocked on emission on stream detach. Here, timeout server is applied on
the connection. When the emission completes, the connection goes to
idle, but the timer will still armed, and thus will be triggered on the
idle connection.

To prevent this, explicitely reset h2c timer to TICK_ETERNITY for idle
backend connection via h2c_update_timeout().

This patch is explicitely not scheduled for backport for now, as it is
difficult to estimate the real impact of the previous code state.

2 months agoBUG/MINOR: rhttp: ensure GOAWAY can be emitted after reversal
Amaury Denoyelle [Thu, 10 Apr 2025 15:41:39 +0000 (17:41 +0200)] 
BUG/MINOR: rhttp: ensure GOAWAY can be emitted after reversal

GOAWAY emission should not be emitted before preface. Thus, max_id field
from h2c acting as a server is initialized to -1, which prevents its
emission until preface is received from the peer. If acting as a client,
max_id is initialized to a valid value on the first h2s emission.

This causes an issue with reverse HTTP on the active side. First, it
starts as a client, so the peer does not emit a preface but instead a
simple SETTINGS frame. As role are switched, max_id is initialized much
later when the first h2s response is emitted. Thus, if the connection
must be terminated before any stream transfer, GOAWAY cannot be emitted.

To fix this, ensure max_id is initialized to 0 on h2_conn_reverse() for
active connect side. Thus, a GOAWAY indicating that no stream has been
handled can be generated.

Note that passive connect side is not impacted, as it max_id is
initialized thanks to preface reception.

This should be backported up to 2.9.

2 months agoBUG/MINOR: rhttp: fix reconnect if timeout connect unset
Amaury Denoyelle [Thu, 10 Apr 2025 16:05:55 +0000 (18:05 +0200)] 
BUG/MINOR: rhttp: fix reconnect if timeout connect unset

Active connect on reverse http relies on connect timeout to detect
connection failure. Thus, if this timeout was unset, connection failure
may not be properly detected.

Fix this by fallback on hardcoded value of 1s for connect if timeout is
unset in the configuration. This is considered as a minor bug, as
haproxy advises against running with timeout unset.

This must be backported up to 2.9.

2 months agoBUG/MINOR: mux-h2: prevent past scheduling with idle connections
Amaury Denoyelle [Wed, 9 Apr 2025 12:26:54 +0000 (14:26 +0200)] 
BUG/MINOR: mux-h2: prevent past scheduling with idle connections

While reviewing HTTP/2 MUX timeout, it seems there is a possibility that
MUX task is requeued via h2c_update_timeout() with an already expired
date. This can happens with idle connections on two cases :
* first with shut timeout, as timer is not refreshed if already set
* second with http-request and keep-alive timers, which are based on
  idle_start

Queuing an already expired task is an undefined behavior. Fix this by
using task_wakeup() instead of task_queue() at the end of
h2c_update_timeout() if such case occurs.

This should be backported up to 2.6.

2 months agoBUG/MEDIUM: hlua: fix hlua_applet_{http,tcp}_fct() yield regression (lost data)
Aurelien DARRAGON [Thu, 17 Apr 2025 12:21:20 +0000 (14:21 +0200)] 
BUG/MEDIUM: hlua: fix hlua_applet_{http,tcp}_fct() yield regression (lost data)

Jacques Heunis from bloomberg reported on the mailing list [1] that
with haproxy 2.8 up to master, yielding from a Lua tcp service while
data was still buffered inside haproxy would eat some data which was
definitely lost.

He provided the reproducer below which turned out to be really helpful:

  global
      log stdout format raw local0 info
      lua-load haproxy_yieldtest.lua

  defaults
      log global
      timeout connect         10s
      timeout client          1m
      timeout server          1m

  listen echo
      bind *:9090
      mode tcp
      tcp-request content use-service lua.print_input

haproxy_yieldtest.lua:

  core.register_service("print_input", "tcp", function(applet)
      core.Info("Start printing input...")
      while true do
          local inputs = applet:getline()
          if inputs == nil or string.len(inputs) == 0 then
              core.Info("closing input connection")
              return
          end
          core.Info("Received line: "..inputs)
          core.yield()
      end
  end)

And the script below:

  #!/usr/bin/bash
  for i in $(seq 1 9999); do
      for j in $(seq 1 50); do
          echo "${i}_foo_${j}"
      done
      sleep 2
  done

Using it like this:
  ./test_seq.sh | netcat localhost 9090

We can clearly see the missing data for every "foo" burst (every 2
seconds), as they are holes in the numbering.

Thanks to the reproducer, it was quickly found that only versions
>= 2.8 were affected, and that in fact this regression was introduced
by commit 31572229e ("MEDIUM: hlua/applet: Use the sedesc to report and
detect end of processing")

In fact in 31572229e 2 mistakes were made during the refaco.
Indeed, both in hlua_applet_tcp_fct() (which is involved in the reproducer
above) and hlua_applet_http_fct(), the request (buffer) is now
systematically consumed when returning from the function, which wasn't the
case prior to this commit: when HLUA_E_AGAIN is returned, it means a
yield was requested and that the processing is not done yet, thus we
should not consume any data, like we did prior to the refacto.

Big thanks to Jacques who did a great job reproducing and reporting this
issue on the mailing list.

[1]: https://www.mail-archive.com/haproxy@formilux.org/msg45778.html

It should be backported up to 2.8 with commit 31572229e

2 months agoMEDIUM: h3: use absolute URI form with :authority
Amaury Denoyelle [Wed, 16 Apr 2025 13:17:57 +0000 (15:17 +0200)] 
MEDIUM: h3: use absolute URI form with :authority

Change the representation of the start-line URI when parsing a HTTP/3
request into HTX. Adopt the same conversion as HTTP/2. If :authority
header is used (default case), the URI is encoded using absolute-form,
with scheme, host and path concatenated. If only a plain host header is
used instead, fallback to the origin form.

This commit may cause some configuration to be broken if parsing is
performed on the URI. Indeed, now most of the HTTP/3 requests will be
represented with an absolute-form URI at the stream layer.

Note that prior to this commit a check was performed on the path used as
URI to ensure that it did not contain any invalid characters. Now, this
is directly performed on the URI itself, which may include the path.

This must not be backported.

2 months agoBUG/MINOR: h3: reject request URI with invalid characters
Amaury Denoyelle [Wed, 16 Apr 2025 13:27:03 +0000 (15:27 +0200)] 
BUG/MINOR: h3: reject request URI with invalid characters

Ensure that the HTX start-line generated after parsing an HTTP/3 request
does not contain any invalid character, i.e. control or whitespace
characters.

Note that for now path is used directly as URI. Thus, the check is
performed directly over it. A patch will change this to generate an
absolute-form URI in most cases, but it won't be backported to avoid
configuration breaking in stable versions.

This must be backported up to 2.6.

2 months agoBUG/MINOR: h3: reject invalid :path in request
Amaury Denoyelle [Wed, 16 Apr 2025 09:17:20 +0000 (11:17 +0200)] 
BUG/MINOR: h3: reject invalid :path in request

RFC 9114 specifies some requirements for :path pseudo-header when using
http or https scheme. This commit enforces this by rejecting a request
if needed. Thus, path cannot be empty, and it must either start with a
'/' character or contains only '*'.

This must be backported up to 2.6.

2 months agoBUG/MINOR: h3: filter upgrade connection header
Amaury Denoyelle [Wed, 16 Apr 2025 09:20:42 +0000 (11:20 +0200)] 
BUG/MINOR: h3: filter upgrade connection header

As specified in RFC 9114, connection headers required special care in
HTTP/3. When a request is received with connection headers, the stream
is immediately closed. Conversely, when translating the response from
HTX, such headers are not encoded but silently ignored.

However, "upgrade" was not listed in connection headers. This commit
fixes this by adding a check on it both on request parsing and response
encoding.

This must be backported up to 2.6.

2 months agoBUG/MEDIUM: h3: trim whitespaces in header value prior to QPACK encoding
Amaury Denoyelle [Wed, 16 Apr 2025 15:29:41 +0000 (17:29 +0200)] 
BUG/MEDIUM: h3: trim whitespaces in header value prior to QPACK encoding

This commit does a similar job than the previous one, but it acts now on
the response path. Any leading or trailing whitespaces characters from a
HTX block header value are removed, prior to the header encoding via
QPACK.

This must be backported up to 2.6.

2 months agoBUG/MEDIUM: h3: trim whitespaces when parsing headers value
Amaury Denoyelle [Wed, 16 Apr 2025 13:47:42 +0000 (15:47 +0200)] 
BUG/MEDIUM: h3: trim whitespaces when parsing headers value

Remove any leading and trailing whitespace from header field values
prior to inserting a new HTX header block. This is done when parsing a
HEADERS frame, both as headers and trailers.

This must be backported up to 2.6.

2 months agoMINOR: acme: free acme_ctx once the task is done
William Lallemand [Wed, 16 Apr 2025 15:54:34 +0000 (17:54 +0200)] 
MINOR: acme: free acme_ctx once the task is done

Free the acme_ctx task context once the task is done.
It frees everything but the config and the httpclient,
everything else is free.

The ckch_store is freed in case of error, but when the task is
successful, the ptr is set to NULL to prevent the free once inserted in
the tree.

2 months agoMINOR: acme: register the task in the ckch_store
William Lallemand [Wed, 16 Apr 2025 15:12:43 +0000 (17:12 +0200)] 
MINOR: acme: register the task in the ckch_store

This patch registers the task in the ckch_store so we don't run 2 tasks
at the same time for a given certificate.

Move the task creation under the lock and check if there was already a
task under the lock.

2 months agoBUG/MINOR: acme/cli: fix certificate name in error message
William Lallemand [Wed, 16 Apr 2025 15:06:52 +0000 (17:06 +0200)] 
BUG/MINOR: acme/cli: fix certificate name in error message

The acme command had a new parameter so the certificate name is not
correct anymore because args[1] is not the certificate value anymore.

2 months agoMINOR: acme: add a success message to the logs
William Lallemand [Wed, 16 Apr 2025 12:51:18 +0000 (14:51 +0200)] 
MINOR: acme: add a success message to the logs

Add a success log when the certificate was updated.

Ex:

  acme: foobar.pem: Successful update of the certificate.

2 months agoMINOR: acme: emit logs instead of ha_notice
William Lallemand [Wed, 16 Apr 2025 12:39:39 +0000 (14:39 +0200)] 
MINOR: acme: emit logs instead of ha_notice

Emit logs using the global logs when the ACME task failed or retries,
instead of using ha_notice().

2 months agoDOC: configuration: specify limitations of ACME for 3.2
William Lallemand [Wed, 16 Apr 2025 12:30:45 +0000 (14:30 +0200)] 
DOC: configuration: specify limitations of ACME for 3.2

Specify the version for which the limitation applies.

2 months agoBUG/MINOR: acme: fix the exponential backoff of retries
William Lallemand [Wed, 16 Apr 2025 12:16:02 +0000 (14:16 +0200)] 
BUG/MINOR: acme: fix the exponential backoff of retries

Exponential backoff values was multiplied by 3000 instead of 3 with a
second to ms conversion. Leading to a 9000000ms value at the 2nd
attempt.

Fix the issue by setting the value in seconds and converting the value
in tick_add().

No backport needed.

2 months agoBUG/MINOR: acme: key not restored upon error in acme_res_certificate() V2
William Lallemand [Wed, 16 Apr 2025 12:05:04 +0000 (14:05 +0200)] 
BUG/MINOR: acme: key not restored upon error in acme_res_certificate() V2

When receiving the final certificate, it need to be loaded by
ssl_sock_load_pem_into_ckch(). However this function will remove any
existing private key in the struct ckch_store.

In order to fix the issue, the ptr to the key is swapped with a NULL
ptr, and restored once the new certificate is commited.

However there is a discrepancy when there is an error in
ssl_sock_load_pem_into_ckch() fails and the pointer is lost.

This patch fixes the issue by restoring the pointer in the error path.

This must fix issue #2933.

2 months agoRevert "BUG/MINOR: acme: key not restored upon error in acme_res_certificate()"
William Lallemand [Wed, 16 Apr 2025 12:03:08 +0000 (14:03 +0200)] 
Revert "BUG/MINOR: acme: key not restored upon error in acme_res_certificate()"

This reverts commit 7a43094f8d8fe3c435ecc003f07453dd9de8134a.

Part of another incomplete patch was accidentally squash into the patch.

2 months agoMEDIUM: sink: add a new dpapi ring buffer
William Lallemand [Wed, 16 Apr 2025 11:56:12 +0000 (13:56 +0200)] 
MEDIUM: sink: add a new dpapi ring buffer

Add a 1MB ring buffer called "dpapi" for communication with the
dataplane API. It would first be used to transmit ACME informations to
the dataplane API but could be used for more.

2 months agoDOC: configuration: fix a typo in ACME documentation
William Lallemand [Wed, 16 Apr 2025 11:55:25 +0000 (13:55 +0200)] 
DOC: configuration: fix a typo in ACME documentation

Fix "supposed" typo in ACME documentation.

2 months agoCI: fedora rawhide: enable unit tests
Ilia Shipitsin [Tue, 15 Apr 2025 14:32:53 +0000 (16:32 +0200)] 
CI: fedora rawhide: enable unit tests

Run the new make unit-tests on the CI.

2 months agoBUG/MEDIUM: http-ana: Report 502 from req analyzer only during rsp forwarding
Christopher Faulet [Tue, 15 Apr 2025 06:18:48 +0000 (08:18 +0200)] 
BUG/MEDIUM: http-ana: Report 502 from req analyzer only during rsp forwarding

A server abort must be handled by the request analyzers only when the
response forwarding was already started. Otherwise, it it the responsability
of the response analyzer to detect this event. L7-retires and conditions to
decide to silently close a client conneciotn are handled by this analyzer.

Because a reused server connections closed too early could be detected at
the wrong place, it was possible to get a 502/SH instead of a silent close,
preventing the client to safely retries its request.

Thanks to this patch, we are able to silently close the client connection in
this case and eventually to perform a L7 retry.

This patch must be backported as far as 2.8.

2 months agoBUG/MINOR: http-ana: Properly detect client abort when forwarding the response
Christopher Faulet [Tue, 15 Apr 2025 05:54:19 +0000 (07:54 +0200)] 
BUG/MINOR: http-ana: Properly detect client abort when forwarding the response

During the response payload forwarding, if the back SC is closed, we try to
figure out if it is because of a client abort or a server abort. However,
the condition was not accurrate, especially when abortonclose option is
set. Because of this issue, a server abort may be reported (SD-- in logs)
instead of a client abort (CD-- in logs).

The right way to detect a client abort when we try to forward the response
is to test if the back SC was shut down (SC_FL_SHUT_DOWN flag set) AND
aborted (SC_FL_ABRT_DONE flag set). When these both flags are set, it means
the back connection underwent the shutdown, which should be converted to a
client abort at this stage.

This patch should be backported as far as 2.8. It should fix last strange SD
report in the issue #2749.

2 months agoBUILD: incompatible pointer type suspected with -DDEBUG_UNIT 20250415-gcc-15-unittest
William Lallemand [Tue, 15 Apr 2025 13:49:44 +0000 (15:49 +0200)] 
BUILD: incompatible pointer type suspected with -DDEBUG_UNIT

src/jws.c: In function '__jws_init':
src/jws.c:594:38: error: passing argument 2 of 'hap_register_unittest' from incompatible pointer type [-Wincompatible-pointer-types]
  594 |         hap_register_unittest("jwk", jwk_debug);
      |                                      ^~~~~~~~~
      |                                      |
      |                                      int (*)(int,  char **)
In file included from include/haproxy/api.h:36,
                 from include/import/ebtree.h:251,
                 from include/import/ebmbtree.h:25,
                 from include/haproxy/jwt-t.h:25,
                 from src/jws.c:5:
include/haproxy/init.h:37:52: note: expected 'int (*)(void)' but argument is of type 'int (*)(int,  char **)'
   37 | void hap_register_unittest(const char *name, int (*fct)());
      |                                              ~~~~~~^~~~~~

GCC 15 is warning because the function pointer does have its
arguments in the register function.

Should fix issue #2929.

2 months agoCLEANUP: acme: stored value is overwritten before it can be used
William Lallemand [Tue, 15 Apr 2025 09:44:45 +0000 (11:44 +0200)] 
CLEANUP: acme: stored value is overwritten before it can be used

   >>>     CID 1609049:  Code maintainability issues  (UNUSED_VALUE)
   >>>     Assigning value "NULL" to "new_ckchs" here, but that stored value is overwritten before it can be used.
   592             struct ckch_store *old_ckchs, *new_ckchs = NULL;

Coverity reported an issue where a variable is initialized to NULL then
directry overwritten with another value. This doesn't arm but this patch
removes the useless initialization.

Must fix issue #2932.

2 months agoBUG/MINOR: acme: fix possible NULL deref
William Lallemand [Tue, 15 Apr 2025 09:36:26 +0000 (11:36 +0200)] 
BUG/MINOR: acme: fix possible NULL deref

Task was dereferenced when setting ctx but was checked after.
This patch move the setting of ctx after the check.

Should fix issue #2931

2 months agoMINOR: debug: detect call instructions and show the branch target in backtraces
Willy Tarreau [Mon, 14 Apr 2025 18:06:48 +0000 (20:06 +0200)] 
MINOR: debug: detect call instructions and show the branch target in backtraces

In backtraces, sometimes it's difficult to know what was called by a
given point, because some functions can be fairly long making one
doubt about the correct pointer of unresolved ones, others might
just use a tail branch instead of a call + return, etc. On common
architectures (x86 and aarch64), it's not difficult to detect and
decode a relative call, so let's do it on both of these platforms
and show the branch location after a '>'. Example:

x86_64:
   call trace(19):
   |       0x6bd644 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95 > ha_thread_dump_one
   | 0x7feb3e5383a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
   | 0x7feb3e53748b <c0 b8 03 00 00 00 0f 05]: libpthread:__close+0x3b/0x8b
   |       0x7619e4 <44 89 ff e8 fc 97 d4 ff]: _fd_delete_orphan+0x1d4/0x1d6 > main-0x2130
   |       0x743862 <8b 7f 68 e8 8e e1 01 00]: sock_conn_ctrl_close+0x12/0x54 > fd_delete
   |       0x5ac822 <c0 74 05 4c 89 e7 ff d0]: main+0xff512
   |       0x5bc85c <48 89 ef e8 04 fc fe ff]: main+0x10f54c > main+0xff150
   |       0x5be410 <4c 89 e7 e8 c0 e1 ff ff]: main+0x111100 > main+0x10f2c0
   |       0x6ae6a4 <28 00 00 00 00 ff 51 58]: cli_io_handler+0x31524
   |       0x6aeab4 <7c 24 08 e8 fc fa ff ff]: sc_destroy+0x14/0x2a4 > cli_io_handler+0x31430
   |       0x6c685d <48 89 ef e8 43 82 fe ff]: process_chk_conn+0x51d/0x1927 > sc_destroy

aarch64:
   call trace(15):
   | 0xaaaaad0c1540 <60 6a 60 b8 c3 fd ff 97]: debug_handler+0x9c/0xbc > ha_thread_dump_one
   | 0xffffa8c177ac <c2 e0 3b d5 1f 20 03 d5]: linux-vdso:__kernel_rt_sigreturn
   | 0xaaaaad0b0964 <c0 03 5f d6 d2 ff ff 97]: cli_io_handler+0x28e44 > sedesc_new
   | 0xaaaaad0b22a4 <00 00 80 d2 94 f9 ff 97]: sc_new_from_strm+0x1c/0x54 > cli_io_handler+0x28dd0
   | 0xaaaaad0167e8 <21 00 80 52 a9 6e 02 94]: stream_new+0x258/0x67c > sc_new_from_strm
   | 0xaaaaad0b21f8 <e1 03 13 aa e7 90 fd 97]: sc_new_from_endp+0x38/0xc8 > stream_new
   | 0xaaaaacfda628 <21 18 40 f9 e7 5e 03 94]: main+0xcaca8 > sc_new_from_endp
   | 0xaaaaacfdb95c <42 c0 00 d1 02 f3 ff 97]: main+0xcbfdc > main+0xc8be0
   | 0xaaaaacfdd3f0 <e0 03 13 aa f5 f7 ff 97]: h1_io_cb+0xd0/0xb90 > main+0xcba40

2 months agoMINOR: debug: in call traces, dump the 8 bytes before the return address, not after
Willy Tarreau [Mon, 14 Apr 2025 17:28:22 +0000 (19:28 +0200)] 
MINOR: debug: in call traces, dump the 8 bytes before the return address, not after

In call traces, we're interested in seeing the code that was executed, not
the code that was not yet. The return address is where the CPU will return
to, so we want to see the bytes that precede this location. In the example
below on x86 we can clearly see a number of direct "call" instructions
(0xe8 + 4 bytes). There are also indirect calls (0xffd0) that cannot be
exploited but it gives insights about where the code branched, which will
not always be the function above it if that one used tail branching for
example. Here's an example dump output:

         call ------------,
                          v
       0x6bd634 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95
 0x7fa4ea2593a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
       0x752132 <00 00 00 00 00 90 41 55]: htx_remove_blk+0x2/0x354
       0x5b1a2c <4c 89 ef e8 04 07 1a 00]: main+0x10471c
       0x5b5f05 <48 89 df e8 8b b8 ff ff]: main+0x108bf5
       0x60b6f4 <89 ee 4c 89 e7 41 ff d0]: tcpcheck_eval_send+0x3b4/0x14b2
       0x610ded <00 00 00 e8 53 a5 ff ff]: tcpcheck_main+0x7dd/0xd36
       0x6c5ab4 <48 89 df e8 5c ab f4 ff]: wake_srv_chk+0xc4/0x3d7
       0x6c5ddc <48 89 f7 e8 14 fc ff ff]: srv_chk_io_cb+0xc/0x13

2 months agoMINOR: tools: let dump_addr_and_bytes() support dumping before the offset
Willy Tarreau [Mon, 14 Apr 2025 17:25:27 +0000 (19:25 +0200)] 
MINOR: tools: let dump_addr_and_bytes() support dumping before the offset

For code dumps, dumping from the return address is pointless, what is
interesting is to dump before the return address to read the machine
code that was executed before branching. Let's just make the function
support negative sizes to indicate that we're dumping this number of
bytes to the address instead of this number from the address. In this
case, in order to distinguish them, we're using a '<' instead of '[' to
start the series of bytes, indicating where the bytes expand and where
they stop. For example we can now see this:

       0x6bd634 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95
 0x7fa4ea2593a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
       0x752132 <00 00 00 00 00 90 41 55]: htx_remove_blk+0x2/0x354
       0x5b1a2c <4c 89 ef e8 04 07 1a 00]: main+0x10471c
       0x5b5f05 <48 89 df e8 8b b8 ff ff]: main+0x108bf5
       0x60b6f4 <89 ee 4c 89 e7 41 ff d0]: tcpcheck_eval_send+0x3b4/0x14b2
       0x610ded <00 00 00 e8 53 a5 ff ff]: tcpcheck_main+0x7dd/0xd36
       0x6c5ab4 <48 89 df e8 5c ab f4 ff]: wake_srv_chk+0xc4/0x3d7
       0x6c5ddc <48 89 f7 e8 14 fc ff ff]: srv_chk_io_cb+0xc/0x13

2 months agoDEBUG: counters: add the ability to enable/disable updating the COUNT_IF counters
Willy Tarreau [Mon, 14 Apr 2025 16:31:25 +0000 (18:31 +0200)] 
DEBUG: counters: add the ability to enable/disable updating the COUNT_IF counters

These counters can have a noticeable cost on large machines, though not
dramatic. There's no single good choice to keep them enabled or disabled.
This commit adds multiple choices:
  - DEBUG_COUNTERS set to 2 will automatically enable them by default, while
    1 will disable them by default
  - the global "debug.counters on/off" will allow to change the setting at
    boot, regardless of DEBUG_COUNTERS as long as it was at least 1.
  - the CLI "debug counters on/off" will also allow to change the value at
    run time, allowing to observe a phenomenon while it's happening, or to
    disable counters if it's suspected that their cost is too high

Finally, the "debug counters" command will append "(stopped)" at the end
of the CNT lines when these counters are stopped.

Not that the whole mechanism would easily support being extended to all
counter types by specifying the types to apply to, but it doesn't seem
useful at all and would require the user to also type "cnt" on debug
lines. This may easily be changed in the future if it's found relevant.

2 months agoDEBUG: counters: make COUNT_IF() only appear at DEBUG_COUNTERS>=1
Willy Tarreau [Mon, 14 Apr 2025 15:46:18 +0000 (17:46 +0200)] 
DEBUG: counters: make COUNT_IF() only appear at DEBUG_COUNTERS>=1

COUNT_IF() is convenient but can be heavy since some of them were found
to trigger often (roughly 1 counter per request on avg). This might even
have an impact on large setups due to the cost of a shared cache line
bouncing between multiple cores. For now there's no way to disable it,
so let's only enable it when DEBUG_COUNTERS is 1 or above. A future
change will make it configurable.

2 months agoDEBUG: rename DEBUG_GLITCHES to DEBUG_COUNTERS and enable it by default
Willy Tarreau [Mon, 14 Apr 2025 15:32:10 +0000 (17:32 +0200)] 
DEBUG: rename DEBUG_GLITCHES to DEBUG_COUNTERS and enable it by default

Till now the per-line glitches counters were only enabled with the
confusingly named DEBUG_GLITCHES (which would not turn glitches off
when disabled). Let's instead change it to DEBUG_COUNTERS and make sure
it's enabled by default (though it can still be disabled with
-DDEBUG_GLITCHES=0 just like for DEBUG_STRICT). It will later be
expanded to cover more counters.

2 months agoDEBUG: init: report invalid characters in debug description strings
Willy Tarreau [Mon, 14 Apr 2025 17:00:01 +0000 (19:00 +0200)] 
DEBUG: init: report invalid characters in debug description strings

It's easy to leave some trailing \n or even other characters that can
mangle the debug output. Let's verify at boot time that the debug sections
are clean by checking for chars 0x20 to 0x7e inclusive. This is very simple
to do and it managed to find another one in a multi-line message:

  [WARNING]  (23696) : Invalid character 0x0a at position 96 in description string at src/cli.c:2516 _send_status()

This way new offending code will be spotted before being committed.

2 months agoDOC: config: add the missing "force-cfg-parser-pause" to the global kw index
Willy Tarreau [Mon, 14 Apr 2025 16:29:02 +0000 (18:29 +0200)] 
DOC: config: add the missing "force-cfg-parser-pause" to the global kw index

It was documented but missing from the index, let's add it. This can be
backported to 3.1.

2 months agoDOC: config: add the missing "profiling.memory" to the global kw index
Willy Tarreau [Mon, 14 Apr 2025 16:28:09 +0000 (18:28 +0200)] 
DOC: config: add the missing "profiling.memory" to the global kw index

It was in the description but not in the index. This can be backported to
all versions where it applies.

2 months agoBUG/MINOR: debug: remove the trailing \n from BUG_ON() statements
Willy Tarreau [Mon, 14 Apr 2025 16:45:35 +0000 (18:45 +0200)] 
BUG/MINOR: debug: remove the trailing \n from BUG_ON() statements

These ones were added by mistake during the change of the cfgparse
mechanism in 3.1, but they're corrupting the output of "debug counters"
by leaving stray ']' on their own lines. We could possibly check them
all once at boot but it doens't seem worth it.

This should be backported to 3.1.

2 months agoDOC: acme: explain how to configure and run ACME
William Lallemand [Mon, 14 Apr 2025 14:12:26 +0000 (16:12 +0200)] 
DOC: acme: explain how to configure and run ACME

Add configuration about the acme section in the configuration manual, as
well as the acme command in the management guide.

2 months agoMINOR: acme: default to 2048bits for RSA
William Lallemand [Mon, 14 Apr 2025 13:28:54 +0000 (15:28 +0200)] 
MINOR: acme: default to 2048bits for RSA

Change the default RSA value to 2048 bits.

2 months agoBUG/MINOR: thread: protect thread_cpus_enabled_at_boot with USE_THREAD
Valentine Krasnobaeva [Sat, 12 Apr 2025 09:16:08 +0000 (11:16 +0200)] 
BUG/MINOR: thread: protect thread_cpus_enabled_at_boot with USE_THREAD

Following error is triggered at linker invokation, when we try to compile with
USE_THREAD=0 and -O0.

  make -j 8 TARGET=linux-glibc USE_LUA=1 USE_PCRE2=1 USE_LINUX_CAP=1 \
   USE_MEMORY_PROFILING=1 OPT_CFLAGS=-O0  USE_THREAD=0

  /usr/bin/ld: src/thread.o: warning: relocation against `thread_cpus_enabled_at_boot' in read-only section `.text'
  /usr/bin/ld: src/thread.o: in function `thread_detect_count':
  /home/vk/projects/haproxy/src/thread.c:1619: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: /home/vk/projects/haproxy/src/thread.c:1619: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: /home/vk/projects/haproxy/src/thread.c:1620: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: warning: creating DT_TEXTREL in a PIE
  collect2: error: ld returned 1 exit status
  make: *** [Makefile:1044: haproxy] Error 1

thread_cpus_enabled_at_boot is only available when we compiled with
USE_THREAD=1, which is the default for the most targets now.

In some cases, we need to recompile in mono-thread mode, thus
thread_cpus_enabled_at_boot should be protected with USE_THREAD in
thread_detect_count().

thread_detect_count() is always called during the process initialization
never mind of multi thread support. It sets some defaults in global.nbthread
and global.nbtgroups.

This patch is related to GitHub issue #2916.
No need to be backported as it was added in 3.2-dev9 version.

2 months agoBUG/MINOR: acme: key not restored upon error in acme_res_certificate()
William Lallemand [Mon, 14 Apr 2025 08:44:24 +0000 (10:44 +0200)] 
BUG/MINOR: acme: key not restored upon error in acme_res_certificate()

When receiving the final certificate, it need to be loaded by
ssl_sock_load_pem_into_ckch(). However this function will remove any
existing private key in the struct ckch_store.

In order to fix the issue, the ptr to the key is swapped with a NULL
ptr, and restored once the new certificate is commited.

However there is a discrepancy when there is an error in
ssl_sock_load_pem_into_ckch() fails and the pointer is lost.

This patch fixes the issue by restoring the pointer in the error path.

This must fix issue #2933.

3 months agoBUG/MINOR: cpu-topo: check the correct variable for NULL after malloc()
Willy Tarreau [Sat, 12 Apr 2025 16:22:34 +0000 (18:22 +0200)] 
BUG/MINOR: cpu-topo: check the correct variable for NULL after malloc()

We were testing ha_cpu_topo instead of ha_cpu_clusters after an allocation,
making the check ineffective.

No backport is needed.