From: Frédéric Lécaille Date: Tue, 31 Oct 2023 15:23:05 +0000 (+0100) Subject: MEDIUM: quic: Heavy task mode with non contiguously bufferized CRYPTO data X-Git-Tag: v2.9-dev10~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a8dd48e3031a873f548e65e685fe8c777d69330;p=thirdparty%2Fhaproxy.git MEDIUM: quic: Heavy task mode with non contiguously bufferized CRYPTO data This patch sets the handshake task in heavy task mode when receiving in disorder CRYPTO data which results in in order bufferized CRYPTO data. This is done thanks to a non-contiguous buffer and from qc_handle_crypto_frm() after having potentially bufferized CRYPTO data in this buffer. qc_treat_rx_crypto_frms() is no more called from qc_treat_rx_pkts() but instead this is where the task is set in heavy task mode. Consequently, this is the job of qc_ssl_provide_all_quic_data() to call directly qc_treat_rx_crypto_frms() to provide the in order bufferized CRYPTO data to the TLS stack. As this function releases the non-contiguous buffer for the CRYPTO data, if possible, there is no need to do that from qc_treat_rx_crypto_frms() anymore. --- diff --git a/include/haproxy/quic_rx.h b/include/haproxy/quic_rx.h index 828309be81..aea208c6cd 100644 --- a/include/haproxy/quic_rx.h +++ b/include/haproxy/quic_rx.h @@ -33,5 +33,7 @@ int qc_parse_hd_form(struct quic_rx_packet *pkt, void quic_free_ncbuf(struct ncbuf *ncbuf); int qc_release_lost_pkts(struct quic_conn *qc, struct quic_pktns *pktns, struct list *pkts, uint64_t now_us); +int qc_treat_rx_crypto_frms(struct quic_conn *qc, struct quic_enc_level *el, + struct ssl_sock_ctx *ctx); #endif /* _HAPROXY_QUIC_RX_H */ diff --git a/src/quic_rx.c b/src/quic_rx.c index 69067bc471..e2f3f89563 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -871,6 +871,9 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, goto leave; } + if (ncb_data(ncbuf, 0)) + HA_ATOMIC_OR(&qc->wait_event.tasklet->state, TASK_HEAVY); + done: ret = 1; leave: @@ -1262,9 +1265,8 @@ static void qc_rm_hp_pkts(struct quic_conn *qc, struct quic_enc_level *el) * stream for this level. * Return 1 if succeeded, 0 if not. */ -static int qc_treat_rx_crypto_frms(struct quic_conn *qc, - struct quic_enc_level *el, - struct ssl_sock_ctx *ctx) +int qc_treat_rx_crypto_frms(struct quic_conn *qc, struct quic_enc_level *el, + struct ssl_sock_ctx *ctx) { int ret = 0; struct ncbuf *ncbuf; @@ -1411,9 +1413,13 @@ int qc_treat_rx_pkts(struct quic_conn *qc) qel->pktns->flags |= QUIC_FL_PKTNS_NEW_LARGEST_PN; } - if (qel->cstream && !qc_treat_rx_crypto_frms(qc, qel, qc->xprt_ctx)) { - // trace already emitted by function above - goto leave; + if (qel->cstream) { + struct ncbuf *ncbuf = &qel->cstream->rx.ncbuf; + + if (!ncb_is_null(ncbuf) && ncb_data(ncbuf, 0)) { + /* Some in order CRYPTO data were bufferized. */ + HA_ATOMIC_OR(&qc->wait_event.tasklet->state, TASK_HEAVY); + } } /* Release the Initial encryption level and packet number space. */ diff --git a/src/quic_ssl.c b/src/quic_ssl.c index fc3c26fe76..14a5eca86c 100644 --- a/src/quic_ssl.c +++ b/src/quic_ssl.c @@ -673,10 +673,8 @@ int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx) QUIC_EV_CONN_PHPKTS, qc, qel); } - if (ncb_is_empty(ncbuf)) { - TRACE_DEVEL("freeing crypto buf", QUIC_EV_CONN_PHPKTS, qc, qel); - quic_free_ncbuf(ncbuf); - } + if (!qc_treat_rx_crypto_frms(qc, qel, ctx)) + ssl_ret = 0; if (!ssl_ret) goto leave;