]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 months agoMEDIUM: tasks: Mutualize the TASK_KILLED code between tasks and tasklets
Olivier Houchard [Tue, 29 Apr 2025 13:46:20 +0000 (15:46 +0200)] 
MEDIUM: tasks: Mutualize the TASK_KILLED code between tasks and tasklets

The code to handle a task/tasklet when it's been killed before it were
to run is mostly identical, so move it outside of task and tasklet
specific code, and inside the common code.

This commit is just cosmetic, and should have no impact.

2 months agoMINOR: tasks: Remove unused tasklet_remove_from_tasklet_list
Olivier Houchard [Tue, 29 Apr 2025 13:25:53 +0000 (15:25 +0200)] 
MINOR: tasks: Remove unused tasklet_remove_from_tasklet_list

Remove tasklet_remove_from_tasklet_list, as the function hasn't been
used for a long time, and there is little reason to keep it.

2 months agoMEDIUM: tasks: Remove TASK_IN_LIST and use TASK_QUEUED instead.
Olivier Houchard [Tue, 29 Apr 2025 13:24:54 +0000 (15:24 +0200)] 
MEDIUM: tasks: Remove TASK_IN_LIST and use TASK_QUEUED instead.

TASK_QUEUED was used to mean "the task has been scheduled to run",
TASK_IN_LIST was used to mean "the tasklet has been scheduled to run",
remove TASK_IN_LIST and just use TASK_QUEUED for tasklets instead.

This commit is just cosmetic, and should not have any impact.

2 months agoMEDIUM: tasks: More code factorization
Olivier Houchard [Tue, 29 Apr 2025 13:15:27 +0000 (15:15 +0200)] 
MEDIUM: tasks: More code factorization

There is some code that should run no matter if the task was killed or
not, and was needlessly duplicated, so only use one instance.
This also fixes a small bug when a tasklet that got killed before it
could run would still count as a tasklet that ran, when it should not,
which just means that we'd run one less useful task before going back to
the poller.
This commit is mostly cosmetic, and should not have any impact.

2 months agoMEDIUM: tasks: Mutualize code between tasks and tasklets.
Olivier Houchard [Tue, 29 Apr 2025 13:15:01 +0000 (15:15 +0200)] 
MEDIUM: tasks: Mutualize code between tasks and tasklets.

The code that checks if we're currently running, and waits if so, was
identical between tasks and tasklets, so move it in code common to tasks
and tasklets.
This commit is just cosmetic, and should not have any impact.

2 months agoMINOR: acme: use acme_ctx_destroy() upon error
William Lallemand [Wed, 30 Apr 2025 15:18:46 +0000 (17:18 +0200)] 
MINOR: acme: use acme_ctx_destroy() upon error

Use acme_ctx_destroy() instead of a simple free() upon error in the
"acme renew" error handling.

It's better to use this function to be sure than everything has been
been freed.

2 months agoMINOR: acme: acme_ctx_destroy() returns upon NULL
William Lallemand [Wed, 30 Apr 2025 15:17:58 +0000 (17:17 +0200)] 
MINOR: acme: acme_ctx_destroy() returns upon NULL

acme_ctx_destroy() returns when its argument is NULL.

2 months agoMINOR: ssl/cli: "acme ps" shows the acme tasks
William Lallemand [Wed, 30 Apr 2025 13:49:53 +0000 (15:49 +0200)] 
MINOR: ssl/cli: "acme ps" shows the acme tasks

Implement a way to display the running acme tasks over the CLI.

It currently only displays a "Running" status with the certificate name
and the acme section from the configuration.

The displayed running tasks are limited to the size of a buffer for now,
it will require a backref list later to be called multiple times to
resume the list.

2 months agoDOC: config: restore default values for resolvers hold directive
Aurelien DARRAGON [Wed, 30 Apr 2025 14:56:00 +0000 (16:56 +0200)] 
DOC: config: restore default values for resolvers hold directive

Default values for hold directive (resolver context) used to be documented
but this was lost when the keyword description was reworked in 24b319b
("Default value is 10s for "valid", 0s for "obsolete" and 30s for
others.")

Restoring the part that describes the default value.

It may be backported to all stable versions with 24b319b

2 months agoMINOR: hlua_fcn: enforce yield after *_get_stats() methods
Aurelien DARRAGON [Wed, 30 Apr 2025 14:41:16 +0000 (16:41 +0200)] 
MINOR: hlua_fcn: enforce yield after *_get_stats() methods

{listener,proxy,server}_get_stats() methods are know to be expensive,
expecially if used under an iteration. Indeed, while automatic yield
is performed every X lua instructions (defaults to 10k), computing an
object's stats 10K times in a single cpu loop is not desirable and
could create contention.

In this patch we leverage hlua_yield_asap() at the end of *_get_stats()
methods in order to force the automatic yield to occur ASAP after the
method returns. Hopefully this should help in similar scenarios as the
one described in GH #2903

2 months agoMINOR: add hlua_yield_asap() helper
Aurelien DARRAGON [Wed, 30 Apr 2025 14:37:56 +0000 (16:37 +0200)] 
MINOR: add hlua_yield_asap() helper

When called, this function will try to enforce a yield (if available) as
soon as possible. Indeed, automatic yield is already enforced every X
Lua instructions. However, there may be some cases where we know after
running heavy operation that we should yield already to avoid taking too
much CPU at once.

This is what this function offers, instead of asking the user to manually
yield using "core.yield()" from Lua itself after using an expensive
Lua method offered by haproxy, we can directly enforce the yield without
the need to do it in the Lua script.

2 months agoMINOR: mux-quic: limit emitted MSD frames count per qcs
Amaury Denoyelle [Mon, 28 Apr 2025 13:36:44 +0000 (15:36 +0200)] 
MINOR: mux-quic: limit emitted MSD frames count per qcs

The previous commit has implemented a new calcul method for
MAX_STREAM_DATA frame emission. Now, a frame may be emitted as soon as a
buffer was consumed by a QCS instance.

This will probably increase the number of MAX_STREAM_DATA frame
emission. It may even cause a series of frame emitted for the same
stream with increasing values under high load, which is completely
unnecessary.

To improve this, limit the number of MAX_STREAM_DATA frames built to one
per QCS instance. This is implemented by storing a reference to this
frame in QCS structure via a new member <tx.msd_frm>.

Note that to properly reset QCS msd_frm member, emission of flow-control
frames have been changed. Now, each frame is emitted individually. On
one side, it is better as it prevent to emit frames related to different
streams in a single datagram, which is not desirable in case of packet
loss. However, this can also increase sendto() syscall invocation.

2 months agoMEDIUM: mux-quic: increase flow-control on each bufsize
Amaury Denoyelle [Wed, 19 Mar 2025 15:09:08 +0000 (16:09 +0100)] 
MEDIUM: mux-quic: increase flow-control on each bufsize

Recently, QCS Rx allocation buffer method has been improved. It is now
possible to allocate multiple buffers per QCS instances, which was
necessary to improve HTTP/3 POST throughput.

However, a limitation remained related to the emission of
MAX_STREAM_DATA. These frames are only emitted once at least half of the
receive capacity has been consumed by its QCS instance. This may be too
restrictive when a client need to upload a large payload.

Improve this by adjusting MAX_STREAM_DATA allocation. If QCS capacity is
still limited to 1 or 2 buffers max, the old calcul is still used. This
is necessary when user has limited upload throughput via their
configuration. If QCS capacity is more than 2 buffers, a new frame is
emitted if at least a buffer was consumed.

This patch has reduced number of STREAM_DATA_BLOCKED frames received in
POST tests with some specific clients.

2 months agoBUG/MINOR: mux-spop: Use the right bitwise operator in spop_ctl()
Christopher Faulet [Wed, 30 Apr 2025 13:58:53 +0000 (15:58 +0200)] 
BUG/MINOR: mux-spop: Use the right bitwise operator in spop_ctl()

Becaues of a typo, '||' was used instead of '|' to test the SPOP conneciton
flags and decide if the mux is ready or not. The regression was introduced
in the commit fd7ebf117 ("BUG/MEDIUM: mux-spop: Wait end of handshake to
declare a spop connection ready").

This patch must be backported to 3.1 with the commit above.

2 months agoBUILD: ssl: Fix wolfssl build
Remi Tricot-Le Breton [Wed, 30 Apr 2025 13:26:30 +0000 (15:26 +0200)] 
BUILD: ssl: Fix wolfssl build

The newly added SSL traces require an extra 'conn' parameter to
ssl_sock_chose_sni_ctx which was added in the "regular" code but not in
the wolfssl specific one.
Wolfssl also has a different prototype for some getter functions
(SSL_get_servername for instance), which do not expect a const SSL while
openssl version does.

2 months agoBUG/MINOR: mux-h1: Fix trace message in h1_detroy() to not relay on connection
Christopher Faulet [Wed, 30 Apr 2025 12:32:16 +0000 (14:32 +0200)] 
BUG/MINOR: mux-h1: Fix trace message in h1_detroy() to not relay on connection

h1_destroy() may be called to release a H1C after a multiplexer upgrade. In
that case, the connection is no longer attached to the H1C. It must not be
used in the h1 trace message because the connection context is no longer a H1C.

Because of this bug, when a H1>H2 upgrade is performed, a crash may be
experienced if the H1 traces are enabled.

This patch must be backport to all stable versions.

2 months agoBUG/MINOR: mux-h1: Don't pretend connection was released for TCP>H1>H2 upgrade
Christopher Faulet [Wed, 30 Apr 2025 12:16:42 +0000 (14:16 +0200)] 
BUG/MINOR: mux-h1: Don't pretend connection was released for TCP>H1>H2 upgrade

When an applicative upgrade of the H1 multiplexer is performed, we must not
pretend the connection was released.  Indeed, in that case, a H1 stream is
still their with a stream connector attached on it. It must be detached
first before releasing the H1 connection and the underlying connection. So
it is important to not pretend the connection was already released.

Concretely, in that case h1_process() must return 0 instead of -1. It is
minor error because, AFAIK, it is harmless. But it is not correct. So let's
fix it to avoid futur bugs.

To be clear, this happens when a TCP connection is upgraded to H1 connection
and a H2 preface is detected, leading to a second upgrade from H1 to H2.

This patch may be backport to all stable versions.

2 months agoBUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame
Christopher Faulet [Mon, 28 Apr 2025 06:08:06 +0000 (08:08 +0200)] 
BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame

In the SPOE specification, when an error occurred on the SPOP connection,
HAProxy must send a DISCONNECT frame and wait for the agent DISCONNECT frame
in return before trully closing the connection.

However, this part was not properly handled by the SPOP multiplexer. In this
case, the SPOP connection should be in the CLOSING state. But this state was
not used at all. Depending on when the error was encountered, the connection
could be closed immediately, without sending any DISCONNECT frame. It was
the case when an early error was detected during the AGENT-HELLO frame
parsing. Or it could be moved from ERROR to FRAME_H state, as if no error
were detected. This case was less dramatic than it seemed because some flags
were also set to prevent any problem. But it was not obvious.

So now, the SPOP connection is properly switch to CLOSING state when an
DISCONNECT is sent to the agent to be able to wait for its DISCONNECT in
reply. spop_process_demux() was updated to parse frames in that state and
some validity checks was added.

This patch must be backport to 3.1.

2 months agoBUG/MEDIUM: mux-spop: Wait end of handshake to declare a spop connection ready
Christopher Faulet [Mon, 28 Apr 2025 06:01:40 +0000 (08:01 +0200)] 
BUG/MEDIUM: mux-spop: Wait end of handshake to declare a spop connection ready

A SPOP connection must not be considered as ready while the hello handshake
is not finished with success. In addition, no error or shutdown must have
been reported for the underlying connection. Otherwise a freshly openned
spop connexion may be reused while it is in fact dead, leading to a
connection retry.

This patch must be backported to 3.1.

2 months agoMINOR: Add 'conn' param to ssl_sock_chose_sni_ctx
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:58 +0000 (17:26 +0200)] 
MINOR: Add 'conn' param to ssl_sock_chose_sni_ctx

This is only useful in the traces, the conn parameter won't be used
otherwise.

2 months agoMINOR: ssl: Add traces about sigalg extension parsing in clientHello callback
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:57 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces about sigalg extension parsing in clientHello callback

We had to parse the sigAlg extension by hand in order to properly select
the certificate used by the SSL frontends. These traces allow to dump
the allowed sigAlg list sent by the client in its clientHello.

2 months agoMINOR: ssl: Add traces to the switchctx callback
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:56 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces to the switchctx callback

This callback allows to pick the used certificate on an SSL frontend.
The certificate selection is made according to the information sent by
the client in the clientHello. The traces that were added will allow to
better understand what certificate was chosen and why. It will also warn
us if the chosen certificate was the default one.
The actual certificate parsing happens in ssl_sock_chose_sni_ctx. It's
in this function that we actually get the filename of the certificate
used.

2 months agoMINOR: ssl: Add ocsp stapling callback traces
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:55 +0000 (17:26 +0200)] 
MINOR: ssl: Add ocsp stapling callback traces

If OCSP stapling fails because of a missing or invalid OCSP response we
used to silently disable stapling for the given session. We can now know
a bit more what happened regarding OCSP stapling.

2 months agoMINOR: ssl: Add traces to verify callback
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:54 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces to verify callback

Those traces allow to know which errors were met during certificate
chain validation as well as which ones were ignored.

2 months agoMINOR: ssl: Add traces around SSL_do_handshake call
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:53 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces around SSL_do_handshake call

Those traces dump information about the multiple SSL_do_handshake calls
(renegotiation and regular call). Some errors coud also be dumped in
case of rejected early data.
Depending on the chosen verbosity, some information about the current
handshake can be dumped as well (servername, tls version, chosen cipher
for instance).
In case of failed handshake, the error codes and messages will also be
dumped in the log to ease debugging.

2 months agoMINOR: ssl: Add traces to ssl_sock_io_cb function
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:52 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces to ssl_sock_io_cb function

Add new SSL traces.

2 months agoMINOR: ssl: Add traces to recv/send functions
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:51 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces to recv/send functions

Those traces will allow to identify sessions on which early data is used
as well as some forcefully closed connections.

2 months agoMINOR: ssl: Add traces to ssl init/close functions
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:50 +0000 (17:26 +0200)] 
MINOR: ssl: Add traces to ssl init/close functions

Add a dedicated trace for some unlikely allocation failures and async
errors. Those traces will ostly be used to identify the start and end of
a given SSL connection.

2 months agoMINOR: Add "sigalg" to "sigalg name" helper function
Remi Tricot-Le Breton [Fri, 18 Apr 2025 15:26:49 +0000 (17:26 +0200)] 
MINOR: Add "sigalg" to "sigalg name" helper function

This function can be used to convert a TLSv1.3 sigAlg entry (2bytes)
from the signature_agorithms client hello extension into a string.

In order to ease debugging, some TLSv1.2 combinations can also be
dumped. In TLSv1.2 those signature algorithms pairs were built out of a
one byte signature identifier combined to a one byte hash identifier.
In TLSv1.3 those identifiers are two bytes blocs that must be treated as
such.

2 months agoMINOR: tools: make my_strndup() take a size_t len instead of and int
Willy Tarreau [Wed, 30 Apr 2025 03:15:22 +0000 (05:15 +0200)] 
MINOR: tools: make my_strndup() take a size_t len instead of and int

In relation to issue #2954, it appears that turning some size_t length
calculations to the int that uses my_strndup() upsets coverity a bit.
Instead of dealing with such warnings each time, better address it at
the root. An inspection of all call places show that the size passed
there is always positive so we can safely use an unsigned type, and
size_t will always suit it like for strndup() where it's available.

2 months agoDOC: ring: refer to newer RFC5424
Lukas Tribus [Mon, 28 Apr 2025 12:07:31 +0000 (12:07 +0000)] 
DOC: ring: refer to newer RFC5424

In the ring configuration example we refer to RFC3164 - the original BSD
syslog protocol without support for structured data (SDATA).

Let's refer to RFC5424 instead so SDATA is by default forwarded if
someone copy & pastes from the documentation:

https://discourse.haproxy.org/t/structured-data-lost-when-forwarding-logs-voa-syslog-forwarding-feature/11741/5

Should be backported to 2.6.

2 months agoCLEANUP: proxy: mention that px->conn_retries isn't relevant in some cases
Aurelien DARRAGON [Mon, 28 Apr 2025 14:52:33 +0000 (16:52 +0200)] 
CLEANUP: proxy: mention that px->conn_retries isn't relevant in some cases

Since 91e785edc ("MINOR: stream: Rely on a per-stream max connection
retries value"), px->conn_retries may be ignored in the following cases:

 * proxy not part of a list which gets properly post-init (ie: main proxy
   list, log-forward list, sink list)
 * proxy lacking the CAP_FE capability

Documenting such cases where the px->conn_retries is set but effectively
ignored, so that we either remove ignored statements or fix them in
the future if they are really needed. In fact all cases affected here are
automomous applets that already handle the retries themselves so the fact
that 91e785edc made ->conn_retries ineffective should not be a big deal
anyway.

2 months agoBUG/MINOR: dns: prevent ds accumulation within dss
Aurelien DARRAGON [Tue, 29 Apr 2025 08:22:38 +0000 (10:22 +0200)] 
BUG/MINOR: dns: prevent ds accumulation within dss

when dns session callback (dns_session_release()) is called upon error
(ie: when some pending queries were not sent), we try our best to
re-create the applet in order to preserve the pending queries and give
them a chance to be retried. This is done at the end of
dns_session_release().

However, doing so exposes to an issue: if the error preventing queries
from being sent is still encountered over and over the dns session could
stay there indefinitely. Meanwhile, other dns sessions may be created on
the same dns_stream_server periodically. If previous failing dns sessions
don't terminate but we also keep creating new ones, we end up accumulating
failing sessions on a given dns_stream_server, which can eventually cause
ressource shortage.

This issue was found when trying to address ("BUG/MINOR: dns: add tempo
between 2 connection attempts for dns servers")

To fix it, we track the number of failed consecutive sessions for a given
dns server. When we reach the threshold (set to 100), we consider that the
link to the dns server is broken (at least temporarily) and we force
dns_session_new() to fail, so that we stop creating new sessions until one
of the existing one eventually succeeds.

A workaround for this fix consists in setting the "maxconn" parameter on
nameserver directive (under resolvers section) to a reasonnable value so
that no more than "maxconn" sessions may co-exist on the same server at
a given time.

This may be backported to all stable versions.
("CLEANUP: dns: remove unused dns_stream_server struct member") may be
backported to ease the backport.

2 months agoCLEANUP: dns: remove unused dns_stream_server struct member
Aurelien DARRAGON [Tue, 29 Apr 2025 14:48:28 +0000 (16:48 +0200)] 
CLEANUP: dns: remove unused dns_stream_server struct member

dns_stream_server "max_slots" is unused, let's get rid of it

2 months agoBUG/MINOR: dns: add tempo between 2 connection attempts for dns servers
Aurelien DARRAGON [Tue, 29 Apr 2025 18:13:00 +0000 (20:13 +0200)] 
BUG/MINOR: dns: add tempo between 2 connection attempts for dns servers

As reported by Lukas Tribus on the mailing list [1], trying to connect to
a nameserver with invalid network settings causes haproxy to retry a new
connection attempt immediately which eventually causes unexpected CPU usage
on the thread responsible for the applet (namely 100% on one CPU will be
observed).

This can be reproduced with the test config below:

 resolvers default
  nameserver ns1 tcp4@8.8.8.8:53 source 192.168.99.99
 listen listen
  mode http
  bind :8080
  server s1 www.google.com resolvers default init-addr none

To fix this the issue, we add a temporisation of one second between a new
connection attempt is retried. We do this in dns_session_create() when we
know that the applet was created in the release callback (when previous
query attempt was unsuccessful), which means initial connection is not
affected.

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

This should fix GH #2909 and may be backported to all stable versions.
This patch depends on ("MINOR: applet: add appctx_schedule() macro")

2 months agoMINOR: applet: add appctx_schedule() macro
Aurelien DARRAGON [Mon, 28 Apr 2025 16:03:36 +0000 (18:03 +0200)] 
MINOR: applet: add appctx_schedule() macro

Just like task_schedule() but for applets to wakeup an applet at a
specific time, leverages _task_schedule() internally

2 months agoBUG/MINOR: acme: remove references to virt@acme
William Lallemand [Tue, 29 Apr 2025 14:35:35 +0000 (16:35 +0200)] 
BUG/MINOR: acme: remove references to virt@acme

"virt@acme" was the default map used during development, now this must
be configured in the acme section or it won't try to use any map.

This patch removes the references to virt@acme in the comments and the
code.

2 months agoMEDIUM: acme: use a map to store tokens and thumbprints
William Lallemand [Tue, 29 Apr 2025 14:08:31 +0000 (16:08 +0200)] 
MEDIUM: acme: use a map to store tokens and thumbprints

The stateless mode which was documented previously in the ACME example
is not convenient for all use cases.

First, when HAProxy generates the account key itself, you wouldn't be
able to put the thumbprint in the configuration, so you will have to get
the thumbprint and then reload.
Second, in the case you are using multiple account key, there are
multiple thumbprint, and it's not easy to know which one you want to use
when responding to the challenger.

This patch allows to configure a map in the acme section, which will be
filled by the acme task with the token corresponding to the challenge,
as the key, and the thumbprint as the value. This way it's easy to reply
the right thumbprint.

Example:
    http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].%[path,field(-1,/),map(virt@acme)]\n" if { path_beg '/.well-known/acme-challenge/' }

2 months agoMEDIUM: quic: limit global Tx memory
Amaury Denoyelle [Tue, 29 Apr 2025 09:39:42 +0000 (11:39 +0200)] 
MEDIUM: quic: limit global Tx memory

Define a new settings tune.quic.frontend.max-tot-window. It contains a
size argument which can be used to set a limit on the sum of all QUIC
connections congestion window. This is applied both on
quic_cc_path_set() and quic_cc_path_inc().

Note that this limitation cannot reduce a congestion window more than
the minimal limit which is set to 2 datagrams.

2 months agoMINOR: quic: account for global congestion window
Amaury Denoyelle [Mon, 28 Apr 2025 06:52:43 +0000 (08:52 +0200)] 
MINOR: quic: account for global congestion window

Use the newly defined cshared type to account for the sum of congestion
window of every QUIC connection. This value is stored in global counter
quic_mem_global defined in proto_quic module.

2 months agoMINOR: thread: define cshared type
Amaury Denoyelle [Fri, 25 Apr 2025 09:37:07 +0000 (11:37 +0200)] 
MINOR: thread: define cshared type

Define a new type "struct cshared". This can be used as a tool to
manipulate a global counter with thread-safety ensured. Each thread
would declare its thread-local cshared type, which would point to a
global counter.

Each thread can then add/substract value to their owned thread-local
cshared instance via cshared_add(). If the difference exceed a
configured limit, either positively or negatively, the global counter is
updated and thread-local instance is reset to 0. Each thread can safely
read the global counter value using cshared_read().

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

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

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

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

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

2 months agoMINOR: quic: refactor BBR API
Amaury Denoyelle [Mon, 28 Apr 2025 07:22:37 +0000 (09:22 +0200)] 
MINOR: quic: refactor BBR API

Write minor adjustments to QUIC BBR functions. The objective is to
centralize every modification of path cwnd field.

No functional change. This patch will be useful to simplify
implementation of global QUIC Tx memory usage limitation.

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

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

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

This should be backported up to 3.1.

2 months agoBUG/MINOR: acme: creating an account should not end the task
William Lallemand [Tue, 29 Apr 2025 12:09:46 +0000 (14:09 +0200)] 
BUG/MINOR: acme: creating an account should not end the task

The account creation was mistakenly ending the task instead of being
wakeup for the NewOrder state, it was preventing the creation of the
certificate, however the account was correctly created.

To fix this, only the jump to the end label need to be remove, the
standard leaving codepath of the function will allow to be wakeup.

No backport needed.

2 months agoMINOR: tcp: add support for setting TCP_NOTSENT_LOWAT on both sides
Willy Tarreau [Tue, 29 Apr 2025 09:43:46 +0000 (11:43 +0200)] 
MINOR: tcp: add support for setting TCP_NOTSENT_LOWAT on both sides

TCP_NOTSENT_LOWAT is very convenient as it indicates when to report
EAGAIN on the sending side. It takes a margin on top of the estimated
window, meaning that it's no longer needed to store too many data in
socket buffers. Instead there's just enough to fill the send window
and a little bit of margin to cover the scheduling time to restart
sending. Experiments on a 100ms network have shown a 10-fold reduction
in the memory used by socket buffers by just setting this value to
tune.bufsize, without noticing any performance degradation. Theoretically
the responsiveness on multiplexed protocols such as H2 should also be
improved.

2 months agoBUG/MINOR: mux-h2: fix the offset of the pattern for the ping frame
Willy Tarreau [Tue, 29 Apr 2025 10:05:08 +0000 (12:05 +0200)] 
BUG/MINOR: mux-h2: fix the offset of the pattern for the ping frame

The ping frame's pattern must be written at offset 9 (frame header
length), not 8. This was added in 3.2 with commit 4dcfe098a6 ("MINOR:
mux-h2: prepare to support PING emission"), so no backport is needed.

2 months agoBUG/MINOR: acme: does not try to unlock after a failed trylock
William Lallemand [Tue, 29 Apr 2025 09:29:52 +0000 (11:29 +0200)] 
BUG/MINOR: acme: does not try to unlock after a failed trylock

Return after a failed trylock in acme_update_certificate() instead of
jumping to the error label which does an unlock.

2 months agoDOC: configuration: add quic4 to the ssl-f-use example
William Lallemand [Tue, 29 Apr 2025 08:50:39 +0000 (10:50 +0200)] 
DOC: configuration: add quic4 to the ssl-f-use example

The ssl-f-use keyword is very useful in the case of multiple SSL bind
lines. Add a quic4 bind line in the example to show that.

2 months agoCLEANUP: acme: remove old TODO for account key
William Lallemand [Tue, 29 Apr 2025 07:59:32 +0000 (09:59 +0200)] 
CLEANUP: acme: remove old TODO for account key

Remove old TODO comments about the account key.

2 months agoDOC: configuration: acme account key are auto generated
William Lallemand [Tue, 29 Apr 2025 07:27:45 +0000 (09:27 +0200)] 
DOC: configuration: acme account key are auto generated

Explain that account key are auto generated when they do not exist.

2 months agoMEDIUM: mcli: replicate the current mode when enterin the worker process
Willy Tarreau [Mon, 28 Apr 2025 17:09:02 +0000 (19:09 +0200)] 
MEDIUM: mcli: replicate the current mode when enterin the worker process

While humans can find it convenient to enter the worker process in prompt
mode, for external tools it will not be convenient to have to systematically
disable it. A better approach is to replicate the master socket's mode
there, since it has already been configured to suit the user: interactive,
prompt and timed modes are automatically passed to the worker process.
This makes the using the worker commands more natural from the master
process, without having to systematically adapt it for each new connection.

2 months agoMEDIUM: mcli: make the prompt mode configurable between i/p
Willy Tarreau [Mon, 28 Apr 2025 16:51:47 +0000 (18:51 +0200)] 
MEDIUM: mcli: make the prompt mode configurable between i/p

Support the same syntax in master mode as in worker mode in order to
configure the prompt. The only thing is that for now the master doesn't
have a non-interactive mode and it doesn't seem necessary to implement
it, so we only support the interactive and prompt modes. However the code
was written in a way that makes it easy to change this later if desired.

2 months agoMEDIUM: cli: make the prompt mode configurable between n/i/p
Willy Tarreau [Mon, 28 Apr 2025 16:36:57 +0000 (18:36 +0200)] 
MEDIUM: cli: make the prompt mode configurable between n/i/p

Now the prompt mode can more finely be configured between non-interactive
(default), interactive without prompt, and interactive with prompt. This
will ease the usage from automated tools which are not necessarily
interested in having to consume '> ' after each command nor displaying
"+" on payload lines. This can also be convenient when coming from the
master CLI to keep the same output format.

2 months agoMINOR: cli: split APPCTX_CLI_ST1_PROMPT into two distinct flags
Willy Tarreau [Mon, 28 Apr 2025 15:42:03 +0000 (17:42 +0200)] 
MINOR: cli: split APPCTX_CLI_ST1_PROMPT into two distinct flags

The CLI's "prompt" command toggles two distinct things:
  - displaying or hiding the prompt at the beginning of the line
  - single-command vs interactive mode

These are two independent concepts and the prompt mode doesn't
always cope well with tools that would like to upload data without
having to read the prompt on return. Also, the master command line
works in interactive mode by default with no prompt, which is not
consistent (and not convenient for tools). So let's start by splitting
the bit in two, and have a new APPCTX_CLI_ST1_INTER flag dedicated
to the interactive mode. For now the "prompt" command alone continues
to toggle the two at once.

2 months agoMINOR: compiler: add more macros to detect macro definitions
Willy Tarreau [Mon, 28 Apr 2025 06:56:56 +0000 (08:56 +0200)] 
MINOR: compiler: add more macros to detect macro definitions

We add __equals_0(NAME) which is only true if NAME is defined as zero,
and __def_as_empty(NAME) which is only true if NAME is defined as an
empty string.

2 months agoMEDIUM: acme: use 'crt-base' to load the account key
William Lallemand [Mon, 28 Apr 2025 15:52:28 +0000 (17:52 +0200)] 
MEDIUM: acme: use 'crt-base' to load the account key

Prefix the filename with the 'crt-base' before loading the account key,
in order to work like every other keypair in haproxy.

2 months agoMEDIUM: acme: generate the account file when not found
William Lallemand [Mon, 28 Apr 2025 15:40:26 +0000 (17:40 +0200)] 
MEDIUM: acme: generate the account file when not found

Generate the private key on the account file when the file does not
exists. This generate a private key of the type and parameters
configured in the acme section.

2 months agoMINOR: acme: failure when no directory is specified
William Lallemand [Mon, 28 Apr 2025 15:37:21 +0000 (17:37 +0200)] 
MINOR: acme: failure when no directory is specified

The "directory" parameter of the acme section is mandatory. This patch
exits with an alert when this parameter is not found.

2 months agoMINOR: acme: separate the code generating private keys
William Lallemand [Mon, 28 Apr 2025 14:27:45 +0000 (16:27 +0200)] 
MINOR: acme: separate the code generating private keys

acme_EVP_PKEY_gen() generates private keys of specified <keytype>,
<curves> and <bits>. Only RSA and EC are supported for now.

2 months agoBUG/MINOR: ssl/acme: free EVP_PKEY upon error
William Lallemand [Mon, 28 Apr 2025 14:33:48 +0000 (16:33 +0200)] 
BUG/MINOR: ssl/acme: free EVP_PKEY upon error

Free the EPV_PKEY upon error when the X509_REQ generation failed.

No backport needed.

2 months agoMEDIUM: thread: set DEBUG_THREAD to 1 by default
Willy Tarreau [Mon, 28 Apr 2025 13:57:26 +0000 (15:57 +0200)] 
MEDIUM: thread: set DEBUG_THREAD to 1 by default

Setting DEBUG_THREAD to 1 allows recording the lock history for each
thread. Tests have shown that (as predicted) the cost of updating a
single thread-local variable is not perceptible in the noise, especially
when compared to the cost of obtaining a lock. Since this can provide
useful value when debugging deadlocks, let's enable it by default when
threads are enabled.

2 months agoMINOR: threads/cli: display the lock history on "show threads"
Willy Tarreau [Mon, 28 Apr 2025 13:19:35 +0000 (15:19 +0200)] 
MINOR: threads/cli: display the lock history on "show threads"

This will display the lock labels and modes for each non-empty step
at the end of "show threads" when these are defined. This allows to
emit up to the last 8 locking operation for each thread on 64 bit
machines.

2 months agoMEDIUM: threads: keep history of taken locks with DEBUG_THREAD > 0
Willy Tarreau [Mon, 28 Apr 2025 07:42:58 +0000 (09:42 +0200)] 
MEDIUM: threads: keep history of taken locks with DEBUG_THREAD > 0

by only storing a word in each thread context, we can keep the history
of all taken/dropped locks by label. This is expected to be very cheap
and to permit to store up to 8 consecutive lock operations in 64 bits.
That should significantly help detect recursive locks as well as figure
what thread was likely to hinder another one waiting for a lock.

For now we only store the final state of the lock, we don't store the
attempt to get it. It's just a matter of space since we already need
4 ops (rd,sk,wr,un) which take 2 bits, leaving max 64 labels. We're
already around 45. We could also multiply by 5 and still keep 8 bits
total per lock, that would limit us to 51 locks max. It seems that
most of the time if we get a watchdog panic, anyway the victim thread
will be perfectly located so that we don't need a specific value for
this. Another benefit is that we perform a single memory write per
lock.

2 months agoMINOR: threads: turn the full lock debugging to DEBUG_THREAD=2
Willy Tarreau [Mon, 28 Apr 2025 07:05:02 +0000 (09:05 +0200)] 
MINOR: threads: turn the full lock debugging to DEBUG_THREAD=2

At level 1 it now does nothing. This is reserved for some subsequent
patches which will implement lighter debugging.

2 months agoMINOR: threads: prepare DEBUG_THREAD to receive more values
Willy Tarreau [Mon, 28 Apr 2025 07:00:00 +0000 (09:00 +0200)] 
MINOR: threads: prepare DEBUG_THREAD to receive more values

We now default the value to zero and make sure all tests properly take
care of values above zero. This is in preparation for supporting several
degrees of debugging.

2 months agoBUILD: leastconn: fix build warning when building without threads on old machines
Willy Tarreau [Mon, 28 Apr 2025 14:48:42 +0000 (16:48 +0200)] 
BUILD: leastconn: fix build warning when building without threads on old machines

Machines lacking CAS8B/DWCAS and emit a warning in lb_fwlc.c without
threads due to declaration ordering. Let's just move the variable
declaration into the block that uses it as a last variable. No
backport is needed.

2 months agoBUILD: acme: use my_strndup() instead of strndup()
Willy Tarreau [Mon, 28 Apr 2025 14:35:24 +0000 (16:35 +0200)] 
BUILD: acme: use my_strndup() instead of strndup()

Not all systems have strndup(), that's why we have our "my_strndup()",
so let's make use of it here. This fixes the build on Solaris 10. No
backport is needed.

2 months agoMINOR: promex: expose ST_I_PX_RATE (current_session_rate)
Aurelien DARRAGON [Mon, 28 Apr 2025 10:19:36 +0000 (12:19 +0200)] 
MINOR: promex: expose ST_I_PX_RATE (current_session_rate)

It has been requested to have the current_session_rate exposed at the
frontend level. For now only the per-process value was exposed
(ST_I_INF_SESS_RATE).

Thanks to the work done lately to merge promex and stat_cols_px[]
array, let's simply defined an .alt_name for the ST_I_PX_RATE metric in
order to have promex exposing it as current_session_rate for relevant
contexts.

2 months agoDOC: config: clarify log-forward "host" option
Aurelien DARRAGON [Mon, 28 Apr 2025 10:09:45 +0000 (12:09 +0200)] 
DOC: config: clarify log-forward "host" option

log-forward "host" option may be confusing because we often mention the
host field when talking about syslog RFC3164 or RFC5424 messages, but
neither rfc actually define "host" field. In fact, everywhere we used
"host field" we actually meant "hostname field" as documented in RFC5424.
This was a language abuse on our side.

In this patch we replace "host" with "hostname" where relevant in the
documentation to prevent confusion.

Thanks to Nick Ramirez for having reported the issue.

2 months agoDOC: config: fix ACME paragraph rendering issue
Aurelien DARRAGON [Mon, 28 Apr 2025 09:30:01 +0000 (11:30 +0200)] 
DOC: config: fix ACME paragraph rendering issue

Nick Ramirez reported that the ACME paragraph (3.13) caused a rendering
issue where simple text was rendered as a directive. This was caused
by the use of unescaped <name> which confuses dconv.

Let's escape <name> by putting quotes around it to prevent the rendering
issue.

No backport needed.

2 months agoMINOR: ssl/cli: add a '-t' option to 'show ssl sni'
William Lallemand [Mon, 28 Apr 2025 09:35:11 +0000 (11:35 +0200)] 
MINOR: ssl/cli: add a '-t' option to 'show ssl sni'

Add a -t option to 'show ssl sni', allowing to add an offset to the
current date so it would allow to check which certificates are expired
after a certain period of time.

2 months agoBUG/MAJOR: listeners: transfer connection accounting when switching listeners
Willy Tarreau [Fri, 25 Apr 2025 16:32:02 +0000 (18:32 +0200)] 
BUG/MAJOR: listeners: transfer connection accounting when switching listeners

Since we made it possible for a bind_conf to listen to multiple thread
groups with shards in 2.8 with commit 9d360604bd ("MEDIUM: listener:
rework thread assignment to consider all groups"), the per-listener
connection count was not properly transferred to the target listener
with the connection when switching to another thread group. This results
in one listener possibly reaching high values and another one possibly
reaching negative values. Usually it's not visible, unless a maxconn is
set on the bind_conf, in which case comparisons will quickly put an end
to the willingness to accept new connections.

This problem only happens when thread groups are enabled, and it seems
very hard to trigger it normally, it only impacts sockets having a single
shard, hence currently the CLI (or any conf with "bind ... shards 1"),
where it can be reproduced with a config having a very low "maxconn" on
the stats socket directive (here, 4), and issuing a few tens of
socat <<< "show activity" in parallel, or sending HTTP connections to a
single-shared listener. Very quickly, haproxy stops accepting connections
and eats CPU in the poller which tries to get its connections accepted.

A BUG_ON(l->nbconn<0) after HA_ATOMIC_DEC() in listener_release() also
helps spotting them better.

Many thanks to Christian Ruppert who once again provided a very accurate
report in GH #2951 with the required data permitting this analysis.

This fix must be backported to 2.8.

2 months agoBUG/MAJOR: tasklets: Make sure he tasklet can't run twice
Olivier Houchard [Fri, 25 Apr 2025 10:17:07 +0000 (12:17 +0200)] 
BUG/MAJOR: tasklets: Make sure he tasklet can't run twice

tasklets were originally designed to alway run on only one thread, so it
was not possible to have it run on 2 threads concurrently.
The API has been extended so that another thread may wake the tasklet,
the idea was still that we wanted to have it run on one thread only.
However, the way it's been done meant that unless a tasklet was bound to
a specific tid with tasklet_set_tid(), or we explicitely used
tasklet_wakeup_on() to specify the thread for the target to run on, it
would be scheduled to run on the current thread.
This is in fact a desirable feature. There is however a race condition
in which the tasklet would be scheduled on a thread, while it is running
on another. This could lead to the same tasklet to run on multiple
threads, which we do not want.
To fix this, just do what we already do for regular tasks, set the
"TASK_RUNNING" flag, and when it's time to execute the tasklet, wait
until that flag is gone.
Only one case has been found in the current code, where the tasklet
could run on different threads depending on who wakes it up, in the
leastconn load balancer, since commit
627280e15f03755b8f59f0191cd6d6bcad5afeb3.
It should not be a problem in practice, as the function called can be
called concurrently.
If a bug is eventually found in relation to this problem, and this patch
should be backported, the following patches should be backported too :
MEDIUM: quic: Make sure we return the tasklet from quic_accept_run
MEDIUM: quic: Make sure we return NULL in quic_conn_app_io_cb if needed
MEDIUM: quic: Make sure we return the tasklet from qcc_io_cb
MEDIUM: mux_fcgi: Make sure we return the tasklet from fcgi_deferred_shut
MEDIUM: listener: Make sure w ereturn the tasklet from accept_queue_process
MEDIUM: checks: Make sure we return the tasklet from srv_chk_io_cb

2 months agoMEDIUM: quic: Make sure we return the tasklet from quic_accept_run
Olivier Houchard [Fri, 25 Apr 2025 11:03:29 +0000 (13:03 +0200)] 
MEDIUM: quic: Make sure we return the tasklet from quic_accept_run

In quic_accept_run, return the tasklet to tell the scheduler the tasklet
is still alive, it is not yet needed, but will be soon.

2 months agoMEDIUM: quic: Make sure we return NULL in quic_conn_app_io_cb if needed
Olivier Houchard [Fri, 25 Apr 2025 11:02:47 +0000 (13:02 +0200)] 
MEDIUM: quic: Make sure we return NULL in quic_conn_app_io_cb if needed

In quic_conn_app_io_cb, make sure we return NULL if the tasklet has been
destroyed, so that the scheduler knows. It is not yet needed, but will
be soon.

2 months agoMEDIUM: quic: Make sure we return the tasklet from qcc_io_cb
Olivier Houchard [Fri, 25 Apr 2025 11:01:58 +0000 (13:01 +0200)] 
MEDIUM: quic: Make sure we return the tasklet from qcc_io_cb

In qcc_io_cb, return the tasklet to tell the scheduler the tasklet is
still alive, it is not yet needed, but will be soon.

2 months agoMEDIUM: mux_fcgi: Make sure we return the tasklet from fcgi_deferred_shut
Olivier Houchard [Fri, 25 Apr 2025 11:01:15 +0000 (13:01 +0200)] 
MEDIUM: mux_fcgi: Make sure we return the tasklet from fcgi_deferred_shut

In fcgi_deferred_shut, return the tasklet to tell the scheduler the
tasklet is still alive, it is not yet needed, but will be soon.

2 months agoMEDIUM: listener: Make sure w ereturn the tasklet from accept_queue_process
Olivier Houchard [Fri, 25 Apr 2025 11:00:34 +0000 (13:00 +0200)] 
MEDIUM: listener: Make sure w ereturn the tasklet from accept_queue_process

In accept_queue_process, return the tasklet to tell the scheduler the
tasklet is still alive, it is not yet needed, but will be soon.

2 months agoMEDIUM: checks: Make sure we return the tasklet from srv_chk_io_cb
Olivier Houchard [Fri, 25 Apr 2025 10:59:37 +0000 (12:59 +0200)] 
MEDIUM: checks: Make sure we return the tasklet from srv_chk_io_cb

In srv_chk_io_cb, return the tasklet to tell the scheduler the tasklet
is still alive, it is not yet needed, but will be soon.

2 months ago[RELEASE] Released version 3.2-dev12 v3.2-dev12
Willy Tarreau [Fri, 25 Apr 2025 08:19:03 +0000 (10:19 +0200)] 
[RELEASE] Released version 3.2-dev12

Released version 3.2-dev12 with the following main changes :
    - BUG/MINOR: quic: do not crash on CRYPTO ncbuf alloc failure
    - BUG/MINOR: proxy: always detach a proxy from the names tree on free()
    - CLEANUP: proxy: detach the name node in proxy_free_common() instead
    - CLEANUP: Slightly reorder some proxy option flags to free slots
    - MINOR: proxy: Add options to drop HTTP trailers during message forwarding
    - MINOR: h1-htx: Skip C-L and T-E headers for 1xx and 204 messages during parsing
    - MINOR: mux-h1: Keep custom "Content-Length: 0" header in 1xx and 204 messages
    - MINOR: hlua/h1: Use http_parse_cont_len_header() to parse content-length value
    - CLEANUP: h1: Remove now useless h1_parse_cont_len_header() function
    - BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames
    - MINOR: http-act: Add 'pause' action to temporarily suspend the message analysis
    - MINOR: acme/cli: add the 'acme renew' command to the help message
    - MINOR: httpclient: add an "https" log-format
    - MEDIUM: acme: use a customized proxy
    - MEDIUM: acme: rename "uri" into "directory"
    - MEDIUM: acme: rename "account" into "account-key"
    - MINOR: stick-table: use a separate lock label for updates
    - MINOR: h3: simplify h3_rcv_buf return path
    - BUG/MINOR: mux-quic: fix possible infinite loop during decoding
    - BUG/MINOR: mux-quic: do not decode if conn in error
    - BUG/MINOR: cli: Issue an error when too many args are passed for a command
    - MINOR: cli: Use a full prompt command for bidir connections with workers
    - MAJOR: cli: Refacor parsing and execution of pipelined commands
    - MINOR: cli: Rename some CLI applet states to reflect recent refactoring
    - CLEANUP: applet: Update st0/st1 comment in appctx structure
    - BUG/MINOR: hlua: Fix I/O handler of lua CLI commands to not rely on the SC
    - BUG/MINOR: ring: Fix I/O handler of "show event" command to not rely on the SC
    - MINOR: cli/applet: Move appctx fields only used by the CLI in a private context
    - MINOR: cache: Add a pointer on the cache in the cache applet context
    - MINOR: hlua: Use the applet name in error messages for lua services
    - MINOR: applet: Save the "use-service" rule in the stream to init a service applet
    - CLEANUP: applet: Remove unsued rule pointer in appctx structure
    - BUG/MINOR: master/cli: properly trim the '@@' process name in error messages
    - MEDIUM: resolvers: add global "dns-accept-family" directive
    - MINOR: resolvers: add command-line argument -4 to force IPv4-only DNS
    - MINOR: sock-inet: detect apparent IPv6 connectivity
    - MINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6
    - MEDIUM: acme: use Retry-After value for retries
    - MEDIUM: acme: reset the remaining retries
    - MEDIUM: acme: better error/retry management of the challenge checks
    - BUG/MEDIUM: cli: Handle applet shutdown when waiting for a command line
    - Revert "BUG/MINOR: master/cli: properly trim the '@@' process name in error messages"
    - BUG/MINOR: master/cli: only parse the '@@' prefix on complete lines
    - MINOR: resolvers: use the runtime IPv6 status instead of boot time one

2 months agoMINOR: resolvers: use the runtime IPv6 status instead of boot time one
Willy Tarreau [Fri, 25 Apr 2025 07:26:44 +0000 (09:26 +0200)] 
MINOR: resolvers: use the runtime IPv6 status instead of boot time one

On systems where the network is not reachable at boot time (certain HA
systems for example, or dynamically addressed test machines), we'll want
to be able to periodically revalidate the IPv6 reachability status. The
current code makes it complicated because it sets the config bits once
for all at boot time. This commit changes this so that the config bits
are not changed, but instead we rely on a static inline function that
relies on sock_inet6_seems_reachable for every test (really cheap). This
also removes the now unneeded resolvers late init code.

This variable for now is still set at boot time but this will ease the
transition later, as the resolvers code is now ready for this.

2 months agoBUG/MINOR: master/cli: only parse the '@@' prefix on complete lines
Willy Tarreau [Fri, 25 Apr 2025 06:40:57 +0000 (08:40 +0200)] 
BUG/MINOR: master/cli: only parse the '@@' prefix on complete lines

The new adhoc parser for the '@@' prefix forgot to require the presence
of the LF character marking the end of the line. This is the reason why
entering incomplete commands would display garbage, because the line was
expected to have its LF character replaced with a zero.

The problem is well illustrated by using socat in raw mode:

   socat /tmp/master.sock STDIO,raw,echo=0

then entering "@@1 show info" one character at a time would error just
after the second "@". The command must take care to report an incomplete
line and wait for more data in such a case.

2 months agoRevert "BUG/MINOR: master/cli: properly trim the '@@' process name in error messages"
Willy Tarreau [Fri, 25 Apr 2025 06:43:48 +0000 (08:43 +0200)] 
Revert "BUG/MINOR: master/cli: properly trim the '@@' process name in error messages"

This reverts commit 0e94339eaf1c8423132debb6b1b485d8bb1bb7da.

This patch was in fact fixing the symptom, not the cause. The root cause
of the problem is that the parser was processing an incomplete line when
looking for '@@'. When the LF is present, this problem does not exist
as it's properly replaced with a zero. This can be verified using socat
in raw mode:

  socat /tmp/master.sock STDIO,raw,echo=0

Then entering "@@1 show info" one character at a time will immediately
fail on "@@" without going further. A subsequent patch will fix this.
No backport is needed.

2 months agoBUG/MEDIUM: cli: Handle applet shutdown when waiting for a command line
Christopher Faulet [Thu, 24 Apr 2025 16:54:32 +0000 (18:54 +0200)] 
BUG/MEDIUM: cli: Handle applet shutdown when waiting for a command line

When the CLI applet was refactord in the commit 20ec1de21 ("MAJOR: cli:
Refacor parsing and execution of pipelined commands"), a regression was
introduced. The applet shutdown was not longer handled when the applet was
waiting for the next command line. It is especially visible when a client
timeout occurred because the client connexion is no longer closed.

To fix the issue, the test on the SE_FL_SHW flag was reintroduced in
CLI_ST_PARSE_CMDLINE state, but only is there is no pending input data.

It is a 3.2-specific issue. No backport needed.

2 months agoMEDIUM: acme: better error/retry management of the challenge checks
William Lallemand [Thu, 24 Apr 2025 17:58:56 +0000 (19:58 +0200)] 
MEDIUM: acme: better error/retry management of the challenge checks

When the ACME task is checking for the status of the challenge, it would
only succeed or retry upon failure.

However that's not the best way to do it, ACME objects contain an
"status" field which could have a final status or a in progress status,
so we need to be able to retry.

This patch adds an acme_ret enum which contains OK, RETRY and FAIL.

In the case of the CHKCHALLENGE, the ACME could return a "pending" or a
"processing" status, which basically need to be rechecked later with the
RETRY. However a "invalid" or "valid" status is final and will return
either a FAIL or a OK.

So instead of retrying in any case, the "invalid" status will ends the
task with an error.

2 months agoMEDIUM: acme: reset the remaining retries
William Lallemand [Thu, 24 Apr 2025 15:50:29 +0000 (17:50 +0200)] 
MEDIUM: acme: reset the remaining retries

When a request succeed, reset the remaining retries to the default
ACME_RETRY value (3 by default).

2 months agoMEDIUM: acme: use Retry-After value for retries
William Lallemand [Thu, 24 Apr 2025 15:31:51 +0000 (17:31 +0200)] 
MEDIUM: acme: use Retry-After value for retries

Parse the Retry-After header in response and store it in order to use
the value as the next delay for the next retry, fallback to 3s if the
value couldn't be parse or does not exist.

2 months agoMINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6
Willy Tarreau [Thu, 24 Apr 2025 15:18:06 +0000 (17:18 +0200)] 
MINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6

Instead of always having to force IPv4 or IPv6, let's now also offer
"auto" which will only enable IPv6 if the system has a default gateway
for it. This means that properly configured dual-stack systems will
default to "ipv4,ipv6" while those lacking a gateway will only use
"ipv4". Note that no real connectivity test is performed, so firewalled
systems may still get it wrong and might prefer to rely on a manual
"ipv4" assignment.

2 months agoMINOR: sock-inet: detect apparent IPv6 connectivity
Willy Tarreau [Thu, 24 Apr 2025 15:05:14 +0000 (17:05 +0200)] 
MINOR: sock-inet: detect apparent IPv6 connectivity

In order to ease dual-stack deployments, we could at least try to
check if ipv6 seems to be reachable. For this we're adding a test
based on a UDP connect (no traffic) on port 53 to the base of
public addresses (2001::) and see if the connect() is permitted,
indicating that the routing table knows how to reach it, or fails.
Based on this result we're setting a global variable that other
subsystems might use to preset their defaults.

2 months agoMINOR: resolvers: add command-line argument -4 to force IPv4-only DNS
Willy Tarreau [Thu, 24 Apr 2025 14:31:47 +0000 (16:31 +0200)] 
MINOR: resolvers: add command-line argument -4 to force IPv4-only DNS

In order to ease troubleshooting and testing, the new "-4" command line
argument enforces queries and processing of "A" DNS records only, i.e.
those representing IPv4 addresses. This can be useful when a host lack
end-to-end dual-stack connectivity. This overrides the global
"dns-accept-family" directive and is equivalent to value "ipv4".

2 months agoMEDIUM: resolvers: add global "dns-accept-family" directive
Willy Tarreau [Thu, 24 Apr 2025 14:29:11 +0000 (16:29 +0200)] 
MEDIUM: resolvers: add global "dns-accept-family" directive

By default, DNS resolvers accept both IPv4 and IPv6 addresses. This can be
influenced by the "resolve-prefer" keywords on server lines as well as the
family argument to the "do-resolve" action, but that is only a preference,
which does not block the other family from being used when it's alone. In
some environments where dual-stack is not usable, stumbling on an unreachable
IPv6-only DNS record can cause significant trouble as it will replace a
previous IPv4 one which would possibly have continued to work till next
request. The "dns-accept-family" global option permits to enforce usage of
only one (or both) address families. The argument is a comma-delimited list
of the following words:
  - "ipv4": query and accept IPv4 addresses ("A" records)
  - "ipv6": query and accept IPv6 addresses ("AAAA" records)

When a single family is used, no request will be sent to resolvers for the
other family, and any response for the othe family will be ignored. The
default value is "ipv4,ipv6", which effectively enables both families.

2 months agoBUG/MINOR: master/cli: properly trim the '@@' process name in error messages
Willy Tarreau [Thu, 24 Apr 2025 15:47:23 +0000 (17:47 +0200)] 
BUG/MINOR: master/cli: properly trim the '@@' process name in error messages

When '@@' alone is sent on the master CLI (no trailing LF), we get an
error that displays anything past these two characters in the buffer
since there's no room for a \0. Let's make sure to limit the length of
the process name in this case. No backport is needed since this was added
with 00c967fac4 ("MINOR: master/cli: support bidirectional communications
with workers").

2 months agoCLEANUP: applet: Remove unsued rule pointer in appctx structure
Christopher Faulet [Thu, 24 Apr 2025 14:19:11 +0000 (16:19 +0200)] 
CLEANUP: applet: Remove unsued rule pointer in appctx structure

Thanks to previous commits, the "rule" field in the appctx structure is no
longer used. So we can safely remove it.

2 months agoMINOR: applet: Save the "use-service" rule in the stream to init a service applet
Christopher Faulet [Thu, 24 Apr 2025 14:08:48 +0000 (16:08 +0200)] 
MINOR: applet: Save the "use-service" rule in the stream to init a service applet

When a service is initialized, the "use-service" rule that was executed is
now saved in the stream, using "current_rule" field, instead of saving it
into the applet context. It is safe to do so becaues this field is unused at
this stage. To avoid any issue, it is reset after the service
initialization. Doing so, it is no longer necessary to save it in the applet
context. It was the last usage of the rule pointer in the applet context.

The init functions for TCP and HTTP lua services were updated accordingly.

2 months agoMINOR: hlua: Use the applet name in error messages for lua services
Christopher Faulet [Thu, 24 Apr 2025 13:59:31 +0000 (15:59 +0200)] 
MINOR: hlua: Use the applet name in error messages for lua services

The lua function name was used in error messages of HTTP/TCP lua services
while the applet name can be used. Concretely, this will not change
anything, because when a lua service is regiestered, the lua function name
is used to name the applet. But it is easier, cleaner and more logicial
because it is really the applet name that should be displayed in these error
messages.

2 months agoMINOR: cache: Add a pointer on the cache in the cache applet context
Christopher Faulet [Thu, 24 Apr 2025 13:48:57 +0000 (15:48 +0200)] 
MINOR: cache: Add a pointer on the cache in the cache applet context

Thanks to this change, when a response is delivered from the cache, it is no
longer necessary to get the cache filter configuration from the http
"use-cache" rule saved in the appctx to get the currently used cache. It was
a bit complex to get an info that can be directly and naturally stored in
the cache applet context.

2 months agoMINOR: cli/applet: Move appctx fields only used by the CLI in a private context
Christopher Faulet [Thu, 24 Apr 2025 09:17:07 +0000 (11:17 +0200)] 
MINOR: cli/applet: Move appctx fields only used by the CLI in a private context

There are several fields in the appctx structure only used by the CLI. To
make things cleaner, all these fields are now placed in a dedicated context
inside the appctx structure. The final goal is to move it in the service
context and add an API for cli commands to get a command coontext inside the
cli context.

2 months agoBUG/MINOR: ring: Fix I/O handler of "show event" command to not rely on the SC
Christopher Faulet [Wed, 23 Apr 2025 14:38:25 +0000 (16:38 +0200)] 
BUG/MINOR: ring: Fix I/O handler of "show event" command to not rely on the SC

Thanks to the CLI refactoring ("MAJOR: cli: Refacor parsing and execution of
pipelined commands"), it is possible to fix "show event" I/O handle function
to no longer use the SC.

When the applet API was refactored to no longer manipulate the channels or
the stream-connectors, this part was missed. However, without the patch
above, it could not be fixed. It is now possible so let's do it.

This patch must not be backported becaues it depends on refactoring of the
CLI applet.

2 months agoBUG/MINOR: hlua: Fix I/O handler of lua CLI commands to not rely on the SC
Christopher Faulet [Wed, 23 Apr 2025 14:32:55 +0000 (16:32 +0200)] 
BUG/MINOR: hlua: Fix I/O handler of lua CLI commands to not rely on the SC

Thanks to the CLI refactoring ("MAJOR: cli: Refacor parsing and execution of
pipelined commands"), it is possible to fix the I/O handler function used by
lua CLI commands to no longer use the SC.

When the applet API was refactored to no longer manipulate the channels or
the stream-connectors, this part was missed. However, without the patch
above, it could not be fixed. It is now possible so let's do it.

This patch must not be backported becaues it depends on refactoring of the
CLI applet.