]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-quic: handle when sending buffer is full
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 3 Dec 2021 13:40:01 +0000 (14:40 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 7 Dec 2021 14:44:45 +0000 (15:44 +0100)
Handle the case when the app layer sending buffer is full. A new flag
QC_SF_BLK_MROOM is set in this case and the transfer is interrupted. It
is expected that then the conn-stream layer will subscribe to SEND.

The MROOM flag is reset each time the muxer transfer data from the app
layer to its own buffer. If the app layer has been subscribed on SEND it
is woken up.

include/haproxy/mux_quic-t.h
src/h3.c
src/hq_interop.c
src/mux_quic.c

index 3bded6753388cf54751cf66062017d25f864a87a..1515a5bc5b53e484a7cabc47a157bc643e318267 100644 (file)
@@ -55,6 +55,7 @@ struct qcc {
 
 #define QC_SF_NONE              0x00000000
 #define QC_SF_FIN_STREAM        0x00000001  // FIN bit must be set for last frame of the stream
+#define QC_SF_BLK_MROOM         0x00000002  // app layer is blocked waiting for room in the qcs.tx.buf
 
 struct qcs {
        struct qcc *qcc;
index 359b27676ca41b2e197ad3b5279d1a52d73dd3fc..0ed1800270a77aca447387703a996c156ed866fe 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -534,11 +534,14 @@ static int h3_resp_data_send(struct qcs *qcs, struct buffer *buf, size_t count)
                b_slow_realign(res, trash.area, b_data(res));
        }
 
-       /* not enough room for headers and at least one data byte, block the
-        * stream
+       /* Not enough room for headers and at least one data byte, block the
+        * stream. It is expected that the conn-stream layer will subscribe on
+        * SEND.
         */
-       if (b_size(&outbuf) <= hsize)
-               ABORT_NOW();
+       if (b_size(&outbuf) <= hsize) {
+               qcs->flags |= QC_SF_BLK_MROOM;
+               goto end;
+       }
 
        if (b_size(&outbuf) < hsize + fsize)
                fsize = b_size(&outbuf) - hsize;
@@ -579,7 +582,7 @@ size_t h3_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int
 
        htx = htx_from_buf(buf);
 
-       while (count && !htx_is_empty(htx)) {
+       while (count && !htx_is_empty(htx) && !(qcs->flags & QC_SF_BLK_MROOM)) {
                idx = htx_get_head(htx);
                blk = htx_get_blk(htx, idx);
                btype = htx_get_blk_type(blk);
index 3d530f4bfb56a940d87dda4f996717bd7e45e868..075e785b04514adc201894ea30d095f1c16beeb9 100644 (file)
@@ -81,7 +81,7 @@ static size_t hq_interop_snd_buf(struct conn_stream *cs, struct buffer *buf,
        res = mux_get_buf(qcs);
        outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
 
-       while (count && !htx_is_empty(htx)) {
+       while (count && !htx_is_empty(htx) && !(qcs->flags & QC_SF_BLK_MROOM)) {
                /* Not implemented : QUIC on backend side */
                idx = htx_get_head(htx);
                blk = htx_get_blk(htx, idx);
index c11e1cedd30826048bcabae3b92dea86c4f48f5b..2a28a5155e2c3baa4a5eeb983d59a2496148cb96 100644 (file)
@@ -193,6 +193,9 @@ static int qc_send(struct qcc *qcc)
 
                        if (ret > 0) {
                                qcs_notify_send(qcs);
+                               if (qcs->flags & QC_SF_BLK_MROOM)
+                                       qcs->flags &= ~QC_SF_BLK_MROOM;
+
                                xprt_wake = 1;
                        }