]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: qpack: generate headers list on decoder
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 24 Aug 2021 13:13:20 +0000 (15:13 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Sep 2021 13:27:25 +0000 (15:27 +0200)
TMP -> non-free strdup
TMP -> currently only support indexed field line or literal field line
with name reference

include/haproxy/qpack-dec.h
src/h3.c
src/qpack-dec.c

index 517d617f96b37f28daf44f0145ac0052ae617784..f45246f766a39362939c648dacea01fee0150cdd 100644 (file)
@@ -24,6 +24,7 @@
 #include <haproxy/mux_quic-t.h>
 
 struct h3_uqs;
+struct http_hdr;
 
 /* Internal QPACK processing errors.
  *Nothing to see with the RFC.
@@ -43,7 +44,8 @@ struct qpack_dec {
        uint64_t krc;
 };
 
-int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp);
+int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp,
+                    struct http_hdr *list);
 int qpack_decode_enc(struct h3_uqs *h3_uqs, void *ctx);
 int qpack_decode_dec(struct h3_uqs *h3_uqs, void *ctx);
 
index c90e63a68aa1395f8d6057996b013b3ce6939f81..78d43a71a1f378fc34e435d9570e60989f312219 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -121,6 +121,8 @@ static int h3_decode_qcs(struct qcs *qcs, void *ctx)
 {
        struct buffer *rxbuf = &qcs->rx.buf;
        struct h3 *h3 = ctx;
+       struct http_hdr list[global.tune.max_http_hdr];
+       int hdr_idx;
 
        h3_debug_printf(stderr, "%s: STREAM ID: %llu\n", __func__, qcs->by_id.key);
        if (!b_data(rxbuf))
@@ -152,7 +154,7 @@ static int h3_decode_qcs(struct qcs *qcs, void *ctx)
                        size_t len = b_data(rxbuf);
                        struct buffer *tmp = get_trash_chunk();
 
-                       if (qpack_decode_fs(buf, len, tmp) < 0) {
+                       if (qpack_decode_fs(buf, len, tmp, list) < 0) {
                                h3->err = QPACK_DECOMPRESSION_FAILED;
                                return -1;
                        }
index 95ec720b75c27544d3bc9ecb6f7903d4968ff500..54e7f164ad3e6815087b970eea3503d137b1629c 100644 (file)
 #include <haproxy/h3.h>
 #include <haproxy/qpack-t.h>
 #include <haproxy/qpack-dec.h>
+#include <haproxy/qpack-tbl.h>
 #include <haproxy/hpack-huff.h>
 #include <haproxy/hpack-tbl.h>
+#include <haproxy/http-hdr.h>
 #include <haproxy/tools.h>
 
 #define DEBUG_HPACK
@@ -177,12 +179,14 @@ static int qpack_decode_fs_pfx(uint64_t *enc_ric, uint64_t *db, int *sign_bit,
 /* Decode a field section from <len> bytes length <raw> buffer.
  * Produces the output into <tmp> buffer.
  */
-int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
+int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp,
+                    struct http_hdr *list)
 {
        uint64_t enc_ric, db;
        int s;
        unsigned int efl_type;
        int ret;
+       int hdr_idx = 0;
 
        qpack_debug_hexdump(stderr, "[QPACK-DEC-FS] ", (const char *)raw, 0, len);
 
@@ -227,7 +231,8 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                        /* XXX Value string XXX */
                        raw += length;
                        len -= length;
-               } else if (efl_type == QPACK_IFL_WPBI) {
+               }
+               else if (efl_type == QPACK_IFL_WPBI) {
                        /* Indexed field line with post-base index */
                        uint64_t index;
 
@@ -240,7 +245,8 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                        }
 
                        qpack_debug_printf(stderr, " index=%llu", (unsigned long long)index);
-               } else if (efl_type & QPACK_IFL_BIT) {
+               }
+               else if (efl_type & QPACK_IFL_BIT) {
                        /* Indexed field line */
                        uint64_t index;
                        unsigned int t;
@@ -254,8 +260,12 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                                goto out;
                        }
 
+                       if (t)
+                               list[hdr_idx++] = qpack_sht[index];
+
                        qpack_debug_printf(stderr,  " t=%d index=%llu", !!t, (unsigned long long)index);
-               } else if (efl_type & QPACK_LFL_WNR_BIT) {
+               }
+               else if (efl_type & QPACK_LFL_WNR_BIT) {
                        /* Literal field line with name reference */
                        uint64_t index, length;
                        unsigned int t, n, h;
@@ -270,6 +280,9 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                                goto out;
                        }
 
+                       if (t)
+                               list[hdr_idx] = qpack_sht[index];
+
                        qpack_debug_printf(stderr, " n=%d t=%d index=%llu", !!n, !!t, (unsigned long long)index);
                        h = *raw & 0x80;
                        length = qpack_get_varint(&raw, &len, 7);
@@ -298,11 +311,14 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                                }
 
                                qpack_debug_printf(stderr, " [name huff %d->%d '%s']", (int)length, (int)nlen, trash);
+                               list[hdr_idx].v = ist(strdup(trash));
                        }
                        /* XXX Value string XXX */
                        raw += length;
                        len -= length;
-               } else if (efl_type & QPACK_LFL_WLN_BIT) {
+                       ++hdr_idx;
+               }
+               else if (efl_type & QPACK_LFL_WLN_BIT) {
                        /* Literal field line with literal name */
                        unsigned int n, hname, hvalue;
                        uint64_t name_len, value_len;
@@ -338,6 +354,9 @@ int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
                qpack_debug_printf(stderr, "\n");
        }
 
+       /* put an end marker */
+       list[hdr_idx].n = list[hdr_idx].v = IST_NULL;
+
  out:
        qpack_debug_printf(stderr, "-- done: ret=%d\n", ret);
        return ret;