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;
 			}