Commit Graph

16767 Commits

Author SHA1 Message Date
Marno Krahmer
a690b73fba MINOR: stats: Add dark mode support for socket rows
In commit e9ed63e548 dark mode support was added to the stats page. The
initial commit does not include  dark mode color overwrites for the
.socket CSS class. This commit colors socket rows the same way as
backends that acre active but do not have a health check defined.

This fixes an issue where reading information from socket lines became
really hard in dark mode due to suboptimal coloring of the cell
background and the font in it.
2022-03-08 14:47:23 +01:00
Amaury Denoyelle
20f89cac95 BUG/MEDIUM: quic: do not drop packet on duplicate stream/decoding error
Change the return value to success in qc_handle_bidi_strm_frm for two
specific cases :
* if STREAM frame is an already received offset
* if application decoding failed

This ensures that the packet is not dropped and properly acknowledged.
Previous to this fix, the return code was set to error which prevented
the ACK to be generated.

The impact of the bug might be noticeable in environment with packet
loss and retransmission. Due to haproxy not generating ACK for packets
containing STREAM frames with already received offset, the client will
probably retransmit them again, which will worsen the network
transmission.
2022-03-08 14:36:32 +01:00
William Lallemand
b0dfd099c5 BUG/MINOR: cli: shows correct mode in "show sess"
The "show sess" cli command only handles "http" or "tcp" as a fallback
mode, replace this by a call to proxy_mode_str() to show all the modes.

Could be backported in every maintained versions.
2022-03-08 12:21:36 +01:00
William Lallemand
06715af9e5 BUG/MINOR: add missing modes in proxy_mode_str()
Add the missing PR_MODE_SYSLOG and PR_MODE_PEERS in proxy_mode_str().

Could be backported in every maintained versions.
2022-03-08 12:21:36 +01:00
Willy Tarreau
c4e56dc58c MINOR: pools: add a new global option "no-memory-trimming"
Some users with very large numbers of connections have been facing
extremely long malloc_trim() calls on reload that managed to trigger
the watchdog! That's a bit counter-productive. It's even possible
that some implementations are not perfectly reliable or that their
trimming time grows quadratically with the memory used. Instead of
constantly trying to work around these issues, let's offer an option
to disable this mechanism, since nobody had been complaining in the
past, and this was only meant to be an improvement.

This should be backported to 2.4 where trimming on reload started to
appear.
2022-03-08 10:45:03 +01:00
Frédéric Lécaille
5bcfd33063 BUG/MAJOR: quic: Wrong quic_max_available_room() returned value
Around limits for QUIC integer encoding, this functions could return
wrong values which lead to qc_build_frms() to prepare wrong CRYPTO (less chances)
or STREAM frames (more chances). qc_do_build_pkt() could build wrong packets
with bad CRYPTO/STREAM frames which could not be decoded by the peer.
In such a case ngtcp2 closes the connection with an ENCRYPTION_ERROR error
in a transport CONNECTION_CLOSE frame.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
4fe7d8a5b2 MINOR: quic: Add quic_max_int_by_size() function
This function returns the maximum integer which may be encoded with a number of
bytes passed as parameter. Useful to precisely compute the number of bytes which
may used to fulfill a buffer with lengths as QUIC enteger encoded prefixes for the
number of following bytes.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
9777ead2ed CLEANUP: quic: Remove window redundant variable from NewReno algorithm state struct
We use the window variable which is stored in the path struct.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
0e7c9a7143 MINOR: quic: More precise window update calculation
When in congestion avoidance state and when acknowledging an <acked> number bytes
we must increase the congestion window by at most one datagram (<path->mtu>)
by congestion window. So thanks to this patch we apply a ratio to the current
number of acked bytes : <acked> * <path->mtu> / <cwnd>.
So, when <cwnd> bytes are acked we precisely increment <cwnd> by <path->mtu>.
Furthermore we take into an account the number of remaining acknowledged bytes
each time we increment the window by <acked> storing their values in the algorithm
struct state (->remain_acked) so that it might be take into an account at the
next ACK event.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
abdf4a1533 BUG/MINOR: quic: Confusion betwen "in_flight" and "prep_in_flight" in quic_path_prep_data()
This function returns the remaining number of bytes which can be sent on the
network before fulfilling the congestion window. There is a counter for
the number of prepared data and another one for the really in flight number
of bytes (in_flight). These variable have been mixed up.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
5f6783094d CLEANUP: quic: Remove useless definitions from quic_cc_event struct
Since the persistent congestion detection is done out of the congestion
controllers, there is no need to pass them information through quic_cc_event struct.
We remove its useless members. Also remove qc_cc_loss_event() which is no more used.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
a5ee0ae6a2 MINOR: quic: Persistent congestion detection outside of controllers
We establish the persistent congestion out of any congestion controller
to improve the algorithms genericity. This path characteristic detection may
be implemented regarless of the underlying congestion control algorithm.

Send congestion (loss) event using directly quic_cc_event(), so without
qc_cc_loss_event() wrapper function around quic_cc_event().

Take the opportunity of this patch to shorten "newest_time_sent" member field
of quic_cc_event to "time_sent".
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
83bfca6c71 MINOR: quic: Add a "slow start" callback to congestion controller
We want to be able to make the congestion controllers re-enter the slow
start state outside of the congestion controllers themselves. So,
we add a callback ->slow_start() to do so.
Define this callback for NewReno algorithm.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
ba9db40b07 CLEANUP: quic: Remove QUIC path manipulations out of the congestion controller
QUIC connection path in flight bytes is a variable which should not be manipulated
by the congestion controller. This latter aim is to compute the congestion window.
So, we pass it as less as parameters as possible to do so.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
4d3d36b670 BUG/MINOR: quic: Missing recovery start timer reset
The recovery start time must be reset after a persistent congestion has been
detected.
2022-03-04 17:47:32 +01:00
Frédéric Lécaille
05e30ee7d5 MINOR: quic: Retry on qc_build_pkt() failures
This is done going to stop_build label when qc_build_pkt() fails
because of a lack of buffer room (returns -1).
2022-03-04 17:47:32 +01:00
David Carlier
43a568575f BUILD: fix kFreeBSD build.
kFreeBSD needs to be treated as a distinct target from FreeBSD
since the underlying system libc is the GNU one. Thus, relying
only on __GLIBC__ no longer suffice.

- freebsd-glibc new target, key difference is including crypt.h
  and linking to libdl like linux.
- cpu affinity available but the api is still the FreeBSD's.
- enabling auxiliary data access only for Linux.

Patch based on preliminary work done by @bigon.

closes #1555
2022-03-04 17:19:12 +01:00
Amaury Denoyelle
c055e30176 MEDIUM: mux-quic: implement MAX_STREAMS emission for bidir streams
Implement the locally flow-control streams limit for opened
bidirectional streams. Add a counter which is used to count the total
number of closed streams. If this number is big enough, emit a
MAX_STREAMS frame to increase the limit of remotely opened bidirectional
streams.

This is the first commit to implement QUIC flow-control. A series of
patches should follow to complete this.

This is required to be able to handle more than 100 client requests.
This should help to validate the Multiplexing interop test.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
e9c4cc13fc MINOR: mux-quic: retry send opportunistically for remaining frames
This commit should fix the possible transfer interruption caused by the
previous commit. The MUX always retry to send frames if there is
remaining data after a send call on the transport layer. This is useful
if the transport layer is not blocked on the sending path.

In the future, the transport layer should retry by itself the send
operation if no blocking condition exists. The MUX layer will always
subscribe to retry later if remaining frames are reported which indicate
a blocking on the transport layer.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
2c71fe58f0 MEDIUM: mux-quic: use direct send transport API for STREAMs
Modify the STREAM emission in qc_send. Use the new transport function
qc_send_app_pkts to directly send the list of constructed frames. This
allows to remove the tasklet wakeup on the quic_conn and should reduce
the latency.

If not all frames are send after the transport call, subscribe the MUX
on the lower layer to be able to retry. Currently there is a bug because
the transport layer does not retry to send frames in excess after a
successful sendto. This might cause the transfer to be interrupted.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
414df7684a MINOR: mux-quic: define new unions for flow-control fields
Define two new unions in the qcc structure named 'lfctl' and 'rfctl'.
For the moment they are empty. They will be completed to store the
initial and current level for flow-control on the local and remote side.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
0dc40f06d1 MINOR: mux-quic: complete functions to detect stream type
Improve the functions used to detect the stream characteristics :
uni/bidirectional and local/remote initiated.

Most notably, these functions are now designed to work transparently for
a MUX in the frontend or backend side. For this, we use the connection
to determine the current MUX side. This will be useful if QUIC is
implemented on the server side.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
749cb647b1 MINOR: mux-quic: refactor transport parameters init
Since QUIC accept handling has been improved, the MUX is initialized
after the handshake completion. Thus its safe to access transport
parameters in qc_init via the quic_conn.

Remove quic_mux_transport_params_update which was called by the
transport for the MUX. This improves the architecture by removing a
direct call from the transport to the MUX.

The deleted function body is not transfered to qc_init because this part
will change heavily in the near future when implementing the
flow-control.
2022-03-04 17:00:12 +01:00
Frédéric Lécaille
c2f561ce1e MINOR: quic: Export qc_send_app_pkts()
This is at least to make this function be callable by the mux.
2022-03-04 17:00:12 +01:00
Frédéric Lécaille
edc81469a8 MINOR: quic: Make qc_build_frms() build ack-eliciting frames from a list
We want to be able to build ack-eliciting frames to be embedded into QUIC packets
from a prebuilt list of ack-eliciting frames. This will be helpful for the mux
which would like to send STREAM frames asap after having builts its own prebuilt
list.
To do so, we only add a parameter as struct list to this function to handle
such a prebuilt list.
2022-03-04 17:00:12 +01:00
Frédéric Lécaille
28c7ea3725 MINOR: quic: Send short packet from a frame list
We want to be able to send ack-elicting packets from a list of ack-eliciting
frames. So, this patch adds such a paramaters to the function responsible of
building 1RTT packets. The entry point function is qc_send_app_pkts() which
is used with the underlying packet number space TX frame list as parameter.
2022-03-04 17:00:12 +01:00
Frédéric Lécaille
1c5968b275 MINOR: quic: qc_prep_app_pkts() implementation
We want to get rid of the code used during the handshake step. qc_prep_app_pkts()
aim is to build short packets which are also datagrams.
Make quic_conn_app_io_cb() call this new function to prepare short packets.
2022-03-04 17:00:12 +01:00
Amaury Denoyelle
1455113e93 CLEANUP: quic: complete ABORT_NOW with a TODO comment
Add a TODO comment to not forget to properly implement error returned by
qcs_push_frame.
2022-03-04 16:56:51 +01:00
Willy Tarreau
d8ac3f5dbf CI: coverity: simplify debugging options
We used to rely on a call to "sed" to modify the DEBUG option in the
makefile when running under Coverity because it splits words around
spaces and does not allow to pass multi-word build options. As reported
by Tim in issue #1592, this broke with commit 8de7f2822 ("BUILD: makefile:
enable both DEBUG_STRICT and DEBUG_MEMORY_POOLS by default") when the
default DEBUG options changed.

Let's change this to pass all DEBUG options one at a time instead and
get rid of this sed.
2022-03-04 14:33:55 +01:00
Willy Tarreau
3dfb7da04b CLEANUP: tree-wide: remove a few rare non-ASCII chars
As reported by Tim in issue #1428, our sources are clean, there are
just a few files with a few rare non-ASCII chars for the paragraph
symbol, a few typos, or in Fred's name. Given that Fred already uses
the non-accentuated form at other places like on the public list,
let's uniformize all this and make sure the code displays equally
everywhere.
2022-03-04 08:58:32 +01:00
Willy Tarreau
f9eba78fb8 BUG/MEDIUM: pools: fix ha_free() on area in the process of being freed
Commit e81248c0c ("BUG/MINOR: pool: always align pool_heads to 64 bytes")
added a free of the allocated pool in pool_destroy() using ha_free(), but
it added a subtle bug by which once the pool is released, setting its
address to NULL inside the structure itself cannot work because the area
has just been freed.

This will need to be backported wherever the patch above is backported.
2022-03-03 18:42:49 +01:00
Amaury Denoyelle
2d0f873cd8 BUG/MINOR: quic: fix segfault on CC if mux uninitialized
A segfault happens when receiving a CONNECTION_CLOSE during handshake.
This is because the mux is not initialized at this stage but the
transport layer dereferences it.

Fix this by ensuring that the MUX is initialized before. Thanks to Willy
for his help on this one. Welcome in the QUIC-men team !
2022-03-03 18:09:37 +01:00
Willy Tarreau
c48c8b8701 DEV: udp: add an optional argument to set the prng seed
This will help reproduce certain sequences that were observed.
2022-03-03 18:01:26 +01:00
Willy Tarreau
e7a7fb4390 DEV: udp: implement pseudo-random reordering/loss
By passing a 3rd argument it's now possible to set a randomness level
according to which received packets will be replaced by one of the 20
previous ones. This happens in both directions and the buffer is common
so that it's possible to receive responses on requests and conversely,
which adds to the perturbation. E.g:

    ./dev/udp/udp-perturb 127.0.0.4:9443 127.0.0.4:8443 10

This will add 10% randomness on forwarded packets between these two
ports.
2022-03-03 17:54:04 +01:00
Willy Tarreau
c927137785 DEV: udp: add a tiny UDP proxy for testing
QUIC really needs more traffic perturbation for the tests. Let's have
a tiny UDP proxy for this, mostly derived from the 'connect' test suite.
For now it only supports a single "connection" at once, but the code is
here to support more. A new "connection" will simply replace the previous
one. It doesn't yet cause traffic perturbations, this is still to be added.
Some of the setsockopt() are possibly unneeded. The error handling is
almost inexistent, and polling for sends is not implemented at all (will
cause losses). No stats are collected.
2022-03-03 17:49:13 +01:00
Willy Tarreau
e81248c0c8 BUG/MINOR: pool: always align pool_heads to 64 bytes
This is the pool equivalent of commit 97ea9c49f ("BUG/MEDIUM: fd: always
align fdtab[] to 64 bytes"). After a careful code review, it happens that
the pool heads are the other structures allocated with malloc/calloc that
claim to be aligned to a size larger than what the allocator can offer.
While no issue was reported on them, no memset() is performed and no type
is large, this is a problem waiting to happen, so better fix it. In
addition, it's relatively easy to do by storing the allocation address
inside the pool_head itself and use it at free() time. Finally, threads
might benefit from the fact that the caches will really be aligned and
that there will be no false sharing.

This should be backported to all versions where it applies easily.
2022-03-02 18:22:08 +01:00
William Lallemand
10a37360c8 BUG/MEDIUM: httpclient/lua: infinite appctx loop with POST
When POSTing a request with a payload, and reusing the same httpclient
lua instance, one could encounter a spinning of the httpclient appctx.

Indeed the sent counter is not reset between 2 POSTs and the condition
for sending the EOM flag is never met.

Must fixed issue #1593.

To be backported in 2.5.
2022-03-02 16:32:47 +01:00
Willy Tarreau
06e66c84fc DEBUG: reduce the footprint of BUG_ON() calls
Many inline functions involve some BUG_ON() calls and because of the
partial complexity of the functions, they're not inlined anymore (e.g.
co_data()). The reason is that the expression instantiates the message,
its size, sometimes a counter, then the atomic OR to taint the process,
and the back trace. That can be a lot for an inline function and most
of it is always the same.

This commit modifies this by delegating the common parts to a dedicated
function "complain()" that takes care of updating the counter if needed,
writing the message and measuring its length, and tainting the process.
This way the caller only has to check a condition, pass a pointer to the
preset message, and the info about the type (bug or warn) for the tainting,
then decide whether to dump or crash. Note that this part could also be
moved to the function but resulted in complain() always being at the top
of the stack, which didn't seem like an improvement.

Thanks to these changes, the BUG_ON() calls do not result in uninlining
functions anymore and the overall code size was reduced by 60 to 120 kB
depending on the build options.
2022-03-02 16:00:42 +01:00
Willy Tarreau
a631b86523 BUILD: tcpcheck: do not declare tcp_check_keywords_register() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
2022-03-02 14:54:44 +01:00
Willy Tarreau
4de2cda104 BUILD: trace: do not declare trace_registre_source() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
2022-03-02 14:53:00 +01:00
Willy Tarreau
368479c3fc BUILD: http_rules: do not declare http_*_keywords_registre() inline
The 3 functions http_{req,res,after_res}_keywords_register() are
referenced in initcalls by their pointer, it makes no sense to declare
them inline. At best it causes function duplication, at worst it doesn't
build on older compilers.
2022-03-02 14:50:38 +01:00
Willy Tarreau
d318e4e022 BUILD: connection: do not declare register_mux_proto() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
2022-03-02 14:46:45 +01:00
Willy Tarreau
e4149cdbc6 BUILD: conn_stream: avoid null-deref warnings on gcc 6
gcc 6 continues its saga with excessive reports of null-deref warnings.
This time it was in the IS_HTX_CS() macro. Let's use __cs_conn() after
cs_conn() was checked.
2022-03-02 14:39:39 +01:00
Frédéric Lécaille
bd24208673 MINOR: quic: Assemble QUIC TLS flags at the same level
Do not distinguish the direction (TX/RX) when settings TLS secrets flags.
There is not such a distinction in the RFC 9001.
Assemble them at the same level: at the upper context level.
2022-03-01 16:34:03 +01:00
Frédéric Lécaille
9355d50f73 CLEANUP: quic: Indentation fix in qc_prep_pkts()
Non-invasive modification.
2022-03-01 16:22:35 +01:00
Frédéric Lécaille
7d845f15fd CLEANUP: quic: Useless tests in qc_try_rm_hp()
There is no need to test <qel>. Furthermore the packet type has already checked
by the caller.
2022-03-01 16:22:35 +01:00
Frédéric Lécaille
51c9065f66 MINOR: quic: Drop the packets of discarded packet number spaces
This is required since this previous commit:
   "MINOR: quic: Post handshake I/O callback switching"
If not, such packets remain endlessly in the RX buffer and cannot be parsed
by the new I/O callback used after the handshake has been confirmed.
2022-03-01 16:22:35 +01:00
Frédéric Lécaille
00e2400fa6 MINOR: quic: Post handshake I/O callback switching
Implement a simple task quic_conn_app_io_cb() to be used after the handshakes
have completed.
2022-03-01 16:22:35 +01:00
Frédéric Lécaille
5757b4a50e MINOR: quic: Ensure PTO timer is not set in the past
Wakeup asap the timer task when setting its timer in the past.
Take also the opportunity of this patch to make simplify quic_pto_pktns():
calling tick_first() is useless here to compare <lpto> with <tmp_pto>.
2022-03-01 16:22:35 +01:00
Julien Thomas
59e6bcdcea BUILD: ssl: another build warning on LIBRESSL_VERSION_NUMBER
We had several warnings when building haproxy 2.5.4 with
old openssl 1.0.1e. This version of openssl is the latest
available in EOL centos 6.

  include/haproxy/openssl-compat.h:157:51: \
  warning: "LIBRESSL_VERSION_NUMBER" is not defined

This patch fixed the build. It changes the #if condition,
as done in other similar parts of openssl-compat.h.
2022-03-01 15:49:30 +01:00