MEDIUM: mux-quic: handle when sending buffer is full
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.
diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h
index 3bded67..1515a5b 100644
--- a/include/haproxy/mux_quic-t.h
+++ b/include/haproxy/mux_quic-t.h
@@ -55,6 +55,7 @@
#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;
diff --git a/src/h3.c b/src/h3.c
index 359b276..0ed1800 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -534,11 +534,14 @@
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 @@
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);
diff --git a/src/hq_interop.c b/src/hq_interop.c
index 3d530f4..075e785 100644
--- a/src/hq_interop.c
+++ b/src/hq_interop.c
@@ -81,7 +81,7 @@
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);
diff --git a/src/mux_quic.c b/src/mux_quic.c
index c11e1ce..2a28a51 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -193,6 +193,9 @@
if (ret > 0) {
qcs_notify_send(qcs);
+ if (qcs->flags & QC_SF_BLK_MROOM)
+ qcs->flags &= ~QC_SF_BLK_MROOM;
+
xprt_wake = 1;
}