25322 Commits

Author SHA1 Message Date
Willy Tarreau
a771b14541 MEDIUM: stick-tables: give up on lock contention in process_table_expire()
process_table_expire() can take quite a lot of time running over all
shards. During this time it will hinder track-sc rules and peers, which
will experience an increased latency to do their work, especially peers
where each message will cause a lock, whose cumulated time can exceed
the watchdog's patience.

Here, we proceed just like in stktable_trash_oldest(), which is that
we're using a trylock to detect contention. The first time it happens,
if we hadn't purged anything, we switch to a regular lock to perform
the operation, and next time it happens we abort. This guarantees that
some entries will be expired and that contention will be reduced with
when detected.

With this change, various tests didn't manage to produce any warning,
including at the end of the load generation session.

This should be backported to 3.2 after a bit more testing.
2025-09-09 17:56:37 +02:00
Willy Tarreau
f87cf8b76e MEDIUM: stick-tables: relax stktable_trash_oldest() to only purge what is needed
stktable_trash_oldest() does insist a lot on purging what was requested,
only limited by STKTABLE_MAX_UPDATES_AT_ONCE. This is called in two
conditions, one to allocate a new stksess, and the other one to purge
entries of a stopping process. The cost of iterating over all shards
is huge, and a shard lock is taken each time before looking up entries.

Moreover, multiple threads can end up doing the same and looking hard for
many entries to purge when only one is needed. Furthermore, all threads
start from the same shard, hence synchronize their locks. All of this
costs a lot to other operations such as access from peers.

This commit simplifies the approach by ignoring the budget, starting
from a random shard number, and using a trylock so as to be able to
give up early in case of contention. The approach chosen here consists
in trying hard to flush at least one entry, but once at least one is
evicted or at least one trylock failed, then a failure on the trylock
will result in finishing.

The function now returns a success as long as one entry was freed.

With this, tests no longer show watchdog warnings during tests, though
a few still remain when stopping the tests (which are not related to
this function but to the contention from process_table_expire()).

With this change, under high contention some entries' purge might be
postponed and the table may occasionally contain slightly more entries
than their size (though this already happens since stksess_new() first
increments ->current before decrementing it).

Measures were made on a 64-core system with 8 peers
of 16 threads each, at CPU saturation (350k req/s each doing 10
track-sc) for 10M req, with 3 different approaches:

  - this one resulted in 1500 failures to find an entry (0.015%
    size overhead), with the lowest contention and the fairest
    peers distibution.

  - leaving only after a success resulted in 229 failures (0.0029%
    size overhead) but doubled the time spent in the function (on
    the write lock precisely).

  - leaving only when both a success and a failed lock were met
    resulted in 31 failures (0.00031% overhead) but the contention
    was high enough again so that peers were not all up to date.

Considering that a saturated machine might exceed its entries by
0.015% is pretty minimal, the mechanism is kept.

This should be backported to 3.2 after a bit more testing as it
resolves some watchdog warnings and panics. It requires precedent
commit "MINOR: stick-table: permit stksess_new() to temporarily
allocate more entries" to over-allocate instead of failing in case
of contention.
2025-09-09 17:56:37 +02:00
Willy Tarreau
b119280f60 MINOR: stick-table: permit stksess_new() to temporarily allocate more entries
stksess_new() calls stktable_trash_oldest() to release some entries.
If it fails however, it will fail to allocate an entry. This is a problem
because it doesn't permit stktable_trash_oldest() to be used in best effort
mode, which forces it to impose high contention. There's no problem with
allocating slightly more in practice. In the worst case if all entries are
in use, it's not shocking to temporarily exceed the number of entries by a
few units.

Let's relax this problematic rule. This patch might need to be backported
to 3.2 after a bit more testing in order to support locking relaxation.
2025-09-09 17:56:37 +02:00
Willy Tarreau
0f33a55171 DEBUG: peers: export functions that use locks
The following functions take locks and are often involved in warnings
but are currently not resolved, so let's export them so that they are
properly decoded:

  peer_prepare_updatemsg(), peer_send_teachmsgs(),
  peer_treat_updatemsg(), peer_send_msgs(), peer_io_handler()

This should be backported to 3.2.
2025-09-09 17:56:14 +02:00
Willy Tarreau
25195ba1e7 MINOR: debug: report the time since last wakeup and call
When task profiling is enabled, the current thread knows when the
currently running task was woken up and called, so we can calculate
how long ago it was woken up and called. This is convenient to figure
whether or not a warning or panic is caused by this task or by a
previous one, so let's report this info in thread outputs when known.

It would be useful to backport this to 3.2.
2025-09-09 17:56:14 +02:00
Willy Tarreau
12bc4f9c44 MINOR: debug: report the number of loops and ctxsw for each thread
When multiple similar warnings are emitted, it can be difficult to know
whether only one task is looping slowly or if many are sharing the CPU.
Let's report the number of context switches and polling loop turns in
thread dumps so that warnings are easier to understand.

This should be backported to 3.2.
2025-09-09 17:56:14 +02:00
Willy Tarreau
c3f94fbd9b DEBUG: stream: count the number of passes in the connect loop
Normally the connect loop cannot loop, but some recent traces can easily
convince one of the opposite. Let's add a counter, including in panic
dumps, in order to avoid the repeated long head scratching sessions
starting with "and what if...". In addition, if it's found to loop, this
time it will be certain and will indicate what to zoom in. This should
be backported to 3.2.
2025-09-09 17:56:14 +02:00
Willy Tarreau
8153cf1e51 MINOR: debug: report the process id in warnings and panics
Warning and panic messages currently do not report the PID. This is
annoying when trying to reproduce problems because warnings do not
allow know which process to attach to in order to debug, and panics
do not permit to know which core dump corresponds to which dump.
Let's add them in both messages. This should probably be backported
at least to 3.2.
2025-09-09 17:56:14 +02:00
Amaury Denoyelle
0678d0a69b MINOR: check: reject invalid check config on a QUIC server
QUIC is now supported on the backend side. The previous commit ensures
that simple checks can be activated on QUIC servers without any issue.

The current patch ensures that check server settings remain compatible
with a QUIC server. Thus, configuration is now invalid if check
specifies an explicit MUX proto other than QUIC, disables SSL or try to
use PROXY protocol.
2025-09-09 16:55:09 +02:00
Amaury Denoyelle
cd3027a7ee BUG/MINOR: check: ensure checks are compatible with QUIC servers
Previously, checks were only performed on TCP. However, QUIC is now
supported on backend. Prior to this patch, check activation for QUIC
servers would result in a crash.

To ensure compatibility between QUIC servers and checks, adjust
protocol_lookup() performed during check connect step. Instead of using
a hardcoded PROTO_TYPE_STREAM, the value is now derived from server
settings.

This does not need to be backported.
2025-09-09 16:55:09 +02:00
Amaury Denoyelle
c6d33c09fc BUG/MEDIUM: checks: fix ALPN inheritance from server
If no specific check settings are defined on a server line, it is
expected that these checks will be performed with the same parameters as
normal connections on the same server.

ALPN must be carefully taken into account for checks. Most notably, MUX
initialization is delayed so that it is performed only after SSL
handshake.

Prior to this patch, MUX init delay was only performed if ALPN was
defined via check settings. Thus, with the following settings, checks
would be performed on HTTP/1.1 without consulting ALPN negotiation
result from the server :

  server s1 127.0.0.1:443 ssl crt <...> alpn h2 check

This bug may result in checks reporting failure, for example in case of
a server answering HTTP/2 to ALPN negotiation to the configuration
above. Besides, there is incoherency between normal and check
connections, which is not what the documentation specifies.

This patch fixes this code. Now server parameters are also taken into
account. This ensures that checks and normal connections by default
use the same connection method.

This must be backported up to 2.4.
2025-09-09 16:55:09 +02:00
Amaury Denoyelle
fee3bd48b4 OPTIM: check: do not delay MUX for ALPN if SSL not active
To ensure ALPN is properly applied on checks, MUX initialization is
delayed so that it is created on SSL handshake completion. However, this
does not check if SSL is really active for the connection.

This patch adjusts the condition so that MUX init is not delayed if SSL
is not active for the check connection. A similar process is already
conducted for normal connections via connect_server().

This must be backported up to 2.4. Despite not being a bug, it must be
backported for the following patch which fixes check ALPN inheritance
from server settings.
2025-09-09 16:55:09 +02:00
Amaury Denoyelle
536d2aafa3 BUG/MINOR: hq-interop: adjust parsing/encoding on backend side
HTTP/0.9 is available on top of QUIC. This protocol is reserved for
internal use, mostly interop purpose.

This patch adjusts HTTP/0.9 layer with the following changes :
* version is not emitted anymore on the status line. This is performed
  as some servers does not parse it correctly.
* status line is set explicitely on HTX status-line. This ensures the
  correct HTTP status code is reported to the upper stream layer.

This does not need to be backported.
2025-09-09 16:55:09 +02:00
Christopher Faulet
b901e56acd BUG/MEDIUM: mux-h2: Reinforce conditions to report an error to app-layer stream
This patch relies on the previous one ("BUG/MEDIUM: mux-h2: Report RST/error to
app-layer stream during 0-copy fwding").

When the end of the connection is detected, so when the H2_CF_END_REACHED
flag is set after the shutdown was received and all incoming data were
processed, if a stream is blocked by the flow control (the stream one or the
connection one), an error must be reported to the app-layer stream.

Otherwise, outgoing data won't be sent and the opposite side will handle
this as a lack of room. So the stream will be blocked until the write
timeout is triggerd. By reporting the error early, the stream can be
immediately closed.

This patch should be backported to 3.2. For older versions, it is probably a
good idea to wait for bug report.
2025-09-09 16:30:54 +02:00
Christopher Faulet
22e14f7b54 BUG/MEDIUM: mux-h2: Report RST/error to app-layer stream during 0-copy fwding
In h2_nego_ff(), it is important to report reset and error to app-layer
stream and to send the RST-STREAM frame accordingly. It is not clear if it
is an issue or not. But it is clearly a difference with the classical
forwarding via h2_snd_buf. And it is mandatory for the next fix.

This patch should be backported to 3.2. But is is probably a good idea to
not backport it on older versions, except if a bug is reported in this area.
2025-09-09 16:30:21 +02:00
Christopher Faulet
3b7112aa1d BUG/MINOR: mux-h2: Remove H2_CF_DEM_DFULL flags when the demux buffer is reset
This only happens when a connection error is detected or when the H2
connection is in ERR/ERR2 state. The demux buffer is explicitly reset. In
that case, it is important to remove the flag reporting this buffer as full.

It is probably worth to backport this patch to 3.2. But it is not mandatory
on older versions because it does not fix any known issue.
2025-09-09 16:29:14 +02:00
Christopher Faulet
12edcccc82 BUG/MEDIUM: mux-h2: Restart reading when mbuf ring is no longer full
When the mbuf ring buffer is full, the flag H2_CF_DEM_MROOM is set on the H2
connection to block any demux. It is important to properly handle ACK
frames. However, we must take care to restart reading when some data were
removed from the mbuf. Otherwise, we may block the demux for no reason. It
is especially an issue if the demux buffer is full. In that case, the H2
connection is blocked, waiting for the timeout.

This patch should be backported to 3.2. But is is probably a good idea to
not backport it on older versions, except if a bug is reported in this area.
2025-09-09 16:07:20 +02:00
Christopher Faulet
c6e4584d2b BUG/MEDIUM: mux-h2; Don't block reveives in H2_CS_ERROR and H2_CS_ERROR2 states
The H2 connection is switched to ERR when a GOAWAY must be sent and in ERR2
when it is sent. In these states, no more data can be emitted by the
mux. But there is no reason to not try to process incoming data or to not
try to receive data. It is espcially important to be able to get the
shutdown from the TCP connection when a SSL connection was previously
detected. Otherwise, it is possible to block a H2 connection until its
timeout expiration to be able to close it.

This patch should be backported to 3.2. But is is probably a good idea to
not backport it on older versions, except if a bug is reported in this
area.
2025-09-09 16:07:20 +02:00
Christopher Faulet
626d7934cf BUG/MEDIUM: mux-h2: Reset MUX blocking flags when a send error is caught
When an send error is detected on the underlying connection, a pending error
is reported to the H2 connection by setting H2_CF_ERR_PENDING flag. When
this happen the tail of the mux ring buffer is reset. However some blocking
flags remain set and have no chance to be removed later because of the
pending error. Especially the flag H2_CF_DEM_MROOM which block data
demultiplexing. Thus, it is possible to block a H2 connection with unparsed
incoming data.

Worse, if a read event is received, it could lead to a wakeup loop between
the H2 connection and the underlying SSL connection. The H2 connection is
unable to convert the pending error to a fatal error because the
demultiplexing is blocked. In the mean time, it tries to receive more data
because of the not-consumed read event. On the underlying connection side,
the error detected earlier blocks the read, but the H2 connection is woken
up to handle the error.

To fix the issue, blocking flags must be removed when a send error is caught,
H2_CF_MUX_MFULL and H2_CF_DEM_MROOM flags. But, it is not necessary to only
release the tail of the mbuf ring. When a send error is detected, all outgoing
data can be flushed. So, now, in h2_send(), h2_release_mbuf() function is called
on pending error. The mbuf ring is fully released and H2_CF_MUX_MFULL and
H2_CF_DEM_MROOM flags are removed.

Many thanks to Krzysztof Kozłowski for its help to spot this issue.

This patch could be backported at least as far as 2.8. But it is a bit
sensitive. So, it is probably a good idea to backport it to 3.2 for now and
wait for bug report on older versions.
2025-09-09 16:07:20 +02:00
Amaury Denoyelle
0b6908385e BUG/MINOR: quic: properly support GSO on backend side
Previously, GSO emission was explicitely disabled on backend side. This
is not true since the following patch, thus GSO can be used, for example
when transfering large POST requests to a HTTP/3 backend.

  commit e064e5d46171d32097a84b8f84ccc510a5c211db
  MINOR: quic: duplicate GSO unsupp status from listener to conn

However, GSO on the backend side may cause crash when handling EIO. In
this case, GSO must be completely disabled. Previously, this was
performed by flagging listener instance. In backend side, this would
cause a crash as listener is NULL.

This patch fixes it by supporting GSO disable flag for servers. Thus, in
qc_send_ppkts(), EIO can be converted either to a listener or server
flag depending on the quic_conn proxy side. On backend side, server
instance is retrieved via <qc.conn.target>. This is enough to guarantee
that server is not deleted.

This does not need to be backported.
2025-09-08 16:18:05 +02:00
Christopher Faulet
e653dc304e MINOR: pools: Don't dump anymore info about pools when purge is forced
Historically, when the purge of pools was forced by sending a SIGQUIT to
haproxy, information about the pools were first dumped. It is now totally
pointless because these info can be retrieved via the CLI. It is even less
relevant now because the purge is forced typically when there are memroy
issues and to dump pools information, data must be allocated.

dump_pools_info() function was simplified because it is now called only from
an applet. No reason to still try to dump info on stderr.
2025-09-08 16:04:40 +02:00
Christopher Faulet
982805e6a3 BUG/MINOR: pools: Fix the dump of pools info to deal with buffers limitations
The "show pools" CLI command was not designed to dump information exceeding
the size of a buffer. But there is now much more pools than few years ago
and when detailed information are dumped, we exceeds the buffer limit and
the output is truncated.

To fix the issue, the command must be refactored to be able to stream the
result. To do so, the array containing pools info is now part of the command
context and it is dynamically allocated. A dedicated function was created to
fill all info. In addition, the index of the next pool to dump is saved in
the command context too to properly handle resumption cases. Finally global
information about pools are also stored in the command context for
convenience.

This patch should fix the issue #3067. It must be backported to 3.2. On
older release, the buffer limit is never reached.
2025-09-08 16:01:51 +02:00
Christopher Faulet
d75718af14 REGTESTS: ssl: Fix the script about automatic SNI selection
First, the barrier to delay the client execution was moved before the client
definition. Otherwise, the connection is established too early and with
short timeouts it could be closed before the requests are sent.

The main purpose of the barrier was to workaround slow health-checks. This
is also the reason why the script was flagged as slow. But it can be
significantly speed-up by setting a slow "inter" value. It is now set to
100ms and the script is no longer slow.
2025-09-08 15:55:56 +02:00
Amaury Denoyelle
f645cd3c74 MINOR: quic: restore QUIC_HP_SAMPLE_LEN constant
The below patch fixes padding emission for small packets, which is
required to ensure that header protection removal can be performed by
the recipient.

  commit d7dea408c64c327cab6aebf4ccad93405b675565
  BUG/MINOR: quic: too short PADDING frame for too short packets

In addition to the proper fix, constant QUIC_HP_SAMPLE_LEN was removed
and replaced by QUIC_TLS_TAG_LEN. However, it still makes sense to have
a dedicated constant which represent the size of the sample used for
header protection. Thus, this patch restores it.

Special instructions for backport : above patch mentions that no
backport is needed. However, this is incorrect, as bug is introduced by
another patch scheduled for backport up to 2.6. Thus, it is first
mandatory to schedule d7dea408c64c327cab6aebf4ccad93405b675565 after it.
Then, this patch can also be used for the sake of code clarity.
2025-09-08 14:49:03 +02:00
Amaury Denoyelle
c20c71a079 TESTS: quic: add unit-tests for QUIC TX part
Define a new "quic_tx" unit-test which is used to test QUIC TX module.
For the moment, a single test is performed on qc_do_build_pkt(). It
checks that PADDING is correctly added for HP sampling in case of a
small packet.
2025-09-08 14:49:03 +02:00
Amaury Denoyelle
fb8c6e2030 CLEANUP: quic: fix typo in quic_tx trace
Fix trace in qc_may_build_pkt().

This can be backported up to 3.0.
2025-09-08 14:49:03 +02:00
Aurelien DARRAGON
b9ef55d56d MINOR: stats-file: use explicit unsigned integer bitshift for user slots
As reported in GH #3104, there remained a place where (1 << shift was
used to set or remove bits from uint64_t users bitfield. It is incorrect
and could lead to bugs for values > 32 bits.

Instead, let's use 1ULL to ensure the operation remains 64bits consistent.

No backport needed.
2025-09-08 13:38:49 +02:00
Aurelien DARRAGON
9272b8ce74 BUG/MEDIUM: proxy: fix crash with stop_proxy() called during init
Willy reported that the following config would segfault right after the
"removing incomplete section 'peer' is emitted:

  peers peers
	bind :2300
  	server n10 127.0.0.1:2310

  listen dummy
  bind localhost:9999

This is caused by the fact that stop_proxy(), which tries to read shared
counters, is called during early init while shared counters are not yet
initialized. To fix the crash, let's check if we're still during starting
phase, in which case we assume the counters are not initialized and we
assume 0 value instead.

No backport needed unless 16eb0fab31 ("MAJOR: counters: dispatch counters
over thread groups") is.
2025-09-08 13:38:38 +02:00
Frederic Lecaille
6f9fccec1f MINOR: quic: SSL session reuse for QUIC
Mimic the same behavior as the one for SSL/TCP connetion to implement the
SSL session reuse.

Extract the code which try to reuse the SSL session for SSL/TCP connections
to implement ssl_sock_srv_try_reuse_sess().
Call this function from QUIC ->init() xprt callback (qc_conn_init()) as this
done for SSL/TCP connections.
2025-09-08 11:46:26 +02:00
Olivier Houchard
b3e685ac3d BUG/MEDIUM: ssl: Properly initialize msg_controllen.
When kTLS is compiled in, make sure msg_controllen is initialized to 0.
If we're not actually kTLS, then it won't be set, but we'll check that
it is non-zero later to check if we ancillary data.
This does not need to be backported.
This should fix CID 1620865, as reported in github issue #3106.
2025-09-06 14:19:48 +02:00
Willy Tarreau
75bd9255dd BUG/MINOR: cpu_topo: work around a small bug in musl's CPU_ISSET()
As found in GH issue #3103, CPU_ISSET() on musl 1.25 doesn't match the man
page which says it's returning an int. The reason is pretty simple, it's
a macro that operates on the bits directly and returns the result of the
bit field applied to the mask as an unsigned long. Bits above 31 will
simply be dropped if returned as an int, which causes CPUs 32..63 to
appear as absent from cpu_sets.

The fix is trivial, it consists in just comparing the result against zero
(i.e. turning it to a boolean), but before it's merged and deployed we'll
have to face such deployments, so better implement the same workaround
in the code here since we have access to the raw long value.

This workaround should be backported to 3.0.
2025-09-06 11:05:52 +02:00
Frederic Lecaille
d7dea408c6 BUG/MINOR: quic: too short PADDING frame for too short packets
This bug arrvived with this commit:

    MINOR: quic: centralize padding for HP sampling on packet building

What was missed is the fact that at the centralization point for the
PADDING frame to add for too short packet, <len> payload length  already includes
<*pn_len> the packet number field length value.

So when computing the length of the PADDING frame, the packet field length must
not be considered and added to the payload length (<len>).

This bug leaded too short PADDING frame to too short packets. This was the case,
most of times with Application level packets with a 1-byte packet number field
followed by a 1-byte PING frame. A 1-byte PADDING frame was added in this case
in place of a correct 2-bytes PADDINF frame. The header packet protection of
such packet could not be removed by the clients as for instance for ngtcp2 with
such traces:

    I00001828 0x5a135c81e803f092c74bac64a85513b657 pkt could not decrypt packet number

As the header protection could no be removed, the header keyupdate bit could also
not be read by packet analyzers such as pyshark used during the keyupdate tests.

No need to backport.
2025-09-05 16:17:11 +02:00
Frederic Lecaille
71336bdd08 MINOR: quic: add useful trace about padding params values
When adding a PADDING frame for too short packets, add a trace about variable
values whose this PADDING frame length depends on.
2025-09-05 16:17:11 +02:00
Christopher Faulet
cc8af125be REGTESTS: ssl: Add a script to test the automatic SNI selection
The script reg-tests/ssl/ssl_sni_auto.vtc tests the automatic SNI selection
for regular server connections and for health-check ones. It rely on a
3.3-dev8 feature (in fact, it was pushed just after the dev8).
2025-09-05 15:56:42 +02:00
Christopher Faulet
f9a6ae727c OPTIM: tcpcheck: Reorder tcpchek_connect structure fields to fill holes
Thanks to this patch, two 4-bytes holes are now filled in the
tcpchek_connect structure.
2025-09-05 15:56:42 +02:00
Christopher Faulet
ffc1f096e0 MEDIUM: httpcheck/ssl: Base the SNI value on the HTTP host header by default
Similarly to the automic SNI selection for regulat SSL traffic, the SNI of
health-checks HTTPS connection is now automatically set by default by using
the host header value. "check-sni-auto" and "no-check-sni-auto" server
settings were added to change this behavior.

Only implicit HTTPS health-checks can take advantage of this feature. In
this case, the host header value from the "option httpchk" directive is used
to extract the SNI. It is disabled if http-check rules are used. So, the SNI
must still be explicitly specified via a "http-check connect" rule.

This patch with should paritally fix the issue #3081.
2025-09-05 15:56:42 +02:00
Christopher Faulet
668916c1a2 MEDIUM: server/ssl: Base the SNI value to the HTTP host header by default
For HTTPS outgoing connections, the SNI is now automatically set using the
Host header value if no other value is already set (via the "sni" server
keyword). It is now the default behavior. It could be disabled with the
"no-sni-auto" server keyword. And eventually "sni-auto" server keyword may
be used to reset any previous "no-sni-auto" setting. This option can be
inherited from "default-server" settings. Finally, if no connection name is
set via "pool-conn-name" setting, the selected value is used.

The automatic selection of the SNI is enabled by default for all outgoing
connections. But it is concretely used for HTTPS connections only. The
expression used is "req.hdr(host),host_only".

This patch should paritally fix the issue #3081. It only covers the server
part. Another patch will add the feature for HTTP health-checks.
2025-09-05 15:56:42 +02:00
Christopher Faulet
58555b8653 BUG/MINOR: tcpcheck: Don't use sni as pool-conn-name for non-SSL connections
When we try to ruse connection to perform an healtcheck, the SNI, from the
tcpcheck connection or the healthcheck itself, must not be used as
connection name for non-SSL connections.

This patch must be backported to 3.2.
2025-09-05 15:56:42 +02:00
Christopher Faulet
eb3d4eb59f OPTIM: tcpcheck: Don't set SNI and ALPN for non-ssl connections
There is no reason to set the SNI and ALPN for non-ssl connections. It is
not really an issue because ssl_sock_set_servername() and
ssl_sock_set_alpn() functions will do nothing. But it is cleaner this way
and this could avoid bugs in future.

No backport needed, because there is no bug.
2025-09-05 15:56:42 +02:00
Christopher Faulet
ef07d3511a OPTIM: proto_rhttp: Don't set SNI for non-ssl connections
There is no reason to set the SNI for non-ssl connections. It is not really
an issue because ssl_sock_set_servername() function will do nothing. But
there is no reason to uselessly evaluate an expression.

No backport needed, because there is no bug.
2025-09-05 15:56:42 +02:00
Christopher Faulet
52866349a1 OPTIM: backend: Don't set SNI for non-ssl connections
There is no reason to set the SNI for non-ssl connections. It is not really
an issue because ssl_sock_set_servername() function will do nothing. But
there is no reason to uselessly evaluate an expression.

No backport needed, because there is no bug.
2025-09-05 15:56:42 +02:00
Christopher Faulet
a97bd0f505 BUG/MINOR: server: Update healthcheck when server settings are changed via CLI
not all changes are concerned. But when the SSL is enabled or disabled for a
server, the healthcheck xprt must be eventually be updated too. This happens
when the healthcheck relies on the server settings.

In the same spirit, when the healthcheck address and port are updated, we
must fallback on the raw xprt if the SSL is not explicitly enabled for the
healthcheck with a "check-ssl" parameter.

This patch should be backported to all stable versions.
2025-09-05 15:56:42 +02:00
Christopher Faulet
f8f94ffc9c BUG/MEDIUM: server: Use sni as pool connection name for SSL server only
By default, for a given server, when no pool-conn-name is specified, the
configured sni is used. However, this must only be done when SSL is in-use
for the server. Of course, it is uncommon to have a sni expression for
now-ssl server. But this may happen.

In addition, the SSL may be disabled via the CLI. In that case, the
pool-conn-name must be discarded if it was copied from the sni. And, we must
of course take care to set it if the ssl is enabled.

Finally, when the attac-srv action is checked, we now checked the
pool-conn-name expression.

This patch should be backported as far as 3.0. It relies on "MINOR: server:
Parse sni and pool-conn-name expressions in a dedicated function" which
should be backported too.
2025-09-05 15:56:08 +02:00
Christopher Faulet
086a248645 MINOR: server: Parse sni and pool-conn-name expressions in a dedicated function
This change is mandatory to fix an issue. The parsing of sni and
pool-conn-name expressions (from string to expression) is now handled in a
dedicated function. This will avoid to duplicate the same code at different
places.
2025-09-05 11:32:21 +02:00
Christopher Faulet
bb407ba8e3 BUG/MINOR: acl: Fix error message about several '-m' parameters
There is a typo in the commit * c51ddd5c3 ("MINOR: acl: Only allow one '-m'
matching method") . '*m' was reported in the error message instead of '-m'.

In addition, it is now mentionned that only the last one should be keep if
an old config triggers the error.

No backport needed, except if the commit above is backported.
2025-09-05 11:32:20 +02:00
Willy Tarreau
b167d545cf [RELEASE] Released version 3.3-dev8
Released version 3.3-dev8 with the following main changes :
    - BUG/MEDIUM: mux-h2: fix crash on idle-ping due to unwanted ABORT_NOW
    - BUG/MINOR: quic-be: missing Initial packet number space discarding
    - BUG/MEDIUM: quic-be: crash after backend CID allocation failures
    - BUG/MEDIUM: ssl: apply ssl-f-use on every "ssl" bind
    - BUG/MAJOR: stream: Remove READ/WRITE events on channels after analysers eval
    - MINOR: dns: dns_connect_nameserver: fix fd leak at error path
    - BUG/MEDIUM: quic: reset padding when building GSO datagrams
    - BUG/MINOR: quic: do not emit probe data if CONNECTION_CLOSE requested
    - BUG/MAJOR: quic: fix INITIAL padding with probing packet only
    - BUG/MINOR: quic: don't coalesce probing and ACK packet of same type
    - MINOR: quic: centralize padding for HP sampling on packet building
    - MINOR: http_ana: fix typo in http_res_get_intercept_rule
    - BUG/MEDIUM: http_ana: handle yield for "stats http-request" evaluation
    - MINOR: applet: Rely on applet flag to detect the new api
    - MINOR: applet: Add function to test applet flags from the appctx
    - MINOR: applet: Add a flag to know an applet is using HTX buffers
    - MINOR: applet: Make some applet functions HTX aware
    - MEDIUM: applet: Set .rcv_buf and .snd_buf functions on default ones if not set
    - BUG/MEDIUM: mux-spop: Reject connection attempts from a non-spop frontend
    - REGTESTS: jwt: create dynamically "cert.ecdsa.pem"
    - BUG/MEDIUM: spoe: Improve error detection in SPOE applet on client abort
    - MINOR: haproxy: abort config parsing on fatal errors for post parsing hooks
    - MEDIUM: server: split srv_init() in srv_preinit() + srv_postinit()
    - MINOR: proxy: handle shared listener counters preparation from proxy_postcheck()
    - DOC: configuration: reword 'generate-certificates'
    - BUG/MEDIUM: quic-be: avoid crashes when releasing Initial pktns
    - BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets
    - MINOR: ssl: diagnostic warning when both 'default-crt' and 'strict-sni' are used
    - MEDIUM: ssl: convert diag to warning for strict-sni + default-crt
    - DOC: configuration: clarify 'default-crt' and implicit default certificates
    - MINOR: quic: remove ->offset qf_crypto struct field
    - BUG/MINOR: mux-quic: trace with non initialized qcc
    - BUG/MINOR: acl: set arg_list->kw to aclkw->kw string literal if aclkw is found
    - BUG/MEDIUM: mworker: fix startup and reload on macOS
    - BUG/MINOR: connection: rearrange union list members
    - BUG/MINOR: connection: remove extra session_unown_conn() on reverse
    - MINOR: cli: display failure reason on wait command
    - BUG/MINOR: server: decrement session idle_conns on del server
    - BUG/MINOR: mux-quic: do not access conn after idle list insert
    - MINOR: session: document explicitely that session_add_conn() is safe
    - MINOR: session: uninline functions related to BE conns management
    - MINOR: session: refactor alloc/lookup of sess_conns elements
    - MEDIUM: session: protect sess conns list by idle_conns_lock
    - MINOR: server: shard by thread sess_conns member
    - MEDIUM: server: close new idle conns if server in maintenance
    - MEDIUM: session: close new idle conns if server in maintenance
    - MINOR: server: cleanup idle conns for server in maint already stopped
    - MINOR: muxes: enforce thread-safety for private idle conns
    - MEDIUM: conn/muxes/ssl: reinsert BE priv conn into sess on IO completion
    - MEDIUM: conn/muxes/ssl: remove BE priv idle conn from sess on IO
    - MEDIUM: mux-quic: enforce thread-safety of backend idle conns
    - MAJOR: server: implement purging of private idle connections
    - MEDIUM: session: account on server idle conns attached to session
    - MAJOR: server: do not remove idle conns in del server
    - BUILD: mworker: fix ignoring return value of ‘read’
    - DOC: unreliable sockpair@ on macOS
    - MINOR: muxes: adjust takeover with buf_wait interaction
    - OPTIM: backend: set release on takeover for strict maxconn
    - DOC: configuration: confuse "strict-mode" with "zero-warning"
    - MINOR: doc: add missing statistics column
    - MINOR: doc: add missing statistics column
    - MINOR: stats: display new curr_sess_idle_conns server counter
    - MINOR: proxy: extend "show servers conn" output
    - MEDIUM: proxy: Reject some header names for 'http-send-name-header' directive
    - BUG/BUILD: stats: fix build due to missing stat enum definition
    - DOC: proxy-protocol: Make example for PP2_SUBTYPE_SSL_SIG_ALG accurate
    - CLEANUP: quic: remove a useless CRYPTO frame variable assignment
    - BUG/MEDIUM: quic: CRYPTO frame freeing without eb_delete()
    - BUG/MAJOR: mux-quic: fix crash on reload during emission
    - MINOR: conn/muxes/ssl: add ASSUME_NONNULL() prior to _srv_add_idle
    - REG-TESTS: map_redirect: Don't use hdr_dom in ACLs with "-m end" matching method
    - MINOR: acl: Only allow one '-m' matching method
    - MINOR: acl; Warn when matching method based on a suffix is overwritten
    - BUG/MEDIUM: server: Duplicate healthcheck's alpn inherited from default server
    - BUG/MINOR: server: Duplicate healthcheck's sni inherited from default server
    - BUG/MINOR: acl: Properly detect overwritten matching method
    - BUG/MINOR: halog: Add OOM checks for calloc() in filter_count_srv_status() and filter_count_url()
    - BUG/MINOR: log: Add OOM checks for calloc() and malloc() in logformat parser and dup_logger()
    - BUG/MINOR: acl: Add OOM check for calloc() in smp_fetch_acl_parse()
    - BUG/MINOR: cfgparse: Add OOM check for calloc() in cfg_parse_listen()
    - BUG/MINOR: compression: Add OOM check for calloc() in parse_compression_options()
    - BUG/MINOR: tools: Add OOM check for malloc() in indent_msg()
    - BUG/MINOR: quic: ignore AGAIN ncbuf err when parsing CRYPTO frames
    - MINOR: quic/flags: complete missing flags
    - BUG/MINOR: quic: fix room check if padding requested
    - BUG/MINOR: quic: fix padding issue on INITIAL retransmit
    - BUG/MINOR: quic: pad Initial pkt with CONNECTION_CLOSE on client
    - MEDIUM: quic: strengthen BUG_ON() for unpad Initial packet on client
    - DOC: configuration: rework the jwt_verify keyword documentation
    - BUG/MINOR: haproxy: be sure not to quit too early on soft stop
    - BUILD: acl: silence a possible null deref warning in parse_acl_expr()
    - MINOR: quic: Add more information about RX packets
    - CI: fix syntax of Quic Interop pipelines
    - MEDIUM: cfgparse: warn when using user/group when built statically
    - BUG/MEDIUM: stick-tables: don't leave the expire loop with elements deleted
    - BUG/MINOR: stick-tables: never leave used entries without expiration
    - BUG/MEDIUM: peers: don't fail twice to grab the update lock
    - MINOR: stick-tables: limit the number of visited nodes during expiration
    - OPTIM: stick-tables: exit expiry faster when the update lock is held
    - MINOR: counters: retrieve detailed errmsg upon failure with counters_{fe,be}_shared_prepare()
    - MINOR: stats-file: introduce shm-stats-file directive
    - MEDIUM: stats-file: processes share the same clock source from shm-stats-file
    - MINOR: stats-file: add process slot management for shm stats file
    - MEDIUM: stats-file/counters: store and preload stats counters as shm file objects
    - DOC: config: document "shm-stats-file" directive
    - OPTIM: stats-file: don't unnecessarily die hard on shm_stats_file_reuse_object()
    - MINOR: compiler: add ALWAYS_PAD() macro
    - BUILD: stats-file: fix aligment issues
    - MINOR: stats-file: reserve some bytes in exported structs
    - MEDIUM: stats-file: add some BUG_ON() guards to ensure exported structs are not changed by accident
    - BUG/MINOR: check: ensure check-reuse is compatible with SSL
    - BUG/MINOR: check: fix dst address when reusing a connection
    - REGTESTS: explicitly use "balance roundrobin" where RR is needed
    - MAJOR: backend: switch the default balancing algo to "random"
    - BUG/MEDIUM: conn: fix UAF on connection after reversal on edge
    - BUG/MINOR: connection: streamline conn detach from lists
    - BUG/MEDIUM: quic-be: too early SSL_SESSION initialization
    - BUG/MINOR: log: fix potential memory leak upon error in add_to_logformat_list()
    - MEDIUM: init: always warn when running as root without being asked to
    - MINOR: sample: Add base2 converter
    - MINOR: version: add -vq, -vqb, and -vqs flags for concise version output
    - BUILD: trace: silence a bogus build warning at -Og
    - MINOR: trace: accept trace spec right after "-dt" on the command line
    - BUILD: makefile: bump the default minimum linux version to 4.17
v3.3-dev8
2025-09-05 09:54:34 +02:00
Willy Tarreau
85ac6a6f7b BUILD: makefile: bump the default minimum linux version to 4.17
As explained during the 3.3-dev7 announcement below:
  https://www.mail-archive.com/haproxy@formilux.org/msg46073.html

no regularly maintained distro supports a kernel older than 4.18 anymore,
and KTLS is supported since 4.17. So it's about the right moment to bump
the default minimum kernel version supported by glibc and musl to
automatically cover new features. The linux-glibc-legacy target still
supports 2.6.28 and above.
2025-09-05 09:44:56 +02:00
Willy Tarreau
670dc299d3 MINOR: trace: accept trace spec right after "-dt" on the command line
I continue to mistakenly set the traces using "-dtXXX" and to have to
refer to the doc to figure that it requires a separate argument and
differs from some other options. Worse, "-dthelp" doesn't say anything
and silently ignores the argument.

Let's make the parser take whatever follows "-dt" as the argument if
present, otherwise take the next one (as it currently does). Doing
this even allows to simplify the code, and is easier to figure the
syntax since "-dthelp" now works.
2025-09-05 09:33:28 +02:00
Willy Tarreau
abfd6f3b93 BUILD: trace: silence a bogus build warning at -Og
gcc-13.3 at -Og emits an incorrect build warning in trace.c about a
possibly initialized variable:

  In file included from include/haproxy/api.h:35,
                   from src/trace.c:22:
  src/trace.c: In function 'trace_parse_cmd':
  include/haproxy/bug.h:431:17: warning: 'arg' may be used uninitialized [-Wmaybe-uninitialized]
    431 |                 free(*__x);                                             \
        |                 ^~~~~~~~~~
  src/trace.c:1136:9: note: in expansion of macro 'ha_free'
   1136 |         ha_free(&oarg);
        |         ^~~~~~~
  src/trace.c:1008:15: note: 'arg' was declared here
   1008 |         char *arg, *oarg;
        |               ^~~

The warning is obviously wrong since the field is initialized in one of
the two branches of an "if" whose complementary one returns. But the
compiler doesn't seem to see this because the if is in fact two ifs each
with an opposite condition: "if (arg_src)" then "if (!arg_src)". Let's
just move upwards the default one that returns and eliminate the other
one. Reading the diff with "git diff -b" better shows the tiny change.

It could be backported to 3.0.
2025-09-05 09:19:24 +02:00
Nikita Kurashkin
ef73fe2584 MINOR: version: add -vq, -vqb, and -vqs flags for concise version output
This patch introduces three new command line flags to display HAProxy version
info more flexibly:

- `-vqs` outputs the short version string without commit info (e.g., "3.3.1").
- `-vqb` outputs only the branch (major.minor) part of the version (e.g., "3.3").
- `-vq` outputs the full version string with suffixes (e.g., "3.3.1-dev5-1bb975-71").

This allows easier parsing of version info in automation while keeping existing -v and -vv behaviors.

The command line argument parsing now calls `display_version_plain()` with a
display_mode parameter to select the desired output format. The function handles
stripping of commit or patch info as needed, depending on the mode.

Signed-off-by: Nikita Kurashkin <nkurashkin@stsoft.ru>
2025-09-05 08:57:57 +02:00