MINOR: quic: RX buffer full due to wrong CRYPTO data handling

Do not leave in the RX buffer packets with CRYPTO data which were
already received. We do this when parsing CRYPTO frame. If already
received we must not consider such frames as if they were not received
in order! This had as side effect to interrupt the transfer of long streams
(ACK frames not parsed).
This commit is contained in:
Frédéric Lécaille 2021-12-02 11:25:58 +01:00 committed by Amaury Denoyelle
parent 84ea8dcbc4
commit f9cb3a9b0e

View File

@ -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: <cfdebug> 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: <cfdebug> 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: <cf> 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: <cf> 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: