Commit Graph

589 Commits

Author SHA1 Message Date
Frédéric Lécaille
2766e78f3b 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.
2021-09-23 15:27:25 +02:00
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
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
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
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
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
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
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
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
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
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
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
f3d078d22e MINOR: quic: Make qc_lstnr_pkt_rcv() be thread safe.
Modify the I/O dgram handler principal function used to parse QUIC packets
be thread safe. Its role is at least to create new incoming connections
add to two trees protected by the same RW lock. The packets are for now on
fully parsed before possibly creating new connections.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
6de7287cc7 MINOR: quic: Connection allocations rework
Allocate everything needed for a connection (struct quic_conn) from the same
function.
Rename qc_new_conn_init() to qc_new_conn() to reflect these modifications.
Insert these connection objects in their tree after returning from this function.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
7fd59789f2 MINOR: quic: Do not wakeup the xprt task on ACK receipt
This is an old statement which was there before implemeting the PTO and
packet loss detection. There is no reason to keep for now on.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
2e7ffc9d31 MINOR: quic: Add useful traces for I/O dgram handler
This traces have already help in diagnosing multithreading issues.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
a11d0e26d4 MINOR: quic: Replace the RX unprotected packet list by a thread safety one.
This list is shared between the I/O dgram handler and the task responsible
for processing the QUIC packets inside.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c28aba2a8d MINOR: quic: Replace the RX list of packet by a thread safety one.
This list is shared between the I/O dgram handler and the task responsible
for processing the QUIC packets.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
1eaec33cb5 MINOR: quic: Replace quic_conn_ctx struct by ssl_sock_ctx struct
Some SSL call may be called with pointer to ssl_sock_ctx struct as parameter
which does not match the quic_conn_ctx struct type (see ssl_sock_infocb()).
I am not sure we have to keep such callbacks for QUIC but we must ensure
the SSL and QUIC xprts use the same data structure as context.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
a5fe49f44a MINOR: quic: Move the connection state
Move the connection state from quic_conn_ctx struct to quic_conn struct which
is the structure which is used to store the QUIC connection part information.
This structure is initialized by the I/O dgram handler for each new connection
to QUIC listeners. This is needed for the multithread support so that to not
to have to depend on the connection context potentially initialized by another
thread.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
9fccace8b0 MINOR: quic: Add a lock for RX packets
We must protect from concurrent the tree which stores the QUIC packets received
by the dgram I/O handler, these packets being also parsed by the xprt task.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
654c691731 MINOR: quic: Do not stop the packet parsing too early in qc_treat_rx_packets()
Continue to parse the packets even if we will not be able to acknowledge them.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
6fe21b0dec BUG/MINOR: quic: Wrong RX packet reference counter usage
No need to call free_quic_rx_packet() after calling quic_rx_packet_eb64_delete()
as this latter already calls quic_rx_packet_refdec() also called by
free_quic_rx_packet().
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c4b93ea57d CLEAUNUP: quic: Usage of a useless variable in qc_treat_rx_pkts()
The usage of a <drop> variable is unnecessary here.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
8ba4276d13 BUG/MINOR: quic: Missing cases treatement when updating ACK ranges
Let's say that we have to insert a range R between to others A and B
with A->first <= R->first <= B->first. We have to remove the ranges
which are overlapsed by R during. This was correctly done when
the intersection between A and R was not empty, but not when the
intersection between R and B was not empty. If this latter case
after having inserting a new range R we set <new> variable as the
node to consider to check the overlaping between R and its following
ranges.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
c825eba5f9 MINOR: quic: Remove a useless variable in quic_update_ack_ranges_list()
This very minor modification is there to ease the readibilyt of this function.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
d3f4dd8014 MINOR: quic: Useless test in quic_update_ack_ranges_list()
At this place, the condition "le_ar->first.key <= ar->first" is true because
<le_ar> is the ack-range just below <ar> ack range.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
9ef64cd078 MINOR: quic: quic_update_ack_ranges_list() code factorization
Very minor modification to avoid repeating the same code section in this function
when allocation new ack range.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
baea284c3c BUG/MINOR: quic: Wrong memory free in quic_update_ack_ranges_list()
Wrong call to free() in place of pool_free() for an object allocated from a pool
memory.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
1a5e88c86a MINOR: quic: Remove header protection also for Initial packets
Make qc_try_rm_hp() be able to remove the header protection of Initial packets
which are the first incoming packets of a connection without context.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
497fa78ad8 MINOR: quic: Derive the initial secrets asap
Make depends qc_new_isecs() only on quic_conn struct initialization only (no more
dependency on connection struct initialization) to be able to run it as soon as
the quic_conn struct is initialized (from the I/O handler) before running ->accept()
quic proto callback.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
d24c2ecb16 MINOR: quic: Remove header protection for conn with context
We remove the header protection of packet only for connection with already
initialized context. This latter keep traces of the connection state.
Furthermore, we enqueue the first Initial packet for a new connection
after having completely parsed the packet so that to not start the accept
process for nothing.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
3d77fa754d MINOR: quic: QUIC conn initialization from I/O handler
Move the QUIC conn (struct quic_conn) initialization from quic_sock_accept_conn()
to qc_lstnr_pkt_rcv() as this is done for the server part.
Move the timer initialization to ->start xprt callback to ensure the connection
context is done : it is initialized by the ->accept callback which may be run
by another thread than the one for the I/O handler which also run ->start.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
de935f34e5 BUG/MINOR: quic: Do not check the acception of a new conn from I/O handler.
As the ->conn member of quic_conn struct is reset to NULL value by the ->accept
callback potentially run by another thread, this check is irrelevant.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
1e1aad4ff4 MINOR: quic: Move an SSL func call from QUIC I/O handler to the xprt init.
Move the call to SSL_set_quic_transport_params() from the listener I/O dgram
handler to the ->init() callback of the xprt (qc_conn_init()) which initializes
its context where is stored the SSL context itself, needed by
SSL_set_quic_transport_params(). Furthermore this is already what is done for the
server counterpart of ->init() QUIC xprt callback. As the ->init() may be run
by another thread than the one for the I/O handler, the xprt context could
not be potentially already initialized before calling SSL_set_quic_transport_params()
from the I/O handler.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
785c9c998a MINOR: quic: Replace max_packet_size by max_udp_payload size.
The name the maximum packet size transport parameter was ambiguous and replaced
by maximum UDP payload size. Our code would be also ambiguous if it does not
reflect this change.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
422a39cf2c MINOR: quic: Add callbacks for (un)scribing to QUIC xprt.
Add these callbacks so that the QUIC mux may (un)scribe to the read/write xprt
events.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
fbe3b77c4e MINOR: quic: Disable the action of ->rcv_buf() xprt callback
Deactivate the action of this callback at this time. I am not sure
we will keep it for QUIC as it does not really make sense for QUIC:
the QUIC packet are already recvfrom()'ed by the low level I/O handler
used for all the connections.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
dfbae766b2 MINOR: mux_quic: Add QUIC mux layer.
This file has been derived from mux_h2.c removing all h2 parts. At
QUIC mux layer, there must not be any reference to http. This will be the
responsability of the application layer (h3) to open streams handled by the mux.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
5aa4143d6c MINOR: quic: Move transport parmaters to anynomous struct.
We move ->params transport parameters to ->rx.params. They are the
transport parameters which will be sent to the peer, and used for
the endpoint flow control. So, they will be used to received packets
from the peer (RX part).
Also move ->rx_tps transport parameters to ->tx.params. They are the
transport parameter which are sent by the peer, and used to respect
its flow control limits. So, they will be used when sending packets
to the peer (TX part).
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
577fe48890 BUG/MINOR: quic: Possible NULL pointer dereferencing when dumping streams.
This bug may occur when displaying streams traces. It came with this commit:
242fb1b63 ("MINOR: quic: Drop packets with STREAM frames with wrong direction.").
2021-09-23 15:27:25 +02:00
Ilya Shipitsin
01881087fc CLEANUP: assorted typo fixes in the code and comments
This is 25th iteration of typo fixes
2021-08-16 12:37:59 +02:00
Willy Tarreau
7deb28ce65 BUG/MEDIUM: quic: fix null deref on error path in qc_conn_init()
When ctx is NULL, we go to the "err" label, which could dereference it.
No backport is needed.
2021-05-10 07:40:27 +02:00
Willy Tarreau
2b71810cb3 CLEANUP: lists/tree-wide: rename some list operations to avoid some confusion
The current "ADD" vs "ADDQ" is confusing because when thinking in terms
of appending at the end of a list, "ADD" naturally comes to mind, but
here it does the opposite, it inserts. Several times already it's been
incorrectly used where ADDQ was expected, the latest of which was a
fortunate accident explained in 6fa922562 ("CLEANUP: stream: explain
why we queue the stream at the head of the server list").

Let's use more explicit (but slightly longer) names now:

   LIST_ADD        ->       LIST_INSERT
   LIST_ADDQ       ->       LIST_APPEND
   LIST_ADDED      ->       LIST_INLIST
   LIST_DEL        ->       LIST_DELETE

The same is true for MT_LISTs, including their "TRY" variant.
LIST_DEL_INIT keeps its short name to encourage to use it instead of the
lazier LIST_DELETE which is often less safe.

The change is large (~674 non-comment entries) but is mechanical enough
to remain safe. No permutation was performed, so any out-of-tree code
can easily map older names to new ones.

The list doc was updated.
2021-04-21 09:20:17 +02:00
Willy Tarreau
b41a6e9101 MINOR: fd: move .linger_risk into fdtab[].state
No need to keep this flag apart any more, let's merge it into the global
state. The CLI's output state was extended to 6 digits and the linger/cloned
flags moved inside the parenthesis.
2021-04-07 18:07:49 +02:00
Willy Tarreau
f509065191 MEDIUM: fd: merge fdtab[].ev and state for FD_EV_* and FD_POLL_* into state
For a long time we've had fdtab[].ev and fdtab[].state which contain two
arbitrary sets of information, one is mostly the configuration plus some
shutdown reports and the other one is the latest polling status report
which also contains some sticky error and shutdown reports.

These ones used to be stored into distinct chars, complicating certain
operations and not even allowing to clearly see concurrent accesses (e.g.
fd_delete_orphan() would set the state to zero while fd_insert() would
only set the event to zero).

This patch creates a single uint with the two sets in it, still delimited
at the byte level for better readability. The original FD_EV_* values
remained at the lowest bit levels as they are also known by their bit
value. The next step will consist in merging the remaining bits into it.

The whole bits are now cleared both in fd_insert() and _fd_delete_orphan()
because after a complete check, it is certain that in both cases these
functions are the only ones touching these areas. Indeed, for
_fd_delete_orphan(), the thread_mask has already been zeroed before a
poller can call fd_update_event() which would touch the state, so it
is certain that _fd_delete_orphan() is alone. Regarding fd_insert(),
only one thread will get an FD at any moment, and it as this FD has
already been released by _fd_delete_orphan() by definition it is certain
that previous users have definitely stopped touching it.

Strictly speaking there's no need for clearing the state again in
fd_insert() but it's cheap and will remove some doubts during some
troubleshooting sessions.
2021-04-07 18:04:39 +02:00
Willy Tarreau
e44989369d CLEANUP: quic: use pool_zalloc() instead of pool_alloc+memset
Two places used to alloc then zero the area, let's have the allocator do it.
2021-03-22 23:20:21 +01:00
Olivier Houchard
1b3c931bff MEDIUM: connections: Introduce a new XPRT method, start().
Introduce a new XPRT method, start(). The init() method will now only
initialize whatever is needed for the XPRT to run, but any action the XPRT
has to do before being ready, such as handshakes, will be done in the new
start() method. That way, we will be sure the full stack of xprt will be
initialized before attempting to do anything.
The init() call is also moved to conn_prepare(). There's no longer any reason
to wait for the ctrl to be ready, any action will be deferred until start(),
anyway. This means conn_xprt_init() is no longer needed.
2021-03-19 15:33:04 +01:00
Willy Tarreau
7416314145 CLEANUP: task: make sure tasklet handlers always indicate their statuses
When tasklets were derived from tasks, there was no immediate need for
the scheduler to know their status after execution, and in a spirit of
simplicity they just started to always return NULL. The problem is that
it simply prevents the scheduler from 1) accounting their execution time,
and 2) keeping track of their current execution status. Indeed, a remote
wake-up could very well end up manipulating a tasklet that's currently
being executed. And this is the reason why those handlers have to take
the idle lock before checking their context.

In 2.5 we'll take care of making tasklets and tasks work more similarly,
but trouble is to be expected if we continue to propagate the trend of
returning NULL everywhere, especially if some fixes relying on a stricter
model later need to be backported. For this reason this patch updates all
known tasklet handlers to make them return NULL only when the tasklet was
freed. It has no effect for now and isn't even guaranteed to always be
100% safe but it puts the code into the right direction for this.
2021-03-13 11:30:19 +01:00
Willy Tarreau
144f84a09d MEDIUM: task: extend the state field to 32 bits
It's been too short for quite a while now and is now full. It's still
time to extend it to 32-bits since we have room for this without
wasting any space, so we now gained 16 new bits for future flags.

The values were not reassigned just in case there would be a few
hidden u16 or short somewhere in which these flags are placed (as
it used to be the case with stream->pending_events).

The patch is tagged MEDIUM because this required to update the task's
process() prototype to use an int instead of a short, that's quite a
bunch of places.
2021-03-05 08:30:08 +01:00
Willy Tarreau
61cfdf4fd8 CLEANUP: tree-wide: replace free(x);x=NULL with ha_free(&x)
This makes the code more readable and less prone to copy-paste errors.
In addition, it allows to place some __builtin_constant_p() predicates
to trigger a link-time error in case the compiler knows that the freed
area is constant. It will also produce compile-time error if trying to
free something that is not a regular pointer (e.g. a function).

The DEBUG_MEM_STATS macro now also defines an instance for ha_free()
so that all these calls can be checked.

178 occurrences were converted. The vast majority of them were handled
by the following Coccinelle script, some slightly refined to better deal
with "&*x" or with long lines:

  @ rule @
  expression E;
  @@
  - free(E);
  - E = NULL;
  + ha_free(&E);

It was verified that the resulting code is the same, more or less a
handful of cases where the compiler optimized slightly differently
the temporary variable that holds the copy of the pointer.

A non-negligible amount of {free(str);str=NULL;str_len=0;} are still
present in the config part (mostly header names in proxies). These
ones should also be cleaned for the same reasons, and probably be
turned into ist strings.
2021-02-26 21:21:09 +01:00
Willy Tarreau
691d503896 MINOR: xprt/mux: export all *_io_cb functions so that "show fd" resolves them
In FD dumps it's often very important to figure what upper layer function
is going to be called. Let's export the few I/O callbacks that appear as
tasklet functions so that "show fd" can resolve them instead of printing
a pointer relative to main. For example:

   1028 : st=0x21(R:rA W:Ra) ev=0x01(heopI) [lc] tmask=0x2 umask=0x2 owner=0x7f00b889b200 iocb=0x65b638(sock_conn_iocb) back=0 cflg=0x00001300 fe=recv mux=H2 ctx=0x7f00c8824de0 h2c.st0=FRH .err=0 .maxid=795 .lastid=-1 .flg=0x0000 .nbst=0 .nbcs=0 .fctl_cnt=0 .send_cnt=0 .tree_cnt=0 .orph_cnt=0 .sub=1 .dsi=795 .dbuf=0@(nil)+0/0 .msi=-1 .mbuf=[1..1|32],h=[0@(nil)+0/0],t=[0@(nil)+0/0] xprt=SSL xprt_ctx=0x7f00c86d0750 xctx.st=0 .xprt=RAW .wait.ev=1 .subs=0x7f00c88252e0(ev=1 tl=0x7f00a07d1aa0 tl.calls=1047 tl.ctx=0x7f00c8824de0 tl.fct=h2_io_cb) .sent_early=0 .early_in=0
2021-01-20 17:17:39 +01:00
Ilya Shipitsin
1e9a66603f CLEANUP: assorted typo fixes in the code and comments
This is 14th iteration of typo fixes
2021-01-06 16:26:50 +01:00
Frdric Lcaille
153d4a89d0 BUG/MINOR: quic: NULL pointer dereferences when building post handshake frames.
The second one was detected by cppcheck contrary to the first one.
Fixes issue #1032.
Thank you to Ilya for having reported this.
2021-01-06 13:59:05 +01:00
Frdric Lcaille
242fb1b639 MINOR: quic: Drop packets with STREAM frames with wrong direction.
A server initiates streams with odd-numbered stream IDs.
Also add useful traces when parsing STREAM frames.
2021-01-04 12:31:28 +01:00
Frdric Lcaille
ea60499912 BUG/MINOR: quic: Possible CRYPTO frame building errors.
This is issue is due to the fact that when we call the function
responsible of building CRYPTO frames to fill a buffer, the Length
field of this packet did not take into an account the trailing 16 bytes for
the AEAD tag. Furthermore, the remaining <room> available in this buffer
was not decremented by the CRYPTO frame length, but only by the CRYPTO data length
of this frame.
2021-01-04 12:31:28 +01:00
Frdric Lcaille
6c1e36ce55 CLEANUP: quic: Remove useless QUIC event trace definitions.
Remove QUIC_EV_CONN_E* event trace macros which were defined for  errors.
Replace QUIC_EV_CONN_ECHPKT by QUIC_EV_CONN_BCFRMS used in qc_build_cfrms()
2021-01-04 12:31:28 +01:00
Frdric Lcaille
f63921fc24 MINOR: quic: Add traces for quic_packet_encrypt().
Add traces to have an idea why this function may fail. In fact
in never fails when the passed parameters are correct, especially the
lengths. This is not the case when a packet is not correctly built
before being encrypted.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
133e8a7146 MINOR: quic: make a packet build fails when qc_build_frm() fails.
Even if the size of frames built by qc_build_frm() are computed so that
not to overflow a buffer, do not rely on this and always makes a packet
build fails if we could not build a frame.
Also add traces to have an idea where qc_build_frm() fails.
Fixes a memory leak in qc_build_phdshk_apkt().
2020-12-23 11:57:26 +01:00
Frdric Lcaille
f7e0b8d6ae MINOR: quic: Add traces for in flght ack-eliciting packet counter.
Add trace for this counter. Also shorten its variable name (->ifae_pkts).
2020-12-23 11:57:26 +01:00
Frdric Lcaille
47c433fdcb MINOR: quic: Display the SSL alert in ->ssl_send_alert() callback.
At least displays the SSL alert error code passed to ->ssl_send_alert()
QUIC BIO method and the SSL encryption level. This function is newly called
when using picoquic client with a recent version of BoringSSL (Nov 19 2020).
This is not the case with OpenSSL with 32 as QUIC draft implementation.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
0c14020f11 MINOR: quic: Code reordering to help in reviewing/modifying.
Reorder by increasing type the switch/case in qc_parse_pkt_frms()
which is the high level frame parser.
Add new STREAM_X frame types to support some tests with ngtcp2 client.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
f7fe9659f0 MINOR: quic: Flag RX packet as ack-eliciting from the generic parser.
Add ->flags to the QUIC frame parser as this has been done for the builder so
that to flag RX packets as ack-eliciting at low level. This should also be
helpful to maintain the code if we have to add new flags to RX packets.
Remove the statements which does the same thing as higher level in
qc_parse_pkt_frms().
2020-12-23 11:57:26 +01:00
Frdric Lcaille
04ffb66bc9 MINOR: quic: Make usage of the congestion control window.
Remove ->ifcdata which was there to control the CRYPTO data sent to the
peer so that not to saturate its reception buffer. This was a sort
of flow control.
Add ->prep_in_flight counter to the QUIC path struct to control the
number of bytes prepared to be sent so that not to saturare the
congestion control window. This counter is increased each time a
packet was built. This has nothing to see with ->in_flight which
is the real in flight number of bytes which have really been sent.
We are olbiged to maintain two such counters to know how many bytes
of data we can prepared before sending them.
Modify traces consequently which were useful to diagnose issues about
the congestion control window usage.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
c5e72b9868 MINOR: quic: Attempt to make trace more readable
As there is a lot of information in this protocol, this is not
easy to make the traces readable. We remove here a few of them and
shorten some line shortening the variable names.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
8090b51e92 MAJOR: quic: Make usage of ebtrees to store QUIC ACK ranges.
Store QUIC ACK ranges in ebtrees in place of lists with a 0(n) time complexity
for insertion.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
a7e7ce957d MINOR: quic: Import C source code files for QUIC protocol.
This patch imports all the C files for QUIC protocol implementation with few
modifications from 20200720-quic branch of quic-dev repository found at
https://github.com/haproxytech/quic-dev.

Traces were implemented to help with the development.
2020-12-23 11:57:26 +01:00