16131 Commits

Author SHA1 Message Date
Remi Tricot-Le Breton
f87c67e5e4 MINOR: ssl: Add 'show ssl providers' cli command and providers list in -vv option
Starting from OpenSSLv3, providers are at the core of cryptography
functions. Depending on the provider used, the way the SSL
functionalities work could change. This new 'show ssl providers' CLI
command allows to show what providers were loaded by the SSL library.
This is required because the provider configuration is exclusively done
in the OpenSSL configuration file (/usr/local/ssl/openssl.cnf for
instance).
A new line is also added to the 'haproxy -vv' output containing the same
information.
2022-04-21 14:54:45 +02:00
Amaury Denoyelle
97e84c6c69 MINOR: cfg-quic: define tune.quic.conn-buf-limit
Add a new global configuration option to set the limit of buffers per
QUIC connection. By default, this value is set to 30.
2022-04-21 12:04:04 +02:00
Amaury Denoyelle
1b2dba531d MINOR: mux-quic: implement immediate send retry
Complete qc_send function. After having processed each qcs emission, it
will now retry send on qcs where transfer can continue. This is useful
when qc_stream_desc buffer is full and there is still data present in
qcs buf.

To implement this, each eligible qcs is inserted in a new list
<qcc.send_retry_list>. This is done on send notification from the
transport layer through qcc_streams_sent_done(). Retry emission until
send_retry_list is empty or the transport layer cannot proceed more
data.

Several send operations are now called on two different places. Thus a
new _qc_send_qcs() function is defined to factorize the code.

This change should maximize the throughput during QUIC transfers.
2022-04-21 12:04:04 +02:00
Amaury Denoyelle
d2f80a2e63 MINOR: quic: limit total stream buffers per connection
MUX streams can now allocate multiple buffers for sending. quic-conn is
responsible to limit the total count of allowed allocated buffers. A
counter is stored in the new field <stream_buf_count>.

For the moment, the value is hardcoded to 30.

On stream buffer allocation failure, the qcc MUX is flagged with
QC_CF_CONN_FULL. The MUX is then woken up as soon as a buffer is freed,
most notably on ACK reception.
2022-04-21 12:04:04 +02:00
Amaury Denoyelle
1b81dda3e0 MINOR: quic-stream: refactor ack management
Acknowledge of STREAM has been complexified with the introduction of
stream multi buffers. Two functions are executing roughly the same set
of instructions in xprt_quic.c.

To simplify this, move the code complexity in a new function
qc_stream_desc_ack(). It will handle offset calculation, removal of
data, freeing oldest buffer and freeing stream instance if required.
The qc_stream_desc API is cleaner as qc_stream_desc_free_buf() ambiguous
function has been removed.
2022-04-21 12:04:04 +02:00
Amaury Denoyelle
a456920491 MEDIUM: quic: implement multi-buffered Tx streams
Complete the qc_stream_desc type to support multiple buffers on
emission. The main objective is to increase the transfer throughput.
The MUX is now able to transfer more data without having to wait ACKs.

To implement this feature, a new type qc_stream_buf is declared. it
encapsulates a buffer with a list element. New functions are defined to
retrieve the current buffer, release it or allocate a new one. Each
buffer is kept in the qc_stream_desc list until all of its data is
acknowledged.

On the MUX side, a qcs uses the current stream buffer to transfer data.
Once the buffer is full, it is released and a new one will be allocated
on a future qc_send() invocation.
2022-04-21 12:03:20 +02:00
Amaury Denoyelle
b22c0460d6 MINOR: quic-stream: add qc field
Add a new member <qc> in qc_stream_desc structure. This change is
possible since previous patch which add quic-conn argument to
qc_stream_desc_new().

The purpose of this change is to simplify the future evolution of
qc-stream-desc API. This will avoid to repeat qc as argument in various
functions which already used a qc_stream_desc.
2022-04-21 11:55:29 +02:00
Amaury Denoyelle
e4301da5ed MINOR: quic-stream: use distinct tree nodes for quic stream and qcs
Simplify the model qcs/qc_stream_desc. Each types has now its own tree
node, stored respectively in qcc and quic-conn trees. It is still
necessary to mark the stream as detached by the MUX once all data is
transfered to the lower layer.

This might improve slightly the performance on ACK management as now
only the lookup in quic-conn is necessary. On the other hand, memory
size of qcs structure is increased.
2022-04-21 11:05:58 +02:00
Amaury Denoyelle
0cc02a345b REORG: quic: use a dedicated module for qc_stream_desc
Regroup all type definitions and functions related to qc_stream_desc in
the source file src/quic_stream.c.

qc_stream_desc complexity will be increased with the development of Tx
multi-buffers. Having a dedicated module is useful to mix it with
pure transport/quic-conn code.
2022-04-21 11:05:27 +02:00
Amaury Denoyelle
da6ad2092a MINOR: mux-quic: split xfer and STREAM frames build
Split qcs_push_frame() in two functions.

The first one is qcs_xfer_data(). Its purpose is to transfer data from
qcs.tx.buf to qc_stream_desc buffer. The second function is named
qcs_build_stream_frm(). It generates a STREAM frame using qc_stream_desc
buffer as payload.

The trace events previously associated with qcs_push_frame() has also
been split in two to reflect the new code structure.

The purpose of this refactoring is first to better reflect how sending
is implemented. It will also simplify the implementation of Tx
multi-buffer per streams.
2022-04-21 09:27:43 +02:00
Remi Tricot-Le Breton
c69be7cd3c BUILD: ssl: Fix compilation with OpenSSL 1.0.2
The DH parameters used for OpenSSL versions 1.1.1 and earlier where
changed. For OpenSSL 1.0.2 and LibreSSL the newly introduced
ssl_get_dh_by_nid function is not used since we keep the original
parameters.
2022-04-20 22:34:44 +02:00
Remi Tricot-Le Breton
1d6338ea96 MEDIUM: ssl: Disable DHE ciphers by default
DHE ciphers do not present a security risk if the key is big enough but
they are slow and mostly obsoleted by ECDHE. This patch removes any
default DH parameters. This will effectively disable all DHE ciphers
unless a global ssl-dh-param-file is defined, or
tune.ssl.default-dh-param is set, or a frontend has DH parameters
included in its PEM certificate. In this latter case, only the frontends
that have DH parameters will have DHE ciphers enabled.
Adding explicitely a DHE ciphers in a "bind" line will not be enough to
actually enable DHE. We would still need to know which DH parameters to
use so one of the three conditions described above must be met.

This request was described in GitHub issue #1604.
2022-04-20 17:30:55 +02:00
Remi Tricot-Le Breton
528b3fd9be MINOR: ssl: Use DH parameters defined in RFC7919 instead of hard coded ones
RFC7919 defined sets of DH parameters supposedly strong enough to be
used safely. We will then use them when we can instead of our hard coded
ones (namely the ffdhe2048 and ffdhe4096 named groups).
The ffdhe2048 and ffdhe4096 named groups were integrated in OpenSSL
starting with version 1.1.1. Instead of duplicating those parameters in
haproxy for older versions of OpenSSL, we will keep using our own
parameters when they are not provided by the SSL library.
We will also need to keep our 1024 bits DH parameters since they are
considered not safe enough to have a dedicated named group in RFC7919
but we must still keep it for retrocompatibility with old Java clients.

This request was described in GitHub issue #1604.
2022-04-20 17:30:52 +02:00
Willy Tarreau
43041aaefd BUILD: calltrace: fix wrong include when building with TRACE=1
calltrace wasn't updated after the move of "now" from time.h to clock.h.
This must be backported to 2.5 where the breakage happened.
2022-04-19 08:23:30 +02:00
David CARLIER
7747d465d5 MINOR: tcp_sample: extend support for get_tcp_info to macOs.
MacOS can feed fc_rtt, fc_rttvar, fc_sacked, fc_lost and fc_retrans
so let's expose them on this platform.

Note that at the tcp(7) level, the API is slightly different, as
struct tcp_info is called tcp_connection_info and TCP_INFO is
called TCP_CONNECTION_INFO, so for convenience these ones were
defined to point to their equivalent. However there is a small
difference now in that tcpi_rtt is called tcpi_rttcur on this
platform, which forces us to make a special case for it before
other platforms.
2022-04-15 17:51:09 +02:00
David CARLIER
5c83e3a156 MINOR: tcp_sample: clarifying samples support per os, for further expansion.
While there is some overlap between what each OS provides in terms of
retrievable info, each set is not a real subset of another one and this
results in increasing complexity when trying to add support for new OSes.
Let's just condition each item to the OS that support it. It's not pretty
but at least it will avoid a real mess later.

Note that fc_rtt and fc_rttvar are supported on any OS that has TCP_INFO,
not just linux/freebsd/netbsd, so we continue to expose them unconditionally.
2022-04-15 17:51:09 +02:00
Christopher Faulet
39e436e222 BUG/MEDIUM: compression: Don't forget to update htx_sl and http_msg flags
If the response is compressed, we must update the HTX start-line flags and
the HTTP message flags. It is especially important if there is another
filter enabled. Otherwise, there is no way to know the C-L header was
removed and T-E one was added. Except by looping on headers.

This patch is related to the issue #1660. It must backported as far as 2.0
(for HTX part only).
2022-04-15 16:22:33 +02:00
Christopher Faulet
32af9a7830 BUG/MEDIUM: fcgi-app: Use http_msg flags to know if C-L header can be added
Instead of relying on the HTX start-line flags, it is better to rely on
http_msg flags to know if a content-length header can be added or not. In
addition, if the header is added, HTTP_MSGF_CNT_LEN flag must be added.

Because of this bug, an invalid message can be emitted when the response is
compressed because it may contain C-L and a T-E headers.

This patch should fix the issue #1660. It must be backported as far as 2.2.
2022-04-15 16:11:55 +02:00
Amaury Denoyelle
f7ff9cbfe1 BUG/MEDIUM: quic: properly clean frames on stream free
A released qc_stream_desc is freed as soon as all its buffer content has
been acknowledged. However, it may still contains other frames waiting
for ACK pointing to deleted buffer content. This can happen on
retransmission.

When freeing a qc_stream_desc, free all its frames in acked_frms tree to
fix memory leak. This may also possibly fix a crash on retransmission.
Now, the frames are properly removed from a packet. This ensure we do
not retransmit a frame whose buffer is deallocated.
2022-04-15 13:45:28 +02:00
Christopher Faulet
2bb5edcf19 BUG/MEDIUM: connection: Don't crush context pointer location if it is a CS
The issue only concerns the backend connection. The conn-stream is now owned
by the stream and persists during all the stream life. Thus we must not
crush it when the backend connection is released.

It is 2.6-specific. No backport is needed.
2022-04-15 10:57:11 +02:00
Willy Tarreau
cef08c20c7 MINOR: extcheck: fill in the server's UNIX socket address when known
While it's often a pain to try to figure a UNIX socket address, the
server ones are reliable and may be emitted in the check provided
they are retrieved in time. We cannot rely on addr_to_str() because
it only reports "unix" since it may be used to log client addresses
or listener addresses (which are renamed).

The address length was extended to 256 chars to deal with long paths
as previously it was limited to INET6_ADDRSTRLEN+1.

This addresses github issue #101. There's no point backporting this,
external checks are almost never used.
2022-04-14 19:56:32 +02:00
Willy Tarreau
c7edc9880a CLEANUP: extcheck: do not needlessly preset the server's address/port
During the config parsing we preset the server's address and port, but
that's pointless since it's replaced during each check in order to deal
with the possibility that the address was changed since.
2022-04-14 19:54:50 +02:00
Willy Tarreau
a544c66716 BUG/MEDIUM: stream: do not abort connection setup too early
Github issue #472 reports a problem with short client connections making
stick-table entries disappear. The problem is in fact totally different
and stems at the connection establishment step.

What happens is that the stick-table there has a single entry. The
"stick-on" directive is forced to purge an existing entry before being
able to create a new one. The new entry will be committed during the
call to process_store_rules() on the response path.

But if the client sends the FIN immediately after the connection is set
up (e.g. using nc -z) then the SHUTR is received and will cancel the
connection setup just after it starts. This cancellation will induce a
call to cs_shutw() which will in turn leave the server-side state in
ST_DIS. This transition from ST_CON to ST_DIS doesn't belong to the
list of handled transition during the connection setup so it will be
handled right after on the regular path, causing the connection to be
closed. Because of this, we never pass through back_establish() and
the backend's analysers are never set on the response channel, which
is why process_store_rules() is not called and the stick-tables entry
never committed.

The comment above the code that causes this transition clearly says
that the function is to be used after the connection is established
with the server, but there's no such protection, and we always have
the AUTO_CLOSE flag there (but there's hardly any available condition
to eliminate it).

This patch adds a test for the connection not being in ST_CON or for
option abortonclose being set. It's sufficient to do the job and it
should not cause issues.

One concern was that the transition could happen during cs_recv()
after the connection switches from CON to RDY then the read0 would
be taken into account and would cause DIS to appear, which is not
handled either. But that cannot happen because cs_recv() doesn't do
anything until it's in ST_EST state, hence the read0() cannot be
called from CON/RDY. Thus the transition from CON to DIS is only
possible in back_handle_st_con() and back_handle_st_rdy() both of
which are called when dealing with the transition already, or when
abortonclose is set and the client aborts before connect() succeeds.

It's possible that some further improvements could be made to detect
this specific transition but it doesn't seem like anything would have
to be added.

This issue was first reported on 2.1. The abortonclose area is very
sensitive so it would be wise to backport slowly, and probably no
further than 2.4.
2022-04-14 17:39:48 +02:00
Amaury Denoyelle
5d774dee55 MINOR: quic: emit CONNECTION_CLOSE on app init error
Emit a CONNECTION_CLOSE if the app layer cannot be properly initialized
on qc_xprt_start. This force the quic-conn to enter the closing state
before being closed.

Without this, quic-conn normal operations continue, despite the
app-layer reported as not initialized. This behavior is undefined, in
particular when handling STREAM frames.
2022-04-14 15:09:32 +02:00
Amaury Denoyelle
05d4ae6436 BUG/MINOR: quic: fix return value for error in start
Fix the return value used in quic-conn start callback for error. The
caller expects a negative value in this case.

Without this patch, the quic-conn and the connection stack are not
closed despite an initialization failure error, which is an undefined
behavior and may cause a crash in the end.
2022-04-14 15:08:16 +02:00
Amaury Denoyelle
622ec4166b BUG/MINOR: quic-sock: do not double free session on conn init failure
In the quic_session_accept, connection is in charge to call the
quic-conn start callback. If this callback fails for whatever reason,
there is a crash because of an explicit session_free.

This happens because the connection is now the owner of the session due
to previous conn_complete_session call. It will automatically calls
session_free. Fix this by skipping the session_free explicit invocation
on error.

In practice, currently this has never happened as there is only limited
cases of failures for conn_xprt_start for QUIC.
2022-04-14 14:50:12 +02:00
Amaury Denoyelle
2461bd534a BUG/MINOR: mux-quic: prevent a crash in session_free on mux.destroy
Implement qc_destroy. This callback is used to quickly release all MUX
resources.

session_free uses this callback. Currently, it can only be called if
there was an error during connection initialization. If not defined, the
process crashes.
2022-04-14 14:50:12 +02:00
Christopher Faulet
67df95a8a2 BUILD: http-client: Avoid dead code when compiled without SSL support
When an HTTP client is started on an HAProxy compiled without the SSL
support, an error is triggered when HTTPS is used. In this case, the freshly
created conn-stream is released. But this code is specific to the non-SSL
part. Thus it is moved the in right #if/#else section.

This patch should fix the issue #1655.
2022-04-14 12:02:35 +02:00
Christopher Faulet
ae660be547 BUG/MEDIUM: mux-h1: Don't request more room on partial trailers
The commit 744451c7c ("BUG/MEDIUM: mux-h1: Properly detect full buffer cases
during message parsing") introduced a regression if trailers are not
received in one time. Indeed, in this case, nothing is appended in the
channel buffer, while there are some data in the input buffer. In this case,
we must not request more room to the upper layer, especially because the
channel buffer can be empty.

To fix the issue, on trailers parsing, we consider the H1 stream as
congested when the max size allowed is reached. Of course, the H1 stream is
also considered as congested if the trailers are too big and the channel
buffer is not empty.

This patch should fix the issue #1657. It must be backported as far as 2.0.
2022-04-14 11:57:06 +02:00
Christopher Faulet
cea05437c0 MINOR: conn-stream: Use unsafe functions to get conn/appctx in cs_detach_endp
There is no reason to rely on safe functions here. This patch should fix the
issue #1656.
2022-04-14 11:57:06 +02:00
Christopher Faulet
4de1bff866 MINOR: muxes: Don't expect to call release function with no mux defined
For all muxes, the function responsible to release a mux is always called
with a defined mux. Thus there is no reason to test if it is defined or not.

Note the patch may seem huge but it is just because of indentation changes.
2022-04-14 11:57:06 +02:00
Christopher Faulet
4e61096e30 MINOR: muxes: Don't handle proto upgrade for muxes not supporting it
Several muxes (h2, fcgi, quic) don't support the protocol upgrade. For these
muxes, there is no reason to have code to support it. Thus in the destroy
callback, there is now a BUG_ON() and the release function is simplified
because the connection is always owned by the mux..
2022-04-14 11:57:06 +02:00
Christopher Faulet
7c452ccbff MINOR: muxes: Don't expect to have a mux without connection in destroy callback
Once a mux initialized, the underlying connection alwaus exists from its
point of view and it is never removed until the mux is released. It may be
owned by another mux during an upgrade. But the pointer remains set. Thus
there is no reason to test it in the destroy callback function.

This patch should fix the issue #1652.
2022-04-14 11:57:05 +02:00
Willy Tarreau
86b08a3e3e BUG/MINOR: mux-h2: use timeout http-request as a fallback for http-keep-alive
The doc states that timeout http-keep-alive is not set, timeout http-request
is used instead. As implemented in commit  15a4733d5 ("BUG/MEDIUM: mux-h2:
make use of http-request and keep-alive timeouts"), we use http-keep-alive
unconditionally between requests, with a fallback on client/server. Let's
make sure http-request is always used as a fallback for http-keep-alive
first.

This needs to be backported wherever the commit above is backported.

Thanks to Christian Ruppert for spotting this.
2022-04-14 11:45:36 +02:00
Willy Tarreau
6ff91e2023 BUG/MINOR: mux-h2: do not use timeout http-keep-alive on backend side
Commit 15a4733d5 ("BUG/MEDIUM: mux-h2: make use of http-request and
keep-alive timeouts") omitted to check the side of the connection, and
as a side effect, automatically enabled timeouts on idle backend
connections, which is totally contrary to the principle that they
must be autonomous.

This needs to be backported wherever the patch above is backported.
2022-04-14 11:43:35 +02:00
Frédéric Lécaille
bc964bd1ae BUG/MINOR: quic: Avoid starting the mux if no ALPN sent by the client
If the client does not sent an ALPN, the SSL ALPN negotiation callback
is not called. However, the handshake is reported as successful. Check
just after SSL_do_handshake if an ALPN was negotiated. If not, emit a
CONNECTION_CLOSE with a TLS alert to close the connection.

This prevent a crash in qcc_install_app_ops() called with null as second
parameter value.
2022-04-13 16:48:43 +02:00
Christopher Faulet
186354beac MINOR: mux-h1: Rely on the endpoint instead of the conn-stream when possible
Instead of testing if a conn-stream exists or not, we rely on CS_EP_ORPHAN
endpoint flag. In addition, if possible, we access the endpoint from the
h1s. Finally, the endpoint flags are now reported in trace messages.
2022-04-13 15:10:16 +02:00
Christopher Faulet
22050e0a2c MINOR: muxes: Improve show_fd callbacks to dump endpoint flags
H1, H2 and FCGI multiplexers define a show_fd callback to dump some internal
info. The stream endpoint and its flags are now dumped if it exists.
2022-04-13 15:10:16 +02:00
Christopher Faulet
1336ccffab CLEANUP: conn-stream: rename cs_register_applet() to cs_applet_create()
cs_register_applet() was not a good name because it suggests it happens
during startup, just like any other registration mechanisms..
2022-04-13 15:10:16 +02:00
Christopher Faulet
aa69d8fa1c MINOR: conn-stream: Use a dedicated function to conditionally remove a CS
cs_free_cond() must now be used to remove a CS. cs_free() may be used on
error path to release a freshly allocated but unused CS. But in all other
cases cs_free_cond() must be used. This function takes care to release the
CS if it is possible (no app and detached from any endpoint).

In fact, this function is only used internally. From the outside,
cs_detach_* functions are used.
2022-04-13 15:10:16 +02:00
Christopher Faulet
a97ccedf6f CLEANUP: muxes: Remove MX_FL_CLEAN_ABRT flag
This flag is unused. Thus, it may be removed. No reason to still set it. It
also cleans up "haproxy -vv" output.
2022-04-13 15:10:16 +02:00
Christopher Faulet
177a0e60ee MEDIUM: check: Use a new conn-stream for each health-check run
It is a partial revert of 54e85cbfc ("MAJOR: check: Use a persistent
conn-stream for health-checks"). But with the CS refactoring, the result is
cleaner now. A CS is allocated when a new health-check run is started. The
same CS is then used throughout the run. If there are several connections,
the endpoint is just reset. At the end of the run, the CS is released. It
means, in the tcp-check part, the CS is always defined.
2022-04-13 15:10:16 +02:00
Christopher Faulet
9ed7742673 DOC: conn-stream: Add comments on functions of the new CS api
With the conn-stream refactoring, new functions were added. This patch adds
missing comments to help devs to use them.
2022-04-13 15:10:16 +02:00
Christopher Faulet
265e165d82 CLEANUP: conn-stream: Don't export internal functions
cs_new() and cs_attach_app() are only used internally. Thus, there is no
reason to export them.
2022-04-13 15:10:16 +02:00
Christopher Faulet
6b0a0fb2f9 CLEANUP: tree-wide: Remove any ref to stream-interfaces
Stream-interfaces are gone. Corresponding files can be safely be removed. In
addition, comments are updated accordingly.
2022-04-13 15:10:16 +02:00
Christopher Faulet
582a226a2c MINOR: conn-stream: Remove the stream-interface from the conn-stream
The stream-interface API is no longer used. Thus, it is removed from the
conn-stream. From now, stream-interfaces are now longer used !
2022-04-13 15:10:16 +02:00
Christopher Faulet
c77ceb6ad1 MEDIUM: stream: Don't use the stream-int anymore in process_stream()
process_stream() and all associated functions now manipulate conn-streams.
stream-interfaces are no longer used. In addition, function to dump info
about a stream no longer print info about stream-interfaces.
2022-04-13 15:10:16 +02:00
Christopher Faulet
7739799ab4 MINOR: http-ana: Use CS to perform L7 retries
do_l7_retry function now manipulated a conn-stream instead of a
stream-interface.
2022-04-13 15:10:16 +02:00
Christopher Faulet
0eb32c0dd1 MINOR: stream: Use conn-stream to report server error
the stream's srv_error callback function now manipulates a conn-stream
instead of a stream-interface.
2022-04-13 15:10:16 +02:00
Christopher Faulet
5e29b76ea6 MEDIUM: stream-int/conn-stream: Move I/O functions to conn-stream
cs_conn_io_cb(), cs_conn_sync_recv() and cs_conn_sync_send() are moved in
conn_stream.c. Associated functions are moved too (cs_notify, cs_conn_read0,
cs_conn_recv, cs_conn_send and cs_conn_process).
2022-04-13 15:10:15 +02:00