]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: support full request channel buffer
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 2 May 2022 09:07:06 +0000 (11:07 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 2 May 2022 09:19:02 +0000 (11:19 +0200)
If the request channel buffer is full, H3 demuxing must be interrupted
on the stream until some read is performed. This condition is reported
if the HTX stream buffer qcs.rx.app_buf is full.

In this case, qcs instance is marked with a new flag QC_SF_DEM_FULL.
This flag cause the H3 demuxing to be interrupted. It is cleared when
the HTX buffer is read by the conn-stream layer through rcv_buf
operation.

When the flag is cleared, the MUX tasklet is woken up. However, as MUX
iocb does not treat Rx for the moment, this is useless. It must be fix
to prevent possible freeze on POST transfers.

In practice, for the moment the HTX buffer is never full as the current
Rx code is limited by the quic-conn receive buffer size and the
incomplete flow-control implementation. So for now this patch is not
testable under the current conditions.

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

index eafa62d15df78d25dc54684efec2a0d231212e59..bd8b1c31c9ae5902474a78b52807862b900e8d45 100644 (file)
@@ -92,6 +92,7 @@ struct qcc {
 #define QC_SF_BLK_MROOM         0x00000004  /* app layer is blocked waiting for room in the qcs.tx.buf */
 #define QC_SF_DETACH            0x00000008  /* cs is detached but there is remaining data to send */
 #define QC_SF_BLK_SFCTL         0x00000010  /* stream blocked due to stream flow control limit */
+#define QC_SF_DEM_FULL          0x00000020  /* demux blocked on request channel buffer full */
 
 struct qcs {
        struct qcc *qcc;
index fe3ae1384665206a87edbba84b320cafe2e39d30..61ea09a722dd091075cfc640bb7b4b4236b38cc2 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -223,8 +223,10 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
        head = b_head(buf);
  retry:
        htx_space = htx_free_data_space(htx);
-       if (!htx_space)
+       if (!htx_space) {
+               qcs->flags |= QC_SF_DEM_FULL;
                goto out;
+       }
 
        if (len > htx_space) {
                len = htx_space;
@@ -264,7 +266,7 @@ static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx)
        if (!b_data(rxbuf))
                return 0;
 
-       while (b_data(rxbuf)) {
+       while (b_data(rxbuf) && !(qcs->flags & QC_SF_DEM_FULL)) {
                uint64_t ftype, flen;
                struct buffer b;
                char last_stream_frame = 0;
index db32de146338223cf57f7e09e3133396302f5c8c..db16ca0cf8873aa6d85cb54f9411cd45666123da 100644 (file)
@@ -1308,8 +1308,13 @@ static size_t qc_rcv_buf(struct conn_stream *cs, struct buffer *buf,
                }
        }
 
-       if (ret)
+       /* TODO QUIC MUX iocb does not treat RX : following wake-up is thus
+        * useless for the moment. This may causes freezing transfer on POST.
+        */
+       if (ret) {
+               qcs->flags &= ~QC_SF_DEM_FULL;
                tasklet_wakeup(qcs->qcc->wait_event.tasklet);
+       }
 
        TRACE_LEAVE(QMUX_EV_STRM_RECV, qcs->qcc->conn, qcs);