diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 1515a5bc5..2c5c55538 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -85,7 +85,7 @@ struct qcs { struct qcc_app_ops { int (*init)(struct qcc *qcc); int (*attach_ruqs)(struct qcs *qcs, void *ctx); - int (*decode_qcs)(struct qcs *qcs, void *ctx); + int (*decode_qcs)(struct qcs *qcs, int fin, void *ctx); size_t (*snd_buf)(struct conn_stream *cs, struct buffer *buf, size_t count, int flags); int (*finalize)(void *ctx); }; diff --git a/include/haproxy/quic_frame-t.h b/include/haproxy/quic_frame-t.h index fcc04fc0b..1d5438c60 100644 --- a/include/haproxy/quic_frame-t.h +++ b/include/haproxy/quic_frame-t.h @@ -149,6 +149,7 @@ struct quic_stream { struct buffer *buf; struct eb64_node offset; uint64_t len; + int fin; const unsigned char *data; }; diff --git a/src/h3.c b/src/h3.c index 0ed180027..970b95752 100644 --- a/src/h3.c +++ b/src/h3.c @@ -96,7 +96,7 @@ static inline size_t h3_decode_frm_header(uint64_t *ftype, uint64_t *flen, /* Decode remotely initiated bidi-stream. * Returns <0 on error else 0. */ -static int h3_decode_qcs(struct qcs *qcs, void *ctx) +static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx) { struct buffer *rxbuf = &qcs->rx.buf; struct h3 *h3 = ctx; @@ -220,6 +220,9 @@ static int h3_decode_qcs(struct qcs *qcs, void *ctx) b_del(rxbuf, flen); } + if (fin && !b_data(rxbuf)) + htx->flags |= HTX_FL_EOM; + return 0; fail: diff --git a/src/hq_interop.c b/src/hq_interop.c index dc1e1154e..9d0d56635 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -9,7 +9,7 @@ #include #include -static int hq_interop_decode_qcs(struct qcs *qcs, void *ctx) +static int hq_interop_decode_qcs(struct qcs *qcs, int fin, void *ctx) { struct buffer *rxbuf = &qcs->rx.buf; struct htx *htx; @@ -54,6 +54,9 @@ static int hq_interop_decode_qcs(struct qcs *qcs, void *ctx) b_del(rxbuf, b_data(rxbuf)); b_free(&htx_buf); + if (fin) + htx->flags |= HTX_FL_EOM; + return 0; } diff --git a/src/quic_frame.c b/src/quic_frame.c index dfb6103fc..f938d40be 100644 --- a/src/quic_frame.c +++ b/src/quic_frame.c @@ -427,6 +427,8 @@ static int quic_parse_stream_frame(struct quic_frame *frm, struct quic_conn *qc, else if (!quic_dec_int(&stream->len, buf, end) || end - *buf < stream->len) return 0; + stream->fin = (frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT); + stream->data = *buf; *buf += stream->len; diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 2e7cf5c5c..250c2b80a 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2076,7 +2076,7 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt, goto store_frm; ret = qc_strm_cpy(&strm->rx.buf, strm_frm); - if (ret && qc->qcc->app_ops->decode_qcs(strm, qc->qcc->ctx) < 0) { + if (ret && qc->qcc->app_ops->decode_qcs(strm, strm_frm->fin, qc->qcc->ctx) < 0) { TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM); return 0; }