]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-quic: implement recv on io-cb
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 16 May 2022 11:54:59 +0000 (13:54 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 18 May 2022 13:43:22 +0000 (15:43 +0200)
Previously, qc_io_cb() of mux-quic only dealt with TX. Add support for
RX in it. This is done through a new function qc_recv(qcc). It loops
over all QCS instances and call qcc_decode_qcs(qcs).

This has no impact from the quic-conn layer as qcc_decode_qcs(qcs) is
called directly. However, this allows to have a resume point when demux
is blocked on the upper layer HTX full buffer.

Note that for the moment, only RX for bidirectional streams is managed
in qc_io_cb(). Unidirectional streams use their own mechanism for both
TX/RX. It should be unified in the near future in a refactoring.

src/mux_quic.c

index f5de5510588ed03f4a9011221f871712d93dea43..bd671af9de99479f795f18adc573e50c97b64f19 100644 (file)
@@ -1034,6 +1034,40 @@ static int qc_send(struct qcc *qcc)
        return total;
 }
 
+/* Proceed on receiving. Loop through all streams from <qcc> and use decode_qcs
+ * operation.
+ *
+ * Returns 0 on success else non-zero.
+ */
+static int qc_recv(struct qcc *qcc)
+{
+       struct eb64_node *node;
+       struct qcs *qcs;
+
+       node = eb64_first(&qcc->streams_by_id);
+       while (node) {
+               qcs = eb64_entry(node, struct qcs, by_id);
+
+               /* TODO unidirectional streams have their own mechanism for Rx.
+                * This should be unified.
+                */
+               if (quic_stream_is_uni(qcs->id)) {
+                       node = eb64_next(node);
+                       continue;
+               }
+
+               if (!ncb_data(&qcs->rx.ncbuf, 0) || (qcs->flags & QC_SF_DEM_FULL)) {
+                       node = eb64_next(node);
+                       continue;
+               }
+
+               qcc_decode_qcs(qcc, qcs);
+               node = eb64_next(node);
+       }
+
+       return 0;
+}
+
 /* Release all streams that are already marked as detached. This is only done
  * if their TX buffers are empty or if a CONNECTION_CLOSE has been received.
  *
@@ -1086,6 +1120,8 @@ static struct task *qc_io_cb(struct task *t, void *ctx, unsigned int status)
                }
        }
 
+       qc_recv(qcc);
+
        TRACE_LEAVE(QMUX_EV_QCC_WAKE);
 
        return NULL;
@@ -1335,9 +1371,6 @@ static size_t qc_rcv_buf(struct conn_stream *cs, struct buffer *buf,
                }
        }
 
-       /* 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);