From fd7cdc3e7099c113209de98829e51eaf85d0e3ae Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 24 Aug 2021 15:13:20 +0200 Subject: [PATCH] MINOR: qpack: generate headers list on decoder TMP -> non-free strdup TMP -> currently only support indexed field line or literal field line with name reference --- include/haproxy/qpack-dec.h | 4 +++- src/h3.c | 4 +++- src/qpack-dec.c | 29 ++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/haproxy/qpack-dec.h b/include/haproxy/qpack-dec.h index 517d617f9..f45246f76 100644 --- a/include/haproxy/qpack-dec.h +++ b/include/haproxy/qpack-dec.h @@ -24,6 +24,7 @@ #include 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); diff --git a/src/h3.c b/src/h3.c index c90e63a68..78d43a71a 100644 --- 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; } diff --git a/src/qpack-dec.c b/src/qpack-dec.c index 95ec720b7..54e7f164a 100644 --- a/src/qpack-dec.c +++ b/src/qpack-dec.c @@ -29,8 +29,10 @@ #include #include #include +#include #include #include +#include #include #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 bytes length buffer. * Produces the output into 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;