]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic: Heavy task mode with non contiguously bufferized CRYPTO data
authorFrédéric Lécaille <flecaille@haproxy.com>
Tue, 31 Oct 2023 15:23:05 +0000 (16:23 +0100)
committerFrédéric Lécaille <flecaille@haproxy.com>
Thu, 9 Nov 2023 09:32:31 +0000 (10:32 +0100)
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.

include/haproxy/quic_rx.h
src/quic_rx.c
src/quic_ssl.c

index 828309be81e7b91829ee5d76a9d4e4340d25d1f4..aea208c6cd8f7c6c01b69ae246b4cd3c7c1483c4 100644 (file)
@@ -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 */
index 69067bc4716201b77fb2c7e7c350f061a350a2fb..e2f3f8956330f73021212ba6560adf298aa2198d 100644 (file)
@@ -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. */
index fc3c26fe765c4f71828f4d0528b9cf9faefef8b9..14a5eca86cb1d9f99f158c7f84c9ae2542f89096 100644 (file)
@@ -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;