diff --git a/include/haproxy/quic_tls-t.h b/include/haproxy/quic_tls-t.h index 95f77dfc6..e12c9471d 100644 --- a/include/haproxy/quic_tls-t.h +++ b/include/haproxy/quic_tls-t.h @@ -226,6 +226,7 @@ struct quic_cstream { struct { uint64_t offset; /* absolute current base offset of ncbuf */ struct ncbuf ncbuf; /* receive buffer - can handle out-of-order offset frames */ + struct buffer buf; /* receive buffer - handle only in-order data */ } rx; struct { uint64_t offset; /* last offset of data ready to be sent */ diff --git a/src/quic_rx.c b/src/quic_rx.c index 14f4ca26c..653739dd0 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -720,8 +720,14 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, } if (crypto_frm->offset == cstream->rx.offset && ncb_is_empty(ncbuf)) { + struct buffer *buf = &qel->cstream->rx.buf; struct qf_crypto *qf_crypto; + if (!b_alloc(buf)) { + TRACE_ERROR("in-order buffer allocation failed", QUIC_EV_CONN_PRSHPKT, qc); + goto leave; + } + qf_crypto = pool_alloc(pool_head_qf_crypto); if (!qf_crypto) { TRACE_ERROR("CRYPTO frame allocation failed", QUIC_EV_CONN_PRSHPKT, qc); @@ -730,7 +736,8 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, qf_crypto->offset = crypto_frm->offset; qf_crypto->len = crypto_frm->len; - qf_crypto->data = crypto_frm->data; + qf_crypto->data = (unsigned char *)b_tail(buf); + b_putblk(buf, (char *)crypto_frm->data, crypto_frm->len); qf_crypto->qel = qel; LIST_APPEND(&qel->rx.crypto_frms, &qf_crypto->list); diff --git a/src/quic_ssl.c b/src/quic_ssl.c index 668497339..1a350b935 100644 --- a/src/quic_ssl.c +++ b/src/quic_ssl.c @@ -671,6 +671,7 @@ int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx) TRACE_ENTER(QUIC_EV_CONN_PHPKTS, qc); list_for_each_entry(qel, &qc->qel_list, list) { struct qf_crypto *qf_crypto, *qf_back; + struct quic_cstream *cstream = qel->cstream; list_for_each_entry_safe(qf_crypto, qf_back, &qel->rx.crypto_frms, list) { const unsigned char *crypto_data = qf_crypto->data; @@ -688,9 +689,12 @@ int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx) QUIC_EV_CONN_PHPKTS, qc, qel); } - if (!qel->cstream) + if (!cstream) continue; + b_free(&cstream->rx.buf); + cstream->rx.buf = BUF_NULL; + if (!qc_treat_rx_crypto_frms(qc, qel, ctx)) goto leave; } diff --git a/src/quic_tls.c b/src/quic_tls.c index 581d615ce..de1c61423 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -124,6 +124,7 @@ void quic_cstream_free(struct quic_cstream *cs) } quic_free_ncbuf(&cs->rx.ncbuf); + b_free(&cs->rx.buf); qc_stream_desc_release(cs->desc, 0); pool_free(pool_head_quic_cstream, cs); @@ -145,6 +146,7 @@ struct quic_cstream *quic_cstream_new(struct quic_conn *qc) cs->rx.offset = 0; cs->rx.ncbuf = NCBUF_NULL; + cs->rx.buf = BUF_NULL; cs->rx.offset = 0; cs->tx.offset = 0;