MINOR: quic: Do not forget STREAM frames received in disorder

Add a function to process all STREAM frames received and ordered
by their offset (qc_treat_rx_strm_frms()) and modify
qc_handle_bidi_strm_frm() consequently.
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 3f63cd3..bc4b074 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2053,6 +2053,69 @@
 	return ret;
 }
 
+/* Copy as most as possible STREAM data from <strm_frm> into <buf> buffer.
+ * Also update <strm_frm> frame to reflect the data which have been consumed.
+ */
+static size_t qc_rx_strm_frm_cpy(struct buffer *buf,
+                                 struct quic_rx_strm_frm *strm_frm)
+{
+	size_t ret;
+
+	ret = 0;
+	while (strm_frm->len) {
+		size_t try;
+
+		try = b_contig_space(buf);
+		if (!try)
+			break;
+
+		if (try > strm_frm->len)
+			try = strm_frm->len;
+		memcpy(b_tail(buf), strm_frm->data, try);
+		strm_frm->len -= try;
+		strm_frm->offset_node.key += try;
+		b_add(buf, try);
+		ret += try;
+	}
+
+	return ret;
+}
+
+/* Process as much as possible RX STREAM frames received for <qcs> */
+static size_t qc_treat_rx_strm_frms(struct qcs *qcs)
+{
+	int total;
+	struct eb64_node *frm_node;
+
+	total = 0;
+	frm_node = eb64_first(&qcs->rx.frms);
+	while (frm_node) {
+		int ret;
+		struct quic_rx_strm_frm *frm;
+
+		frm = eb64_entry(&frm_node->node, struct quic_rx_strm_frm, offset_node);
+		if (frm->offset_node.key != qcs->rx.offset)
+			break;
+
+		ret = qc_rx_strm_frm_cpy(&qcs->rx.buf, frm);
+		qcs->rx.offset += ret;
+		total += ret;
+		if (frm->len) {
+			/* If there is remaining data in this frame
+			 * this is because the destination buffer is full.
+			 */
+			break;
+		}
+
+		frm_node = eb64_next(frm_node);
+		quic_rx_packet_refdec(frm->pkt);
+		eb64_delete(&frm->offset_node);
+		pool_free(pool_head_quic_rx_strm_frm, frm);
+	}
+
+	return total;
+}
+
 /* Handle <strm_frm> bidirectional STREAM frame. Depending on its ID, several
  * streams may be open. The data are copied to the stream RX buffer if possible.
  * If not, the STREAM frame is stored to be treated again later.
@@ -2063,6 +2126,7 @@
                                    struct quic_stream *strm_frm,
                                    struct quic_conn *qc)
 {
+	int total;
 	struct qcs *strm;
 	struct eb64_node *strm_node, *frm_node;
 	struct quic_rx_strm_frm *frm;
@@ -2082,6 +2146,7 @@
 		goto out;
 	}
 
+	total = 0;
 	if (strm_frm->offset.key == strm->rx.offset) {
 		int ret;
 
@@ -2090,14 +2155,16 @@
 		}
 
 		ret = qc_strm_cpy(&strm->rx.buf, strm_frm);
-		if (ret && qc->qcc->app_ops->decode_qcs(strm, strm_frm->fin, qc->qcc->ctx) < 0) {
-			TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM);
-			return 0;
-		}
-
+		total += ret;
 		strm->rx.offset += ret;
 	}
 
+	total += qc_treat_rx_strm_frms(strm);
+	if (total && qc->qcc->app_ops->decode_qcs(strm, strm_frm->fin, qc->qcc->ctx) < 0) {
+		TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM);
+		return 0;
+	}
+
 	if (!strm_frm->len)
 		goto out;