MINOR: mux-quic: support full request channel buffer

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.
This commit is contained in:
Amaury Denoyelle 2022-05-02 11:07:06 +02:00
parent 026fef98a0
commit f1fc0b393b
3 changed files with 11 additions and 3 deletions

View 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_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_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_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 qcs {
struct qcc *qcc; struct qcc *qcc;

View File

@ -223,8 +223,10 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
head = b_head(buf); head = b_head(buf);
retry: retry:
htx_space = htx_free_data_space(htx); htx_space = htx_free_data_space(htx);
if (!htx_space) if (!htx_space) {
qcs->flags |= QC_SF_DEM_FULL;
goto out; goto out;
}
if (len > htx_space) { if (len > htx_space) {
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)) if (!b_data(rxbuf))
return 0; return 0;
while (b_data(rxbuf)) { while (b_data(rxbuf) && !(qcs->flags & QC_SF_DEM_FULL)) {
uint64_t ftype, flen; uint64_t ftype, flen;
struct buffer b; struct buffer b;
char last_stream_frame = 0; char last_stream_frame = 0;

View 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); tasklet_wakeup(qcs->qcc->wait_event.tasklet);
}
TRACE_LEAVE(QMUX_EV_STRM_RECV, qcs->qcc->conn, qcs); TRACE_LEAVE(QMUX_EV_STRM_RECV, qcs->qcc->conn, qcs);