]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: decode as much STREAM as possible
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 27 Apr 2022 14:53:16 +0000 (16:53 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 28 Apr 2022 14:10:10 +0000 (16:10 +0200)
Add a loop in the bidi STREAM function. This will call repeatdly
qcc_decode_qcs() and dequeue buffered frames.

This is useful when reception of more data is interrupted because the
MUX buffer was full. qcc_decode_qcs() has probably free some space so it
is useful to immediatly retry reception of buffered frames of the qcs
tree.

This may fix occurences of stalled Rx transfers with large payload.
Note however that there is still room for improvment. The conn-stream
layer is not able at this moment to retrigger demuxing. This is because
the mux io-handler does not treat Rx : this may continue to cause
stalled tranfers.

src/h3.c
src/xprt_quic.c

index f5da7613aeef36bd9bd62a734590f392bfe53cd6..fe3ae1384665206a87edbba84b320cafe2e39d30 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -321,6 +321,10 @@ static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx)
                h3s->demux_frame_len -= ret;
        }
 
+       /* TODO may be useful to wakeup the MUX if blocked due to full buffer.
+        * However, currently, io-cb of MUX does not handle Rx.
+        */
+
        return 0;
 }
 
index 773b62b0d0ee889a9f48d279e3ac4481aa7a3ece..582088649cff27d4e68133d6402cab23100b7e80 100644 (file)
@@ -2139,7 +2139,7 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
        struct quic_rx_strm_frm *frm;
        struct eb64_node *frm_node;
        struct qcs *qcs = NULL;
-       size_t done;
+       size_t done, buf_was_full;
        int ret;
 
        ret = qcc_recv(qc->qcc, strm_frm->id, strm_frm->len,
@@ -2176,6 +2176,13 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
                        return 1;
        }
 
+       /* Decode the data if buffer is already full as it's not possible to
+        * dequeue a frame in this condition.
+        */
+       if (b_full(&qcs->rx.buf))
+               qcc_decode_qcs(qc->qcc, qcs);
+
+ retry:
        /* Frame received (partially or not) by the mux.
         * If there is buffered frame for next offset, it may be possible to
         * receive them now.
@@ -2212,9 +2219,17 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
                pool_free(pool_head_quic_rx_strm_frm, frm);
        }
 
+       buf_was_full = b_full(&qcs->rx.buf);
        /* Decode the received data. */
        qcc_decode_qcs(qc->qcc, qcs);
 
+       /* Buffer was full so the reception was stopped. Now the buffer has
+        * space available thanks to qcc_decode_qcs(). We can now retry to
+        * handle more data.
+        */
+       if (buf_was_full && !b_full(&qcs->rx.buf))
+               goto retry;
+
        return 1;
 }