593 Commits

Author SHA1 Message Date
Frédéric Lécaille
b80b20c6ff MINOR: quic: Do not wakeup the I/O handler before the mux is started
If we wakeup the I/O handler before the mux is started, it is possible
it has enough time to parse the ClientHello TLS message and update the
mux transport parameters, leading to a crash.
So, we initialize ->qcc quic_conn struct member at the very last time,
when the mux if fully initialized. The condition to wakeup the I/O handler
from lstnr_rcv_pkt() is: xprt context and mux both initialized.
Note that if the xprt context is initialized, it implies its tasklet is
initialized. So, we do not check anymore this latter condition.
2022-01-12 18:08:29 +01:00
Frédéric Lécaille
bec186dde5 MINOR: quic: As server, skip 0-RTT packet number space
This is true only when we are building packets. A QUIC server never
sends 0-RTT packets. So let't skip the associated TLS encryption level.
2022-01-12 18:08:29 +01:00
Amaury Denoyelle
9ab2fb3921 MINOR: quic: free xprt tasklet on its thread
Free the ssl_sock_ctx tasklet in quic_close() instead of
quic_conn_drop(). This ensures that the tasklet is destroyed safely by
the same thread.

This has no impact as the free operation was previously conducted with
care and should not be responsible of any crash.
2022-01-12 15:21:27 +01:00
Amaury Denoyelle
b76ae69513 MEDIUM: quic: implement Retry emission
Implement the emission of Retry packets. These packets are emitted in
response to Initial from clients without token. The token from the Retry
packet contains the ODCID from the Initial packet.

By default, Retry packet emission is disabled and the handshake can
continue without address validation. To enable Retry, a new bind option
has been defined named "quic-force-retry". If set, the handshake must be
conducted only after receiving a token in the Initial packet.
2022-01-12 11:08:48 +01:00
Amaury Denoyelle
c3b6f4d484 MINOR: quic: define retry_source_connection_id TP
Define a new QUIC transport parameter retry_source_connection_id. This
parameter is set only by server, after issuing a Retry packet.
2022-01-12 11:08:48 +01:00
Amaury Denoyelle
5ff1c9778c MEDIUM: quic: implement Initial token parsing
Implement the parsing of token from Initial packets. It is expected that
the token contains a CID which is the DCID from the Initial packet
received from the client without token which triggers a Retry packet.
This CID is then used for transport parameters.

Note that at the moment Retry packet emission is not implemented. This
will be achieved in a following commit.
2022-01-12 11:08:48 +01:00
Amaury Denoyelle
ce340fe4a7 MINOR: quic: fix return of quic_dgram_read
It is expected that quic_dgram_read() returns the total number of bytes
read. Fix the return value when the read has been successful. This bug
has no impact as in the end the return value is not checked by the
caller.
2022-01-12 11:08:48 +01:00
Frédéric Lécaille
1aa57d32bb MINOR: quic: Do not dereference ->conn quic_conn struct member
->conn quic_conn struct member is a connection struct object which may be
released from several places. With this patch we do our best to stop dereferencing
this member as much as we can.
2022-01-12 09:49:49 +01:00
Frédéric Lécaille
ba85acdc70 MINOR: quid: Add traces quic_close() and quic_conn_io_cb()
This is to have an idea of possible remaining issues regarding the
connection terminations.
2022-01-11 16:56:04 +01:00
Frédéric Lécaille
81cd3c8eed MINOR: quic: Wrong CRYPTO frame concatenation
This commit was not correct:
	 "MINOR: quic: Only one CRYPTO frame by encryption level"
Indeed, when receiving CRYPTO data from TLS stack for a packet number space,
there are rare cases where there is already other frames than CRYPTO data frames
in the packet number space, especially for 01RTT packet number space.  This is
very often with quant as client.
2022-01-11 16:12:31 +01:00
Frédéric Lécaille
2fe8b3be20 MINOR: quic: Flag the connection as being attached to a listener
We do not rely on connection objects to know if we are a listener or not.
2022-01-11 16:12:31 +01:00
Frédéric Lécaille
5f7f118b31 MINOR: quic: Remaining TRACEs with connection as firt arg
This is a quic_conn struct which is expected by TRACE_()* macros
2022-01-11 16:12:31 +01:00
Frédéric Lécaille
99942d6f4c MINOR: quic: Non-optimal use of a TX buffer
When full, after having reset the writer index, let's reuse the TX buffer in
any case.
2022-01-07 17:58:26 +01:00
Frédéric Lécaille
f010f0aaf2 MINOR: quic: Missing retransmission from qc_prep_fast_retrans()
In fact we must look for the first packet with some ack-elicting frame to
in the packet number space tree to retransmit from. Obviously there
may be already retransmit packets which are not deemed as lost and
still present in the packet number space tree for TX packets.
2022-01-07 17:58:26 +01:00
Frédéric Lécaille
d4ecf94827 MINOR: quic: Only one CRYPTO frame by encryption level
When receiving CRYPTO data from the TLS stack, concatenate the CRYPTO data
to the first allocated CRYPTO frame if present. This reduces by one the number
of handshake packets built for a connection with a standard size certificate.
2022-01-07 17:58:26 +01:00
Ilya Shipitsin
37d3e38130 CLEANUP: assorted typo fixes in the code and comments
This is 30th iteration of typo fixes
2022-01-07 14:42:54 +01:00
Frédéric Lécaille
6b6631593f MINOR: quic: Re-arm the PTO timer upon datagram receipt
When block by the anti-amplification limit, this is the responsability of the
client to unblock it sending new datagrams. On the server side, even if not
well parsed, such datagrams must trigger the PTO timer arming.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
078634d126 MINOR: quic: PTO timer too often reset
It must be reset when the anti-amplication was reached but only if the
peer address was not validated.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
41a076087b MINOR: quic: Flag asap the connection having reached the anti-amplification limit
The best location to flag the connection is just after having built the packet
which reached the anti-amplication limit.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
de6f7c503e MINOR: quic: Prepare Handshake packets asap after completed handshake
Switch back to QUIC_HS_ST_SERVER_HANDSHAKE state after a completed handshake
if acks must be send.
Also ensure we build post handshake frames only one time without using prev_st
variable and ensure we discard the Handshake packet number space only one time.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
917a7dbdc7 MINOR: quic: Do not drop secret key but drop the CRYPTO data
We need to be able to decrypt late Handshake packets after the TLS secret
keys have been discarded. If not the peer send Handshake packet which have
not been acknowledged. But for such packets, we discard the CRYPTO data.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
ee2b8b377f MINOR: quic: Improve qc_prep_pkts() flexibility
We want to be able to choose the encryption levels to be used
by qc_prep_pkts() outside of it.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
f7ef97698a MINOR: quic: Comment fix.
When we drop a packet with unknown length, this is the entire datagram which
must be skipped.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
a56054e438 MINOR: quic: Probe several packet number space upon timer expiration
When the loss detection timer expires, we SHOULD include new data in
our probing packets (RFC 9002 par 6.2.4. Sending Probe Packets).
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
db6a4727cf MINOR: quic: Probe Initial packet number space more often
Especially when the PTO expires for Handshake packet number space and when
Initial packets are still flying (for QUIC servers).
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
3bb457c4ba MINOR: quic: Speeding up Handshake Completion
According to RFC 9002 par. 6.2.3. when receving duplicate Initial CRYPTO
data a server may a packet containing non unacknowledged before the PTO
expiry.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
63556772cc MINOR: quic: qc_prep_pkts() code moving
Move the switch default case code out of the switch to improve the readibily.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
5732062cd2 MINOR: quic: Useless test in qc_prep_pkts()
These tests were there to initiate PTO probing but they are not correct.
Furthermore they may break the PTO probing process and lead to useless packet
building.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
dd51da599e MINOR: quic: Wrong packet number space trace in qc_prep_pkts()
It was always the first packet number space information which was dumped.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
466e9da145 MINOR: quic: Remove nb_pto_dgrams quic_conn struct member
For now on we rely on tx->pto_probe pktns struct member to inform
the packet building function we want to probe.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
22576a2e55 MINOR: quic: Wrong ack_delay compution before calling quic_loss_srtt_update()
RFC 9002 5.3. Estimating smoothed_rtt and rttvar:
MUST use the lesser of the acknowledgment delay and the peer's max_ack_delay
after the handshake is confirmed.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
dc90c07715 MINOR: quic: Wrong loss time computation in qc_packet_loss_lookup()
This part as been modified by the RFC since our first implementation.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
22cfd83890 MINOR: quic: Add trace about in flight bytes by packet number space
This parameter is useful to diagnose packet loss detection issues.
2022-01-04 17:30:00 +01:00
Frédéric Lécaille
fde2a98dd1 MINOR: quic: Wrong traces after rework
TRACE_*() macros must take a quic_conn struct as first argument.
2022-01-04 17:30:00 +01:00
Ilya Shipitsin
5e87bcf870 CLEANUP: assorted typo fixes in the code and comments This is 29th iteration of typo fixes 2022-01-03 14:40:58 +01:00
Amaury Denoyelle
9979d0d1ea BUG/MINOR: quic: fix potential use of uninit pointer
Properly initialized the ssl_sock_ctx pointer in qc_conn_init. This is
required to avoid to set an undefined pointer in qc.xprt_ctx if argument
*xprt_ctx is NULL.
2021-12-23 16:33:47 +01:00
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
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
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