]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic/h3: adjust demuxing function return values
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 7 Jun 2022 15:30:55 +0000 (17:30 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 7 Jun 2022 16:15:47 +0000 (18:15 +0200)
Clean the API used by decode_qcs() and transcoder internal functions.
Parsing functions now returns a ssize_t which represents the number of
consumed bytes or a negative error code. The total consumed bytes is
returned via decode_qcs().

The API is now unified and cleaner. The MUX can thus simply use the
return value of decode_qcs() instead of substracting the data bytes in
the buffer before and after the call. Transcoders functions are not
anymore obliged to remove consumed bytes from the buffer which was not
obvious.

include/haproxy/mux_quic-t.h
src/h3.c
src/hq_interop.c
src/mux_quic.c

index 9a69b76387cc4166f94adc0c76b218c89a07bf7b..29d3897b1b0bf5570a83b02031854c7ba1d26edd 100644 (file)
@@ -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);
index 655bf26a0633c35dcc9bfc3a655f106e644357dd..cbf12e4a72365c1cbe26c6c9ef704e46e8d9b240 100644 (file)
--- 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 <qcs> by reading its type from <b>.
  *
- * 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 <qcs> from <rxbuf> 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. <fin> 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. <fin> 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 <len> of payload <buf>.
  *
- * 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.
index 4b4b5222d0a49df52a7d0a97f76db97b64b6ee5c..5000a7e2ef716b3b404cd941a5bc7a447bf7dd36 100644 (file)
@@ -8,7 +8,7 @@
 #include <haproxy/http.h>
 #include <haproxy/mux_quic.h>
 
-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)
index 28a1896a588ed1f40a9b9c2bd3ad31e0d6612d09..c60fdfca8747179ba141b6b9797576cee2b65a72 100644 (file)
@@ -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);
        }