From f77e3435a90d05c3723d94829ed131dfc0726721 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Fri, 25 Feb 2022 17:36:31 +0100 Subject: [PATCH] MINOR: quic: handle partially received buffered stream frame Adjust the function to handle buffered STREAM frames. If the offset of the frame was already fully received, discard the frame. If only partially received, compute the difference and copy only the newly offset. Before this change, a buffered frame representing a fully or partially received offset caused the loop to be interrupted. The frame was preserved, thus preventing frames with greater offset to be handled. This may fix some occurences of stalled transfer on the request channel if there is out-of-order STREAM frames on the Rx path. --- src/xprt_quic.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/xprt_quic.c b/src/xprt_quic.c index a1b89c771..06bcbf683 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2023,11 +2023,21 @@ static size_t qc_treat_rx_strm_frms(struct qcs *qcs) while (frm_node) { int ret; struct quic_rx_strm_frm *frm; + size_t diff; frm = eb64_entry(&frm_node->node, struct quic_rx_strm_frm, offset_node); - if (frm->offset_node.key != qcs->rx.offset) + if (frm->offset_node.key > qcs->rx.offset) break; + if (frm->offset_node.key + frm->len < qcs->rx.offset) { + /* fully already received STREAM offset */ + goto next; + } + + diff = qcs->rx.offset - frm->offset_node.key; + frm->data += diff; + frm->len -= diff; + ret = qc_rx_strm_frm_cpy(&qcs->rx.buf, frm); qcs->rx.offset += ret; total += ret; @@ -2038,13 +2048,14 @@ static size_t qc_treat_rx_strm_frms(struct qcs *qcs) * offset field. */ eb64_delete(&frm->offset_node); - frm->offset_node.key += ret; + frm->offset_node.key += (diff + ret); frm->data += ret; frm->len -= ret; eb64_insert(&qcs->rx.frms, &frm->offset_node); break; } + next: frm_node = eb64_next(frm_node); quic_rx_packet_refdec(frm->pkt); eb64_delete(&frm->offset_node);