]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoBUG/MINOR: http-fetch: Use integer value when possible in "method" sample fetch
Christopher Faulet [Wed, 22 Jun 2022 15:16:41 +0000 (17:16 +0200)] 
BUG/MINOR: http-fetch: Use integer value when possible in "method" sample fetch

Because of the previous fix, if the HTTP parsing is performed when the
"method" sample fetch is called, we always rely on the string representation
of the request method.

Indeed, if no parsing was performed when the "method" sample fetch is
called, the transaction method is HTTP_METH_OTHER because it was just
initialized. However, without this patch, in this case, we always retrieve
the method by reading the request start-line.

Now, when the method is HTTP_METH_OTHER, we systematically try to parse the
request but the method is tested once again after the parsing to be able to
use the integer representation when possible.

This patch must be backported as far as 2.0.

3 years agoBUG/MINOR: http-ana: Set method to HTTP_METH_OTHER when an HTTP txn is created
Christopher Faulet [Wed, 22 Jun 2022 15:12:05 +0000 (17:12 +0200)] 
BUG/MINOR: http-ana: Set method to HTTP_METH_OTHER when an HTTP txn is created

This patch is required to fix "method" sample fetch. But it make sense to
initialize the method of an HTTP transaction to HTTP_METH_OTHER. This way,
before the request parsing, the method is considered as unknown except if we
are able to retrieve the request start-line. It is especially important for
TCP streams.

About the "method" sample fetch, this patch is a way to be sure no random
method is returned when the sample fetch is used on a TCP stream before any
HTTP parsing.

This patch must be backported as far as 2.0.

3 years agoBUG/MINOR: quic: Missing acknowledgments for trailing packets
Frédéric Lécaille [Tue, 21 Jun 2022 13:14:59 +0000 (15:14 +0200)] 
BUG/MINOR: quic: Missing acknowledgments for trailing packets

This bug was revealed by key_update QUIC tracker test. During this test,
after the handshake has succeeded, the client sends a 1-RTT packet containing
only a PING frame. On our side, we do not acknowledge it, because we have
no ack-eliciting packet to send. This is not correct. We must acknowledge all
the ack-eliciting packets unconditionally. But we must not send too much
ACK frames: every two packets since we have sent an ACK frame. This is the test
(nb_aepkts_since_last_ack >= QUIC_MAX_RX_AEPKTS_SINCE_LAST_ACK) which ensure
this is the case. But this condition must be checked at the very last time,
when we are building a packet and when an acknowledgment is required. This
is not to qc_may_build_pkt() to do that. This boolean function decides if
we have packets to send. It must return "true" if there is no more ack-eliciting
packets to send and if an acknowledgement is required.

We must also add a "force_ack" parameter to qc_build_pkt() to force the
acknowledments during the handshakes (for each packet). If not, they will
be sent every two packets. This parameter must be passed to qc_do_build_pkt()
and be checked alongside the others conditions when building a packet to
decide to add an ACK frame or not to this packet.

Must be backported to 2.6.

3 years agoBUG/MINOR: ssl: Do not look for key in extra files if already in pem
Remi Tricot-Le Breton [Tue, 7 Jun 2022 14:29:44 +0000 (16:29 +0200)] 
BUG/MINOR: ssl: Do not look for key in extra files if already in pem

A bug was introduced by commit 9bf3a1f67eb3bc6f02abcabf8ab141840c7a1db2
"BUG/MINOR: ssl: Fix crash when no private key is found in pem".
If a private key is already contained in a pem file, we will still look
for a .key file and load its private key if it exists when we should
not.

This patch should be backported to all branches where the original fix
was backported (all the way to 2.2).

3 years agoBUILD: ssl_ckch: fix "maybe-uninitialized" build error on gcc-9.4 + ARM
Willy Tarreau [Wed, 22 Jun 2022 03:40:25 +0000 (05:40 +0200)] 
BUILD: ssl_ckch: fix "maybe-uninitialized" build error on gcc-9.4 + ARM

As reported in issue #1755, gcc-9.3 and 9.4 emit a "maybe-uninitialized"
warning in cli_io_handler_commit_cafile_crlfile() because it sees that
when the "path" variable is not set, we're jumping to the error label
inside the loop but cannot see that the new state will avoid the places
where the value is used. Thus it's a false positive but a difficult one.
Let's just preset the value to NULL to make it happy.

This was introduced in 2.7-dev by commit ddc8e1cf8 ("MINOR: ssl_ckch:
Simplify I/O handler to commit changes on CA/CRL entry"), thus no
backport is needed for now.

3 years agoTESTS: add a unit test for one_among_mask()
Willy Tarreau [Tue, 21 Jun 2022 18:28:14 +0000 (20:28 +0200)] 
TESTS: add a unit test for one_among_mask()

This one produces random numbers and verifies that the output is correct.
It can also take arguments to test individual values.

3 years agoMINOR: intops: add a function to return a valid bit position from a mask
Willy Tarreau [Tue, 21 Jun 2022 18:19:54 +0000 (20:19 +0200)] 
MINOR: intops: add a function to return a valid bit position from a mask

Sometimes we need to be able to signal one thread among a mask, without
caring much about which bit will be picked. At the moment we use ffsl()
for this but this sometimes results in imbalance at certain specific
places where the same first thread in a set is always the same one that
is selected.

Another approach would consist in using the rank finding function but it
requires a popcount and a setup phase, and possibly a modulo operation
depending on the popcount, which starts to be very expensive.

Here we take a different approach. The idea is an input bit value is
passed, from 0 to LONGBITS-1, and that as much as possible we try to
pick the bit matching it if it is set. Otherwise we look at a mirror
position based on a decreasing power of two, and jump to the side
that still has bits left. In 6 iterations it ends up spotting one bit
among 64 and the operations are very cheap and optimizable. This method
has the benefit that we don't care where the holes are located in the
mask, thus it shows a good distribution of output bits based on the
input ones. A long-time test shows an average of 16 cycles, or ~4ns
per lookup at 3.8 GHz, which is about twice as fast as using the rank
finding function.

Just like for that one, the code was stored into tools.c since we don't
have a C file for intops.

3 years agoBUG/MEDIUM: mworker: use default maxconn in wait mode
William Lallemand [Tue, 21 Jun 2022 09:11:50 +0000 (11:11 +0200)] 
BUG/MEDIUM: mworker: use default maxconn in wait mode

In bug #1751, it was reported that haproxy is consumming too much memory
since the 2.4 version. This is because of a change in the master, which
loses completely its configuration in wait mode, and lose its maxconn.

Without the maxconn, haproxy will try to compute one itself, and will
allocate RAM consequently, too much in our case. Which means the master
will have a too high maxconn and too much RAM allocated.

The patch fixes the issue by setting the maxconn to the default value
when re-executing the master in wait mode.

Must be backported as far as 2.5.

3 years agoMINOR: quic: Dump version_information transport parameter
Frédéric Lécaille [Mon, 20 Jun 2022 17:39:26 +0000 (19:39 +0200)] 
MINOR: quic: Dump version_information transport parameter

Implement quic_tp_version_info_dump() to dump such a transport parameter (only remote).
Call it from quic_transport_params_dump() which dump all the transport parameters.

Can be backported to 2.6 as it's useful for debugging.

3 years agoBUG/MINOR: quic: Acknowledgement must be forced during handshake
Frédéric Lécaille [Mon, 20 Jun 2022 15:51:24 +0000 (17:51 +0200)] 
BUG/MINOR: quic: Acknowledgement must be forced during handshake

All packets received during hanshakes must be acknowledged asap. This was
not the case for Handshake packets received. At this time, this had
no impact because the client has often only one Handshake packet to send
and last handshake to be sent on our side always embeds an HANDSHAKE_DONE
frame which leads the client to consider it has no more handshake packet
to send.

Add <force_ack> to qc_may_build_pkt() to force an ACK frame to be sent.
Set this parameter to 1 when sending packets from Initial or Handshake
packet number spaces, 0 when sending only Application level packet.

Must be backported to 2.6.

3 years agoREGTESTS: ssl: add the same cert for client/server
William Lallemand [Mon, 20 Jun 2022 16:01:30 +0000 (18:01 +0200)] 
REGTESTS: ssl: add the same cert for client/server

Add the same certificate in server and bind line so we can try to catch
problems like in issue #1748 when updating over the CLI.

3 years agoBUG/MEDIUM: ssl/cli: crash when crt inserted into a crt-list
William Lallemand [Mon, 20 Jun 2022 14:51:53 +0000 (16:51 +0200)] 
BUG/MEDIUM: ssl/cli: crash when crt inserted into a crt-list

The crash occures when the same certificate which is used on both a
server line and a bind line is inserted in a crt-list over the CLI.

This is quite uncommon as using the same file for a client and a server
certificate does not make sense in a lot of environments.

This patch fixes the issue by skipping the insertion of the SNI when no
bind_conf is available in the ckch_inst.

Change the reg-test to reproduce this corner case.

Should fix issue #1748.

Must be backported as far as 2.2. (it was previously in ssl_sock.c)

3 years agoBUG/MINOR: qpack: abort on dynamic index field line decoding
Amaury Denoyelle [Mon, 20 Jun 2022 13:47:46 +0000 (15:47 +0200)] 
BUG/MINOR: qpack: abort on dynamic index field line decoding

Add an ABORT_NOW() clause if indexed field line referred to the dynamic
table. This is required as current haproxy QPACK implementation does not
support the dynamic table.

Note that this should not happen as haproxy explicitely advertizes a
null-sized dynamic table to the other peer.

This shoud fix github issue #1753.

No need to backport as this was introduced by commit
  b666c6b26eae3f17eee058eb6bcc9fe1b1c304d2
  MINOR: qpack: improve decoding function

3 years agoBUG/MINOR: quic: free rejected Rx packets
Amaury Denoyelle [Mon, 20 Jun 2022 08:58:03 +0000 (10:58 +0200)] 
BUG/MINOR: quic: free rejected Rx packets

Free Rx packet in the datagram handler if the packet was not taken in
charge by a quic_conn instance. This is reflected by the packet refcount
which is null.

A packet can be rejected for a variety of reasons. For example, failed
decryption, no Initial token and Retry emission or for datagram null
padding.

This patch should resolve the Rx packets memory leak observed via "show
pools" with the previous commit
  2c31e1293661cd44b71457b8fd0567b08ef95b0b
  BUG/MINOR: quic: purge conn Rx packet list on release

This specific memory leak instance was reproduced using quiche client
which uses null datagram padding.

This should partially resolve github issue #1751.

It must be backported up to 2.6.

3 years agoBUG/MINOR: quic: purge conn Rx packet list on release
Amaury Denoyelle [Mon, 20 Jun 2022 08:52:55 +0000 (10:52 +0200)] 
BUG/MINOR: quic: purge conn Rx packet list on release

When releasing a quic_conn instance, free all remaining Rx packets in
quic_conn.rx.pkt_list. This partially fixes a memory leak on Rx packets
which can be observed after several QUIC connections establishment.

This should partially resolve github issue #1751.

It must be backported up to 2.6.

3 years agoBUG/MINOR: quic_stats: Duplicate "quic_streams_data_blocked_bidi" field name
Frédéric Lécaille [Mon, 20 Jun 2022 12:35:40 +0000 (14:35 +0200)] 
BUG/MINOR: quic_stats: Duplicate "quic_streams_data_blocked_bidi" field name

As reported by broxio in GH #1757, there was a duplication field name
for "quic_streams_data_blocked_bidi", due to a copy and paste without
renaming I guess.

Must be backported to 2.6.

3 years agoBUG/MINOR: quic: Unexpected half open connection counter wrapping
Frédéric Lécaille [Fri, 17 Jun 2022 13:11:32 +0000 (15:11 +0200)] 
BUG/MINOR: quic: Unexpected half open connection counter wrapping

This counter must be incremented only one time by connection and decremented
as soon as the handshake has failed or succeeded. This is a gauge. Under certain
conditions this counter could be decremented twice. For instance
after having received a TLS alert, then upon SSL_do_handshake() failure.
To stop having to deal to all the current combinations which can lead to such a
situation (and the next to come), add a connection flag to denote if this counter
has been already decremented for a connection. So, this counter must be decremented
only if this flag has not been already set.

Must be backported up to 2.6.

3 years agoBUILD: quic: Wrong HKDF label constant variable initializations
Frédéric Lécaille [Thu, 16 Jun 2022 15:53:46 +0000 (17:53 +0200)] 
BUILD: quic: Wrong HKDF label constant variable initializations

Non constant expressions were used to initialize constant variables leading to
such compilation errors:
src/xprt_quic.c:66:3: error: initializer element is not a constant expression
   .key_label_len    = strlen(QUIC_HKDF_KEY_LABEL_V1),
Reproduced with CC=gcc-4.9 compilation option.
Fix using macros for each HKDF label.

3 years agoMEDIUM: debug: detect redefinition of symbols upon dlopen()
Willy Tarreau [Sun, 19 Jun 2022 14:49:51 +0000 (16:49 +0200)] 
MEDIUM: debug: detect redefinition of symbols upon dlopen()

In order to better detect the danger caused by extra shared libraries
which replace some symbols, upon dlopen() we now compare a few critical
symbols such as malloc(), free(), and some OpenSSL symbols, to see if
the loaded library comes with its own version. If this happens, a
warning is emitted and TAINTED_REDEFINITION is set. This is important
because some external libs might be linked against different libraries
than the ones haproxy was linked with, and most often this will end
very badly (e.g. an OpenSSL object is allocated by haproxy and freed
by such libs).

Since the main source of dlopen() calls is the Lua lib, via a "require"
statement, it's worth trying to show a Lua call trace when detecting a
symbol redefinition during dlopen(). As such we emit a Lua backtrace if
Lua is detected as being in use.

3 years agoMEDIUM: debug: add a tainted flag when a shared library is loaded
Willy Tarreau [Sun, 19 Jun 2022 14:41:59 +0000 (16:41 +0200)] 
MEDIUM: debug: add a tainted flag when a shared library is loaded

Several bug reports were caused by shared libraries being loaded by other
libraries or some Lua code. Such libraries could define alternate symbols
or include dependencies to alternate versions of a library used by haproxy,
making it very hard to understand backtraces and analyze the issue.

Let's intercept dlopen() and set a new TAINTED_SHARED_LIBS flag when it
succeeds, so that "show info" makes it visible that some external libs
were added.

The redefinition is based on the definition of RTLD_DEFAULT or RTLD_NEXT
that were previously used to detect that dlsym() is usable, since we need
it as well. This should be sufficient to catch most situations.

3 years agoMINOR: hlua: add a new hlua_show_current_location() function
Willy Tarreau [Sun, 19 Jun 2022 15:39:33 +0000 (17:39 +0200)] 
MINOR: hlua: add a new hlua_show_current_location() function

This function may be used to try to show where some Lua code is currently
being executed. It tries hard to detect the initialization phase, both for
the global and the per-thread states, and for runtime states. This intends
to be used by error handlers to provide the users with indications about
what Lua code was being executed when the error triggered.

3 years agoMINOR: hlua: don't dump empty entries in hlua_traceback()
Willy Tarreau [Sun, 19 Jun 2022 15:35:53 +0000 (17:35 +0200)] 
MINOR: hlua: don't dump empty entries in hlua_traceback()

Calling hlua_traceback() sometimes reports empty entries looking like:

   [C]: ?

These ones correspond to certain internal C functions of the Lua library,
but they do not provide any information and even complicate the
interpretation of the dump. Better just skip them.

3 years agoBUG/MINOR: log: Properly test connection retries to fix dontlog-normal option
Christopher Faulet [Fri, 17 Jun 2022 12:53:20 +0000 (14:53 +0200)] 
BUG/MINOR: log: Properly test connection retries to fix dontlog-normal option

The commit 731c8e6cf ("MINOR: stream: Simplify retries counter calculation")
introduced a regression. It broke the dontlog-normal option because the test
on the connection retries counter was not updated accordingly.

This patch should fix the issue #1754. It must be backported to 2.6.

3 years agoCLEANUP: stconn: Don't expect to have no sedesc on detach
Christopher Faulet [Fri, 17 Jun 2022 07:39:59 +0000 (09:39 +0200)] 
CLEANUP: stconn: Don't expect to have no sedesc on detach

The stream connector must always have a defined sedesc. So there is no
reason to test it when the stconn is detached from the endpoint.

3 years agoMINOR: stream: Rely on stconn flags to abort stream destructive upgrade
Christopher Faulet [Fri, 17 Jun 2022 07:36:57 +0000 (09:36 +0200)] 
MINOR: stream: Rely on stconn flags to abort stream destructive upgrade

On destructive connection upgrade, instead of using the new mux name to
abort the old stream, we can relay on the stream connector flags. If it is
detached after the upgrade, it means the stream will not be resused by the
new mux and it must be aborted.

This patch may be backported to 2.6.

3 years agoBUG/MEDIUM: stream: Properly handle destructive client connection upgrades
Christopher Faulet [Thu, 16 Jun 2022 14:24:16 +0000 (16:24 +0200)] 
BUG/MEDIUM: stream: Properly handle destructive client connection upgrades

When the protocol is changed for a client connection at the stream level
(from TCP to H1/H2), there are two cases. The stream may be reused or
not. The first case, when the stream is reused is working. The second one is
buggy since the conn-stream refactoring and leads to a crash.

In this case, the new mux don't reuse the stream. It must be silently
aborted. However, its front stream connector is still referencing the
connection. So it must be detached. But it must be performed in two stages,
to be sure to not loose the context for the upgrade and to be able to
rollback on error. So now, before the upgrade, we prepare to detach the
stconn and it is finally detached if the upgrade succeeds. There is a trick
here. Because we pretend the stconn is detached but its state is preserved.

This patch must be backported to 2.6.

3 years agoBUG/MINOR: task: fix thread assignment in tasklet_kill()
Willy Tarreau [Wed, 15 Jun 2022 13:54:56 +0000 (15:54 +0200)] 
BUG/MINOR: task: fix thread assignment in tasklet_kill()

tasklet_kill() was introduced in 2.5-dev4 with commit 7b368339a
("MEDIUM: task: implement tasklet kill"), but a comparison error
there makes tasklets killed on thread 1 assigned to the killing
thread. Fortunately, the function was finally not used so there's
no harm right now, hence the minor tag, but this must be fixed and
backported in case a later fix relies on it.

This should be backported to 2.5.

3 years agoCLEANUP: quic: Remove any reference to boringssl
Frédéric Lécaille [Thu, 16 Jun 2022 13:06:44 +0000 (15:06 +0200)] 
CLEANUP: quic: Remove any reference to boringssl

I do not think we will support boringssl for QUIC soon ;)

3 years agoMEDIUM: quic: Compatible version negotiation implementation (draft-08)
Frédéric Lécaille [Tue, 14 Jun 2022 15:40:39 +0000 (17:40 +0200)] 
MEDIUM: quic: Compatible version negotiation implementation (draft-08)

At this time haproxy supported only incompatible version negotiation feature which
consists in sending a Version Negotiation packet after having received a long packet
without compatible value in its version field. This version value is the version
use to build the current packet. This patch does not modify this behavior.

This patch adds the support for compatible version negotiation feature which
allows endpoints to negotiate during the first flight or packets sent by the
client the QUIC version to use for the connection (or after the first flight).
This is done thanks to "version_information" parameter sent by both endpoints.
To be short, the client offers a list of supported versions by preference order.
The server (or haproxy listener) chooses the first version it also supported as
negotiated version.

This implementation has an impact on the tranport parameters handling (in both
direcetions). Indeed, the server must sent its version information, but only
after received and parsed the client transport parameters). So we cannot
encode these parameters at the same time we instantiated a new connection.

Add QUIC_TP_DRAFT_VERSION_INFORMATION(0xff73db) new transport parameter.
Add tp_version_information new C struct to handle this new parameter.
Implement quic_transport_param_enc_version_info() (resp.
quic_transport_param_dec_version_info()) to encode (resp. decode) this
parameter.
Add qc_conn_finalize() which encodes the transport parameters and configure
the TLS stack to send them.
Add ->negotiated_ictx quic_conn C struct new member to store the Initial
QUIC TLS context for the negotiated version. The Initial secrets derivation
is version dependent.
Rename ->version to ->original_version and add ->negotiated_version to
this C struct to reflect the QUIC-VN RFC denomination.
Modify most of the QUIC TLS API functions to pass a version as parameter.
Export the QUIC version definitions to be reused at least from quic_tp.c
(transport parameters.
Move the token check after the QUIC connection lookup. As this is the original
version which is sent into a Retry packet, and because this original version is
stored into the connection, we must check the token after having retreived this
connection.
Add packet version to traces.

See https://datatracker.ietf.org/doc/html/draft-ietf-quic-version-negotiation-08
for more information about this new feature.

3 years agoMINOR: quic: Released QUIC TLS extension for QUIC v2 draft
Frédéric Lécaille [Thu, 9 Jun 2022 05:32:06 +0000 (07:32 +0200)] 
MINOR: quic: Released QUIC TLS extension for QUIC v2 draft

This is not clear at all how to distinguish a QUIC draft version number from a
released one. And among these QUIC draft versions, which one must use the draft
QUIC TLS extension.

According to the QUIC implementations which support v2 draft, the TLS extension
(transport parameters) to be used is the released one
(TLS_EXTENSION_QUIC_TRANSPORT_PARAMETERS).

As the unique QUIC draft version we support is 0xff00001d and as at this time the
unique version with 0xff as most significant byte is this latter which must use
the draft TLS extension, we select the draft TLS extension
(TLS_EXTENSION_QUIC_TRANSPORT_PARAMETERS_DRAFT) only for such versions with 0xff
as most signification byte.

3 years agoMEDIUM: quic: Add QUIC v2 draft support
Frédéric Lécaille [Wed, 8 Jun 2022 17:28:36 +0000 (19:28 +0200)] 
MEDIUM: quic: Add QUIC v2 draft support

This is becoming difficult to handle the QUIC TLS related definitions
which arrive with a QUIC version (draft or not). So, here we add
quic_version C struct which does not define only the QUIC version number,
but also the QUIC TLS definitions which depend on a QUIC version.
Modify consequently all the QUIC TLS API to reuse these definitions
through new quic_version C struct.
Implement quic_pkt_type() function which return a packet type (0 up to 3)
depending on the QUIC version number.
Stop harding the Retry packet first byte in send_retry(): this is not more
possible because the packet type field depends on the QUIC version.
Also modify quic_build_packet_long_header() for the same reason: the packet
type depends on the QUIC version.
Add a quic_version C struct member to quic_conn C struct.
Modify qc_lstnr_pkt_rcv() to set this member asap.
Remove the version member from quic_rx_packet C struct: a packet is attached
asap to a connection (or dropped) which is the unique object which should
store the QUIC version.
Modify qc_pkt_is_supported_version() to return a supported quic_version C
struct from a version number.
Add Initial salt for QUIC v2 draft (initial_salt_v2_draft).

3 years agoCLEANUP: quid: QUIC draft-28 no more supported
Frédéric Lécaille [Wed, 8 Jun 2022 13:23:46 +0000 (15:23 +0200)] 
CLEANUP: quid: QUIC draft-28 no more supported

Remove this useless definition.

3 years agoMINOR: quic: Parse long packet version from qc_parse_hd_form()
Frédéric Lécaille [Wed, 8 Jun 2022 11:22:17 +0000 (13:22 +0200)] 
MINOR: quic: Parse long packet version from qc_parse_hd_form()

This is to prepare the support for QUIC v2 version. The packet type
depends on the version. So, we must parse early enough the version
before defining the type of each packet.

3 years agoBUG/MINOR: quic: Wrong PTO calculation
Frédéric Lécaille [Wed, 8 Jun 2022 08:09:39 +0000 (10:09 +0200)] 
BUG/MINOR: quic: Wrong PTO calculation

Due to missing brackets around the ternary C operator, quic_pto() could return zero
at the first run, before the QUIC connection was completely initialized. This leaded
the idle timeout task to be executed before this initialization completion. Then
this connection could be immediately released.

This bug was revealed by the multi_packet_client_hello QUIC tracker test.

Must be backported to 2.6.

3 years agoMINOR: quic: Add several nonce and key definitions for Retry tag
Frédéric Lécaille [Wed, 8 Jun 2022 06:26:03 +0000 (08:26 +0200)] 
MINOR: quic: Add several nonce and key definitions for Retry tag

The nonce and keys used to cipher the Retry tag depend on the QUIC version.
Add these definitions for 0xff00001d (draft-29) and v2 QUIC version. At least
draft-29 is useful for QUIC tracker tests with "quic-force-retry" enabled
on haproxy side.
Validated with -v 0xff00001d ngtcp2 option.
Could not validate the v2 nonce and key at this time because not supported.

3 years agoBUG/MINOR: quic: Stop hardcoding Retry packet Version field
Frédéric Lécaille [Tue, 7 Jun 2022 09:39:00 +0000 (11:39 +0200)] 
BUG/MINOR: quic: Stop hardcoding Retry packet Version field

Use the same version as the one received. This is safe because the
version is treated before anything else sending a Version packet.

Must be backported to 2.6.

3 years agoBUG/BUILD: h3: fix wrong label name
Amaury Denoyelle [Wed, 15 Jun 2022 13:52:27 +0000 (15:52 +0200)] 
BUG/BUILD: h3: fix wrong label name

A pretty ugly mistake introduced recently with an invalid goto statement
which prevents QUIC compilation on haproxy.

This must be backported on 2.6 as a complement to
  60ef19f137bad8cd97598970c708dd0bf4a89a70
  BUG/MINOR: h3/qpack: deal with too many headers

3 years agoMINOR: qpack: implement standalone decoder tool
Amaury Denoyelle [Tue, 14 Jun 2022 14:35:41 +0000 (16:35 +0200)] 
MINOR: qpack: implement standalone decoder tool

Implement a standalone binary to be able to easily a hex-string QPACK
stream. The binary must be compiled via the Makefile. Hex-strings are
specified on stdin.

3 years agoMINOR: qpack: improve decoding function
Amaury Denoyelle [Tue, 14 Jun 2022 15:17:07 +0000 (17:17 +0200)] 
MINOR: qpack: improve decoding function

Adjust decoding loop by using temporary ist for header name and value.
The header is inserted at the end of an iteration, which guarantee that
we do not insert name only in the list in case of an error on value
decoding. This also helps the function readability by centralizing the
LIST insert operation.

The return value of the decoding function is also changed. Now on
success the number of headers inserted in the input list is returned.
This change as no impact as success value is not used by the caller.
This is mainly done to have a behavior similar to hpack decoding
function.

3 years agoBUG/MINOR: h3/qpack: deal with too many headers
Amaury Denoyelle [Tue, 14 Jun 2022 15:38:36 +0000 (17:38 +0200)] 
BUG/MINOR: h3/qpack: deal with too many headers

ensures that we never insert too many entries in a headers input list.
On the decoding side, a new error QPACK_ERR_TOO_LARGE is reported in
this case.

This prevents crash if headers number on a H3 request or response is
superior to tune.http.maxhdr config value. Previously, a crash would
occur in QPACK decoding function.

Note that the process still crashes later with ABORT_NOW() because error
reporting on frame parsing is not implemented for now. It should be
treated with a RESET_STREAM frame in most cases.

This can be backported up to 2.6.

3 years agoMINOR: qpack: add ABORT_NOW on unimplemented decoding
Amaury Denoyelle [Tue, 14 Jun 2022 14:36:15 +0000 (16:36 +0200)] 
MINOR: qpack: add ABORT_NOW on unimplemented decoding

Post-base indices is not supported at the moment for decoding. This
should never be encountered as it is only used with a dynamic table.
However, haproxy deactivates support for the dynamic table via its
SETTINGS.

Use ABORT_NOW() if this situation happens anyway. This should help
debugging instead of silently failed without error reporting.

3 years agoBUG/MINOR: qpack: support header litteral name decoding
Amaury Denoyelle [Tue, 14 Jun 2022 14:34:55 +0000 (16:34 +0200)] 
BUG/MINOR: qpack: support header litteral name decoding

Complete QPACK decoding with full implementation of litteral field name
with litteral value representation. This change is mandatory to support
decoding of headers name not present in the QPACK static table.
Previously, these headers were silently ignored and not transferred on
the backend request.

QPACK decoding should now be sufficient to deal with all real
situations. Only post-base indices representation are not handled but
this should not cause a problem as they are only used for the dynamic
table whose size is null as announced by the haproxy implementation.

The direct impact of this change is that it should now be possible to
use complex webapp through a QUIC frontend.

This must be backported up to 2.6.

3 years agoMINOR: qpack: reduce dependencies on other modules
Amaury Denoyelle [Tue, 14 Jun 2022 14:34:32 +0000 (16:34 +0200)] 
MINOR: qpack: reduce dependencies on other modules

Clean up QPACK decoder API by removing dependencies on ncbuf and
MUX-QUIC. This reduces includes statements. It will also help to
implement a standalone QPACK decoder.

3 years agoMINOR: qpack: add comments and remove a useless trace
Amaury Denoyelle [Tue, 14 Jun 2022 15:34:53 +0000 (17:34 +0200)] 
MINOR: qpack: add comments and remove a useless trace

Add comments on the decoding function to facilitate code analysis.

Also remove the qpack_debug_hexdump() which prints the whole left buffer
on each header parsing. With large HEADERS frame payload, QPACK traces
are complicated to debug with this statement.

3 years agoDOC: design: update the task vs thread affinity requirements
Willy Tarreau [Tue, 14 Jun 2022 13:00:40 +0000 (15:00 +0200)] 
DOC: design: update the task vs thread affinity requirements

It looks like we'll need:
  - one share timers queue for the rare tasks that need to wake up
    anywhere
  - one private timers queue per thread
  - one global queue per group
  - one local queue per thread

And may be we can simply get rid of any global/shared run queue as
we don't seem to have any task bound to a subset of threads.

3 years agoOPTIM: task: do not consult shared WQ when we're already full
Willy Tarreau [Tue, 14 Jun 2022 13:04:34 +0000 (15:04 +0200)] 
OPTIM: task: do not consult shared WQ when we're already full

If we've stopped consulting the local wait queue due to too many tasks
(max_processed <= 0), there's no point starting to lock the shared WQ,
check the first task's expiration date, upgrading the lock just to
refrain from doing the work because of the limit. All this does is
increase contention on an already contended system.

Note that there is still a fairness issue in this WQ dequeuing code. If
each thread is busy with expired tasks, no thread will dequeue the global
ones. In practice it doesn't make much sense and should quickly resorb,
but it could be nice to have an alternating flag indicating where to
start from on next call to improve this.

3 years agoMINOR: thread: get rid of MAX_THREADS_MASK
Willy Tarreau [Tue, 14 Jun 2022 09:18:40 +0000 (11:18 +0200)] 
MINOR: thread: get rid of MAX_THREADS_MASK

This macro was used both for binding and for lookups. When binding tasks
or FDs, using all_threads_mask instead is better as it will later be per
group. For lookups, ~0UL always does the job. Thus in practice the macro
was already almost not used anymore since the rest of the code could run
fine with a constant of all ones there.

3 years agoCLEANUP: hlua: check for at least 2 threads on a task
Willy Tarreau [Tue, 14 Jun 2022 09:00:46 +0000 (11:00 +0200)] 
CLEANUP: hlua: check for at least 2 threads on a task

In 1.9-dev1, commit 5bc9972ed ("BUG/MINOR: lua/threads: Make lua's tasks
sticky to the current thread") to detect unconfigured Lua tasks that could
run on any thread, by comparing their thread mask with MAX_THREADS_MASK.
The proper way to do it is to check for at least 2 threads in their mask
in fact. This is more reliable and allows to get rid of MAX_THREADS_MASK
there.

3 years agoMINOR: tinfo: remove the global thread ID bit (tid_bit)
Willy Tarreau [Tue, 14 Jun 2022 08:43:01 +0000 (10:43 +0200)] 
MINOR: tinfo: remove the global thread ID bit (tid_bit)

Each thread has its own local thread id and its own global thread id,
in addition to the masks corresponding to each. Once the global thread
ID can go beyond 64 it will not be possible to have a global thread Id
bit anymore, so better start to remove it and use only the local one
from the struct thread_info.

3 years agoCLEANUP: quic: use task_new_on() for single-threaded tasks
Willy Tarreau [Mon, 13 Jun 2022 14:31:53 +0000 (16:31 +0200)] 
CLEANUP: quic: use task_new_on() for single-threaded tasks

This simply replaces a call to task_new(1<<thr) with task_new_on(thr)
so that we can later isolate the changes required to add more thread
group stuff.

3 years agoMINOR: task: move profiling bit to per-thread
Willy Tarreau [Mon, 13 Jun 2022 13:59:39 +0000 (15:59 +0200)] 
MINOR: task: move profiling bit to per-thread

Instead of having a global mask of all the profiled threads, let's have
one flag per thread in each thread's flags. They are never accessed more
than one at a time an are better located inside the threads' contexts for
both performance and scalability.

3 years agoBUG/MEDIUM: mux-quic: fix segfault on flow-control frame cleanup
Amaury Denoyelle [Mon, 13 Jun 2022 09:30:46 +0000 (11:30 +0200)] 
BUG/MEDIUM: mux-quic: fix segfault on flow-control frame cleanup

LIST_ELEM macro was incorrectly used in the loop when purging
flow-control frames from qcc.lfctl.frms on MUX release. This caused a
segfault in qc_release() due to an invalid quic_frame pointer instance.

The occurence of this bug seems fairly rare. To happen, some
flow-control frames must have been allocated but not yet sent just as
the MUX release is triggered.

I did not find a reproducer scenario. Instead, I artificially triggered
it by inserting a quic_frame in qcc.lfctl.frms just before purging it in
qc_release() using the following snippet.

        struct quic_frame *frm;
        frm = pool_zalloc(pool_head_quic_frame);
        LIST_INIT(&frm->reflist);
        frm->type = QUIC_FT_MAX_DATA;
        frm->max_data.max_data = 0;
        LIST_APPEND(&qcc->lfctl.frms, &frm->list);

This should fix github issue #1747.

This must be backported up to 2.6.

3 years agoBUG/MEDIUM: cli: Notify cli applet won't consume data during request processing
Christopher Faulet [Wed, 1 Jun 2022 15:25:42 +0000 (17:25 +0200)] 
BUG/MEDIUM: cli: Notify cli applet won't consume data during request processing

The CLI applet process one request after another. Thus, when several
requests are pipelined, it is important to notify it won't consume remaining
outgoing data while it is processing a request. Otherwise, the applet may be
woken up in loop. For instance, it may happen with the HTTP client while we
are waiting for the server response if a shutr is received.

This patch must be backported in all supported versions after an observation
period. But a massive refactoring was performed in 2.6. So, for the 2.5 and
below, the patch will have to be adapted. Note also that, AFAIK, the bug can
only be triggered by the HTTP client for now.

3 years agoBUG/MEDIUM: stconn: Don't wakeup applet for send if it won't consume data
Christopher Faulet [Wed, 1 Jun 2022 15:35:34 +0000 (17:35 +0200)] 
BUG/MEDIUM: stconn: Don't wakeup applet for send if it won't consume data

in .chk_snd applet callback function, we must not wake up an applet if
SE_FL_WONT_CONSUME flag is set. Indeed, if an applet explicitly specify it
will not consume any outgoing data, it is useless to wake it up when more
data are sent. Note the applet may still be woken up for another reason. In
this case SE_FL_WONT_CONSUME flag will be removed. It is the applet
responsibility to set it again, if necessary.

This patch must be backported to 2.6 after an observation period. On earlier
versions, the bug probably exists too. However, because a massive
refactoring was performed in 2.6, the patch will have to be adapted and
carefully reviewed/tested if it is backported..

3 years agoCLEANUP: check: Remove useless tests on check's stream-connector
Christopher Faulet [Mon, 13 Jun 2022 05:59:46 +0000 (07:59 +0200)] 
CLEANUP: check: Remove useless tests on check's stream-connector

Since the conn-stream refactoring, from the time the health-check is in
progress, its stream-connector is always defined. So, some tests on it are
useless and can be removed.

This patch should fix the issue #1739.

3 years agoBUG/MINOR: tcp-rules: Make action call final on read error and delay expiration
Christopher Faulet [Fri, 10 Jun 2022 14:48:47 +0000 (16:48 +0200)] 
BUG/MINOR: tcp-rules: Make action call final on read error and delay expiration

When a TCP content ruleset is evaluated, we stop waiting for more data if
the inspect-delay is reached, if there is a read error or if we know no more
data will be received. This last point is only valid for ACLs. An action may
decide to yield for another reason. For instance, in the SPOE, the
"send-spoe-group" action yields while the agent response is not
received. Thus, now, an action call is final only when the inspect-delay is
reached or if there is a read error. But it is possible for an action to
yield if the buffer is full or if CF_EOI flag is set.

This patch could be backported to all supported versions.

3 years agoBUG/MINOR: mux-quic: fix memleak on frames rejected by transport
Amaury Denoyelle [Fri, 10 Jun 2022 13:16:40 +0000 (15:16 +0200)] 
BUG/MINOR: mux-quic: fix memleak on frames rejected by transport

When the MUX transfers a big amount of data to the client, the transport
layer may reject some of them because of the congestion controller
limit. Frames built by the MUX are thus dropped, even if streams transferred
data are kept in buffers for future new frames.

Thus, the MUX is required to free rejected frames. This fixes a memory
leak which may grow with important data transfers.

It should be backported to 2.6 after it has been tested and validated.

3 years agoMINOR: mux-quic: complete BUG_ON on TX flow-control enforcing
Amaury Denoyelle [Fri, 10 Jun 2022 13:18:12 +0000 (15:18 +0200)] 
MINOR: mux-quic: complete BUG_ON on TX flow-control enforcing

TX flow-control enforcing is not straightforward : it requires the usage
of several counters at stream and connection level, in part due to the
difficult sending API between MUX and quic-conn layers.

To strengthen this part and ensures it behaves as expected, some
existing BUG_ON statements were adjusted and new one were added. This
should help to catch errors as early as possible, as in the case with
github issue #1738.

3 years agoBUG/MEDIUM: mux-quic: fix flow control connection Tx level
Amaury Denoyelle [Fri, 10 Jun 2022 13:16:21 +0000 (15:16 +0200)] 
BUG/MEDIUM: mux-quic: fix flow control connection Tx level

The flow control enforced at connection level is incorrectly calculated.
There is a risk of exceeding the limit. In most cases, this results in a
segfault produced by a BUG_ON which is here to catch this kind of error.
If not compiled with DEBUG_STRICT, this should generate a connection
closed by the client due to the flow control overflow.

The problem is encountered when transfered payload is big enough to fill
the transport congestion window. In this case, some data are rejected by
the transport layer and kept by the MUX to be reemitted later. However,
these preserved data are not counted on the connection flow control when
resubmitted, which gradually amplify the gap between expected and real
consumed flow control.

To fix this, handle the flow-control at the connection level in the same
way as the stream level. A new field qcc.tx.offsets is incremented as
soon as data are transfered between stream TX buffers. The field
qcc.tx.sent_offsets is preserved to count bytes handled by the transport
layer and stop the MUX transfer if limit is reached.

As already stated, this bug can occur during transfers with enough
emitted data, over multiple streams. When using a single stream, the
flow control at the stream level hides it.

The BUG_ON crash is reproduced systematically with quiche client :
$ quiche-client --no-verify --http-version HTTP/3 -n 10000 https://127.0.0.1:20443/10K

This must be backported up to 2.6 when confirmed to work as expected.

This should fix github issue #1738.

3 years agoDOC: design: update the notes on thread groups
Willy Tarreau [Fri, 10 Jun 2022 14:05:59 +0000 (16:05 +0200)] 
DOC: design: update the notes on thread groups

Some (few) elements were already done, others were clarified and worth
mentionning.

3 years agoBUG/MINOR: cli/stats: add missing trailing LF after "show info json"
Willy Tarreau [Fri, 10 Jun 2022 13:12:21 +0000 (15:12 +0200)] 
BUG/MINOR: cli/stats: add missing trailing LF after "show info json"

This is the continuation of commit 5a0e7ca5d ("BUG/MINOR: cli/stats: add
missing trailing LF after JSON outputs"). There's also a "show info json"
command which was also missing the trailing LF. It's constructed exactly
like the "show stat json", in that it dumps a series of fields without any
LF. The difference however is that for the stats output, everything was
enclosed in an array which required an LF *after* the closing bracket,
while here there's no such array so we have to emit the LF after the loop.
That makes the two functions a bit inconsistent, it's quite annoying, but
making them better would require sending one LF per line in the stats
output, which is not particularly interesting.

Given that it took 5+ years to spot that this code wasn't working as
expected it doesn't seem worth investing much time trying to refactor
it to make it look cleaner at the risk of breaking other obscure parts.

3 years agoBUG/MINOR: server: do not enable DNS resolution on disabled proxies
Willy Tarreau [Fri, 10 Jun 2022 09:11:44 +0000 (11:11 +0200)] 
BUG/MINOR: server: do not enable DNS resolution on disabled proxies

Leonhard Wimmer reported an interesting bug in github issue #1742.
Servers in disabled proxies that are configured for resolution are still
subscribed to DNS resolutions, but the LB algos are not initialized at
all since the proxy is disabled, so when the server state changes,
attempts to update its status cause a crash when the server's weight
is recalculated via a divide by the proxy's total weight which is zero.

This should be backported to all versions. Beware that before 2.5 or
so, there's no PR_FL_DISABLED flag, instead px->disabled should be
used (2.3-2.4) or PR_STSTOPPED for older versions.

Thanks to Leonhard for his report and quick test!

3 years agoBUG/MINOR: cli/stats: add missing trailing LF after JSON outputs
Willy Tarreau [Fri, 10 Jun 2022 07:21:22 +0000 (09:21 +0200)] 
BUG/MINOR: cli/stats: add missing trailing LF after JSON outputs

Patrick Hemmer reported that we have a bug in the CLI commands
"show stat json" and "show schema json" in that they forget the trailing
LF that's required to mark the end of the response. This has been the
case since the introduction of the feature in 1.8-dev1 by commit 6f6bb380e
("MEDIUM: stats: Add show json schema"), so this fix may be backported to
all versions.

3 years agoBUG/MEDIUM: h3: fix SETTINGS parsing
Amaury Denoyelle [Thu, 9 Jun 2022 09:54:38 +0000 (11:54 +0200)] 
BUG/MEDIUM: h3: fix SETTINGS parsing

Function used to parse SETTINGS frame is incorrect as it does not stop
at the frame length but continue to parse beyond it. In most cases, it
will result in a connection closed with error H3_FRAME_ERROR.

This bug can be reproduced with clients that sent more than just a
SETTINGS frame on the H3 control stream. This is notably the case with
aioquic which emit a MAX_PUSH_ID after SETTINGS.

This bug has been introduced in the current dev release, by the
following patch
  62eef85961f4a2a241e0b24ef540cc91f156b842
  MINOR: mux-quic: simplify decode_qcs API
thus, it does not need to be backported.

3 years agoBUG/MINOR: h3: fix frame type definition
Amaury Denoyelle [Thu, 9 Jun 2022 09:51:01 +0000 (11:51 +0200)] 
BUG/MINOR: h3: fix frame type definition

Frame type has changed during HTTP/3 specification process. Adjust it to
reflect the latest RFC 9114 status.

Concretly, type for GOAWAY and MAX_PUSH_ID frames has been adjusted.
The impact of this bug is limited as currently these frames are not
handled by haproxy and are ignored.

This can be backported up to 2.6.

3 years agoOPTIM: mux-h2: increase h2_settings_initial_window_size default to 64k
Glenn Strauss [Sun, 5 Jun 2022 02:11:50 +0000 (22:11 -0400)] 
OPTIM: mux-h2: increase h2_settings_initial_window_size default to 64k

This changes the default from RFC 7540's default 65535 (64k-1) to avoid
avoid some degenerative WINDOW_UPDATE behaviors in the wild observed with
clients using 65536 as their buffer size, and have to complete each block
with a 1-byte frame, which with some servers tend to degenerate in 1-byte
WU causing more 1-byte frames to be sent until the transfer almost only
uses 1-byte frames.

More details here: https://github.com/nghttp2/nghttp2/issues/1722

As mentioned in previous commit (MEDIUM: mux-h2: try to coalesce outgoing
WINDOW_UPDATE frames) the issue could not be reproduced with haproxy but
individual WU frames are sent so theoretically nothing prevents this from
happening. As such it should be backported as a workaround for already
deployed clients after watching for any possible side effect with rare
clients. As an added benefit, uploads from curl now use less DATA frames
(all are 16384 now). Note that the previous patch alone is sufficient to
stop the issue with curl in case this one would need to be reverted.

[wt: edited commit messaged, updated doc]

3 years agoMEDIUM: mux-h2: try to coalesce outgoing WINDOW_UPDATE frames
Willy Tarreau [Wed, 8 Jun 2022 14:32:22 +0000 (16:32 +0200)] 
MEDIUM: mux-h2: try to coalesce outgoing WINDOW_UPDATE frames

Glenn Strauss from Lighttpd reported a corner case affecting curl+lighttpd
that causes some uploads to degenerate to extremely suboptimal conditions
under certain circumstances, and noted that many other implementations
were possibly not safe against this degradation.

Glenn's detailed analysis is available here:

   https://github.com/nghttp2/nghttp2/issues/1722

In short, curl uses a 65536 bytes buffer and the default stream window
is 65535, with 16384 bytes per frame. Curl will then send 3 frames of
16384 bytes followed by one of 16383, will wait for a window update to
send the last byte before recycling the buffer to read the next 64kB.
On each round like this, one extra single-byte frame will be sent, and
if ACKs for these single-byte frames are not aggregated, this will only
allow the client to send one extra byte at a time. At some point it is
possible (at least Glenn observed it) to have mostly 1-byte frames in
the transfer, resulting in huge CPU usage and a long transfer.

It was not possible to reproduce this with haproxy, even when playing
with frame sizes, buffer sizes nor window sizes. One reason seems to
be that we're using the same buffer size for the connection and the
stream and that the frame headers prevent the filling of the window
from happening on the same boundaries as on the sender. However it
does occasionally happen to see up to two 1-byte data frames in a row,
indicating that there's definitely room for improvement.

The WINDOW_UPDATE frames for the connection are sent at the end of the
demuxing, but the ones for the streams are currently sent immediately
after a DATA frame is processed, mostly for convenience. But we don't
need to proceed like this, we already have the counter of unacked bytes
in rcvd_s, so we can simply use that to decide when to send an ACK. It
must just be done before processing a new frame. The benefit is that
contiguous frames for the same stream will now only produce a single
WU, like for the connection. On complicated tests involving a client
that was limited to 100 Mbps transfers and a dummy Lua-based payload
consumer, it was possible to see the number of stream WU frames being
halved for a 100 MB transfer, which is already a nice saving anyway.

Glenn proposed a better workaround consisting in increasing the
default window size to 65536. This will be done in a separate patch
so that both can be studied independently in field and backported as
needed.

This patch is not much complicated and shold be backportable. It just
needs to be tested in development first.

3 years agoBUG/MINOR: h3: fix incorrect BUG_ON assert on SETTINGS parsing
Amaury Denoyelle [Wed, 8 Jun 2022 16:21:32 +0000 (18:21 +0200)] 
BUG/MINOR: h3: fix incorrect BUG_ON assert on SETTINGS parsing

BUG_ON() assertion to check for incomplete SETTINGS frame is incorrect.
It should check if frame length is greater, not smaller, than current
buffer data. Anyway, this BUG_ON() is useless as h3_decode_qcs()
prevents parsing of an incomplete frame, except for H3 DATA. Remove it
to fix this bug.

This bug was introduced in the current dev tree by commit
  commit 62eef85961f4a2a241e0b24ef540cc91f156b842
  MINOR: mux-quic: simplify decode_qcs API
Thus it does not need to be backported.

This fixes crashes which happen with DEBUG_STRICT=2. Most notably, this
is reproducible with clients that emit more than just a SETTINGS frame
on the H3 control stream. It can be reproduced with aioquic for example.

3 years agoREGTESTS: healthcheckmail: Relax health-check failure condition
Christopher Faulet [Wed, 8 Jun 2022 14:55:21 +0000 (16:55 +0200)] 
REGTESTS: healthcheckmail: Relax health-check failure condition

The info field in the log message may change. For instance, on FreeBSD, a
"broken pipe" is reported. Thus, the expected log message must be more
generic.

3 years agoREGTESTS: healthcheckmail: Update the test to be functionnal again
Christopher Faulet [Wed, 8 Jun 2022 09:57:52 +0000 (11:57 +0200)] 
REGTESTS: healthcheckmail: Update the test to be functionnal again

This reg-test is broken since a while. It was simplified to be
functionnal. Now, it only test email alerts.

3 years agoBUG/MEDIUM: mailers: Set the object type for check attached to an email alert
Christopher Faulet [Wed, 8 Jun 2022 07:17:14 +0000 (09:17 +0200)] 
BUG/MEDIUM: mailers: Set the object type for check attached to an email alert

The health-check attached to an email alert has no type. It is unexpected,
and since the 2.6, it is important because we rely on it to know the
application type in front of a connection at the stream-connector
level. Because the object type is not set, the SE descriptor is not properly
initialized, leading to a segfault when a connection to the SMTP server is
established.

This patch must be backported to 2.6 and may be backported as far as
2.0. However, it is only an issue for the 2.6 and upper.

3 years agoBUG/MINOR: checks: Properly handle email alerts in trace messages
Christopher Faulet [Wed, 8 Jun 2022 07:12:58 +0000 (09:12 +0200)] 
BUG/MINOR: checks: Properly handle email alerts in trace messages

There is no server for email alerts. So the trace messages must be adapted
to handle this case. Information related to the server are now skipped for
email alerts and "[EMAIL]" prefix is used.

This patch must be backported as far as 2.4.

3 years agoBUG/MINOR: trace: Test server existence for health-checks to get proxy
Christopher Faulet [Wed, 8 Jun 2022 07:06:15 +0000 (09:06 +0200)] 
BUG/MINOR: trace: Test server existence for health-checks to get proxy

Email alerts are based on health-checks but with no server. Thus, in
__trace() function, responsible to write a trace message, we must be
prepared to have no server and thus no proxy.

This patch must be backported as far as 2.4.

3 years agoDEV: tcploop: add minimal UDP support
Willy Tarreau [Tue, 7 Jun 2022 10:09:55 +0000 (12:09 +0200)] 
DEV: tcploop: add minimal UDP support

Passing "-u" turns to SOCK_DGRAM + IPPROTO_UDP, which still allows
bind/connect()/recv()/send() and can be convenient for experimentation
purposes.

3 years agoDEV: tcploop: add a new "bind" command to bind to ip/port.
Willy Tarreau [Tue, 7 Jun 2022 10:03:48 +0000 (12:03 +0200)] 
DEV: tcploop: add a new "bind" command to bind to ip/port.

The Listen command automatically relies on it (without passing its
argument), and both Listen and Connect now support working with the
existing socket, so that it's possible to Bind an ip:port on an
existing socket or to create a new one for the purpose of listening
or connecting. It now becomes possible to do:

   tcploop 0 L1234 C8888

to connect from port 1234 to port 8888.

3 years agoDEV: tcploop: permit port 0 to ease handling of default options
Willy Tarreau [Tue, 7 Jun 2022 10:06:04 +0000 (12:06 +0200)] 
DEV: tcploop: permit port 0 to ease handling of default options

This will also be convenient when binding to an IP and no port.

3 years agoDEV: tcploop: factor out the socket creation
Willy Tarreau [Tue, 7 Jun 2022 09:55:45 +0000 (11:55 +0200)] 
DEV: tcploop: factor out the socket creation

This will later permit to separately bind() before connect(). Let's
first deal with existing sockets.

3 years agoDEV: tcploop: make it possible to change the target address of a connect()
Willy Tarreau [Tue, 7 Jun 2022 09:46:57 +0000 (11:46 +0200)] 
DEV: tcploop: make it possible to change the target address of a connect()

Sometimes it's more convenient to be able to specify where to connect on
the connect() statement, let's make it possible to pass it in argument to
the C command.

3 years agoDEV: tcploop: make the current address the default address
Willy Tarreau [Tue, 7 Jun 2022 09:36:20 +0000 (11:36 +0200)] 
DEV: tcploop: make the current address the default address

It's difficult to refine bind/connect right now, let's make the address
optionall by turning it to the default one.

3 years agoDEV: tcploop: reorder options in the usage message
Willy Tarreau [Tue, 7 Jun 2022 09:29:16 +0000 (11:29 +0200)] 
DEV: tcploop: reorder options in the usage message

Options have become difficult to find, let's reorder them alphabetically.

3 years agoBUILD: compiler: implement unreachable for older compilers too
Willy Tarreau [Wed, 8 Jun 2022 10:14:23 +0000 (12:14 +0200)] 
BUILD: compiler: implement unreachable for older compilers too

Benoit Dolez reported that gcc-4.4 emits several "may be used
uninitialized" warnings around places where there are BUG_ON()
or ABORT_NOW(). The reason is that __builtin_unreachable() was
introduced in gcc-4.5 thus older ones do not know that the code
after such statements is not reachable.

This patch solves the problem by deplacing the statement with
an infinite loop on older versions. The compiler knows that the
code following it cannot be reached, and this is quite cheap
(2 to 4 bytes depending on architectures). It even reduces the
code size a little bit as the compiler doesn't have to optimize
for branches that do not exist.

This may be backported to older versions.

3 years agoBUILD: quic: fix anonymous union for gcc-4.4
Benoit DOLEZ [Wed, 8 Jun 2022 07:28:56 +0000 (09:28 +0200)] 
BUILD: quic: fix anonymous union for gcc-4.4

Building QUIC with gcc-4.4 on el6 shows this error:

src/xprt_quic.c: In function 'qc_release_lost_pkts':
src/xprt_quic.c:1905: error: unknown field 'loss' specified in initializer
compilation terminated due to -Wfatal-errors.
make: *** [src/xprt_quic.o] Error 1
make: *** Waiting for unfinished jobs....

Initializing an anonymous form of union like :
     struct quic_cc_event ev = {
          (...)
          .loss.time_sent = newest_lost->time_sent,
          (...)
     };

generates an error with gcc-4.4 but not when initializing the
fields outside of the declaration.

3 years agoBUG/MINOR: h3: fix return value on decode_qcs on error
Amaury Denoyelle [Tue, 7 Jun 2022 16:24:34 +0000 (18:24 +0200)] 
BUG/MINOR: h3: fix return value on decode_qcs on error

Convert return code to -1 when an error has been detected. This is
required since the previous API change on return value from the patch :

  1f21ebdd7686bf435682cacd31e635db0c65b061
  MINOR: mux-quic/h3: adjust demuxing function return values

Without this, QUIC MUX won't consider the call as an error and will try
to remove one byte from the buffer. This may cause a BUG_ON failure if
the buffer is empty at this stage.

This bug was introduced in the current dev tree. Does not need to be
backported.

3 years agoMINOR: mux-quic/h3: adjust demuxing function return values
Amaury Denoyelle [Tue, 7 Jun 2022 15:30:55 +0000 (17:30 +0200)] 
MINOR: mux-quic/h3: adjust demuxing function return values

Clean the API used by decode_qcs() and transcoder internal functions.
Parsing functions now returns a ssize_t which represents the number of
consumed bytes or a negative error code. The total consumed bytes is
returned via decode_qcs().

The API is now unified and cleaner. The MUX can thus simply use the
return value of decode_qcs() instead of substracting the data bytes in
the buffer before and after the call. Transcoders functions are not
anymore obliged to remove consumed bytes from the buffer which was not
obvious.

3 years agoMINOR: mux-quic: simplify decode_qcs API
Amaury Denoyelle [Fri, 3 Jun 2022 14:40:34 +0000 (16:40 +0200)] 
MINOR: mux-quic: simplify decode_qcs API

Slightly modify decode_qcs function used by transcoders. The MUX now
gives a buffer instance on which each transcoder is free to work on it.
At the return of the function, the MUX removes consume data from its own
buffer.

This reduces the number of invocation to qcs_consume at the end of a
full demuxing process. The API is also cleaner with the transcoders not
responsible of calling it with the risk of having the input buffer
freed if empty.

3 years agoMINOR: h3: add h3c pointer into h3s instance
Amaury Denoyelle [Fri, 3 Jun 2022 13:29:07 +0000 (15:29 +0200)] 
MINOR: h3: add h3c pointer into h3s instance

As a mirror to qcc/qcs types, add a h3c pointer into h3s struct. This
should help to clean up H3 code and avoid to use qcs.qcc.ctx to retrieve
the h3c instance.

3 years agoMINOR: connection: support HTTP/3.0 for smp_*_http_major fetch
Amaury Denoyelle [Tue, 7 Jun 2022 09:57:20 +0000 (11:57 +0200)] 
MINOR: connection: support HTTP/3.0 for smp_*_http_major fetch

smp_fc_http_major may be used to return the http version as an integer
used on the frontend or backend side. Previously, the handler only
checked for version 2 or 1 as a fallback. Extend it to support version 3
with the QUIC mux.

3 years agoREGTESTS: restrict_req_hdr_names: Extend supported versions
Christopher Faulet [Tue, 7 Jun 2022 06:21:18 +0000 (08:21 +0200)] 
REGTESTS: restrict_req_hdr_names: Extend supported versions

This reg-test was backported as far as 2.0. Thus, extend supported versions
accordingly.

This patch must be backported as far as 2.0.

3 years agoREGTESTS: http_abortonclose: Extend supported versions
Christopher Faulet [Tue, 7 Jun 2022 06:20:12 +0000 (08:20 +0200)] 
REGTESTS: http_abortonclose: Extend supported versions

This reg-test was backported as far as 2.0. Thus, extend supported versions
accordingly.

This patch must be backported as far as 2.0.

3 years agoBUG/MINOR: ssl_ckch: Fix another possible uninitialized value
Christopher Faulet [Fri, 3 Jun 2022 14:34:30 +0000 (16:34 +0200)] 
BUG/MINOR: ssl_ckch: Fix another possible uninitialized value

Commit d6c66f06a ("MINOR: ssl_ckch: Remove service context for "set ssl
crl-file" command") introduced a regression leading to a build error because
of a possible uninitialized value. It is now fixed.

This patch must be backported as far as 2.5.

3 years agoBUILD: ssl_ckch: Fix build error about a possible uninitialized value
Christopher Faulet [Fri, 3 Jun 2022 14:37:31 +0000 (16:37 +0200)] 
BUILD: ssl_ckch: Fix build error about a possible uninitialized value

A build error is reported about the path variable in the switch statement on
the commit type, in cli_io_handler_commit_cafile_crlfile() function. The
enum contains only 2 values, but a default clause has been added to return an
error to make GCC happy.

This patch must be backported as far as 2.5.

3 years agoBUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_crlfile I/O handler
Christopher Faulet [Fri, 3 Jun 2022 14:26:56 +0000 (16:26 +0200)] 
BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_crlfile I/O handler

Commit 9a99e5478 ("BUG/MINOR: ssl_ckch: Dump CRL transaction only once if
show command yield") introduced a regression leading to a build error
because of a possible uninitialized value. It is now fixed.

This patch must be backported as far as 2.5.

3 years agoBUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cafile I/O handler
Christopher Faulet [Fri, 3 Jun 2022 14:25:35 +0000 (16:25 +0200)] 
BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cafile I/O handler

Commit 5a2154bf7 ("BUG/MINOR: ssl_ckch: Dump CA transaction only once if
show command yield") introduced a regression leading to a build error
because of a possible uninitialized value. It is now fixed.

This patch must be backported as far as 2.5.

3 years agoBUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cert I/O handler
Christopher Faulet [Fri, 3 Jun 2022 14:24:02 +0000 (16:24 +0200)] 
BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cert I/O handler

Commit 3e94f5d4b ("BUG/MINOR: ssl_ckch: Dump cert transaction only once if
show command yield") introduced a regression leading to a build error
because of a possible uninitialized value. It is now fixed.

This patch must be backported as far as 2.2.

3 years agoMINOR: ssl_ckch: Remove service context for "set ssl crl-file" command
Christopher Faulet [Fri, 3 Jun 2022 09:59:10 +0000 (11:59 +0200)] 
MINOR: ssl_ckch: Remove service context for "set ssl crl-file" command

This command does not have I/O handle function. All is done in the command
parsing function. So there is no reason to have dedicated context.

3 years agoMINOR: ssl_ckch: Remove service context for "set ssl ca-file" command
Christopher Faulet [Fri, 3 Jun 2022 09:56:26 +0000 (11:56 +0200)] 
MINOR: ssl_ckch: Remove service context for "set ssl ca-file" command

This command does not have I/O handle function. All is done in the command
parsing function. So there is no reason to have dedicated context.

3 years agoMINOR: ssl_ckch: Remove service context for "set ssl cert" command
Christopher Faulet [Fri, 3 Jun 2022 09:50:40 +0000 (11:50 +0200)] 
MINOR: ssl_ckch: Remove service context for "set ssl cert" command

This command does not have I/O handle function. All is done in the command
parsing function. So there is no reason to have dedicated context.

3 years agoMINOR: ssl_ckch: Simplify structure used to commit changes on CA/CRL entries
Christopher Faulet [Fri, 3 Jun 2022 09:42:38 +0000 (11:42 +0200)] 
MINOR: ssl_ckch: Simplify structure used to commit changes on CA/CRL entries

The same type is used for CA and CRL entries. So, in commit_cert_ctx
structure, there is no reason to have different fields for the CA and CRL
entries.

3 years agoCLEANUP: ssl_ckch: Remove unused field in commit_cacrlfile_ctx structure
Christopher Faulet [Fri, 3 Jun 2022 09:35:37 +0000 (11:35 +0200)] 
CLEANUP: ssl_ckch: Remove unused field in commit_cacrlfile_ctx structure

.next_ckchi field is not used by functions responsible to commit changes on
CA/CRL entries. It can be removed.

3 years agoBUG/MINOR: ssl_ckch: Init right field when parsing "commit ssl crl-file" cmd
Christopher Faulet [Fri, 3 Jun 2022 09:32:05 +0000 (11:32 +0200)] 
BUG/MINOR: ssl_ckch: Init right field when parsing "commit ssl crl-file" cmd

.next_ckchi_link field must be initialized to NULL instead of .next_ckchi in
cli_parse_commit_crlfile() function. Only '.nex_ckchi_link' is used in the
I/O handler.

This patch must be backported as far as 2.5 with some adaptations for the 2.5.