Dragan Dosen [Tue, 21 Sep 2021 11:02:09 +0000 (13:02 +0200)]
BUG/MINOR: http-ana: increment internal_errors counter on response error
A bug was introduced in the commit
cff0f739e51 ("MINOR: counters: Review
conditions to increment counters from analysers"). The internal_errors
counter for the target server was incremented twice. The counter for the
session listener needs to be incremented instead.
This must be backported everywhere the commit
cff0f739e51 is.
Christopher Faulet [Tue, 21 Sep 2021 13:50:55 +0000 (15:50 +0200)]
MINOR: stream-int: Notify mux when the buffer is not stuck when calling rcv_buf
The transient flag CO_RFL_BUF_NOT_STUCK should now be set when the mux's
rcv_buf() function is called, in si_cs_recv(), to be sure the mux is able to
perform some optimisation during data copy. This flag is set when we are
sure the channel buffer is not stuck. Concretely, it happens when there are
data scheduled to be sent.
It is not a fix and this flag is not used for now. But it makes sense to have
this info to be sure to be able to do some optimisations if necessary.
This patch is related to the issue #1362. It may be backported to 2.4 to
ease future backports.
Christopher Faulet [Tue, 21 Sep 2021 13:22:12 +0000 (15:22 +0200)]
BUG/MEDIUM: stream-int: Defrag HTX message in si_cs_recv() if necessary
The stream interface is now responsible for defragmenting the HTX message of
the input channel if necessary, before calling the mux's .rcv_buf()
function. The defrag is performed if the underlying buffer contains only
input data while the HTX message free space is not contiguous.
The defrag is important here to be sure the mux and the app layer have the
same criteria to decide if a buffer is full or not. Otherwise, the app layer
may wait for more data because the buffer is not full while the mux is
blocked because it needs more space to proceed.
This patch depends on following commits:
* MINOR: htx: Add an HTX flag to know when a message is fragmented
* MINOR: htx: Add a function to know if the free space wraps
This patch is related to the issue #1362. It may be backported as far as 2.0
after some observation period (not sure it is required or not).
Christopher Faulet [Tue, 21 Sep 2021 13:45:05 +0000 (15:45 +0200)]
MINOR: htx: Add a function to know if the free space wraps
the htx_space_wraps() function may now be used to know if the free space of
an HTX message wraps. It does the same as b_space_wraps().
Christopher Faulet [Tue, 21 Sep 2021 13:39:30 +0000 (15:39 +0200)]
MINOR: htx: Add an HTX flag to know when a message is fragmented
HTX_FL_FRAGMENTED flag is now set on an HTX message when it is
fragmented. It happens when an HTX block is removed in the middle of the
message and flagged as unused. HTX_FL_FRAGMENTED flag is removed when all
data are removed from the message or when the message is defragmented.
Note that some optimisations are still possible because the flag can be
avoided in other situations. For instance when the last header of a bodyless
message is removed.
Christopher Faulet [Tue, 21 Sep 2021 13:14:57 +0000 (15:14 +0200)]
MINOR: stream-int: Set CO_RFL transient/persistent flags apart in si_cs_rcv()
In si_cs_recv(), some CO_RFL flags are set when the mux's .rcv_buf()
function is called. Some are persitent inside si_cs_recv() scope, some
others must be computed at each call to rcv_buf(). This patch takes care of
distinguishing them.
Among others, CO_RFL_KEEP_RECV is a persistent flag while CO_RFL_BUF_WET is
transient.
Christopher Faulet [Thu, 23 Sep 2021 12:46:32 +0000 (14:46 +0200)]
BUG/MEDIUM: stream: Stop waiting for more data if SI is blocked on RXBLK_ROOM
If the stream-interface is waiting for more buffer room to store incoming
data, it is important at the stream level to stop to wait for more data to
continue. Thanks to the previous patch ("BUG/MEDIUM: stream-int: Notify
stream that the mux wants more room to xfer data"), the stream is woken up
when this happens. In this patch, we take care to interrupt the
corresponding tcp-content ruleset or to stop waiting for the HTTP message
payload.
To ease detection of the state, si_rx_blocked_room() helper function has
been added. It returns non-zero if the stream interface's Rx path is blocked
because of lack of room in the input buffer.
This patch is part of a series related to the issue #1362. It should be
backported as ar as 2.0, probably with some adaptations. So be careful
during backports.
Christopher Faulet [Thu, 23 Sep 2021 12:17:20 +0000 (14:17 +0200)]
BUG/MEDIUM: stream-int: Notify stream that the mux wants more room to xfer data
When the mux failed to transfer data to the upper layer because of a lack of
room, it is important to wake the stream up to let it handle this
event. Otherwise, if the stream is waiting for more data, both the stream
and the mux reamin blocked waiting for each other.
When this happens, the mux set the CS_FL_WANT_ROOM flag on the
conn-stream. Thus, in si_cs_recv() we are able to detect this event. Today,
the stream-interface is blocked. But, it is not enough to wake the stream
up. To fix the bug, CF_READ_PARTIAL flag is extended to also handle cases
where a read exception occurred. This flag should idealy be renamed. But for
now, it is good enough. By setting this flag, we are sure the stream will be
woken up.
This patch is part of a series related to the issue #1362. It should be
backported as far as 2.0, probably with some adaptations. So be careful
during backports.
Christopher Faulet [Mon, 20 Sep 2021 05:47:27 +0000 (07:47 +0200)]
BUG/MEDIUM: mux-h1: Adjust conditions to ask more space in the channel buffer
When a message is parsed and copied into the channel buffer, in
h1_process_demux(), more space is requested if some pending data remain
after the parsing while the channel buffer is not empty. To do so,
CS_FL_WANT_ROOM flag is set. It means the H1 parser needs more space in the
channel buffer to continue. In the stream-interface, when this flag is set,
the SI is considered as blocked on the RX path. It is only unblocked when
some data are sent.
However, it is not accurrate because the parsing may be stopped because
there is not enough data to continue. For instance in the middle of a chunk
size. In this case, some data may have been already copied but the parser is
blocked because it must receive more data to continue. If the calling SI is
blocked on RX at this stage when the stream is waiting for the payload
(because http-buffer-request is set for instance), the stream remains stuck
infinitely.
To fix the bug, we must request more space to the app layer only when it is
not possible to copied more data. Actually, this happens when data remain in
the input buffer while the H1 parser is in states MSG_DATA or MSG_TUNNEL, or
when we are unable to copy headers or trailers into a non-empty buffer.
The first condition is quite easy to handle. The second one requires an API
refactoring. h1_parse_msg_hdrs() and h1_parse_msg_tlrs() fnuctions have been
updated. Now it is possible to know when we need more space in the buffer to
copy headers or trailers (-2 is returned). In the H1 mux, a new H1S flag
(H1S_F_RX_CONGESTED) is used to track this state inside h1_process_demux().
This patch is part of a series related to the issue #1362. It should be
backported as far as 2.0, probably with some adaptations. So be careful
during backports.
Christopher Faulet [Thu, 23 Sep 2021 13:38:26 +0000 (15:38 +0200)]
BUG/MINOR: h1-htx: Fix a typo when request parser is reset
In h1_postparse_req_hdrs(), if we need more space to copy headers, the request
parser is reset. However, because of a typo, it was reset as a response parser
instead of a request one. h1m_init_req() must be called.
This patch must be backported as far as 2.2.
Amaury Denoyelle [Wed, 22 Sep 2021 13:28:27 +0000 (15:28 +0200)]
MINOR: quic: fix qcc subs initialization
Amaury Denoyelle [Wed, 22 Sep 2021 12:48:32 +0000 (14:48 +0200)]
MEDIUM: quic: implement mux release/conn free
Amaury Denoyelle [Wed, 22 Sep 2021 09:14:37 +0000 (11:14 +0200)]
MINOR: quic: define close handler
Frédéric Lécaille [Thu, 23 Sep 2021 05:33:20 +0000 (07:33 +0200)]
MINOR: quic: Crash upon too big packets receipt
This bug came with this commit:
("MINOR: quic: RX packets memory leak")
Too big packets were freed twice.
Frédéric Lécaille [Wed, 22 Sep 2021 13:15:46 +0000 (15:15 +0200)]
MINOR: quic: Possible endless loop in qc_treat_rx_pkts()
Ensure we do not endlessly treat always the same encryption level
in qc_treat_rx_pkts().
Frédéric Lécaille [Wed, 22 Sep 2021 13:10:49 +0000 (15:10 +0200)]
MINOR: quic: RX packets memory leak
Missing RX packet reference counter decrementation at the lowest level.
This leaded the memory reserved for RX packets to never be released.
Frédéric Lécaille [Wed, 22 Sep 2021 06:34:21 +0000 (08:34 +0200)]
CLEANUP: quic: Remove useless inline functions
We want to track the packet reference counting more easily, so without
inline functions.
Frédéric Lécaille [Mon, 20 Sep 2021 15:58:22 +0000 (17:58 +0200)]
MINOR: quic: Wake up the xprt from mux
We wake up the xprt as soon as STREAM frames have been pushed to
the TX mux buffer (->tx.buf).
We also make the mux subscribe() to the xprt layer if some data
remain in its ring buffer after having try to transfer them to the
xprt layer (TX mux buffer for the stream full).
Also do not consider a buffer in the ring if not allocated (see b_size(buf))
condition in the for(;;) loop.
Make a call to qc_process_mux() if possible when entering qc_send() to
fill the mux with data from streams in the send or flow control lists.
Frédéric Lécaille [Mon, 20 Sep 2021 15:53:17 +0000 (17:53 +0200)]
MINOR: quic: Implement qc_process_mux()
At this time, we only add calls to qc_resume_each_sending_qcs()
which handle the flow control and send lists.
Frédéric Lécaille [Mon, 20 Sep 2021 15:50:03 +0000 (17:50 +0200)]
MINOR: quic: Stream FIN bit fix in qcs_push_frame()
The FIN of a STREAM frame to be built must be set if there is no more
at all data in the ring buffer.
Do not do anything if there is nothing to transfer the ->tx.buf mux
buffer via b_force_xfer() (without zero copy)
Frédéric Lécaille [Mon, 20 Sep 2021 14:59:51 +0000 (16:59 +0200)]
MINOR: quic: Wake up the mux upon ACK receipt
When ACK have been received by the xprt, it must wake up the
mux if this latter has subscribed to SEND events. This is the
role of qcs_try_to_consume() to detect such a situation. This
is the function which consumes the buffer filled by the mux.
Frédéric Lécaille [Mon, 20 Sep 2021 13:23:17 +0000 (15:23 +0200)]
MINOR: quic: Implement quic_conn_subscribe()
We implement ->subscribe() xprt callback which should be used only by the mux.
Frédéric Lécaille [Mon, 20 Sep 2021 13:11:51 +0000 (15:11 +0200)]
MINOR: mux_quic: Export the mux related flags
These flags should be available from the xprt which must be able to
wake up the mux when blocked.
Frédéric Lécaille [Mon, 20 Sep 2021 09:18:24 +0000 (11:18 +0200)]
MINOR: quic: Add useful trace about pktns discarding
It is important to know if the packet number spaces used during the
handshakes have really been discarding. If not, this may have a
significant impact on the packet loss detection.
Frédéric Lécaille [Mon, 20 Sep 2021 09:00:46 +0000 (11:00 +0200)]
MINOR: quic: Initial packet number spaced not discarded
There were cases where the Initial packet number space was not discarded.
This leaded the packet loss detection to continue to take it into
considuration during the connection lifetime. Some Application level
packets could not be retransmitted.
Frédéric Lécaille [Fri, 17 Sep 2021 15:17:16 +0000 (17:17 +0200)]
MINOR: quic: Wrong packet number space selection in quic_loss_pktns()
Ensure the tick is set for a packet number space loss time before
selecting it.
Frédéric Lécaille [Fri, 17 Sep 2021 15:12:56 +0000 (17:12 +0200)]
MINOR: quic: Wrong packet loss detection due to wrong pktns order
During the packet loss detection we must treat the paquet number
in this order Initial -> Handshake -> O1RTT. This was not the case
due to the chosen order to implement the array of packet number space
which was there before the packet loss detection implementation.
Frédéric Lécaille [Fri, 17 Sep 2021 15:08:03 +0000 (17:08 +0200)]
MINOR: quic_tls: Client/serveur state reordering
This is to ensure that expressions which compare the current
state with others are not polluted by the "handshake failed"
special state.
Frédéric Lécaille [Fri, 17 Sep 2021 15:05:44 +0000 (17:05 +0200)]
MINOR: quic: Constantness fixes for frame builders/parsers.
This is to ensure we do not modify important static variables:
the QUIC frame builders and parsers.
Frédéric Lécaille [Fri, 17 Sep 2021 14:57:14 +0000 (16:57 +0200)]
MINOR: quic: Wrong packet flags settings during frame building
We flag the packet as being ack-eliciting when building the frame.
But a wrong variable was used to to so.
Frédéric Lécaille [Fri, 17 Sep 2021 14:51:51 +0000 (16:51 +0200)]
MINOR: quic: Confusion between TX/RX for the frame builders
QUIC_FL_TX_PACKET_ACK_ELICITING was replaced by QUIC_FL_RX_PACKET_ACK_ELICITING
by this commit due to a copy and paste:
e5b47b637 ("MINOR: quic: Add a mask for TX frame builders and their authorized packet types")
Furthermore the flags for the PADDING frame builder was not initialized.
Frédéric Lécaille [Thu, 16 Sep 2021 09:04:49 +0000 (11:04 +0200)]
MINOR: quic: Add a typedef for unsigned long long
As we manipulate very uint64_t variables which must be cast to
unsigned long long to be printed, let's add this useful type definition.
Frédéric Lécaille [Mon, 13 Sep 2021 14:13:00 +0000 (16:13 +0200)]
MINOR: mux_quic: move qc_process() code to qc_send()
qc_process is supposed to be run for each I/O handler event, not
only for "send" events.
Frédéric Lécaille [Fri, 10 Sep 2021 07:13:39 +0000 (09:13 +0200)]
MINOR: quic: Make use of buffer structs to handle STREAM frames
The STREAM data to send coming from the upper layer must be stored until
having being acked by the peer. To do so, we store them in buffer structs,
one by stream (see qcs.tx.buf). Each time a STREAM is built by quic_push_frame(),
its offset must match the offset of the first byte added to the buffer (modulo
the size of the buffer) by the frame. As they are not always acknowledged in
order, they may be stored in eb_trees ordered by their offset to be sure
to sequentially delete the STREAM data from their buffer, in the order they
have been added to it.
Frédéric Lécaille [Thu, 9 Sep 2021 14:53:33 +0000 (16:53 +0200)]
MINOR: buf: Add b_force_xfer() function
This function does exactly the same thing as b_xfer() which transfers
data from a struct buffer to another one but without zero copy when
the destination buffer is empty. This is at least useful to transfer
h3 data to the QUIC mux from buffer with garbage medata which have
been used to build h3 frames without too much memcopy()/memmove().
Frédéric Lécaille [Wed, 8 Sep 2021 15:08:17 +0000 (17:08 +0200)]
MINOR: quic_sock: Do not flag QUIC connections as being set
This is to let conn_get_src() or conn_get_src() set the source
or destination addresses for the connection.
Frédéric Lécaille [Fri, 3 Sep 2021 14:42:19 +0000 (16:42 +0200)]
MINOR: quic: Missing active_connection_id_limit default value
The peer transport parameter values were not initialized with
the default ones (when absent), especially the
"active_connection_id_limit" parameter with 2 as default value
when absent from received remote transport parameters. This
had as side effect to send too much NEW_CONNECTION_ID frames.
This was the case for curl which does not announce any
"active_connection_id_limit" parameter.
Also rename ->idle_timeout to ->max_idle_timeout to reflect the RFC9000.
Frédéric Lécaille [Fri, 3 Sep 2021 13:56:18 +0000 (15:56 +0200)]
MINOR: quic: Attach the QUIC connection to a thread.
Compute a thread ID from a QUIC CID and attach the I/O handler to this
thread.
Frédéric Lécaille [Tue, 31 Aug 2021 17:10:40 +0000 (19:10 +0200)]
MINOR: quic: Make QUIC-TLS support at least two initial salts
These salts are used to derive initial secrets to decrypt the first Initial packet.
We support draft-29 and v1 QUIC version initial salts.
Add parameters to our QUIC-TLS API functions used to derive these secret for
these salts.
Make our xprt_quic use the correct initial salt upon QUIC version field found in
the first paquet. Useful to support connections with curl which use draft-29
QUIC version.
Frédéric Lécaille [Mon, 30 Aug 2021 15:16:07 +0000 (17:16 +0200)]
MINOR: quic: Shorten some handshakes
Move the "ACK required" bit from the packet number space to the connection level.
Force the "ACK required" option when acknowlegding Handshake or Initial packet.
A client may send three packets with a different encryption level for each. So,
this patch modifies qc_treat_rx_pkts() to consider two encryption level passed
as parameters, in place of only one.
Make qc_conn_io_cb() restart its process after the handshake has succeeded
so that to process any Application level packets which have already been received
in the same datagram as the last CRYPTO frames in Handshake packets.
Amaury Denoyelle [Tue, 24 Aug 2021 14:28:47 +0000 (16:28 +0200)]
MINOR: h3/mux: detect fin on last h3 frame of the stream
Amaury Denoyelle [Tue, 24 Aug 2021 14:24:37 +0000 (16:24 +0200)]
MINOR: h3: send htx data
Amaury Denoyelle [Tue, 24 Aug 2021 14:20:27 +0000 (16:20 +0200)]
MINOR: h3: encode htx headers to QPACK
Amaury Denoyelle [Tue, 24 Aug 2021 14:17:38 +0000 (16:17 +0200)]
MINOR: qpack: encode headers functions
Amaury Denoyelle [Tue, 24 Aug 2021 13:50:32 +0000 (15:50 +0200)]
MINOR: qpack: create qpack-enc module
Amaury Denoyelle [Fri, 27 Aug 2021 12:55:39 +0000 (14:55 +0200)]
MINOR: mux-quic: define FIN stream flag
Amaury Denoyelle [Tue, 24 Aug 2021 14:33:53 +0000 (16:33 +0200)]
MINOR: h3: define snd_buf callback and divert mux ops
Amaury Denoyelle [Fri, 27 Aug 2021 13:05:29 +0000 (15:05 +0200)]
MINOR: mux-quic: send SETTINGS on uni stream
Amaury Denoyelle [Tue, 24 Aug 2021 14:11:18 +0000 (16:11 +0200)]
MEDIUM: mux-quic: implement ring buffer on stream tx
Amaury Denoyelle [Tue, 24 Aug 2021 13:36:02 +0000 (15:36 +0200)]
MINOR: h3: allocate stream on headers
Amaury Denoyelle [Tue, 24 Aug 2021 13:30:12 +0000 (15:30 +0200)]
MINOR: h3: parse headers to htx
Amaury Denoyelle [Tue, 24 Aug 2021 13:13:20 +0000 (15:13 +0200)]
MINOR: qpack: generate headers list on decoder
TMP -> non-free strdup
TMP -> currently only support indexed field line or literal field line
with name reference
Amaury Denoyelle [Tue, 24 Aug 2021 13:36:39 +0000 (15:36 +0200)]
MINOR: qpack: fix wrong comment
Amaury Denoyelle [Tue, 24 Aug 2021 14:29:49 +0000 (16:29 +0200)]
MINOR: quic-enc: fix varint encoding
Amaury Denoyelle [Tue, 24 Aug 2021 13:16:58 +0000 (15:16 +0200)]
MINOR: h3: change default settings
In particular, advertise a 0-length dynamic table for QPACK.
Frédéric Lécaille [Wed, 25 Aug 2021 15:56:22 +0000 (17:56 +0200)]
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.
Frédéric Lécaille [Wed, 25 Aug 2021 14:11:00 +0000 (16:11 +0200)]
MINOR: quic: Wrong short packet minimum length
There is no destination connection ID length field in the short packet header.
Frédéric Lécaille [Wed, 25 Aug 2021 14:08:47 +0000 (16:08 +0200)]
MINOR: quic: Wrong STREAM frame length computing
The ->len and ->offset field of STREAM frame are optional.
Frédéric Lécaille [Mon, 23 Aug 2021 07:50:29 +0000 (09:50 +0200)]
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.
Frédéric Lécaille [Mon, 23 Aug 2021 06:54:28 +0000 (08:54 +0200)]
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.
Frédéric Lécaille [Thu, 19 Aug 2021 15:35:21 +0000 (17:35 +0200)]
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.
Frédéric Lécaille [Thu, 19 Aug 2021 13:35:59 +0000 (15:35 +0200)]
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.
Frédéric Lécaille [Thu, 19 Aug 2021 13:19:09 +0000 (15:19 +0200)]
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.
Frédéric Lécaille [Thu, 19 Aug 2021 05:53:27 +0000 (07:53 +0200)]
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.
Frédéric Lécaille [Thu, 19 Aug 2021 05:33:08 +0000 (07:33 +0200)]
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().
Frédéric Lécaille [Wed, 18 Aug 2021 07:16:01 +0000 (09:16 +0200)]
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.
Frédéric Lécaille [Wed, 18 Aug 2021 07:10:48 +0000 (09:10 +0200)]
MINOR: quic: Fix handshake state debug strings
There was a collision between QUIC_HS_ST_CLIENT_HANDSHAKE_FAILED
and QUIC_HS_ST_CONFIRMED states.
Frédéric Lécaille [Mon, 16 Aug 2021 15:08:26 +0000 (17:08 +0200)]
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).
Frédéric Lécaille [Mon, 16 Aug 2021 10:06:46 +0000 (12:06 +0200)]
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.
Frédéric Lécaille [Tue, 10 Aug 2021 07:54:03 +0000 (09:54 +0200)]
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()".
Frédéric Lécaille [Wed, 4 Aug 2021 13:10:32 +0000 (15:10 +0200)]
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".
Frédéric Lécaille [Wed, 4 Aug 2021 13:27:37 +0000 (15:27 +0200)]
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.
Frédéric Lécaille [Wed, 4 Aug 2021 12:53:06 +0000 (14:53 +0200)]
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.
Frédéric Lécaille [Wed, 4 Aug 2021 08:49:51 +0000 (10:49 +0200)]
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!
Frédéric Lécaille [Tue, 3 Aug 2021 15:07:23 +0000 (17:07 +0200)]
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().
Frédéric Lécaille [Tue, 3 Aug 2021 15:01:25 +0000 (17:01 +0200)]
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.
Frédéric Lécaille [Tue, 3 Aug 2021 14:50:14 +0000 (16:50 +0200)]
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.
Frédéric Lécaille [Tue, 3 Aug 2021 14:45:39 +0000 (16:45 +0200)]
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.
Frédéric Lécaille [Tue, 3 Aug 2021 14:38:49 +0000 (16:38 +0200)]
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.
Frédéric Lécaille [Tue, 3 Aug 2021 14:06:01 +0000 (16:06 +0200)]
MINOR: quic: Atomically handle packet number space ->largest_acked_pn variable
Protect this variable (largest acked packet number) from any concurrent access.
Frédéric Lécaille [Tue, 3 Aug 2021 14:03:09 +0000 (16:03 +0200)]
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).
Frédéric Lécaille [Tue, 3 Aug 2021 13:03:35 +0000 (15:03 +0200)]
MINOR: quic: Add the packet type to quic_tx_packet struct
This is required to build packets from the same function.
Frédéric Lécaille [Tue, 3 Aug 2021 12:29:03 +0000 (14:29 +0200)]
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.
Frédéric Lécaille [Tue, 3 Aug 2021 12:25:36 +0000 (14:25 +0200)]
MINOR: quic: Add the QUIC connection state to traces
This connection variable was missing. It is useful to debug issues.
Frédéric Lécaille [Mon, 2 Aug 2021 14:41:28 +0000 (16:41 +0200)]
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.
Frédéric Lécaille [Fri, 30 Jul 2021 12:42:33 +0000 (14:42 +0200)]
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.
Frédéric Lécaille [Tue, 27 Jul 2021 12:51:54 +0000 (14:51 +0200)]
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.
Frédéric Lécaille [Tue, 27 Jul 2021 09:43:11 +0000 (11:43 +0200)]
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.
Frédéric Lécaille [Mon, 26 Jul 2021 14:42:56 +0000 (16:42 +0200)]
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.
Frédéric Lécaille [Mon, 26 Jul 2021 14:38:14 +0000 (16:38 +0200)]
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.
Frédéric Lécaille [Mon, 26 Jul 2021 14:23:53 +0000 (16:23 +0200)]
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.
Frédéric Lécaille [Wed, 21 Jul 2021 07:34:27 +0000 (09:34 +0200)]
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)).
Frédéric Lécaille [Mon, 19 Jul 2021 12:48:36 +0000 (14:48 +0200)]
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.
Frédéric Lécaille [Fri, 16 Jul 2021 09:42:44 +0000 (11:42 +0200)]
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.
Frédéric Lécaille [Tue, 6 Jul 2021 15:19:44 +0000 (17:19 +0200)]
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.
Frédéric Lécaille [Tue, 6 Jul 2021 15:08:04 +0000 (17:08 +0200)]
MINOR: quic_tls: Make use of the QUIC V1 salt.
This salt is used to derive the Initial secrets.
Frédéric Lécaille [Tue, 6 Jul 2021 14:35:52 +0000 (16:35 +0200)]
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.
Frédéric Lécaille [Tue, 6 Jul 2021 14:25:08 +0000 (16:25 +0200)]
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.
Frédéric Lécaille [Tue, 6 Jul 2021 13:39:26 +0000 (15:39 +0200)]
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.
Frédéric Lécaille [Tue, 6 Jul 2021 13:34:37 +0000 (15:34 +0200)]
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).