diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 9a69b7638..29d3897b1 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -140,7 +140,7 @@ struct qcs { struct qcc_app_ops { int (*init)(struct qcc *qcc); int (*attach)(struct qcs *qcs, void *conn_ctx); - int (*decode_qcs)(struct qcs *qcs, struct buffer *b, int fin); + ssize_t (*decode_qcs)(struct qcs *qcs, struct buffer *b, int fin); size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); void (*detach)(struct qcs *qcs); int (*finalize)(void *ctx); diff --git a/src/h3.c b/src/h3.c index 655bf26a0..cbf12e4a7 100644 --- a/src/h3.c +++ b/src/h3.c @@ -145,10 +145,10 @@ DECLARE_STATIC_POOL(pool_head_h3s, "h3s", sizeof(struct h3s)); /* Initialize an uni-stream by reading its type from . * - * Returns 0 on success else non-zero. + * Returns the count of consumed bytes or a negative error code. */ -static int h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, - struct buffer *b) +static ssize_t h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, + struct buffer *b) { /* decode unidirectional stream type */ struct h3s *h3s = qcs->ctx; @@ -169,7 +169,7 @@ static int h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, case H3_UNI_S_T_CTRL: if (h3c->flags & H3_CF_UNI_CTRL_SET) { qcc_emit_cc_app(qcs->qcc, H3_STREAM_CREATION_ERROR); - return 1; + return -1; } h3c->flags |= H3_CF_UNI_CTRL_SET; h3s->type = H3S_T_CTRL; @@ -183,7 +183,7 @@ static int h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, case H3_UNI_S_T_QPACK_DEC: if (h3c->flags & H3_CF_UNI_QPACK_DEC_SET) { qcc_emit_cc_app(qcs->qcc, H3_STREAM_CREATION_ERROR); - return 1; + return -1; } h3c->flags |= H3_CF_UNI_QPACK_DEC_SET; h3s->type = H3S_T_QPACK_DEC; @@ -193,7 +193,7 @@ static int h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, case H3_UNI_S_T_QPACK_ENC: if (h3c->flags & H3_CF_UNI_QPACK_ENC_SET) { qcc_emit_cc_app(qcs->qcc, H3_STREAM_CREATION_ERROR); - return 1; + return -1; } h3c->flags |= H3_CF_UNI_QPACK_ENC_SET; h3s->type = H3S_T_QPACK_ENC; @@ -207,21 +207,21 @@ static int h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, * streams that have unknown or unsupported types. */ qcs->flags |= QC_SF_READ_ABORTED; - return 1; + return -1; }; h3s->flags |= H3_SF_UNI_INIT; TRACE_LEAVE(H3_EV_H3S_NEW, qcs->qcc->conn, qcs); - return 0; + return len; } /* Parse an uni-stream from which does not contains H3 frames. * This may be used for QPACK encoder/decoder streams for example. * - * Returns 0 on success else non-zero. + * Returns the number of consumed bytes or a negative error code. */ -static int h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b) +static ssize_t h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b) { struct h3s *h3s = qcs->ctx; @@ -231,11 +231,11 @@ static int h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b) switch (h3s->type) { case H3S_T_QPACK_DEC: if (qpack_decode_dec(qcs, NULL)) - return 1; + return -1; break; case H3S_T_QPACK_ENC: if (qpack_decode_enc(qcs, NULL)) - return 1; + return -1; break; case H3S_T_UNKNOWN: default: @@ -243,6 +243,7 @@ static int h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b) ABORT_NOW(); } + /* TODO adjust return code */ return 0; } @@ -320,10 +321,10 @@ static int h3_is_frame_valid(struct h3c *h3c, struct qcs *qcs, uint64_t ftype) * in a local HTX buffer and transfer to the stream connector layer. must be * set if this is the last data to transfer from this stream. * - * Returns the number of bytes handled or a negative error code. + * Returns the number of consumed bytes or a negative error code. */ -static int h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, - uint64_t len, char fin) +static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, + uint64_t len, char fin) { struct buffer htx_buf = BUF_NULL; struct buffer *tmp = get_trash_chunk(); @@ -418,10 +419,10 @@ static int h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, * HTX buffer. must be set if this is the last data to transfer from this * stream. * - * Returns the number of bytes handled or a negative error code. + * Returns the number of consumed bytes or a negative error code. */ -static int h3_data_to_htx(struct qcs *qcs, const struct buffer *buf, - uint64_t len, char fin) +static ssize_t h3_data_to_htx(struct qcs *qcs, const struct buffer *buf, + uint64_t len, char fin) { struct buffer *appbuf; struct htx *htx = NULL; @@ -484,10 +485,10 @@ static int h3_data_to_htx(struct qcs *qcs, const struct buffer *buf, /* Parse a SETTINGS frame of length of payload . * - * Returns the number of bytes handled or a negative error code. + * Returns the number of consumed bytes or a negative error code. */ -static size_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf, - size_t len) +static ssize_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf, + size_t len) { struct buffer b; uint64_t id, value; @@ -568,26 +569,30 @@ static size_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf, * * Returns 0 on success else non-zero. */ -static int h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) +static ssize_t h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) { struct h3s *h3s = qcs->ctx; struct h3c *h3c = h3s->h3c; - ssize_t ret; + ssize_t total = 0, ret; h3_debug_printf(stderr, "%s: STREAM ID: %lu\n", __func__, qcs->id); if (!b_data(b)) return 0; if (quic_stream_is_uni(qcs->id) && !(h3s->flags & H3_SF_UNI_INIT)) { - if (h3_init_uni_stream(h3c, qcs, b)) - return 1; + if ((ret = h3_init_uni_stream(h3c, qcs, b)) < 0) + return -1; + + total += ret; } if (quic_stream_is_uni(qcs->id) && (h3s->flags & H3_SF_UNI_NO_H3)) { /* For non-h3 STREAM, parse it and return immediately. */ - if (h3_parse_uni_stream_no_h3(qcs, b)) - return 1; - return 0; + if ((ret = h3_parse_uni_stream_no_h3(qcs, b)) < 0) + return -1; + + total += ret; + return total; } while (b_data(b) && !(qcs->flags & QC_SF_DEM_FULL)) { @@ -605,6 +610,7 @@ static int h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) h3s->demux_frame_type = ftype; h3s->demux_frame_len = flen; + total += hlen; if (!h3_is_frame_valid(h3c, qcs, ftype)) { qcc_emit_cc_app(qcs->qcc, H3_FRAME_UNEXPECTED); @@ -679,6 +685,7 @@ static int h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) BUG_ON(h3s->demux_frame_len < ret); h3s->demux_frame_len -= ret; b_del(b, ret); + total += ret; } } @@ -686,7 +693,7 @@ static int h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) * However, currently, io-cb of MUX does not handle Rx. */ - return 0; + return total; } /* Returns buffer for data sending. diff --git a/src/hq_interop.c b/src/hq_interop.c index 4b4b5222d..5000a7e2e 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -8,7 +8,7 @@ #include #include -static int hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) +static ssize_t hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) { struct htx *htx; struct htx_sl *sl; @@ -62,7 +62,7 @@ static int hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) sl = htx_add_stline(htx, HTX_BLK_REQ_SL, 0, ist("GET"), path, ist("HTTP/1.0")); if (!sl) - return 1; + return -1; sl->flags |= HTX_SL_F_BODYLESS; sl->info.req.meth = find_http_meth("GET", 3); @@ -72,15 +72,14 @@ static int hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) sc = qc_attach_sc(qcs, &htx_buf); if (!sc) - return 1; + return -1; - b_reset(b); b_free(&htx_buf); if (fin) htx->flags |= HTX_FL_EOM; - return 0; + return b_data(b); } static struct buffer *mux_get_buf(struct qcs *qcs) diff --git a/src/mux_quic.c b/src/mux_quic.c index 28a1896a5..c60fdfca8 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -439,24 +439,19 @@ static void qcs_consume(struct qcs *qcs, uint64_t bytes) static int qcc_decode_qcs(struct qcc *qcc, struct qcs *qcs) { struct buffer b; - size_t data, done; - int ret; + ssize_t ret; TRACE_ENTER(QMUX_EV_QCS_RECV, qcc->conn, qcs); b = qcs_b_dup(&qcs->rx.ncbuf); - data = b_data(&b); - ret = qcc->app_ops->decode_qcs(qcs, &b, qcs->flags & QC_SF_FIN_RECV); - if (ret) { + if (ret < 0) { TRACE_DEVEL("leaving on decoding error", QMUX_EV_QCS_RECV, qcc->conn, qcs); return 1; } - BUG_ON_HOT(data < b_data(&b)); - done = data - b_data(&b); - if (done) { - qcs_consume(qcs, done); + if (ret) { + qcs_consume(qcs, ret); qcs_notify_recv(qcs); }