Commit Graph

16251 Commits

Author SHA1 Message Date
Amaury Denoyelle
c6fab98f9b BUG/MINOR: quic: fix potential null dereference
This is not a real issue because found_in_dcid can not be set if qc is
NULL.
2021-12-23 16:32:19 +01:00
Amaury Denoyelle
76f47caacc MEDIUM: quic: implement refcount for quic_conn
Implement a refcount on quic_conn instance. By default, the refcount is
0. Two functions are implemented to manipulate it.
* qc_conn_take() which increments the refcount
* qc_conn_drop() which decrements it. If the refcount is 0 *BEFORE*
  the substraction, the instance is freed.

The refcount is incremented on retrieve_qc_conn_from_cid() or when
allocating a new quic_conn in qc_lstnr_pkt_rcv(). It is substracted most
notably by the xprt.close operation and at the end of
qc_lstnr_pkt_rcv(). The increments/decrements should be conducted under
the CID lock to guarantee thread-safety.
2021-12-23 16:06:07 +01:00
Amaury Denoyelle
0a29e13835 MINOR: quic: delete timer task on quic_close()
The timer task is attached to the connection-pinned thread. Only this
thread can delete it. With the future refcount implementation of
quic_conn, every thread can be responsible to remove the quic_conn via
quic_conn_free(). Thus, the timer task deletion is moved from the
calling function quic_close().
2021-12-23 16:06:07 +01:00
Amaury Denoyelle
e81fed9a54 MINOR: quic: replace usage of ssl_sock_ctx by quic_conn
Big refactoring on xprt-quic. A lot of functions were using the
ssl_sock_ctx as argument to only access the related quic_conn. All these
arguments are replaced by a quic_conn parameter.

As a convention, the quic_conn instance is always the first parameter of
these functions.

This commit is part of the rearchitecture of xprt-quic layers and the
separation between xprt and connection instances.
2021-12-23 16:06:06 +01:00
Amaury Denoyelle
741eacca47 MINOR: quic: remove unnecessary if in qc_pkt_may_rm_hp()
Remove the shortcut to use the INITIAL encryption level when removing
header protection on first connection packet.

This change is useful for the following change which removes
ssl_sock_ctx in argument lists in favor of the quic_conn instance.
2021-12-23 16:02:24 +01:00
Amaury Denoyelle
7ca7c84fb8 MINOR: quic: store ssl_sock_ctx reference into quic_conn
Add a pointer in quic_conn to its related ssl_sock_ctx. This change is
required to avoid to use the connection instance to access it.

This commit is part of the rearchitecture of xprt-quic layers and the
separation between xprt and connection instances. It will be notably
useful when the connection allocation will be delayed.
2021-12-23 15:51:00 +01:00
Amaury Denoyelle
a83729e9e6 MINOR: quic: remove unnecessary call to free_quic_conn_cids()
free_quic_conn_cids() was called in quic_build_post_handshake_frames()
if an error occured. However, the only error is an allocation failure of
the CID which does not required to call it.

This change is required for future refcount implementation. The CID lock
will be removed from the free_quic_conn_cids() and to the caller.
2021-12-23 15:51:00 +01:00
Amaury Denoyelle
250ac42754 BUG/MINOR: quic: upgrade rdlock to wrlock for ODCID removal
When a quic_conn is found in the DCID tree, it can be removed from the
first ODCID tree. However, this operation must absolutely be run under a
write-lock to avoid race condition. To avoid to use the lock too
frequently, node.leaf_p is checked. This value is set to NULL after
ebmb_delete.
2021-12-23 15:51:00 +01:00
Amaury Denoyelle
d6b166787c REORG: quic: remove qc_ prefix on functions which not used it directly
The qc_* prefix should be reserved to functions which used a specific
quic_conn instance and are expected to be pinned on the connection
thread.
2021-12-23 15:51:00 +01:00
Frédéric Lécaille
010e532e81 MINOR: quic: Add CONNECTION_CLOSE phrase to trace
Some applications may send some information about the reason why they decided
to close a connection. Add them to CONNECTION_CLOSE frame traces.
Take the opportunity of this patch to shorten some too long variable names
without any impact.
2021-12-23 15:48:25 +01:00
Frédéric Lécaille
1ede823d6b MINOR: quic: Add traces for RX frames (flow control related)
Add traces about important frame types to chunk_tx_frm_appendf()
and call this function for any type of frame when parsing a packet.
Move it to quic_frame.c
2021-12-23 15:48:25 +01:00
Willy Tarreau
77bfa66124 DEBUG: ssl: make sure we never change a servername on established connections
Since this case was already met previously with commit 655dec81b
("BUG/MINOR: backend: do not set sni on connection reuse"), let's make
sure that we don't change reused connection settings. This could be
generalized to most settings that are only in effect before the handshake
in fact (like set_alpn and a few other ones).
2021-12-23 15:44:06 +01:00
Willy Tarreau
0d93a81863 MINOR: pools: work around possibly slow malloc_trim() during gc
During 2.4-dev, support for malloc_trim() was implemented to ease
release of memory in a stopping process. This was found to be quite
effective and later backported to 2.3.7.

Then it was found that sometimes malloc_trim() could take a huge time
to complete it if was competing with other threads still allocating and
releasing memory, reason why it was decided in 2.5-dev to move
malloc_trim() under the thread isolation that was already in place in
the shared pool version of pool_gc() (this was commit 26ed1835).

However, other instances of pool_gc() that used to call malloc_trim()
were not updated since they were not using thread isolation. Currently
we have two other such instances, one for when there is absolutely no
pool and one for when there are only thread-local pools.

Christian Ruppert reported in GH issue #1490 that he's sometimes seeing
and old process die upon reload when upgrading from 2.3 to 2.4, and
that this happens inside malloc_trim(). The problem is that since
2.4-dev11 with commit 0bae07592 we detect modern libc that provide a
faster thread-aware allocator and do not maintain shared pools anymore.
As such we're using again the simpler pool_gc() implementations that do
not use thread isolation around the malloc_trim() call.

All this code was cleaned up recently and the call moved to a new
function trim_all_pools(). This patch implements explicit thread isolation
inside that function so that callers do not have to care about this
anymore. The thread isolation is conditional so that this doesn't affect
the one already in place in the larger version of pool_gc(). This way it
will solve the problem for all callers.

This patch must be backported as far as 2.3. It may possibly require
some adaptations. If trim_all_pools() is not present, copy-pasting the
tests in each version of pool_gc() will have the same effect.

Thanks to Christian for his detailed report and his testing.
2021-12-23 15:44:06 +01:00
Frédéric Lécaille
2c15a66b61 MINOR: quic: Drop asap Retry or Version Negotiation packets
These packet are only sent by servers. We drop them as soon as possible
when we are an haproxy listener.
2021-12-22 20:43:22 +01:00
Frédéric Lécaille
e7ff2b265a MINOR: quic: xprt traces fixes
Empty parameters are permitted with TRACE_*() macros. If removed, must
be replaced by NULL.
2021-12-22 20:43:22 +01:00
Frédéric Lécaille
10250b2e93 MINOR: quic: Handle the cases of overlapping STREAM frames
This is the same treatment for bidi and uni STREAM frames. This is a duplication
code which should me remove building a function for both these types of streams.
2021-12-22 20:43:22 +01:00
Frédéric Lécaille
01cfec74f5 MINOR: quic: Wrong dropped packet skipping
There were cases where some dropped packets were not well skipped. This led
the low level QUIC packet parser to continue from wrong packet boundaries.
2021-12-22 20:43:22 +01:00
Frédéric Lécaille
4d118d6a8e MINOR: quic: unchecked qc_retrieve_conn_from_cid() returned value
If qc_retrieve_conn_from_cid() did not manage to retrieve the connection
from packet CIDs, we must drop them.
2021-12-22 17:27:51 +01:00
Frédéric Lécaille
677b99dca7 MINOR: quic: Add stream IDs to qcs_push_frame() traces
This is only for debug purpose.
2021-12-21 16:06:03 +01:00
Amaury Denoyelle
e770ce3980 MINOR: quic: add quic_conn instance in traces for qc_new_conn
The connection instance has been replaced by a quic_conn as first
argument to QUIC traces. It is possible to report the quic_conn instance
in the qc_new_conn(), contrary to the connection which is not
initialized at this stage.
2021-12-21 15:53:19 +01:00
Amaury Denoyelle
7aaeb5b567 MINOR: quic: use quic_conn as argument to traces
Replace the connection instance for first argument of trace callback by
a quic_conn instance. The QUIC trace module is properly initialized with
the first argument refering to a quic_conn.

Replace every connection instances in TRACE_* macros invocation in
xprt-quic by its related quic_conn. In some case, the connection is
still used to access the quic_conn. It may cause some problem on the
future when the connection will be completly separated from the xprt
layer.

This commit is part of the rearchitecture of xprt-quic layers and the
separation between xprt and connection instances.
2021-12-21 15:53:19 +01:00
Amaury Denoyelle
baea96400f MINOR: trace: add quic_conn argument definition
Prepare trace support for quic_conn instances as argument. This will be
used by the xprt-quic layer in replacement of the connection.

This commit is part of the rearchitecture of xprt-quic layers and the
separation between xprt and connection instances.
2021-12-21 15:53:19 +01:00
Amaury Denoyelle
4fd53d772f MINOR: quic: add const qualifier for traces function
Add const qualifier on arguments of several dump functions used in the
trace callback. This is required to be able to replace the first trace
argument by a quic_conn instance. The first argument is a const pointer
and so the members accessed through it must also be const.
2021-12-21 15:53:19 +01:00
Amaury Denoyelle
c15dd9214b MINOR: quic: add reference to quic_conn in ssl context
Add a new member in ssl_sock_ctx structure to reference the quic_conn
instance if used in the QUIC stack. This member is initialized during
qc_conn_init().

This is needed to be able to access to the quic_conn without relying on
the connection instance. This commit is part of the rearchitecture of
xprt-quic layers and the separation between xprt and connection
instances.
2021-12-21 15:53:19 +01:00
Amaury Denoyelle
8a5b27a9b9 REORG: quic: move mux function outside of xprt
Move qcc_get_qcs() function from xprt_quic.c to mux_quic.c. This
function is used to retrieve the qcs instance from a qcc with a stream
id. This clearly belongs to the mux-quic layer.
2021-12-21 15:51:40 +01:00
Amaury Denoyelle
17a741693c CLEANUP: quic: rename quic_conn instances to qc
Use the convention of naming quic_conn instance as qc to not confuse it
with a connection instance. The changes occured for qc_parse_pkt_frms(),
qc_build_frms() and qc_do_build_pkt().
2021-12-21 15:51:30 +01:00
Thierry Fournier
55c40ea177 DOC: fix misspelled keyword "resolve_retries" in resolvers
"resolve_retries" was spelled "resolve_retires".
2021-12-21 08:27:52 +01:00
Frédéric Lécaille
2ce5acf7ed MINOR: quic: Wrong packet refcount handling in qc_pkt_insert()
The QUIC connection I/O handler qc_conn_io_cb() could be called just after
qc_pkt_insert() have inserted a packet in a its tree, and before qc_pkt_insert()
have incremented the reference counter to this packet. As qc_conn_io_cb()
decrement this counter, the packet could be released before qc_pkt_insert()
might increment the counter, leading to possible crashes when trying to do so.
So, let's make qc_pkt_insert() increment this counter before inserting the packet
it is tree. No need to lock anything for that.
2021-12-20 17:33:51 +01:00
Frédéric Lécaille
f1d38cbe15 MINOR: quic: Do not forget STREAM frames received in disorder
Add a function to process all STREAM frames received and ordered
by their offset (qc_treat_rx_strm_frms()) and modify
qc_handle_bidi_strm_frm() consequently.
2021-12-20 17:33:51 +01:00
Frédéric Lécaille
4137b2d316 MINOR: quic: Do not expect to receive only one O-RTT packet
There is nothing about this in the RFC. We must support to receive
several 0-RTT packets before the handshake has completed.
2021-12-20 17:33:51 +01:00
Frédéric Lécaille
ccf973f5ef MINOR: quic: Stop emptying the RX buffer asap.
When a packet is present in the RX buffer at the first place
but without a null reference counter, there is no need to continue
to try to empty the buffer, it is sure the next packet will not
be at the first place!
2021-12-20 17:33:51 +01:00
Frédéric Lécaille
91ac6c3a8a MINOR: quic: Add a function to list remaining RX packets by encryption level
This is only to debug some issues which cause the RX buffer saturation
with "Too big packet" traces.
2021-12-20 17:33:51 +01:00
Frédéric Lécaille
0ece75c66a MINOR: quic: Increase the RX buffer for each connection
Double this buffer size which reaches 16ko for now on.
2021-12-20 17:33:51 +01:00
Remi Tricot-Le Breton
cc750efbc5 MINOR: ssl: Remove empty lines from "show ssl ocsp-response" output
There were empty lines in the output of the CLI's "show ssl
ocsp-response" command (after the certificate ID and between two
certificates). This patch removes them since an empty line should mark
the end of the output.

Must be backported in 2.5.
2021-12-20 12:02:17 +01:00
Remi Tricot-Le Breton
66545c9321 REGTESTS: vars: Remove useless ssl tunes from conditional set-var test
The global section of the cond_set_var.vtc test used some useless SSL
tunes which made the test fail on builds without SSL.
2021-12-20 11:41:13 +01:00
Amaury Denoyelle
dbef985b74 MINOR: quic: simplify the removal from ODCID tree
With the DCID refactoring, the locking is more centralized. It is
possible to simplify the code for removal of a quic_conn from the ODCID
tree.

This operation can be conducted as soon as the connection has been
retrieved from the DCID tree, meaning that the peer now uses the final
DCID. Remove the bit to flag a connection for removal and just uses
ebmb_delete() on each sucessful lookup on the DCID tree. If the
quic_conn has already been removed, it is just a noop thanks to
eb_delete() implementation.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
8efe032bba MINOR: quic: refactor DCID lookup
A new function named qc_retrieve_conn_from_cid() now contains all the
code to retrieve a connection from a DCID. It handle all type of packets
and centralize the locking on the ODCID/DCID trees.

This simplify the qc_lstnr_pkt_rcv() function.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
adb2276524 MINOR: quic: compare coalesced packets by DCID
If an UDP datagram contains multiple QUIC packets, they must all use the
same DCID. The datagram context is used partly for this.

To ensure this, a comparison was made on the dcid_node of DCID tree. As
this is a comparison based on pointer address, it can be faulty when
nodes are removed/readded on the same pointer address.

Replace this comparison by a proper comparison on the DCID data itself.
To this end, the dgram_ctx structure contains now a quic_cid member.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
c92cbfc014 MINOR: quic: refactor concat DCID with address for Initial packets
For first Initial packets, the socket source dest address is
concatenated to the DCID. This is used to be able to differentiate
possible collision between several clients which used the same ODCID.

Refactor the code to manage DCID and the concatenation with the address.
Before this, the concatenation was done on the quic_cid struct and its
<len> field incremented. In the code it is difficult to differentiate a
normal DCID with a DCID + address concatenated.

A new field <addrlen> has been added in the quic_cid struct. The <len>
field now only contains the size of the QUIC DCID. the <addrlen> is
first initialized to 0. If the address is concatenated, it will be
updated with the size of the concatenated address. This now means we
have to explicitely used either cid.len or cid.len + cid.addrlen to
access the DCID or the DCID + the address. The code should be clearer
thanks to this.

The field <odcid_len> in quic_rx_packet struct is now useless and has
been removed. However, a new parameter must be added to the
qc_new_conn() function to specify the size of the ODCID addrlen.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
d496251cde MINOR: quic: rename constant for haproxy CIDs length
On haproxy implementation, generated DCID are on 8 bytes, the minimal
value allowed by the specification. Rename the constant representing
this size to inform that this is haproxy specific.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
260e5e6c24 MINOR: quic: add missing lock on cid tree
All operation on the ODCID/DCID trees must be conducted under a
read-write lock. Add a missing read-lock on the lookup operation inside
listener handler.
2021-12-17 10:59:36 +01:00
Amaury Denoyelle
67e6cd50ef CLEANUP: quic: rename quic_conn conn to qc in quic_conn_free
Rename quic_conn from conn to qc to differentiate it from a struct
connection instance. This convention is already used in the majority of
the code.
2021-12-17 10:59:35 +01:00
Amaury Denoyelle
47e1f6d4e2 CLEANUP: quic: fix spelling mistake in a trace
Initiial -> Initial
2021-12-17 10:59:35 +01:00
Amaury Denoyelle
fdbf63e86e MINOR: mux-quic: fix trace on stream creation
Replace non-initialized qcs.by_id.key by the id to report the proper
stream ID on stream creation.
2021-12-17 09:55:01 +01:00
Frédéric Lécaille
8678eb0d19 CLEANUP: quic: Shorten a litte bit the traces in lstnr_rcv_pkt()
Some traces were too long and confusing when displaying 0 for a non-already
parsed packet number.
2021-12-17 08:38:43 +01:00
Frédéric Lécaille
25eeebe293 MINOR: quic: Do not mix packet number space and connection flags
The packet number space flags were mixed with the connection level flags.
This leaded to ACK to be sent at the connection level without regard to
the underlying packet number space. But we want to be able to acknowleged
packets for a specific packet number space.
2021-12-17 08:38:43 +01:00
Frédéric Lécaille
afd373c232 MINOR: hq_interop: Stop BUG_ON() truncated streams
This is required if we do not want to make haproxy crash during zerortt
interop runner test which makes a client open multiple streams with
long request paths.
2021-12-17 08:38:43 +01:00
Frédéric Lécaille
3fe7df877d CLEANUP: quic: Comment fix for qc_strm_cpy()
This function never returns a negative value... hopefully because it returns
a size_t!!!
2021-12-17 08:38:43 +01:00
Frédéric Lécaille
e629cfd96a MINOR: qpack: Missing check for truncated QPACK fields
Decrementing <len> variable without checking could make haproxy crash (on abort)
when printing a huge buffer (with negative length).
2021-12-17 08:38:43 +01:00
Frédéric Lécaille
a5da31d186 MINOR: quic: Make xprt support 0-RTT.
A client sends a 0-RTT data packet after an Initial one in the same datagram.
We must be able to parse such packets just after having parsed the Initial packets.
2021-12-17 08:38:43 +01:00