]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
10 months agoBUG/MEDIUM: clock: also update the date offset on time jumps
Willy Tarreau [Wed, 4 Sep 2024 14:55:43 +0000 (16:55 +0200)] 
BUG/MEDIUM: clock: also update the date offset on time jumps

In GH issue #2704, @swimlessbird and @xanoxes reported problems handling
time jumps. Indeed, since 2.7 with commit 4eaf85f5d9 ("MINOR: clock: do
not update the global date too often") we refrain from updating the global
offset in case it didn't change. But there's a catch: in case of a large
time jump, if the poller was interrupted, the local time remains the same
and we return immediately from there without updating the offset. It then
becomes incorrect regarding the "date" value, and upon subsequent call to
the poller, there's no way to detect a jump anymore so we apply the old,
incorrect offset and the date becomes wrong. Worse, going back to the
original time (then in the past), global_now_ns remains higher than the
local time and neither get updated anymore.

What is missing in practice is to immediately update the offset when
detecting a time jump. In an ideal world, the offset would be updated
upon every call, that's what was being done prior to commit above but
it's extremely CPU intensive on large systems. However we can perfectly
afford to update the offset every time we detect a time jump, as it's
not as common.

This needs to be backported as far as 2.8. Thanks to both participants
above for providing very helpful details.

10 months agoDEV: patchbot: detect commit IDs starting with 7 chars
Willy Tarreau [Wed, 4 Sep 2024 07:41:40 +0000 (09:41 +0200)] 
DEV: patchbot: detect commit IDs starting with 7 chars

Some commit messages contain commit IDs as short as 7 chars, let's detect
them.

10 months agoDEV: patchbot: add direct links to show only specific categories
Willy Tarreau [Wed, 4 Sep 2024 07:38:43 +0000 (09:38 +0200)] 
DEV: patchbot: add direct links to show only specific categories

The per-category counters are now clickable so that it becomes possible
to list the relevant ones.

10 months agoDEV: patchbot: count the number of backported/non-backported patches
Willy Tarreau [Wed, 4 Sep 2024 07:11:04 +0000 (09:11 +0200)] 
DEV: patchbot: count the number of backported/non-backported patches

It's useful to instantly see how many patches of each category have
already been backported and are still pending, let's count them and
report them at the top of the page.

10 months agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Mon, 26 Aug 2024 21:40:15 +0000 (23:40 +0200)] 
CLEANUP: assorted typo fixes in the code and comments

This is 43rd iteration of typo fixes

10 months agoBUG/MEDIUM: mux-pt: Fix condition to perform a shutdown for writes in mux_pt_shut()
Christopher Faulet [Tue, 3 Sep 2024 13:19:51 +0000 (15:19 +0200)] 
BUG/MEDIUM: mux-pt: Fix condition to perform a shutdown for writes in mux_pt_shut()

A regression was introduced in the commit 76fa71f7a ("BUG/MEDIUM: mux-pt:
Never fully close the connection on shutdown") because of a typo on the
connection flags. CO_FL_SOCK_WR_SH flag must be tested to prevent a call to
conn_sock_shutw() and not CO_FL_SOCK_RD_SH.

Concretly, most of time, it is harmeless because shutdown for writes is
always performed before any shutdown for reads. Except in case describe by
the commit above. But it is not clear if it has an impact or not.

This patch must be backported with the commit above, so as far as 2.9.

10 months agoBUG/MINOR: Crash on O-RTT RX packet after dropping Initial pktns
Frederic Lecaille [Tue, 3 Sep 2024 13:10:25 +0000 (15:10 +0200)] 
BUG/MINOR: Crash on O-RTT RX packet after dropping Initial pktns

This bug arrived with this naive commit:

    BUG/MINOR: quic: Too shord datagram during O-RTT handshakes (aws-lc only)

which omitted to consider the case where the Initial packet number space
could be discarded before receiving 0-RTT packets.

To fix this, append/insert the O-RTT (early-data) packet number space
into the encryption level list depending on the presence or not of
the Initial packet number space.

This issue was revealed when using aws-lc as TLS stack in GH #2701 issue.
Thank you to @Tristan971 for having reported this issue.

Must be backported where the commit mentionned above is supposed to be
backported: as far as 2.9.

10 months agoBUG/MINOR: mux-spop: always clear MUX_MFULL and DEM_MROOM when clearing the mbuf
Willy Tarreau [Mon, 2 Sep 2024 17:54:09 +0000 (19:54 +0200)] 
BUG/MINOR: mux-spop: always clear MUX_MFULL and DEM_MROOM when clearing the mbuf

That's the equivalent of the mux-h2 one, except that here there's no
real risk to loop since normally we cannot feed data that bypass the
closed state check (e.g. no zero-copy forward). But it still remains
dirty to be able to leave and empty mbuf with MFULL and MROOM set, so
better clear them as well.

No backport is needed since this is only in 3.1.

10 months agoBUG/MAJOR: mux-h2: always clear MUX_MFULL and DEM_MROOM when clearing the mbuf
Willy Tarreau [Mon, 2 Sep 2024 13:18:51 +0000 (15:18 +0200)] 
BUG/MAJOR: mux-h2: always clear MUX_MFULL and DEM_MROOM when clearing the mbuf

There exists an extremely tricky code path that was revealed in 3.0 by
the glitches feature, though it might theoretically have existed before.

TL;DR: a mux mbuf may be full after successfully sending GOAWAY, and
discard its remaining contents without clearing H2_CF_MUX_MFULL and
H2_CF_DEM_MROOM, then endlessly loop in h2_send(), until the watchdog
takes care of it.

What can happen is the following: Some data are received, h2_io_cb() is
called. h2_recv() is called to receive the incoming data. Then
h2_process() is called and in turn calls h2_process_demux() to process
input data. At some point, a glitch limit is reached and h2c_error() is
called to close the connection. The input frame was incomplete, so some
data are left in the demux buffer. Then h2_send() is called, which in
turn calls h2_process_mux(), which manages to queue the GOAWAY frame,
turning the state to H2_CS_ERROR2. The frame is sent, and h2_process()
calls h2_send() a last time (doing nothing) and leaves. The streams
are all woken up to notify about the error.

Multiple backend streams were waiting to be scheduled and are woken up
in turn, before their parents being notified, and communicate with the
h2 mux in zero-copy-forward mode, request a buffer via h2_nego_ff(),
fill it, and commit it with h2_done_ff(). At some point the mux's output
buffer is full, and gets flags H2_CF_MUX_MFULL.

The io_cb is called again to process more incoming data. h2_send() isn't
called (polled) or does nothing (e.g. TCP socket buffers full). h2_recv()
may or may not do anything (doesn't matter). h2_process() is called since
some data remain in the demux buf. It goes till the end, where it finds
st0 == H2_CS_ERROR2 and clears the mbuf. We're now in a situation where
the mbuf is empty and MFULL is still present.

Then it calls h2_send(), which doesn't call h2_process_mux() due to
MFULL, doesn't enter the for() loop since all buffers are empty, then
keeps sent=0, which doesn't allow to clear the MFULL flag, and since
"done" was not reset, it loops forever there.

Note that the glitches make the issue more reproducible but theoretically
it could happen with any other GOAWAY (e.g. PROTOCOL_ERROR). What makes
it not happen with the data produced on the parsing side is that we
process a single buffer of input at once, and there's no way to amplify
this to 30 buffers of responses (RST_STREAM, GOAWAY, SETTINGS ACK,
WINDOW_UPDATE, PING ACK etc are all quite small), and since the mbuf is
cleared upon every exit from h2_process() once the error was sent, it is
not possible to accumulate response data across multiple calls. And the
regular h2_snd_buf() path checks for st0 >= H2_CS_ERROR so it will not
produce any data there either.

Probably that h2_nego_ff() should check for H2_CS_ERROR before accepting
to deliver a buffer, but this needs to be carefully studied. In the mean
time the real problem is that the MFULL flag was kept when clearing the
buffer, making the two inconsistent.

Since it doesn't seem possible to trigger this sequence without the
zero-copy-forward mechanism, this fix needs to be backported as far as
2.9, along with previous commit "MINOR: mux-h2: try to clear DEM_MROOM
and MUX_MFULL at more places" which will strengthen the consistency
between these checks.

Many thanks to Annika Wickert for her detailed report that allowed to
diagnose this problem. CVE-2024-45506 was assigned to this problem.

10 months agoMINOR: mux-h2: try to clear DEM_MROOM and MUX_MFULL at more places
Willy Tarreau [Mon, 2 Sep 2024 13:14:16 +0000 (15:14 +0200)] 
MINOR: mux-h2: try to clear DEM_MROOM and MUX_MFULL at more places

The code leading to H2_CF_MUX_MFULL and H2_CF_DEM_MROOM being cleared
is quite complex and assumptions about its state are extremely difficult
when reading the code. There are indeed long sequences where the mux might
possibly be empty, still having the flag set until it reaches h2_send()
which will clear it after the last send. Even then it's not obviour whether
it's always guaranteed to release the flag when invoked in multiple passes.
Let's just simplify the conditionnn so that h2_send() does not depend on
"sent" anymore and that h2_timeout_task() doesn't leave the flags set on
the buffer on emptiness. While it doesn't seem to fix anything, it will
make the code more robust against future changes.

10 months agoBUG/MEDIUM: mux-h1: Properly handle empty message when an error is triggered
Christopher Faulet [Tue, 3 Sep 2024 12:10:29 +0000 (14:10 +0200)] 
BUG/MEDIUM: mux-h1: Properly handle empty message when an error is triggered

When a 400/408/500/501 error is returned by the H1 multiplexer, we first try
to get the error message of the proxy before using the default one. This may
be configured to be mapped on /dev/null or on an empty file. In that case,
no message is emitted, as expected. But everything is handled as the error
was successfully sent.

However, there is an bug here. In h1_send_error() function, this case is not
properly handled. The flag H1C_F_ABRTED is not set on the H1 connection as it
should be and h1_close() function is not called, leaving the H1 connection in an
undefined state.

It is especially an issue when a "empty" 408-Request-Time-out error is emitted
while there are data blocked in the output buffer. In that case, the connection
remains openned until the client closes and a "cR--"/408 is logged repeatedly, every
time the client timeout is reached.

This patch must backported as far as 2.8.

10 months agoBUG/MINOR: quic: unexploited retransmission cases for Initial pktns.
Frederic Lecaille [Tue, 3 Sep 2024 08:52:39 +0000 (10:52 +0200)] 
BUG/MINOR: quic: unexploited retransmission cases for Initial pktns.

qc_prep_hdshk_fast_retrans() job is to pick some packets to be retransmitted
from Initial and Handshake packet number spaces. A packet may be coalesced to
a first one into the same datagram. When a coalesced packet is inspected for
retransmission, it is skipped if its length would make the total datagram length
it is attached to exceeding the anti-amplification limit. But in this case, the
first packet must be kept for the current retransmission. This is tracked by
this trace statemement:
    TRACE_PROTO("will probe Initial packet number space", QUIC_EV_CONN_SPPKTS, qc);
This was not the case because of the wrong "goto end" statement. This latter
must be run only if the Initial packet number space must not be probe with
the first packet found as coalesced to another one which must be skipped.

This bug was revealed by AWS-LC interop runner with handshakeloss and
handshakecorruption which always fail because this stack leads the server
to send more Initial packets.

Thank you to Ilya (@chipitsine) for this issue report in GH #2663.

Must be backported as far as 2.6.

10 months agoBUG/MEDIUM: cli: Always release back endpoint between two commands on the mcli
Christopher Faulet [Mon, 2 Sep 2024 16:29:02 +0000 (18:29 +0200)] 
BUG/MEDIUM: cli: Always release back endpoint between two commands on the mcli

When several commands are chained on the master CLI, the same client
connection is used. Because, it is a TCP connection, the mux PT is used. It
means there is no stream at the mux level. It is not possible to release the
applicative stream between each commands as for the HTTP. So, to work around
this limitation, between two commands, the master CLI is resetting the
stream. It does exactly what it was performed on HTTP to manage keep-alive
connections on old HAProxy versions.

But this part was copied from a code dealing with connection only while the
back endpoint can be an applet or a mux for the master cli. The previous fix
on the mux PT ("BUG/MEDIUM: mux-pt: Never fully close the connection on
shutdown") revealed a bug. Between two commands, the back endpoint was only
released if the connection's XPRT was closed. This works if the back
endpoint is an applet because there is no connection. But for commands sent
to a worker, a connection is used. At this stage, this only works if the
connection's XPRT is closed. Otherwise, the old endpoint is never detached
leading to undefined behavior on the next command execution (most probably a
crash).

Without the commit above, the connection's XPRT is always closed on
shutdown. It is no longer true. At this stage, we must inconditionnally
release the back endpoint by resetting the corresponding sedesc to fix the
bug.

This patch must be backported with the commit above in all stable
versions. On 2.4 and lower, it will need to be adapted.

10 months agoBUG/MEDIUM: mux-pt: Never fully close the connection on shutdown
Christopher Faulet [Mon, 2 Sep 2024 13:30:11 +0000 (15:30 +0200)] 
BUG/MEDIUM: mux-pt: Never fully close the connection on shutdown

When a shutdown is reported to the mux (shutdown for reads or writes), the
connexion is immediately fully closed if the mux detects the connexion is
closed in both directions. Only the passthrough multiplexer is able to
perform this action at this stage because there is no stream and no internal
data. Other muxes perform a full connection close during the mux's release
stage. It was working quite well since recently. But, in theory, the bug is
quite old.

In fact, it seems possible for the lower layer to report an error on the
connection in same time a shutdown is performed on the mux. Depending on how
events are scheduled, the following may happen:

 1. An connection error is detected at the fd layer and a wakeup is
    scheduled on the mux to handle the event.

 2. A shutdown for writes is performed on the mux. Here the mux decides to
    fully close the connexion. If the xprt is not used to log info, it is
    released.

 3. The mux is finally woken up. It tries to retrieve data from the xprt
    because it is not awayre there was an error. This leads to a crash
    because of a NULL-deref.

By reading the code, it is not obvious. But it seems possible with SSL
connection when the handshake is rearmed. It happens when a
SSL_ERROR_WANT_WRITE is reported on a SSL_read() attempt or a
SSL_ERROR_WANT_READ on a SSL_write() attempt.

This bug is only visible if the XPRT is not used to log info. So it is no so
common.

This patch should fix the 2nd crash reported in the issue #2656. It must
first be backported as far as 2.9 and then slowly to all stable versions.

10 months agoMEDIUM: bwlim: Use a read-lock on the sticky session to apply a shared limit
Christopher Faulet [Wed, 28 Aug 2024 08:04:42 +0000 (10:04 +0200)] 
MEDIUM: bwlim: Use a read-lock on the sticky session to apply a shared limit

There is no reason to acquire a write-lock on the sticky session when a
shared limit is applied because only the frequency is updated. The sticky
session itself is not modified. We must just take care it is not removed in
the mean time. So a read-lock may be used instead.

10 months agoMEDIUM: stick-table: Add support of a factor for IN/OUT bytes rates
Christopher Faulet [Wed, 28 Aug 2024 08:02:13 +0000 (10:02 +0200)] 
MEDIUM: stick-table: Add support of a factor for IN/OUT bytes rates

Add a factor parameter to stick-tables, called "brates-factor", that is
applied to in/out bytes rates to work around the 32-bits limit of the
frequency counters. Thanks to this factor, it is possible to have bytes
rates beyond the 4GB. Instead of counting each bytes, we count blocks
of bytes. Among other things, it will be useful for the bwlim filter, to be
able to configure shared limit exceeding the 4GB/s.

For now, this parameter must be in the range ]0-1024].

10 months agoBUG/MINOR: quic: Crash from trace dumping SSL eary data status (AWS-LC)
Frederic Lecaille [Mon, 2 Sep 2024 07:36:19 +0000 (09:36 +0200)] 
BUG/MINOR: quic: Crash from trace dumping SSL eary data status (AWS-LC)

This bug follows this patch:
     MINOR: quic: Add trace for QUIC_EV_CONN_IO_CB event.
where a new third variable was added to be dumped from QUIC_EV_CONN_IO_CB trace
event. The quic_trace() code did not reveal there was already another variable
passed as third argument but not dumped. This leaded to crash when dereferencing
a point to an int in place of a point to an SSL object.

This issue was reproduced only by handshakecorruption aws-lc interop test with
s2n-quic as client.

Note that this patch must be backported with this one:
     BUG/MEDIUM: quic: always validate sender address on 0-RTT
which depends on the commit mentionned above.

10 months agoMEDIUM: protocol: add MPTCP per address support
Aperence [Mon, 26 Aug 2024 09:50:27 +0000 (11:50 +0200)] 
MEDIUM: protocol: add MPTCP per address support

Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension
that enables a TCP connection to use different paths.

Multipath TCP has been used for several use cases. On smartphones, MPTCP
enables seamless handovers between cellular and Wi-Fi networks while
preserving established connections. This use-case is what pushed Apple
to use MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to automatically use the
best performing path, either IPv4 or IPv6. If one path fails, MPTCP
automatically uses the other path.

To benefit from MPTCP, both the client and the server have to support
it. Multipath TCP is a backward-compatible TCP extension that is enabled
by default on recent Linux distributions (Debian, Ubuntu, Redhat, ...).
Multipath TCP is included in the Linux kernel since version 5.6 [3]. To
use it on Linux, an application must explicitly enable it when creating
the socket. No need to change anything else in the application.

This attached patch adds MPTCP per address support, to be used with:

  mptcp{,4,6}@<address>[:port1[-port2]]

MPTCP v4 and v6 protocols have been added: they are mainly a copy of the
TCP ones, with small differences: names, proto, and receivers lists.

These protocols are stored in __protocol_by_family, as an alternative to
TCP, similar to what has been done with QUIC. By doing that, the size of
__protocol_by_family has not been increased, and it behaves like TCP.

MPTCP is both supported for the frontend and backend sides.

Also added an example of configuration using mptcp along with a backend
allowing to experiment with it.

Note that this is a re-implementation of Björn's work from 3 years ago
[4], when haproxy's internals were probably less ready to deal with
this, causing his work to be left pending for a while.

Currently, the TCP_MAXSEG socket option doesn't seem to be supported
with MPTCP [5]. This results in a warning when trying to set the MSS of
sockets in proto_tcp:tcp_bind_listener.

This can be resolved by adding two new variables:
sock_inet(6)_mptcp_maxseg_default that will hold the default
value of the TCP_MAXSEG option. Note that for the moment, this
will always be -1 as the option isn't supported. However, in the
future, when the support for this option will be added, it should
contain the correct value for the MSS, allowing to correctly
set the TCP_MAXSEG option.

Link: https://www.rfc-editor.org/rfc/rfc8684.html
Link: https://www.tessares.net/apples-mptcp-story-so-far/
Link: https://www.mptcp.dev
Link: https://github.com/haproxy/haproxy/issues/1028
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/515
Co-authored-by: Dorian Craps <dorian.craps@student.vinci.be>
Co-authored-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
10 months agoMEDIUM: sock: use protocol when creating socket
Aperence [Mon, 26 Aug 2024 09:50:26 +0000 (11:50 +0200)] 
MEDIUM: sock: use protocol when creating socket

Use the protocol configured for a connection when creating the socket,
instead of always using 0.

This change is needed to allow new protocol to be used when creating
the sockets, such as MPTCP. Note however that this patch won't change
anything for now, as the only other value that proto->sock_prot could
hold is IPPROTO_TCP, which has the same behavior as 0 when passed to
socket.

10 months agoMINOR: server: add a alt_proto field for server
Aperence [Mon, 26 Aug 2024 09:50:25 +0000 (11:50 +0200)] 
MINOR: server: add a alt_proto field for server

Add a new field alt_proto to the server structures that
specify if an alternate protocol should be used for this server.

This field can be transparently passed to protocol_lookup to get
an appropriate protocol structure.

This change allows thus to create servers with different protocols,
and not only TCP anymore.

10 months agoMINOR: tools: extend str2sa_range to add an alt parameter
Aperence [Mon, 26 Aug 2024 09:50:24 +0000 (11:50 +0200)] 
MINOR: tools: extend str2sa_range to add an alt parameter

Add a new parameter "alt" that will store wether this configuration
use an alternate protocol.

This alt pointer will contain a value that can be transparently
passed to protocol_lookup to obtain an appropriate protocol structure.

This change is needed to allow for example the servers to know if it
need to use an alternate protocol or not.

10 months agoBUILD: quic: fix build errors on FreeBSD since recent GSO changes
Willy Tarreau [Fri, 30 Aug 2024 16:52:33 +0000 (18:52 +0200)] 
BUILD: quic: fix build errors on FreeBSD since recent GSO changes

The following commits broke the build on FreeBSD when QUIC is enabled:

  35470d518 ("MINOR: quic: activate UDP GSO for QUIC if supported")
  448d3d388 ("MINOR: quic: add GSO parameter on quic_sock send API")

Indeed, it turns out that netinet/udp.h requires sys/types.h to be
included before. Let's just change the includes order to fix the build.
No backport is needed.

10 months agoBUG/MEDIUM: quic: always validate sender address on 0-RTT
Frederic Lecaille [Fri, 30 Aug 2024 13:38:54 +0000 (15:38 +0200)] 
BUG/MEDIUM: quic: always validate sender address on 0-RTT

It has been reported by Wedl Michael, a student at the University of Applied
Sciences St. Poelten, a potential vulnerability into haproxy as described below.

An attacker could have obtained a TLS session ticket after having established
a connection to an haproxy QUIC listener, using its real IP address. The
attacker has not even to send a application level request (HTTP3). Then
the attacker could open a 0-RTT session with a spoofed IP address
trusted by the QUIC listen to bypass IP allow/block list and send HTTP3 requests.

To mitigate this vulnerability, one decided to use a token which can be provided
to the client each time it successfully managed to connect to haproxy. These
tokens may be reused for future connections to validate the address/path of the
remote peer as this is done with the Retry token which is used for the current
connection, not the next one. Such tokens are transported by NEW_TOKEN frames
which was not used at this time by haproxy.

So, each time a client connect to an haproxy QUIC listener with 0-RTT
enabled, it is provided with such a token which can be reused for the
next 0-RTT session. If no such a token is presented by the client,
haproxy checks if the session is a 0-RTT one, so with early-data presented
by the client. Contrary to the Retry token, the decision to refuse the
connection is made only when the TLS stack has been provided with
enough early-data from the Initial ClientHello TLS message and when
these data have been accepted. Hopefully, this event arrives fast enough
to allow haproxy to kill the connection if some early-data have been accepted
without token presented by the client.

quic_build_post_handshake_frames() has been modified to build a NEW_TOKEN
frame with this newly implemented token to be transported inside.

quic_tls_derive_retry_token_secret() was renamed to quic_do_tls_derive_token_secre()
and modified to be reused and derive the secret for the new token implementation.

quic_token_validate() has been implemented to validate both the Retry and
the new token implemented by this patch. When this is a non-retry token
which could not be validated, the datagram received is marked as requiring
a Retry packet to be sent, and no connection is created.

When the Initial packet does not embed any non-retry token and if 0-RTT is enabled
the connection is marked with this new flag: QUIC_FL_CONN_NO_TOKEN_RCVD. As soon
as the TLS stack detects that some early-data have been provided and accepted by
the client, the connection is marked to be killed (QUIC_FL_CONN_TO_KILL) from
ha_quic_add_handshake_data(). This is done calling qc_ssl_eary_data_accepted()
new function. The secret TLS handshake is interrupted as soon as possible returnin
0 from ha_quic_add_handshake_data(). The connection is also marked as
requiring a Retry packet to be sent (QUIC_FL_CONN_SEND_RETRY) from
ha_quic_add_handshake_data(). The the handshake I/O handler (quic_conn_io_cb())
knows how to behave: kill the connection after having sent a Retry packet.

About TLS stack compatibility, this patch is supported by aws-lc. It is
disabled for wolfssl which does not support 0-RTT at this time thanks
to HAVE_SSL_0RTT_QUIC.

This patch depends on these commits:

     MINOR: quic: Add trace for QUIC_EV_CONN_IO_CB event.
     MINOR: quic: Implement qc_ssl_eary_data_accepted().
     MINOR: quic: Modify NEW_TOKEN frame structure (qf_new_token struct)
     BUG/MINOR: quic: Missing incrementation in NEW_TOKEN frame builder
     MINOR: quic: Token for future connections implementation.
     MINOR: quic: Implement quic_tls_derive_token_secret().
     MINOR: tools: Implement ipaddrcpy().

Must be backported as far as 2.6.

10 months agoMINOR: quic: Add trace for QUIC_EV_CONN_IO_CB event.
Frederic Lecaille [Fri, 30 Aug 2024 13:25:16 +0000 (15:25 +0200)] 
MINOR: quic: Add trace for QUIC_EV_CONN_IO_CB event.

Dump the early data status from QUIC_EV_CONN_IO_CB trace event.
This is very helpful to know if the QUIC server has accepted the
early data received from clients.

10 months agoMINOR: quic: Implement qc_ssl_eary_data_accepted().
Frederic Lecaille [Fri, 30 Aug 2024 13:16:01 +0000 (15:16 +0200)] 
MINOR: quic: Implement qc_ssl_eary_data_accepted().

This function is a wrapper around SSL_get_early_data_status() for
OpenSSL derived stack and SSL_early_data_accepted() boringSSL derived
stacks like AWS-LC. It returns true for a TLS server if it has
accepted the early data received from a client.

Also implement quic_ssl_early_data_status_str() which is dedicated to be used
for debugging purposes (traces). This function converts the enum returned
by the two function mentionned above to a human readable string.

10 months agoMINOR: quic: Modify NEW_TOKEN frame structure (qf_new_token struct)
Frederic Lecaille [Fri, 30 Aug 2024 12:47:08 +0000 (14:47 +0200)] 
MINOR: quic: Modify NEW_TOKEN frame structure (qf_new_token struct)

Modify qf_new_token structure to use a static buffer with QUIC_TOKEN_LEN
as size as defined by the token for future connections (quic_token.c).
Modify consequently the NEW_TOKEN frame parser (see quic_parse_new_token_frame()).
Also add comments to denote that the NEW_TOKEN parser function is used only by
clients and that its builder is used only by servers.

10 months agoBUG/MINOR: quic: Missing incrementation in NEW_TOKEN frame builder
Frederic Lecaille [Fri, 30 Aug 2024 12:25:26 +0000 (14:25 +0200)] 
BUG/MINOR: quic: Missing incrementation in NEW_TOKEN frame builder

quic_build_new_token_frame() is the function which is called to build
a NEW_TOKEN frame into a buffer. The position pointer for this buffer
was not updated, leading the NEW_TOKEN frame to be malformed.

Must be backported as far as 2.6.

10 months agoMINOR: quic: Token for future connections implementation.
Frederic Lecaille [Fri, 30 Aug 2024 07:13:30 +0000 (09:13 +0200)] 
MINOR: quic: Token for future connections implementation.

There exist two sorts of token used by QUIC. They are both used to validate
the peer address (path validation). Retry are used for the current
connection the client want to open. This patch implement the other
sort of tokens which after having been received from a connection, may
be provided for the next connection from the same IP address to validate
it (or validate the network path between the client and the server).

The token generation is implemented by quic_generate_token(), and
the token validation by quic_token_chek(). The same method
is used as for Retry tokens to build such tokens to be reused for
future connections. The format is very simple: one byte for the format
identifier to distinguish these new tokens for the Retry token, followed
by a 32bits timestamps. As this part is ciphered with AEAD as cryptographic
algorithm, 16 bytes are needed for the AEAD tag. 16 more random bytes
are added to this token and a salt to derive the AEAD secret used
to cipher the token. In addition to this salt, this is the client IP address
which is used also as AAD to derive the AEAD secret. So, the length of
the token is fixed: 37 bytes.

10 months agoMINOR: quic: Implement quic_tls_derive_token_secret().
Frederic Lecaille [Fri, 30 Aug 2024 12:14:24 +0000 (14:14 +0200)] 
MINOR: quic: Implement quic_tls_derive_token_secret().

This is function is similar to quic_tls_derive_retry_token_secret().
Its aim is to derive the secret used to cipher the token to be used
for future connections.

This patch renames quic_tls_derive_retry_token_secret() to a more
and reuses its code to produce a more generic one: quic_do_tls_derive_token_secret().
Two arguments are added to this latter to produce both quic_tls_derive_retry_token_secret()
and quic_tls_derive_token_secret() new function which calls
quic_do_tls_derive_token_secret().

10 months agoMINOR: tools: Implement ipaddrcpy().
Frederic Lecaille [Fri, 30 Aug 2024 11:56:15 +0000 (13:56 +0200)] 
MINOR: tools: Implement ipaddrcpy().

Implement ipaddrcpy() new function to copy only the IP address from
a sockaddr_storage struct object into a buffer.

10 months agoCLEANUP: mqtt: fix typo in MQTT_REMAINING_LENGHT_MAX_SIZE
Nicolas CARPi [Tue, 27 Aug 2024 19:51:26 +0000 (21:51 +0200)] 
CLEANUP: mqtt: fix typo in MQTT_REMAINING_LENGHT_MAX_SIZE

There was a typo in the macro name, where LENGTH was incorrectly
written. This didn't cause any issue because the typo appeared in all
occurrences in the codebase.

10 months agoCLEANUP: haproxy: fix typos in code comment
Nicolas CARPi [Tue, 27 Aug 2024 20:02:17 +0000 (22:02 +0200)] 
CLEANUP: haproxy: fix typos in code comment

Use "from" instead of "form" in ha_random_boot function code comments.

10 months agoBUG/MINIR: proxy: Match on 429 status when trying to perform a L7 retry
Christopher Faulet [Fri, 30 Aug 2024 10:11:03 +0000 (12:11 +0200)] 
BUG/MINIR: proxy: Match on 429 status when trying to perform a L7 retry

Support for 429 was recently added to L7 retries (0d142e075 "MINOR: proxy:
Add support of 429-Too-Many-Requests in retry-on status"). But the
l7_status_match() function was not properly updated. The switch statement
must match the 429 status to be able to perform a L7 retry.

This patch must be backported if the commit above is backported. It is
related to #2687.

10 months agoBUG/MEDIUM: stream: Prevent mux upgrades if client connection is no longer ready
Christopher Faulet [Wed, 28 Aug 2024 13:42:22 +0000 (15:42 +0200)] 
BUG/MEDIUM: stream: Prevent mux upgrades if client connection is no longer ready

If an early error occurred on the client connection, we must prevent any
multiplexer upgrades. Indeed, it is unexpected for a mux to be initialized
with no xprt. On a normal workflow it is impossible. So it is not an
issue. But if a mux upgrade is performed at the stream level, an early error
on the connection may have already been handled by the previous mux and the
connection may be already fully closed. If the mux upgrade is still
performed, a crash can be experienced.

It is possible to have a crash with an implicit TCP>HTTP upgrade if there is no
data in the input buffer. But it is also possible to get a crash with an
explicit "switch-mode http" rule.

It must be backported to all stable versions. In 2.2, the patch must be
applied directly in stream_set_backend() function.

10 months agoBUG/MEDIUM: mux-h2: Set ES flag when necessary on 0-copy data forwarding
Christopher Faulet [Tue, 27 Aug 2024 17:16:07 +0000 (19:16 +0200)] 
BUG/MEDIUM: mux-h2: Set ES flag when necessary on 0-copy data forwarding

When DATA frames are sent via the 0-copy data forwarding, we must take care
to set the ES flag on the last DATA frame. It should be performed in
h2_done_ff() when IOBUF_FL_EOI flag was set by the producer. This flag is
here to know when the producer has reached the end of input. When this
happens, the h2s state is also updated. It is switched to "half-closed
local" or "closed" state depending on its previous state.

It is mainly an issue on uploads because the server may be blocked waiting
for the end of the request. A workaround is to disable the 0-copy forwarding
support the the H2 by setting "tune.h2.zero-copy-fwd-send" directive to off
in your global section.

This patch should fix the issue #2665. It must be backported as far as 2.9.

10 months agoMINOR: proxy: Add support of 429-Too-Many-Requests in retry-on status
Christopher Faulet [Tue, 27 Aug 2024 17:09:08 +0000 (19:09 +0200)] 
MINOR: proxy: Add support of 429-Too-Many-Requests in retry-on status

The "429" status can now be specified on retry-on directives. PR_RE_* flags
were updated to remains sorted.

This patch should fix the issue #2687. It is quite simple so it may safely
be backported to 3.0 if necessary.

10 months agoMEDIUM: ssl/sample: add ssl_fc_sigalgs_bin sample fetch
William Lallemand [Fri, 23 Aug 2024 18:53:24 +0000 (20:53 +0200)] 
MEDIUM: ssl/sample: add ssl_fc_sigalgs_bin sample fetch

This new sample fetch allow to extract the binary list contained in the
signature_algorithms (13) TLS extensions.

https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3

10 months agoMEDIUM: ssl: capture the signature_algorithms extension from Client Hello
William Lallemand [Fri, 23 Aug 2024 18:40:47 +0000 (20:40 +0200)] 
MEDIUM: ssl: capture the signature_algorithms extension from Client Hello

Activate the capture of the TLS signature_algorithms extension from the
Client Hello. This list is stored in the ssl_capture buffer when the
global option "tune.ssl.capture-cipherlist-size" is enabled.

10 months agoMEDIUM: ssl/sample: add ssl_fc_supported_versions_bin sample fetch
William Lallemand [Fri, 23 Aug 2024 16:15:52 +0000 (18:15 +0200)] 
MEDIUM: ssl/sample: add ssl_fc_supported_versions_bin sample fetch

This new sample fetch allow to extract the binary list contained in the
supported_versions (43) TLS extensions.

https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.1

10 months agoMEDIUM: ssl: capture the supported_versions extension from Client Hello
William Lallemand [Fri, 23 Aug 2024 15:35:10 +0000 (17:35 +0200)] 
MEDIUM: ssl: capture the supported_versions extension from Client Hello

Activate the capture of the TLS supported_versions extension from the
Client Hello. This list is stored in the ssl_capture buffer when the
global option "tune.ssl.capture-cipherlist-size" is enabled.

10 months agoCLEANUP: ssl: cleanup the clienthello capture
William Lallemand [Fri, 23 Aug 2024 15:11:26 +0000 (17:11 +0200)] 
CLEANUP: ssl: cleanup the clienthello capture

In order to add more extensions, clean up the clienthello capture
function a little bit.

10 months agoBUILD: quic: 32bits build broken by wrong integer conversions for printf()
Frederic Lecaille [Mon, 26 Aug 2024 09:18:15 +0000 (11:18 +0200)] 
BUILD: quic: 32bits build broken by wrong integer conversions for printf()

Since these commits the 32bits build is broken due to several errors as follow:

CC      src/quic_cli.o
src/quic_cli.c: In function ‘dump_quic_full’:
src/quic_cli.c:285:94: error: format ‘%ld’ expects argument of type ‘long int’,
        but argument 5 has type ‘uint64_t’ {aka ‘long long unsigned int’} [-Werror=format=]
  285 |                         chunk_appendf(&trash, "  [initl] rx.ackrng=%-6zu tx.inflight=%-6zu(%ld%%)\n",
      |                                                                                            ~~^
      |                                                                                              |
      |                                                                                              long int
      |                                                                                            %lld
  286 |                                       pktns->rx.arngs.sz, pktns->tx.in_flight,
  287 |                                       pktns->tx.in_flight * 100 / qc->path->cwnd);
      |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                                 |
      |                                                                 uint64_t {aka long long unsigned int}

Replace several %ld by %llu with ull as printf conversion in quic_clic.c and a
%ld by %lld with (long long) as printf conversion in quic_cc_cubic.c.

Thank you to Ilya (@chipitsine) for having reported this issue in GH #2689.

Must be backported to 3.0.

10 months agoCI: QUIC Interop: use different artifact names for uploading logs
Ilya Shipitsin [Sat, 24 Aug 2024 23:22:29 +0000 (01:22 +0200)] 
CI: QUIC Interop: use different artifact names for uploading logs

artifact names must be unique, otherwise only first failed logs are
uploaded, other encounter 409 conflict

10 months agoCI: QUIC Interop: do not run bandwidth measurement tests
Ilya Shipitsin [Sat, 24 Aug 2024 23:22:28 +0000 (01:22 +0200)] 
CI: QUIC Interop: do not run bandwidth measurement tests

crosstraffic, goodput tests are intended to perform bandwidth measurement,
we do not consider GitHub runners for that purpose

GH issue: https://github.com/haproxy/haproxy/issues/2688

10 months agoCI: fix missing comma introduced in 956839c0f68a7722acc586ecd91ffefad2ccb303
Ilya Shipitsin [Sat, 24 Aug 2024 23:22:27 +0000 (01:22 +0200)] 
CI: fix missing comma introduced in 956839c0f68a7722acc586ecd91ffefad2ccb303

in 956839c0f68a7722acc586ecd91ffefad2ccb303 syntax was broken due to missing
comma. it is follow up.

10 months agoCI: QUIC Interop AWS-LC: enable ngtcp2 client
Ilya Shipitsin [Sat, 24 Aug 2024 13:55:45 +0000 (15:55 +0200)] 
CI: QUIC Interop AWS-LC: enable ngtcp2 client

Let's add it and see how it goes.
GH issue: https://github.com/haproxy/haproxy/issues/2688

10 months agoDEV: coccinelle: add a test to detect unchecked calloc()
Ilya Shipitsin [Sat, 24 Aug 2024 13:55:44 +0000 (15:55 +0200)] 
DEV: coccinelle: add a test to detect unchecked calloc()

The coccinelle test "unchecked-calloc.cocci" detects various cases of
unchecked calloc().

10 months agoDEV: coccinelle: add a test to detect unchecked malloc()
Ilya Shipitsin [Sat, 24 Aug 2024 13:55:43 +0000 (15:55 +0200)] 
DEV: coccinelle: add a test to detect unchecked malloc()

The coccinelle test "unchecked-malloc.cocci" detects various cases of
unchecked malloc().

10 months agoBUILD: tools: environ is not defined in OS X and BSD
William Lallemand [Fri, 23 Aug 2024 17:33:22 +0000 (19:33 +0200)] 
BUILD: tools: environ is not defined in OS X and BSD

Add extern char **environ which in order to build the new functions to
manipulate the environment.

Indeed the variable environ is not required to be declared by POSIX, so
it need to be declared manually:

"In addition, the following variable, which must be declared by the user if it is to be used directly:

extern char **environ;"

https://pubs.opengroup.org/onlinepubs/9699919799/functions/environ.html

10 months agoBUG/MINOR: haproxy: free init_env in deinit only if allocated
Valentine Krasnobaeva [Fri, 23 Aug 2024 16:54:31 +0000 (18:54 +0200)] 
BUG/MINOR: haproxy: free init_env in deinit only if allocated

This fixes 7b78e1571 (" MINOR: mworker: restore initial env before wait
mode").

In cases, when haproxy starts without any configuration, for example:
'haproxy -vv', init_env array to backup env variables is never allocated. So,
we need to check in deinit(), when we free its memory, that init_env is not a
NULL ptr.

10 months agoMINOR: mworker: restore initial env before wait mode
Valentine Krasnobaeva [Wed, 21 Aug 2024 17:07:22 +0000 (19:07 +0200)] 
MINOR: mworker: restore initial env before wait mode

This patch is the follow-up of 1811d2a6ba (MINOR: tools: add helpers to
backup/clean/restore env).

In order to avoid unexpected behaviour in master-worker mode during the process
reload with a new configuration, when the old one has contained '*env' keywords,
let's backup its initial environment before calling parse_cfg() and let's clean
and restore it in the context of master process, just before it enters in a wait
polling loop.

This will garantee that new workers will have a new updated environment and not
the previous one inherited from the master, which does not read the configuration,
when it's in a wait-mode.

10 months agoMINOR: tools: add helpers to backup/clean/restore env
Valentine Krasnobaeva [Wed, 21 Aug 2024 17:06:33 +0000 (19:06 +0200)] 
MINOR: tools: add helpers to backup/clean/restore env

'setenv', 'presetenv', 'unsetenv', 'resetenv' keywords in configuration could
modify the process runtime environment. In case of master-worker mode this
creates a problem, as the configuration is read only once before the forking a
worker and then the master process does the reexec without reading any config
files, just to free the memory. So, during the reload a new worker process will
be created, but it will inherited the previous unchanged environment from the
master in wait mode, thus it won't benefit the changes in configuration,
related to '*env' keywords. This may cause unexpected behavior or some parser
errors in master-worker mode.

So, let's add a helper to backup all process env variables just before it will
read its configuration. And let's also add helpers to clean up the current
runtime environment and to restore it to its initial state (as it was before
parsing the config).

10 months agoMINOR: mux-quic: correct qcc_bufwnd_full() documentation
Amaury Denoyelle [Fri, 23 Aug 2024 13:26:54 +0000 (15:26 +0200)] 
MINOR: mux-quic: correct qcc_bufwnd_full() documentation

Fix returned value domment of qcc_bufwnd_full() which was incorrect.

10 months agoMINOR: mux-quic: add buf_in_flight to QCC debug infos
Amaury Denoyelle [Wed, 21 Aug 2024 13:30:17 +0000 (15:30 +0200)] 
MINOR: mux-quic: add buf_in_flight to QCC debug infos

Dump <buf_in_flight> QCC field both in QUIC MUX traces and "show quic".
This could help to detect if MUX does not allocate enough buffers
compared to quic_conn current congestion window.

10 months agoMINOR: config: Created env variables for http and tcp clf formats
Nathan Wehrman [Tue, 20 Aug 2024 16:11:34 +0000 (09:11 -0700)] 
MINOR: config: Created env variables for http and tcp clf formats

Since we already have variables for the other formats and the
change is trivial I thought it would be a nice addition for
completeness

10 months ago[RELEASE] Released version 3.1-dev6 v3.1-dev6
Willy Tarreau [Wed, 21 Aug 2024 15:50:03 +0000 (17:50 +0200)] 
[RELEASE] Released version 3.1-dev6

Released version 3.1-dev6 with the following main changes :
    - BUG/MINOR: proto_tcp: delete fd from fdtab if listen() fails
    - BUG/MINOR: proto_tcp: keep error msg if listen() fails
    - MINOR: proto_tcp: tcp_bind_listener: copy errno in errmsg
    - MINOR: channel: implement ci_insert() function
    - BUG/MEDIUM: mworker/cli: fix pipelined modes on master CLI
    - REGTESTS: mcli: test the pipelined commands on master CLI
    - MINOR: cfgparse: load_cfg_in_mem: fix null ptr dereference reported by coverity
    - MINOR: startup: fix unused value reported by coverity
    - BUG/MINOR: mux-quic: do not send too big MAX_STREAMS ID
    - BUG/MINOR: proto_uxst: delete fd from fdtab if listen() fails
    - BUG/MINOR: cfgparse: parse_cfg: fix null ptr dereference reported by coverity
    - MINOR: proto_uxst: copy errno in errmsg for syscalls
    - MINOR: mux-quic: do not trace error in qcc_send_frames() on empty list
    - BUG/MINOR: h3: properly reject too long header responses
    - CLEANUP: mworker/cli: clean up the mode handling
    - BUG/MINOR: tools: make fgets_from_mem() stop at the end of the input
    - BUG/MINOR: pattern: pat_ref_set: fix UAF reported by coverity
    - BUG/MINOR: pattern: pat_ref_set: return 0 if err was found
    - CI: keep logs for failed QIUC Interop jobs
    - BUG/MINOR: release-estimator: fix relative scheme in CHANGELOG URL
    - MINOR: release-estimator: add requirements.txt
    -  MINOR: release-estimator: add installation steps in README.md
    - MINOR: release-estimator: fix the shebang of the python script
    - DOC: config: correct the table for option tcplog
    - MEDIUM: log: relax some checks and emit diag warnings instead in lf_expr_postcheck()
    - MINOR: log: "drop" support for log-profile steps
    - CI: QUIC Interop LibreSSL: document chacha20 test status
    - CI: modernize codespell action, switch to node 16
    - CI: QUIC Interop AWS-LC: enable chrome client
    - DOC: lua: fix incorrect english in lua.txt
    - MINOR: Implements new log format of option tcplog clf
    - MINOR: cfgparse: limit file size loaded via /dev/stdin
    - BUG/MINOR: stats: fix color of input elements in dark mode
    - CLEANUP: stats: use modern DOCTYPE tag
    - BUG/MINOR: stats: add lang attribute to html tag
    - DOC: quic: fix default minimal value for max window size
    - DOC: quic: document nocc debug congestion algorithm
    - MINOR: quic: extract config window-size parsing
    - MINOR: quic: define max-window-size config setting
    - MINOR: quic: allocate stream txbuf via qc_stream_desc API
    - MINOR: mux-quic: account stream txbuf in QCC
    - MEDIUM: mux-quic: implement API to ignore txbuf limit for some streams
    - MINOR: h3: mark control stream as metadata
    - MINOR: mux-quic: define buf_in_flight
    - MAJOR: mux-quic: allocate Tx buffers based on congestion window
    - MINOR: quic/config: adapt settings to new conn buffer limit
    - MINOR: quic: define sbuf pool
    - MINOR: quic: support sbuf allocation in quic_stream
    - MEDIUM: h3: allocate small buffers for headers frames
    - MINOR: mux-quic: retry after small buf alloc failure
    - BUG/MINOR: cfgparse-global: fix err msg in mworker keyword parser
    - BUG/MINOR: cfgparse-global: clean common_kw_list
    - BUG/MINOR: cfgparse-global: remove redundant goto
    - MINOR: cfgparse-global: move 'pidfile' in global keywords list
    - MINOR: cfgparse-global: move 'expose-*' in global keywords list
    - MINOR: cfgparse-global: move tune options in global keywords list
    - MINOR: cfgparse-global: move unsupported keywords in global list
    - BUG/MINOR: cfgparse-global: remove tune.fast-forward from common_kw_list
    - MINOR: quic: store the lost packets counter in the quic_cc_event element
    - MINOR: quic: support a tolerance for spurious losses
    - MINOR: protocol: properly assign the sock_domain and sock_family
    - MINOR: protocol: add a family lookup
    - MEDIUM: socket: always properly use the sock_domain for requested families
    - MINOR: protocol: add the real address family to the protocol
    - MINOR: socket: don't ban all custom families from reuseport
    - MINOR: protocol: always initialize the receivers list on registration
    - CLEANUP: protocol: no longer initialize .receivers nor .nb_receivers

10 months agoCLEANUP: protocol: no longer initialize .receivers nor .nb_receivers
Willy Tarreau [Wed, 21 Aug 2024 15:15:59 +0000 (17:15 +0200)] 
CLEANUP: protocol: no longer initialize .receivers nor .nb_receivers

Protocol definitions no longer need to initialize these internal fields,
as they're now properly initialized during protocol registration.

10 months agoMINOR: protocol: always initialize the receivers list on registration
Willy Tarreau [Fri, 9 Aug 2024 19:32:29 +0000 (21:32 +0200)] 
MINOR: protocol: always initialize the receivers list on registration

Till now, protocols were required to self-initialize their receivers
list head, which is not very convenient, and is quite error prone.
Indeed, it's too easy to copy-paste a protocol definition and forget
to update the .receivers field to point to itself, resulting in mixed
lists. Let's just do that in protocol_register(). And while we're at
it, let's also zero the nb_receivers entry that works with it, so that
the protocol definition isn't required to pre-initialize stuff related
to internal book-keeping.

10 months agoMINOR: socket: don't ban all custom families from reuseport
Willy Tarreau [Fri, 9 Aug 2024 19:02:24 +0000 (21:02 +0200)] 
MINOR: socket: don't ban all custom families from reuseport

The test on ss_family >= AF_MAX is too strict if we want to support new
custom families, let's apply this to the real_family instead so that we
check that the underlying socket supports reuseport.

10 months agoMINOR: protocol: add the real address family to the protocol
Willy Tarreau [Fri, 9 Aug 2024 18:13:10 +0000 (20:13 +0200)] 
MINOR: protocol: add the real address family to the protocol

For custom families, there's sometimes an underlying real address and
it would be nice to be able to directly use the real family in calls
to bind() and connect() without having to add explicit checks for
exceptions everywhere.

Let's add a .real_family field to struct proto_fam for this. For now
it's always equal to the family except for non-transferable ones such
as rhttp where it's equal to the custom one (anything else could fit).

10 months agoMEDIUM: socket: always properly use the sock_domain for requested families
Willy Tarreau [Fri, 9 Aug 2024 17:37:44 +0000 (19:37 +0200)] 
MEDIUM: socket: always properly use the sock_domain for requested families

Now we make sure to always look up the protocol's domain for an address
family. Previously we would use it as-is, which prevented from properly
using custom addresses (which is when they differ).

This removes some hard-coded tests such as in log.c where UNIX vs UDP
was explicitly checked for example. It requires a bit of care, however,
so as to properly pass value 1 in the 3rd arg of the protocol_lookup()
for DGRAM stuff. Maybe one day we'll change these for defines or enums
to limit mistakes.

10 months agoMINOR: protocol: add a family lookup
Willy Tarreau [Fri, 9 Aug 2024 18:30:31 +0000 (20:30 +0200)] 
MINOR: protocol: add a family lookup

At plenty of places we have access to an address family which may
include some custom addresses but we cannot simply convert them to
the real families without performing some random protocol lookups.

Let's simply add a proto_fam table like we have for the protocols.
The protocols could even be indexed there, but for now it's not worth
it.

10 months agoMINOR: protocol: properly assign the sock_domain and sock_family
Willy Tarreau [Fri, 9 Aug 2024 16:59:46 +0000 (18:59 +0200)] 
MINOR: protocol: properly assign the sock_domain and sock_family

When we finally split sock_domain from sock_family in 2.3, something
was not cleanly finished. The family is what should be stored in the
address while the domain is what is supposed to be passed to socket().
But for the custom addresses, we did the opposite, just because the
protocol_lookup() function was acting on the domain, not the family
(both of which are equal for non-custom addresses).

This is an API bug but there's no point backporting it since it does
not have visible effects. It was visible in the code since a few places
were using PF_UNIX while others were comparing the domain against AF_MAX
instead of comparing the family.

This patch clarifies this in the comments on top of proto_fam, addresses
the indexing issue and properly reconfigures the two custom families.

10 months agoMINOR: quic: support a tolerance for spurious losses
Willy Tarreau [Thu, 25 Jul 2024 12:46:10 +0000 (14:46 +0200)] 
MINOR: quic: support a tolerance for spurious losses

Tests performed between a 1 Gbps connected server and a 100 mbps client,
distant by 95ms showed that:

  - we need 1.1 MB in flight to fill the link
  - rare but inevitable losses are sufficient to make cubic's window
    collapse fast and long to recover
  - a 100 MB object takes 69s to download
  - tolerance for 1 loss between two ACKs suffices to shrink the download
    time to 20-22s
  - 2 losses go to 17-20s
  - 4 losses reach 14-17s

At 100 concurrent connections that fill the server's link:
  - 0 loss tolerance shows 2-3% losses
  - 1 loss tolerance shows 3-5% losses
  - 2 loss tolerance shows 10-13% losses
  - 4 loss tolerance shows 23-29% losses

As such while there can be a significant gain sometimes in setting this
tolerance above zero, it can also significantly waste bandwidth by sending
far more than can be received. While it's probably not a solution to real
world problems, it repeatedly proved to be a very effective troubleshooting
tool helping to figure different root causes of low transfer speeds. In
spirit it is comparable to the no-cc congestion algorithm, i.e. it must
not be used except for experimentation.

10 months agoMINOR: quic: store the lost packets counter in the quic_cc_event element
Willy Tarreau [Thu, 25 Jul 2024 12:32:20 +0000 (14:32 +0200)] 
MINOR: quic: store the lost packets counter in the quic_cc_event element

Upon loss detection, qc_release_lost_pkts() notifies congestion
controllers about the event and its final time. However it does not
pass the number of lost packets, that can provide useful hints for
some controllers. Let's just pass this option.

10 months agoBUG/MINOR: cfgparse-global: remove tune.fast-forward from common_kw_list
Valentine Krasnobaeva [Wed, 14 Aug 2024 18:05:58 +0000 (20:05 +0200)] 
BUG/MINOR: cfgparse-global: remove tune.fast-forward from common_kw_list

Remove tune.fast-forward from common_kw_list. It was replaced by
'tune.disable-fast-forward' and it's no longer present in "if..else if.."
parser from cfg_parse_global(). Otherwise, it may be shown as the best-match
keyword for some tune options, which is now wrong.

Should be backported in versions 2.9 and 3.0.

10 months agoMINOR: cfgparse-global: move unsupported keywords in global list
Valentine Krasnobaeva [Wed, 14 Aug 2024 16:25:41 +0000 (18:25 +0200)] 
MINOR: cfgparse-global: move unsupported keywords in global list

Following the previous commits and in order to clean up cfg_parse_global let's
move unsupported keywords in the global list and let's add for them a dedicated
parser.

10 months agoMINOR: cfgparse-global: move tune options in global keywords list
Valentine Krasnobaeva [Wed, 14 Aug 2024 16:17:11 +0000 (18:17 +0200)] 
MINOR: cfgparse-global: move tune options in global keywords list

In order to clean up cfg_parse_global() and to add the support of the new
MODE_DISCOVERY in configuration parsing, let's move the keywords related to
tune options into the global keywords list and let's add for them two dedicated
parsers. Tune options keywords are sorted between two parsers in dependency of
parameters number, which a given tune option needs.

tune options parser is called by section parser and follows the common API, i.e.
it returns -1 on failure, 0 on success and 1 on recoverable error. In case of
recoverable error we've previously returned ERR_ALERT (0x10) and we have emitted
an alert message at startup. Section parser treats all rc > 0 as ERR_WARN. So in
case, if some tune option was set twice in the global section, tune
options parser will return 1 (in order to respect the common API), section
parser will treat this as ERR_WARN and a warning message will be emitted during
process startup instead of alert, as it was before.

10 months agoMINOR: cfgparse-global: move 'expose-*' in global keywords list
Valentine Krasnobaeva [Wed, 14 Aug 2024 13:15:33 +0000 (15:15 +0200)] 
MINOR: cfgparse-global: move 'expose-*' in global keywords list

Following the previous commit let's also move 'expose-*' keywords in the global
cfg_kws list and let's add for them a dedicated parser. This will simplify the
configuration parsing in the new MODE_DISCOVERY, which allows to read only the
keywords, needed at the early start of haproxy process (i.e. modes, pidfile,
chosen poller).

10 months agoMINOR: cfgparse-global: move 'pidfile' in global keywords list
Valentine Krasnobaeva [Wed, 14 Aug 2024 12:57:16 +0000 (14:57 +0200)] 
MINOR: cfgparse-global: move 'pidfile' in global keywords list

This commit cleans up cfg_parse_global() and prepares the config parser to
support MODE_DISCOVERY. This step is needed in early starting stage, just to
figura out in which mode the process was started, to set some necessary
parameteres needed for this mode and to continue the initialization
stage.

'pidfile' makes part of such common keywords, which are needed to be parsed
very early and which are used almost in all process modes (except the
foreground, '-d').

'pidfile' keyword parser is called by section parser and follows the common
API, i.e. it returns -1 on failure, 0 on success and 1 on recoverable error. In
case of recoverable error we've previously returned ERR_ALERT (0x10) and we have
emitted an alert message at startup. Section parser treats all rc > 0 as
ERR_WARN. So in case, if pidfile was already specified via command line, the
keyword parser will return 1 (in order to respect the common API), section
parser will treat this as ERR_WARN and a warning message will be emitted during
process startup instead of alert, as it was before.

10 months agoBUG/MINOR: cfgparse-global: remove redundant goto
Valentine Krasnobaeva [Wed, 14 Aug 2024 12:49:51 +0000 (14:49 +0200)] 
BUG/MINOR: cfgparse-global: remove redundant goto

In the case, when the given keyword was found in the global 'cfg_kws' list, we
go to 'out' label anyway, after testing rc returned by the keyword's parser. So
there is not a much gain if we perform 'goto out' jump specifically when rc > 0.

10 months agoBUG/MINOR: cfgparse-global: clean common_kw_list
Valentine Krasnobaeva [Wed, 14 Aug 2024 13:00:05 +0000 (15:00 +0200)] 
BUG/MINOR: cfgparse-global: clean common_kw_list

This patch fixes commits 118ac11ce
("MINOR: cfgparse-global: move mode's keywords in cfg_kw_list") and 83ff4db18
(MINOR: cfgparse-global: move no<poller_name> in cfg_kw_list).

'common_kw_list' serves to show the best-match keyword in cfg_parse_global(), if
the given keyword was not parsed in "if..else if.." cases. cfg_parse_global()
is still used as a parser for some keywords from the global section.

Mode-specific and no<poller_name> keywords now have their own parsers. They no
longer take place in the "if..else if.." from cfg_parse_global() and they are
registered in the 'cfg_kws' list. So, there is no longer need to duplicate
them in the 'common_kw_list'. Otherwise, they will be shown twice in parser
error message.

10 months agoBUG/MINOR: cfgparse-global: fix err msg in mworker keyword parser
Valentine Krasnobaeva [Wed, 14 Aug 2024 14:20:15 +0000 (16:20 +0200)] 
BUG/MINOR: cfgparse-global: fix err msg in mworker keyword parser

This patch fixes the commit 118ac11ce
("cfgparse-global: move mode's keywords in cfg_kw_list"). Error message
delivered by keyword parser in **err is always shown with ha_alert() by the
caller cfg_parse_global(). The caller always supplies these alerts with the
filename and the line number.

10 months agoMINOR: mux-quic: retry after small buf alloc failure
Amaury Denoyelle [Mon, 29 Jul 2024 15:01:38 +0000 (17:01 +0200)] 
MINOR: mux-quic: retry after small buf alloc failure

Previous commit switch to small buffers for HTTP/3 HEADERS emission.
This ensures that several parallel streams can allocate their own buffer
without hitting the connection buffer limit based now on the congestion
window size.

However, this prevents the transmission of responses with uncommonly
large headers. Indeed, if all headers cannot be encoded in a single
buffer, an error is reported which cause the whole connection closure.

Adjust this by implementing a realloc API exposed by QUIC MUX. This
allows application layer to switch from a small to a default buffer and
restart its processing. This guarantees that again headers not longer
than bufsize can be properly transferred.

10 months agoMEDIUM: h3: allocate small buffers for headers frames
Amaury Denoyelle [Wed, 14 Aug 2024 09:07:44 +0000 (11:07 +0200)] 
MEDIUM: h3: allocate small buffers for headers frames

A major change was recently implemented to change QUIC MUX Tx buffer
allocation limit, which is now based on the current connection
congestion window size. As this size may be smaller than the previous
static value, it is likely that the limit will be reached more
frequently.

When using HTTP/3, the majority of requests streams are used for small
object exchanges. Every responses start with a HEADERS frames which
should be much smaller in size than the default buffer. But as the whole
buffer size is accounted against the congestion window, a single stream
can block others even if only emitting a single HEADERS frame which is
suboptimal for bandwith usage, if the congestion window is small enough.

To adapt to this new situation, rely on the newly available small
buffers to transfer HEADERS frame response. This at least guarantee that
several parallel streams could allocate their own buffer for the first
part of the response, even with a small congestion window.

The situation could be further improve to use various indication on the
data size and select a small buffer if sufficient. This could be done
for example via the Content-length value or HTX extra field. However
this must be the subject of a dedicated patch.

10 months agoMINOR: quic: support sbuf allocation in quic_stream
Amaury Denoyelle [Thu, 13 Jun 2024 13:26:51 +0000 (15:26 +0200)] 
MINOR: quic: support sbuf allocation in quic_stream

This patch extends qc_stream_desc API to be able to allocate small
buffers. QUIC MUX API is similarly updated as ultimatly each application
protocol is responsible to choose between a default or a smaller buffer.

Internally, the type of allocated buffer is remembered via qc_stream_buf
instance. This is mandatory to ensure that the buffer is released in the
correct pool, in particular as small and standard buffers can be
configured with the same size.

This commit is purely an API change. For the moment, small buffers are
not used. This will changed in a dedicated patch.

10 months agoMINOR: quic: define sbuf pool
Amaury Denoyelle [Tue, 13 Aug 2024 07:34:28 +0000 (09:34 +0200)] 
MINOR: quic: define sbuf pool

Define a new buffer pool reserved to allocate smaller memory area. For
the moment, its usage will be restricted to QUIC, as such it is declared
in quic_stream module.

Add a new config option "tune.bufsize.small" to specify the size of the
allocated objects. A special check ensures that it is not greater than
the default bufsize to avoid unexpected effects.

10 months agoMINOR: quic/config: adapt settings to new conn buffer limit
Amaury Denoyelle [Wed, 14 Aug 2024 09:07:13 +0000 (11:07 +0200)] 
MINOR: quic/config: adapt settings to new conn buffer limit

QUIC MUX buffer allocation limit is now directly based on the underlying
congestion window size. previous static limit based on conn-tx-buffers
is now unused. As such, this commit adds a warning to users to prevent
that it is now obsolete.

Secondly, update max-window-size setting. It is now the main entrypoint
to limit both the maximum congestion window size and the number of QUIC
MUX allocated buffer on emission. Remove its special value '0' which was
used to automatically adjust it on now unused conn-tx-buffers.

10 months agoMAJOR: mux-quic: allocate Tx buffers based on congestion window
Amaury Denoyelle [Thu, 13 Jun 2024 15:06:40 +0000 (17:06 +0200)] 
MAJOR: mux-quic: allocate Tx buffers based on congestion window

Each QUIC MUX may allocate buffers for MUX stream emission. These
buffers are then shared with quic_conn to handle ACK reception and
retransmission. A limit on the number of concurrent buffers used per
connection has been defined statically and can be updated via a
configuration option. This commit replaces the limit to instead use the
current underlying congestion window size.

The purpose of this change is to remove the artificial static buffer
count limit, which may be difficult to choose. Indeed, if a connection
performs with minimal loss rate, the buffer count would limit severely
its throughput. It could be increase to fix this, but it also impacts
others connections, even with less optimal performance, causing too many
extra data buffering on the MUX layer. By using the dynamic congestion
window size, haproxy ensures that MUX buffering corresponds roughly to
the network conditions.

Using QCC <buf_in_flight>, a new buffer can be allocated if it is less
than the current window size. If not, QCS emission is interrupted and
haproxy stream layer will subscribe until a new buffer is ready.

One of the criticals parts is to ensure that MUX layer previously
blocked on buffer allocation is properly woken up when sending can be
retried. This occurs on two occasions :

* after an already used Tx buffer is cleared on ACK reception. This case
  is already handled by qcc_notify_buf() via quic_stream layer.

* on congestion window increase. A new qcc_notify_buf() invokation is
  added into qc_notify_send().

Finally, remove <avail_bufs> QCC field which is now unused.

This commit is labelled MAJOR as it may have unexpected effect and could
cause significant behavior change. For example, in previous
implementation QUIC MUX would be able to buffer more data even if the
congestion window is small. With this patch, data cannot be transferred
from the stream layer which may cause more streams to be shut down on
client timeout. Another effect may be more CPU consumption as the
connection limit would be hit more often, causing more streams to be
interrupted and woken up in cycle.

10 months agoMINOR: mux-quic: define buf_in_flight
Amaury Denoyelle [Tue, 13 Aug 2024 06:51:46 +0000 (08:51 +0200)] 
MINOR: mux-quic: define buf_in_flight

Define a new QCC counter named <buf_in_flight>. Its purpose is to
account the current sum of all allocated stream buffer size used on
emission.

For this moment, this counter is updated and buffer allocation and
deallocation. It will be used to replace <avail_bufs> once congestion
window is used as limit for buffer allocation in a future commit.

10 months agoMINOR: h3: mark control stream as metadata
Amaury Denoyelle [Mon, 19 Aug 2024 08:28:40 +0000 (10:28 +0200)] 
MINOR: h3: mark control stream as metadata

A current work is performed to change QUIC MUX buffer allocation limit
from a configurable static value to use the size of the congestion
window instead. This change may cause the buffer allocation limit to be
triggered more frequently.

To ensure HTTP/3 control emission is not perturbed by this change, mark
the stream with qcc_send_metadata(). This ensures that buffer allocation
for this stream won't be subject to the connection limit. This is
necessary to guarantee that SETTINGS and GOAWAY frames are emitted.

10 months agoMEDIUM: mux-quic: implement API to ignore txbuf limit for some streams
Amaury Denoyelle [Mon, 19 Aug 2024 08:22:02 +0000 (10:22 +0200)] 
MEDIUM: mux-quic: implement API to ignore txbuf limit for some streams

Define a new qc_stream_desc flag QC_SD_FL_OOB_BUF. This is to mark
streams which are not subject to the connection limit on allocated MUX
stream buffer.

The purpose is to simplify handling of QUIC MUX streams which do not
transfer data and as such are not driven by haproxy layer, for example
HTTP/3 control stream. These streams interacts synchronously with QUIC
MUX and cannot retry emission in case of temporary failure.

This commit will be useful once connection buffer allocation limit is
reimplemented to directly rely on the congestion window size. This will
probably cause the buffer limit to be reached more frequently, maybe
even on QUIC MUX initialization. As such, it will be possible to mark
control streams and prevent them to be subject to the buffer limit.

QUIC MUX expose a new function qcs_send_metadata(). It can be used by an
application protocol to specify which streams are used for control
exchanges. For the moment, no such stream use this mechanism.

10 months agoMINOR: mux-quic: account stream txbuf in QCC
Amaury Denoyelle [Tue, 13 Aug 2024 09:57:50 +0000 (11:57 +0200)] 
MINOR: mux-quic: account stream txbuf in QCC

A limit per connection is put on the number of buffers allocated by QUIC
MUX for emission accross all its streams. This ensures memory
consumption remains under control. This limit is simply explained as a
count of buffers which can be concurrently allocated for each
connection.

As such, quic_conn structure was used to account currently allocated
buffers. However, a quic_conn nevers allocates new stream buffers. This
is only done at QUIC MUX layer. As such, this commit moves buffer
accounting inside QCC structure. This simplifies the API, most notably
qc_stream_buf_alloc() usage.

Note that this commit inverts the accounting. Previously, it was
initially set to 0 and increment for each allocated buffer. Now, it is
set to the maximum value and decrement for each buf usage. This is
considered as clearer to use.

10 months agoMINOR: quic: allocate stream txbuf via qc_stream_desc API
Amaury Denoyelle [Tue, 13 Aug 2024 09:08:08 +0000 (11:08 +0200)] 
MINOR: quic: allocate stream txbuf via qc_stream_desc API

This commit simply adjusts QUIC stream buffer allocation. This operation
is conducted by QUIC MUX using qc_stream_desc layer. Previously,
qc_stream_buf_alloc() would return a qc_stream_buf instance and QUIC MUX
would finalized the buffer area allocation. Change this to perform the
buffer allocation directly into qc_stream_buf_alloc().

This patch clarifies the interaction between QUIC MUX and
qc_stream_desc. It is cleaner to allocate the buffer via qc_stream_desc
as it is already responsible to free the buffer.

It also ensures that connection buffer accounting is only done after the
whole qc_stream_buf and its buffer are allocated. Previously, the
increment operation was performed between the two steps. This was not an
issue, as this kind of error triggers the whole connection closure.
However, if in the future this is handled as a stream closure instead,
this commit ensures that the buffer remains valid in all cases.

10 months agoMINOR: quic: define max-window-size config setting
Amaury Denoyelle [Mon, 19 Aug 2024 09:59:28 +0000 (11:59 +0200)] 
MINOR: quic: define max-window-size config setting

Define a new global keyword tune.quic.frontend.max-window-size. This
allows to set globally the maximum congestion window size for each QUIC
frontend connections.

The default value is 0. It is a special value which automatically derive
the size from the configured QUIC connection buffer limit. This is
similar to the previous "quic-cc-algo" behavior, which can be used to
override the maximum window size per bind line.

10 months agoMINOR: quic: extract config window-size parsing
Amaury Denoyelle [Wed, 14 Aug 2024 16:30:34 +0000 (18:30 +0200)] 
MINOR: quic: extract config window-size parsing

quic-cc-algo is a bind line keyword which allow to select a QUIC
congestion algorithm. It can take an optional integer to specify the
maximum window size. This value is an integer and support the suffixes
'k', 'm' and 'g' to specify respectively kilobytes, megabytes and
gigabytes.

Extract the maximum window size parsing in a dedicated function named
parse_window_size(). It accepts as input an integer value with an
optional suffix, 'k', 'm' or 'g'. The first invalid character is
returned by the function to the caller.

No functional change. This commit will allow to quickly implement a new
keyword to configure a default congestion window size in the global
section.

10 months agoDOC: quic: document nocc debug congestion algorithm
Amaury Denoyelle [Wed, 14 Aug 2024 16:00:20 +0000 (18:00 +0200)] 
DOC: quic: document nocc debug congestion algorithm

Document nocc congestion algorithm as an entry of quic-cc-algo.
Highlight the fact that it is reserved for debugging and should not be
used outside of this use case.

10 months agoDOC: quic: fix default minimal value for max window size
Amaury Denoyelle [Wed, 14 Aug 2024 16:25:01 +0000 (18:25 +0200)] 
DOC: quic: fix default minimal value for max window size

It is possible to override the default QUIC congestion algorithm on a
bind line. With the same setting, it is also possible to specify the
maximum congestion window size.

The parser rejects values outside of the range between 10k and 4g. This
is in contradiction with the documentation which specify 1k as the lower
value. Correct this value in the documentation.

This should be backported up to 2.9.

10 months agoBUG/MINOR: stats: add lang attribute to html tag
Nicolas CARPi [Tue, 20 Aug 2024 13:20:10 +0000 (15:20 +0200)] 
BUG/MINOR: stats: add lang attribute to html tag

The "html" element of the stats page was missing a "lang" attribute.
This change specifies the "en" value, which corresponds to english
language.

It is also a required element for WCAG Success Criterion 3.1.1, which
renders the web more accessible through a set of requirements. In this
case it allows assistive technologies such as screen readers to
determine the language of the page.

MDN page: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang
HTML standard: https://html.spec.whatwg.org/multipage/dom.html#attr-lang
WCAG criterion: https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html

10 months agoCLEANUP: stats: use modern DOCTYPE tag
Nicolas CARPi [Tue, 20 Aug 2024 13:12:23 +0000 (15:12 +0200)] 
CLEANUP: stats: use modern DOCTYPE tag

Switching the stats page doctype to the modern standard is shorter and
less complex, and is the recommended doctype by current HTML standard.
It makes it clear that we do not want to run in quirks mode. More information below.

Quirks mode: https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode
HTML Standard: https://html.spec.whatwg.org/multipage/syntax.html#the-doctype

10 months agoBUG/MINOR: stats: fix color of input elements in dark mode
Nicolas CARPi [Tue, 20 Aug 2024 13:08:47 +0000 (15:08 +0200)] 
BUG/MINOR: stats: fix color of input elements in dark mode

Previously the text color was dark, with a dark background, this makes it
white, and thus readable. This is visible on the "Scope" input field.

10 months agoMINOR: cfgparse: limit file size loaded via /dev/stdin
Valentine Krasnobaeva [Tue, 20 Aug 2024 08:04:03 +0000 (10:04 +0200)] 
MINOR: cfgparse: limit file size loaded via /dev/stdin

load_cfg_in_mem() can continuously reallocate memory in order to load an
extremely large input from /dev/stdin, until it fails with ENOMEM, which means
that process has consumed all available RAM. In case of containers and
virtualized environments it's not very good.

So, in order to prevent this, let's introduce MAX_CFG_SIZE as 10MB, which will
limit the size of input supplied via /dev/stdin.

10 months agoMINOR: Implements new log format of option tcplog clf
Nathan Wehrman [Tue, 13 Aug 2024 18:25:38 +0000 (11:25 -0700)] 
MINOR: Implements new log format of option tcplog clf

Some systems require log formats in the CLF format and that meant that I
could not send my logs for proxies in mode tcp to those servers.  This
implements a format that uses log variables that are compatble with TCP
mode frontends and replaces traditional HTTP values in the CLF format
to make them stand out. Instead of logging method and URI like this
"GET /example HTTP/1.1" it will log "TCP " and for a response code I
used "000" so it would be easy to separate from legitimate HTTP
traffic. Now your log servers that require a CLF format can see the
timings for TCP traffic as well as HTTP.

10 months agoDOC: lua: fix incorrect english in lua.txt
Nicolas CARPi [Tue, 13 Aug 2024 20:57:56 +0000 (22:57 +0200)] 
DOC: lua: fix incorrect english in lua.txt

This commit fixes some typos, grammatical errors and unusual english
such as "can not" instead of preferred "cannot".

10 months agoCI: QUIC Interop AWS-LC: enable chrome client
Ilia Shipitsin [Tue, 13 Aug 2024 19:11:29 +0000 (21:11 +0200)] 
CI: QUIC Interop AWS-LC: enable chrome client

chrome is important browser, let's enable it in AWS-LC weekly tests.
the only test supported by chrome is http3

10 months agoCI: modernize codespell action, switch to node 16
Ilia Shipitsin [Tue, 13 Aug 2024 19:11:30 +0000 (21:11 +0200)] 
CI: modernize codespell action, switch to node 16

The following actions uses node12 which is deprecated and will be forced
to run on node16: codespell-project/codespell-problem-matcher@v1. For
more info:
   https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/

10 months agoCI: QUIC Interop LibreSSL: document chacha20 test status
Ilia Shipitsin [Tue, 13 Aug 2024 19:11:28 +0000 (21:11 +0200)] 
CI: QUIC Interop LibreSSL: document chacha20 test status

due to https://github.com/haproxy/haproxy/issues/2569 chacha20 is
disabled completely on LibreSSL. let's add a comment to not forget
enabling it

10 months agoMINOR: log: "drop" support for log-profile steps
Aurelien DARRAGON [Mon, 19 Aug 2024 16:06:19 +0000 (18:06 +0200)] 
MINOR: log: "drop" support for log-profile steps

It is now possible to use "drop" keyword for "on" lines under a
log-profile section to specify that no log at all should be emitted for
the specified step (setting an empty format was not sufficient to do so
because only the log payload would be empty, not the log header, thus the
log would still be emitted).

It may be useful to selectively disable logging at specific steps for a
given log target (since the log profile may be set on log directives):

log-profile myprof
  on request format "blabla" sd "custom sd"
  on response drop

New testcase was added to reg-tests/log/log_profiles.vtc

10 months agoMEDIUM: log: relax some checks and emit diag warnings instead in lf_expr_postcheck()
Aurelien DARRAGON [Tue, 13 Aug 2024 15:49:46 +0000 (17:49 +0200)] 
MEDIUM: log: relax some checks and emit diag warnings instead in lf_expr_postcheck()

With 7a21c3a ("MAJOR: log: implement proper postparsing for logformat
expressions") which finally made postparsing checks reliable, we started
to get report from users that couldn't start haproxy 3.0 with configs that
used to work in the past. The current situation is described in GH #2642.

While the checks are mostly relevant, it turns out there are not strictly
needed anymore from a technical point of view. Most of them were useful in
early logformat implementation to prevent runtime bugs due to the use of
an alias or fetch at runtime from an incompatible proxy. It's been a few
versions already that the code handling fetches and log aliases is robust
enough to support fetches/aliases used from the wrong context: all it
does is that the fetch/alias will silently fail if it's not available.

This can be proved by the fact that even if the postparsing checks were
partially broken in the past, it didn't cause runtime issues (at least
on recent haproxy versions).

Most of these checks can now be seen as configuration hints: when a check
triggers, it will indicate a configuration inconsistency in most cases,
but they are some corner cases where it is not possible to know at config
time if the conditions will be met for the alias/fetch to work properly..
so instead of failing with a hard error like we did so far, let's just be
more permissive and report our findings using "diag_warning": such
warnings are only emitted when haproxy is started with '-dD' cli option.

We also took this opportunity to improve messages clarity and make them
more precise (report the offending item instead of complaining about the
whole expression because of a single element).

With this patch, configs that used to start before 7a21c3a shouldn't
trigger hard errors anymore.

This may be backported in 3.0.

10 months agoDOC: config: correct the table for option tcplog
Nathan Wehrman [Tue, 13 Aug 2024 17:36:28 +0000 (10:36 -0700)] 
DOC: config: correct the table for option tcplog

option tcplog was reported as functional in the backend section in
error. This can be back ported as needed but it simply corrects
that.