diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 9602cc4c0..eaedce4e6 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -186,7 +187,7 @@ struct qcc_app_ops { int (*init)(struct qcc *qcc); int (*attach)(struct qcs *qcs, void *conn_ctx); ssize_t (*decode_qcs)(struct qcs *qcs, struct buffer *b, int fin); - size_t (*snd_buf)(struct qcs *qcs, struct buffer *buf, size_t count, int flags); + size_t (*snd_buf)(struct qcs *qcs, struct htx *htx, size_t count); void (*detach)(struct qcs *qcs); int (*finalize)(void *ctx); void (*shutdown)(void *ctx); /* Close a connection. */ diff --git a/include/haproxy/qmux_http.h b/include/haproxy/qmux_http.h index 776725d71..4a7711401 100644 --- a/include/haproxy/qmux_http.h +++ b/include/haproxy/qmux_http.h @@ -8,6 +8,8 @@ size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count, char *fin); +size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, + char *fin); #endif /* USE_QUIC */ diff --git a/src/h3.c b/src/h3.c index 187c6065b..b8a8f3639 100644 --- a/src/h3.c +++ b/src/h3.c @@ -937,20 +937,17 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx) } /* Returns the total of bytes sent. */ -static int h3_resp_data_send(struct qcs *qcs, struct buffer *buf, size_t count) +static int h3_resp_data_send(struct qcs *qcs, struct htx *htx, size_t count) { struct buffer outbuf; struct buffer *res; size_t total = 0; - struct htx *htx; int bsize, fsize, hsize; struct htx_blk *blk; enum htx_blk_type type; TRACE_ENTER(H3_EV_TX_DATA, qcs->qcc->conn, qcs); - htx = htx_from_buf(buf); - new_frame: if (!count || htx_is_empty(htx)) goto end; @@ -1012,10 +1009,9 @@ static int h3_resp_data_send(struct qcs *qcs, struct buffer *buf, size_t count) return total; } -static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, int flags) +static size_t h3_snd_buf(struct qcs *qcs, struct htx *htx, size_t count) { size_t total = 0; - struct htx *htx; enum htx_blk_type btype; struct htx_blk *blk; uint32_t bsize; @@ -1024,8 +1020,6 @@ static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, int h3_debug_printf(stderr, "%s\n", __func__); - htx = htx_from_buf(buf); - while (count && !htx_is_empty(htx) && !(qcs->flags & QC_SF_BLK_MROOM)) { idx = htx_get_head(htx); blk = htx_get_blk(htx, idx); @@ -1048,9 +1042,8 @@ static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, int break; case HTX_BLK_DATA: - ret = h3_resp_data_send(qcs, buf, count); + ret = h3_resp_data_send(qcs, htx, count); if (ret > 0) { - htx = htx_from_buf(buf); total += ret; count -= ret; if (ret < bsize) @@ -1070,15 +1063,7 @@ static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, int } } - if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx)) - qcs->flags |= QC_SF_FIN_STREAM; - out: - if (total) { - if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) - tasklet_wakeup(qcs->qcc->wait_event.tasklet); - } - return total; } diff --git a/src/hq_interop.c b/src/hq_interop.c index a133cd53b..37bb2e219 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -88,10 +88,9 @@ static struct buffer *mux_get_buf(struct qcs *qcs) return &qcs->tx.buf; } -static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf, - size_t count, int flags) +static size_t hq_interop_snd_buf(struct qcs *qcs, struct htx *htx, + size_t count) { - struct htx *htx; enum htx_blk_type btype; struct htx_blk *blk; int32_t idx; @@ -99,7 +98,6 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf, struct buffer *res, outbuf; size_t total = 0; - htx = htx_from_buf(buf); res = mux_get_buf(qcs); outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0); @@ -148,16 +146,8 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf, } end: - if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx)) - qcs->flags |= QC_SF_FIN_STREAM; - b_add(res, b_data(&outbuf)); - if (total) { - if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) - tasklet_wakeup(qcs->qcc->wait_event.tasklet); - } - return total; } diff --git a/src/mux_quic.c b/src/mux_quic.c index ef1134743..a396e340d 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -2102,6 +2102,7 @@ static size_t qc_snd_buf(struct stconn *sc, struct buffer *buf, { struct qcs *qcs = __sc_mux_strm(sc); size_t ret; + char fin; TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); @@ -2113,7 +2114,14 @@ static size_t qc_snd_buf(struct stconn *sc, struct buffer *buf, goto end; } - ret = qcs->qcc->app_ops->snd_buf(qcs, buf, count, flags); + ret = qcs_http_snd_buf(qcs, buf, count, &fin); + if (fin) + qcs->flags |= QC_SF_FIN_STREAM; + + if (ret) { + if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) + tasklet_wakeup(qcs->qcc->wait_event.tasklet); + } end: TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); diff --git a/src/qmux_http.c b/src/qmux_http.c index bf53df039..c77707460 100644 --- a/src/qmux_http.c +++ b/src/qmux_http.c @@ -61,3 +61,29 @@ size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count, return ret; } + +/* QUIC MUX snd_buf operation using HTX data. HTX data will be transferred from + * to stream buffer. Input buffer is expected to be of length + * . will be set to signal the last data to send for this stream. + * + * Return the size in bytes of transferred data. + */ +size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, + char *fin) +{ + struct htx *htx; + size_t ret; + + TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); + + htx = htx_from_buf(buf); + + ret = qcs->qcc->app_ops->snd_buf(qcs, htx, count); + *fin = (htx->flags & HTX_FL_EOM) && htx_is_empty(htx); + + htx_to_buf(htx, buf); + + TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); + + return ret; +}