diff --git a/src/xprt_quic.c b/src/xprt_quic.c index d70be2cc5..2809de92d 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2230,35 +2230,66 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct break; } case QUIC_FT_CRYPTO: - if (frm.crypto.offset != qel->rx.crypto.offset) { - struct quic_rx_crypto_frm *cf; + { + struct quic_rx_crypto_frm *cf; - cf = pool_alloc(pool_head_quic_rx_crypto_frm); - if (!cf) { - TRACE_DEVEL("CRYPTO frame allocation failed", - QUIC_EV_CONN_PRSHPKT, ctx->conn); - goto err; + if (unlikely(frm.crypto.offset < qel->rx.crypto.offset)) { + if (frm.crypto.offset + frm.crypto.len <= qel->rx.crypto.offset) { + /* XXX TO DO: is used only for the traces. */ + struct quic_rx_crypto_frm cfdebug = { }; + + cfdebug.offset_node.key = frm.crypto.offset; + cfdebug.len = frm.crypto.len; + /* Nothing to do */ + TRACE_PROTO("Already received CRYPTO data", + QUIC_EV_CONN_ELRXPKTS, ctx->conn, pkt, &cfdebug); + break; } + else { + size_t diff = qel->rx.crypto.offset - frm.crypto.offset; + /* XXX TO DO: is used only for the traces. */ + struct quic_rx_crypto_frm cfdebug = { }; - cf->offset_node.key = frm.crypto.offset; - cf->len = frm.crypto.len; - cf->data = frm.crypto.data; - cf->pkt = pkt; - eb64_insert(&qel->rx.crypto.frms, &cf->offset_node); - quic_rx_packet_refinc(pkt); + cfdebug.offset_node.key = frm.crypto.offset; + cfdebug.len = frm.crypto.len; + TRACE_PROTO("Partially already received CRYPTO data", + QUIC_EV_CONN_ELRXPKTS, ctx->conn, pkt, &cfdebug); + frm.crypto.len -= diff; + frm.crypto.data += diff; + frm.crypto.offset = qel->rx.crypto.offset; + } } - else { - /* XXX TO DO: is used only for the traces. */ - struct quic_rx_crypto_frm cf = { }; - cf.offset_node.key = frm.crypto.offset; - cf.len = frm.crypto.len; + if (frm.crypto.offset == qel->rx.crypto.offset) { + /* XXX TO DO: is used only for the traces. */ + struct quic_rx_crypto_frm cfdebug = { }; + + cfdebug.offset_node.key = frm.crypto.offset; + cfdebug.len = frm.crypto.len; if (!qc_provide_cdata(qel, ctx, frm.crypto.data, frm.crypto.len, - pkt, &cf)) + pkt, &cfdebug)) goto err; + + break; } + + /* frm.crypto.offset > qel->rx.crypto.offset */ + cf = pool_alloc(pool_head_quic_rx_crypto_frm); + if (!cf) { + TRACE_DEVEL("CRYPTO frame allocation failed", + QUIC_EV_CONN_PRSHPKT, ctx->conn); + goto err; + } + + cf->offset_node.key = frm.crypto.offset; + cf->len = frm.crypto.len; + cf->data = frm.crypto.data; + cf->pkt = pkt; + eb64_insert(&qel->rx.crypto.frms, &cf->offset_node); + quic_rx_packet_refinc(pkt); break; + } case QUIC_FT_STREAM_8: case QUIC_FT_STREAM_9: case QUIC_FT_STREAM_A: