Commit Graph

15776 Commits

Author SHA1 Message Date
Frédéric Lécaille
a5b1b894c6 MINOR: quic: Prepare STREAM frames to fill QUIC packets
We must take as most as possible data from STREAM frames to be encapsulated
in QUIC packets, almost as this is done for CRYPTO frames whose fields are
variable length fields. The difference is that STREAM frames are only accepted
for short packets without any "Length" field. So it is sufficient to call
max_available_room() for that in place of max_stream_data_size() as this
is done for CRYPTO data.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
f4c5c7bdbb MINOR: quic: Wrong short packet minimum length
There is no destination connection ID length field in the short packet header.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
ca9d32c785 MINOR: quic: Wrong STREAM frame length computing
The ->len and ->offset field of STREAM frame are optional.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
e16f0bd1e3 MINOR: h3: Send h3 settings asap
As it is possible to send Application level packets during the handshake,
let's send the h3 settings asaps.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
4bade77bf9 MINOR: quic: Prepare Application level packet asap.
It is possible the TLS stack stack provides us with 1-RTT TX secrets
at the same time as Handshake secrets are provided. Thanks to this
simple patch we can build Application level packets during the handshake.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
f798096412 MINOR: quic: Post handshake packet building improvements
Make qc_prep_hdshk_pkts() and qui_conn_io_cb() handle the case
where we enter them with QUIC_HS_ST_COMPLETE or QUIC_HS_ST_CONFIRMED
as connection state with QUIC_TLS_ENC_LEVEL_APP and QUIC_TLS_ENC_LEVEL_NONE
to consider to prepare packets.
quic_get_tls_enc_levels() is modified to return QUIC_TLS_ENC_LEVEL_APP
and QUIC_TLS_ENC_LEVEL_NONE as levels to consider when coalescing
packets in the same datagram.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
754f99e995 MINOR: quic: Missing case when discarding HANDSHAKE secrets
With very few packets received by the listener, it is possible
that its state may move from QUIC_HS_ST_SERVER_INITIAL to
QUIC_HS_ST_COMPLETE without transition to QUIC_HS_ST_SERVER_HANDSHAKE state.
This latter state is not mandatory.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
67f47d0125 MINOR: quic: Wrong flags handling for acks
Fixes several concurrent accesses issue regarding QUIC_FL_PKTNS_ACK_RECEIVED and
QUIC_FL_PKTNS_ACK_REQUIRED flags.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
d067088695 MINOR: quic: Coalesce Application level packets with Handshake packets.
This simple enable use to coalesce Application level packet with
Handshake ones at the end of the handshake. This is highly useful
if we do want to send a short Handshake packet followed by Application
level ones.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
31550afe06 MINOR: quic: Missing QUIC encryption level for qc_build_pkt()
qc_build_pkt() has recently been modified to support any type of
supported frame at any encryption level (assuming that an encryption level does
not support any type of frame) but quic_tls_level_pkt_type()
prevented it from building application level packet type because it was written
only for the handshake.
This patch simply adds the remaining encryption level QUIC_TLS_ENC_LEVEL_APP
which must be supported by quic_tls_level_pkt_type().
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
eed7a7d73b MINOR: quic: Atomically get/set the connection state
As ->state quic_conn struct member field is shared between threads
we must atomically get and set its value.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
ee57444382 MINOR: quic: Fix handshake state debug strings
There was a collision between QUIC_HS_ST_CLIENT_HANDSHAKE_FAILED
and QUIC_HS_ST_CONFIRMED states.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
2e459a83d6 MINOR: quic: Update the TLS extension for QUIC transport parameters
0xffa5 value was a draft one. Let's update this extension to the one
defined by the QUIC-TLS RFC 9001.
(See https://www.rfc-editor.org/rfc/rfc9001.html#name-quic-transport-parameters-e).
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
4436cb6606 MINOR: quic: Evaluate the packet lengths in advance
We must evaluate the packet lenghts in advance to be sure we do not
consume a packet number for nothing. The packet building must always
succeeds. This is the role of qc_eval_pkt() implemented by this patch
called before calling qc_do_build_pkt() which was previously modified to
always succeed.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
82b8652ac6 MINOR: quic: Missing acks encoded size updates.
There were cases where the encoded size of acks was not updated leading
to ACK frames building too big compared to the expected size. At this
time, this makes the code "BUG_ON()".
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
8b19a9f162 MINOR: quic: Make use of the last cbuf API when initializing TX ring buffers
Initialize the circular buffer internal buffer from a specific pool for TX ring
buffers named "pool_head_quic_tx_ring".
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
dbe25afbe6 MINOR: quic: Add a pool for TX ring buffer internal buffer
We want to allocate the internal buffer of TX ring buffer from a pool.
This patch add "quic_tx_ring_pool" to do so.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
a2e954a817 MINOR: quic: Make circular buffer internal buffers be variable-sized.
For now on thanks to this simple patch we can use circular buffers with
a variable-sized internal buffer.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
9445abc013 MINOR: quic: Rename functions which do not build only Handshake packets
Rename qc_build_hdshk_pkt() to qc_build_pkt() and qc_do_build_hdshk_pkt()
to qc_do_build_pkt().
Update their comments consequently.
Make qc_do_build_hdshk_pkt() BUG_ON() when it does not manage to build
a packet. This is a bug!
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
5d00b2d7b1 MINOR: quic: Remove Application level related functions
Remove the functions which were specific to the Application level.
This is the same function which build any packet for any encryption
level: quic_prep_hdshk_pkts() directly called from the quic_conn_io_cb().
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
f252adb368 MINOR: quic: qc_do_build_hdshk_pkt() does not need to pass a copy of CRYPTO frame
There is no need to pass a copy of CRYPTO frames to qc_build_frm() from
qc_do_build_hdshk_pkt(). Furthermore, after the previous modifications,
qc_do_build_hdshk_pkt() do not build only CRYPTO frame from ->pktns.tx.frms
MT_LIST but any type of frame.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
a7348f6f85 MINOR: quic: Make qc_build_hdshk_pkt() atomically consume a packet number
Atomically increase the "next packet variable" before building a new packet.
Make the code bug on a packet building failure. This should never happen
if we do not want to consume a packet number for nothing. There are remaining
modifications to come to ensure this is the case.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
91ae7aa7ec MINOR: quic: quic_conn_io_cb() task rework
Modify this task which is called at least each a packet is received by a listener
so that to make it behave almost as qc_do_hdshk(). This latter is no more useful
and removed.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
0ac3851f14 MINOR: quic: Modify qc_build_cfrms() to support any frame
This function was responsible of building CRYPTO frames to fill as much as
possible a packet passed as argument. This patch makes it support any frame
except STREAM frames whose lengths are highly variable.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
59b07c737b MINOR: quic: Atomically handle packet number space ->largest_acked_pn variable
Protect this variable (largest acked packet number) from any concurrent access.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
e1aa0d347a MINOR: quic: Modify qc_do_build_hdshk_pkt() to accept any packet type
With this patch qc_do_build_hdshk_pkt() is also able to build Application level
packet type. Its name should be consequently renamed (to come).
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
0e50e1b0b5 MINOR: quic: Add the packet type to quic_tx_packet struct
This is required to build packets from the same function.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
522c65ce39 MINOR: quic: Store post handshake frame in ->pktns.tx.frms MT_LIST
We want to treat all the frames to be built the same way as frames
built during handshake (CRYPTO frames). So, let't store them at the same
place which is an MT_LIST.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
546186b1cf MINOR: quic: Add the QUIC connection state to traces
This connection variable was missing. It is useful to debug issues.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
db2a7649a9 MINOR: quic: Add a useful function to compute any frame length.
This should be used by the function which build packets to prevent
it from failing. This is important when the packet numbers are consumed
by several threads. The packet number is used to build and encrypt packets
and must be incremented only and only if the packet it refers to has been
successfully built.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
f5821dc7b7 MINOR: quic: Add a mask for TX frame builders and their authorized packet types
As this has been done for RX frame parsers, we add a mask for each TX frame
builder to denote the packet types which are authorized to embed such frames.
Each time a TX frame builder is called, we check that its mask matches the
packet type the frame is built for.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
0ad0458a56 MINOR: quic: Replace quic_tx_frm struct by quic_frame struct
These structures are similar. quic_tx_frm was there to try to reduce the
size of such objects which embed a union for all the QUIC frames.
Furtheremore this patch fixes the issue where quic_tx_frm objects were freed
from the pool for quic_frame.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c88df07bdd MINOR: quic: Make ->tx.frms quic_pktns struct member be thread safe
Replace this member which is a list struct by an mt_list struct.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
120ea6f169 MINOR: quic: Make qc_treat_rx_pkts() be thread safe.
Make quic_rx_packet_ref(inc|dec)() functions be thread safe.
Make use of ->rx.crypto.frms_rwlock RW lock when manipulating RX frames
from qc_treat_rx_crypto_frms().
Modify atomically several variables attached to RX part of quic_enc_level struct.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
98cdeb2f0c MINOR: quic: Rename ->rx.rwlock of quic_enc_level struct to ->rx.pkts_rwlock
As there are at two RW lock in this structure, let's the name of this lock
be more explicit.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
9054d1b564 MINOR: quic: Missing encryption level rx.crypto member initialization and lock.
->rx.crypto member of quic_enc_level struct was not initialized as
this was done for all other members of this structure. This patch
fixes this.
Also adds a RW lock for the frame of this member.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
01abc4612b MINOR: quic: Unitialized mux context upon Client Hello message receipt.
If we let the connection packet handler task (quic_conn_io_cb) process the first
client Initial packet which contain the TLS Client Hello message before the mux
context is initialized, quic_mux_transport_params_update() makes haproxy crash.
->start xprt callback already wakes up this task and is called after all the
connection contexts are initialized. So, this patch do not wakes up quic_conn_io_cb()
if the mux context is not initialized (this was already the case for the connection
context (conn_ctx)).
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
0eb60c5b4d MINOR: quic: Add TX packets at the very last time to their tree.
If we add TX packets to their trees before sending them, they may
be detected as lost before being sent. This may make haproxy crash
when it retreives the prepared packets from TX ring buffers, dereferencing
them after they have been freed.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
b095252a23 MINOR: Add function for TX packets reference counting
Add two functions to encrement or decrement a referenc counter
attached to TX packet structure (struct quic_tx_packet). The packet are freed
when their counters reach the null value.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c8d3f873e8 MINOR: quic: Remove old TX buffer implementation
We use only ring buffers (struct qring) to prepare and send QUIC datagrams.
We can safely remove the old buffering implementation which was not thread safe.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
98ad56a049 MINOR: quic_tls: Make use of the QUIC V1 salt.
This salt is used to derive the Initial secrets.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c5b0c93c26 MINOR: quic: Make use of TX ring buffers to send QUIC packets
We modify the functions responsible of building packets to put these latters
in ring buffers (qc_build_hdshk_pkt() during the handshake step, and
qc_build_phdshk_apkt() during the post-handshake step). These functions
remove a ring buffer from its list to build as much as possible datagrams.
Eache datagram is prepended of two field: the datagram length and the
first packet in the datagram. We chain the packets belonging to the same datagram
in a singly linked list to reach them from the first one: indeed we must
modify some members of each packet when we really send them from send_ppkts().
This function is also modified to retrieved the datagram from ring buffers.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
6b19764e3c MINOR: quic: Initialize pointers to TX ring buffer list
We initialize the pointer to the listener TX ring buffer list.
Note that this is not done for QUIC clients  as we do not fully support them:
we only have to allocate the list and attach it to server struct I guess.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
48f8e1925b MINOR: proto_quic: Allocate TX ring buffers for listeners
We allocate an array of QUIC ring buffer, one by thread, and arranges them in a
MT_LIST. Everything is allocated or nothing: we do not want to usse an incomplete
array of ring buffers to ensure that each thread may safely acquire one of these
buffers.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
22cfdf8d0e MINOR: quic: Add ring buffer definition (struct qring) for QUIC
A ring buffer is made of a circular buffer (->cbuf) and must be arrange
in a MT_LIST (->mt_list).
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
9621565b74 MINOR: net_helper: add functions for pointers
Add two functions to read/write pointer values to/from vectors.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
ed9119f39e BUG/MINOR: quic: Too much reduced computed space to build handshake packets
Before this patch we reserved 16 bytes (QUIC_TLS_TAG_LEN) before building the
handshake packet to be sure to be able to add the tag which comes with the
the packet encryption, decreasing the end offset of the building buffer by 16 bytes.
But this tag length was taken into an account when calling qc_build_frms() which
computes and build crypto frames for the remaining available room thanks to <*len>
parameter which is the length of the already present bytes in the building buffer
before adding CRYPTO frames. This leaded us to waste the 16 last bytes of the buffer
which were not used.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
82d1daa268 MINOR: quic: Add the QUIC v1 initial salt.
See initial_salt value for QUIC-TLS RFC 9001 at
https://www.rfc-editor.org/rfc/rfc9001.html#name-initial-secrets
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
4b1fddcfcf MINOR: quic: Prefer x25519 as ECDH preferred parametes.
This make at least our listeners answer to ngtcp2 clients without
HelloRetryRequest message. It seems the server choses the first
group in the group list ordered by preference and set by
SSL_CTX_set1_curves_list() which match the client ones.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c6bc185c18 MINOR: quic: Add a ring buffer implementation for QUIC
This implementation is inspired from Linux kernel circular buffer implementation
(see include/linux/circ-buf.h). Such buffers may be used at the same time both
by writer and reader (lock-free).
2021-09-23 15:27:25 +02:00