diff --git a/src/h3.c b/src/h3.c index 1006813c5..9f7bb0206 100644 --- a/src/h3.c +++ b/src/h3.c @@ -2179,9 +2179,14 @@ static size_t h3_nego_ff(struct qcs *qcs, size_t count) return ret; } +/* Finalize encoding of a HTTP/3 data frame after zero-copy for stream. + * No frame is encoded if iobuf indicates that no data were transferred. + * + * Return the payload size of the H3 data frame or 0 if no frame encoded. + */ static size_t h3_done_ff(struct qcs *qcs) { - size_t total = qcs->sd->iobuf.data; + size_t total = 0; TRACE_ENTER(H3_EV_STRM_SEND, qcs->qcc->conn, qcs); h3_debug_printf(stderr, "%s\n", __func__); @@ -2189,15 +2194,14 @@ static size_t h3_done_ff(struct qcs *qcs) if (qcs->sd->iobuf.data) { TRACE_DATA("encoding DATA frame (fast forward)", H3_EV_TX_FRAME|H3_EV_TX_DATA, qcs->qcc->conn, qcs); + b_sub(qcs->sd->iobuf.buf, qcs->sd->iobuf.data); b_putchr(qcs->sd->iobuf.buf, 0x00); /* h3 frame type = DATA */ b_quic_enc_int(qcs->sd->iobuf.buf, qcs->sd->iobuf.data, QUIC_VARINT_MAX_SIZE); /* h3 frame length */ b_add(qcs->sd->iobuf.buf, qcs->sd->iobuf.data); - } - qcs->sd->iobuf.buf = NULL; - qcs->sd->iobuf.offset = 0; - qcs->sd->iobuf.data = 0; + total = qcs->sd->iobuf.offset + qcs->sd->iobuf.data; + } TRACE_LEAVE(H3_EV_STRM_SEND, qcs->qcc->conn, qcs); return total; diff --git a/src/hq_interop.c b/src/hq_interop.c index d0c6b43c2..18e9e2ccc 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -214,14 +214,8 @@ static size_t hq_interop_nego_ff(struct qcs *qcs, size_t count) static size_t hq_interop_done_ff(struct qcs *qcs) { - const size_t ret = qcs->sd->iobuf.data; - - /* No header required for HTTP/0.9, simply mark ff as done. */ - qcs->sd->iobuf.buf = NULL; - qcs->sd->iobuf.offset = 0; - qcs->sd->iobuf.data = 0; - - return ret; + /* No header required for HTTP/0.9. */ + return qcs->sd->iobuf.data; } static int hq_interop_attach(struct qcs *qcs, void *conn_ctx) diff --git a/src/mux_quic.c b/src/mux_quic.c index a06b36ddf..24e71ab92 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -3385,12 +3385,14 @@ static size_t qmux_strm_done_ff(struct stconn *sc) goto end; } - if (data) - data += sd->iobuf.offset; total = qcs->qcc->app_ops->done_ff(qcs); + if (total || qcs->flags & QC_SF_FIN_STREAM) + qcc_send_stream(qcs, 0, total); - if (data || qcs->flags & QC_SF_FIN_STREAM) - qcc_send_stream(qcs, 0, data); + /* Reset stconn iobuf information. */ + qcs->sd->iobuf.buf = NULL; + qcs->sd->iobuf.offset = 0; + qcs->sd->iobuf.data = 0; /* Similar to snd_buf callback. */ if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) @@ -3400,7 +3402,7 @@ static size_t qmux_strm_done_ff(struct stconn *sc) end: TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); - return total; + return data; } static int qmux_strm_resume_ff(struct stconn *sc, unsigned int flags)