From d9c40098de3274e9ae6b65e7c0a1cab559be671a Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 22 Jul 2020 09:59:26 +0200 Subject: [PATCH 1/9] Add a flag parameter to hpack_decode and hpack_encode --- inc/hpack.h.in | 4 ++-- inc/hpack_priv.h | 1 + lib/hpack.c | 11 ++++++----- man/cashdumb.c | 2 +- man/cashdump.c | 2 +- man/hpack_dump.c | 2 +- tst/fdecode.c | 2 +- tst/hdecode.c | 2 +- tst/hencode.c | 2 +- tst/hpack_arg.c | 20 ++++++++++---------- tst/hpack_mbm.c | 2 +- 11 files changed, 26 insertions(+), 24 deletions(-) diff --git a/inc/hpack.h.in b/inc/hpack.h.in index 180d882..3504912 100644 --- a/inc/hpack.h.in +++ b/inc/hpack.h.in @@ -59,8 +59,8 @@ struct hpack_alloc { extern const struct hpack_alloc *hpack_default_alloc; -struct hpack * hpack_decoder(size_t, ssize_t, const struct hpack_alloc *); -struct hpack * hpack_encoder(size_t, ssize_t, const struct hpack_alloc *); +struct hpack * hpack_decoder(size_t, ssize_t, const struct hpack_alloc *, uint32_t); +struct hpack * hpack_encoder(size_t, ssize_t, const struct hpack_alloc *, uint32_t); void hpack_free(struct hpack **); enum hpack_result_e hpack_resize(struct hpack **, size_t); diff --git a/inc/hpack_priv.h b/inc/hpack_priv.h index ad79e28..1c18351 100644 --- a/inc/hpack_priv.h +++ b/inc/hpack_priv.h @@ -197,6 +197,7 @@ struct hpack { #define ENCODER_MAGIC 0x8ab1fb4c #define DECODER_MAGIC 0xab0e3218 #define DEFUNCT_MAGIC 0xdffadae9 + uint32_t flags; struct hpack_alloc alloc; struct hpack_size sz; struct hpack_state state; diff --git a/lib/hpack.c b/lib/hpack.c index 3857f83..28023a0 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -88,7 +88,7 @@ const struct hpack_alloc *hpack_default_alloc = &hpack_libc_alloc; static struct hpack * hpack_new(uint32_t magic, size_t mem, size_t max, - const struct hpack_alloc *ha) + const struct hpack_alloc *ha, uint32_t flags) { struct hpack *hp; @@ -104,6 +104,7 @@ hpack_new(uint32_t magic, size_t mem, size_t max, (void)memset(hp, 0, sizeof *hp); hp->magic = magic; + hp->flags = flags; hp->ctx.hp = hp; (void)memcpy(&hp->alloc, ha, sizeof *ha); hp->sz.mem = mem; @@ -116,14 +117,14 @@ hpack_new(uint32_t magic, size_t mem, size_t max, } struct hpack * -hpack_encoder(size_t max, ssize_t lim, const struct hpack_alloc *ha) +hpack_encoder(size_t max, ssize_t lim, const struct hpack_alloc *ha, uint32_t flags) { enum hpack_result_e res; struct hpack *hp, *tmp; size_t mem; mem = lim >= 0 ? (size_t)lim : max; - hp = hpack_new(ENCODER_MAGIC, mem, max, ha); + hp = hpack_new(ENCODER_MAGIC, mem, max, ha, flags); if (lim >= 0 && hp != NULL) { tmp = hp; res = hpack_limit(&tmp, (size_t)lim); @@ -136,14 +137,14 @@ hpack_encoder(size_t max, ssize_t lim, const struct hpack_alloc *ha) } struct hpack * -hpack_decoder(size_t max, ssize_t rsz, const struct hpack_alloc *ha) +hpack_decoder(size_t max, ssize_t rsz, const struct hpack_alloc *ha, uint32_t flags) { size_t mem; mem = rsz >= 0 ? (size_t)rsz : max; if (mem < max) mem = max; - return (hpack_new(DECODER_MAGIC, mem, max, ha)); + return (hpack_new(DECODER_MAGIC, mem, max, ha, flags)); } static enum hpack_result_e diff --git a/man/cashdumb.c b/man/cashdumb.c index 5dd4047..7382686 100644 --- a/man/cashdumb.c +++ b/man/cashdumb.c @@ -201,7 +201,7 @@ main(void) size_t linelen; /* initialization */ - hp = hpack_encoder(TABLE_SIZE, -1, hpack_default_alloc); + hp = hpack_encoder(TABLE_SIZE, -1, hpack_default_alloc, 0); (void)memset(&stt, 0, sizeof stt); stt.fld = static_fld; stt.dmb = static_dmb; diff --git a/man/cashdump.c b/man/cashdump.c index 4062dd2..b124f93 100644 --- a/man/cashdump.c +++ b/man/cashdump.c @@ -131,7 +131,7 @@ main(int argc, char **argv) /* initialization */ first = 1; - hp = hpack_decoder(4096, -1, hpack_default_alloc); + hp = hpack_decoder(4096, -1, hpack_default_alloc, 0); dec.blk = blk; dec.blk_len = 0; dec.buf = buf; diff --git a/man/hpack_dump.c b/man/hpack_dump.c index 1a99230..f397bf9 100644 --- a/man/hpack_dump.c +++ b/man/hpack_dump.c @@ -49,7 +49,7 @@ main(void) { struct hpack *hp; - hp = hpack_encoder(4096, -1, hpack_default_alloc); + hp = hpack_encoder(4096, -1, hpack_default_alloc, 0); if (hp == NULL) return (EXIT_FAILURE); diff --git a/tst/fdecode.c b/tst/fdecode.c index 1cefd02..9b5115f 100644 --- a/tst/fdecode.c +++ b/tst/fdecode.c @@ -234,7 +234,7 @@ main(int argc, char **argv) ctx.blk = blk; - hp = hpack_decoder(tbl_sz, -1, hpack_default_alloc); + hp = hpack_decoder(tbl_sz, -1, hpack_default_alloc, 0); assert(hp != NULL); priv.hp = hp; diff --git a/tst/hdecode.c b/tst/hdecode.c index 6fc5950..b710d47 100644 --- a/tst/hdecode.c +++ b/tst/hdecode.c @@ -270,7 +270,7 @@ main(int argc, char **argv) ctx.blk = blk; - hp = hpack_decoder(tbl_sz, -1, hpack_default_alloc); + hp = hpack_decoder(tbl_sz, -1, hpack_default_alloc, 0); assert(hp != NULL); priv.hp = hp; diff --git a/tst/hencode.c b/tst/hencode.c index fc5ae20..f854d8a 100644 --- a/tst/hencode.c +++ b/tst/hencode.c @@ -343,7 +343,7 @@ main(int argc, char **argv) return (EXIT_FAILURE); } - hp = hpack_encoder(tbl_sz, tbl_mem, hpack_default_alloc); + hp = hpack_encoder(tbl_sz, tbl_mem, hpack_default_alloc, 0); assert(hp != NULL); ctx.res = HPACK_RES_OK; diff --git a/tst/hpack_arg.c b/tst/hpack_arg.c index 7056844..af7a887 100644 --- a/tst/hpack_arg.c +++ b/tst/hpack_arg.c @@ -110,7 +110,7 @@ make_decoder(size_t max, ssize_t rsz, const struct hpack_alloc *ha) { struct hpack *dec; - CHECK_NOTNULL(dec, hpack_decoder, max, rsz, ha); + CHECK_NOTNULL(dec, hpack_decoder, max, rsz, ha, 0); return (dec); } @@ -119,7 +119,7 @@ make_encoder(size_t max, ssize_t lim, const struct hpack_alloc *ha) { struct hpack *enc; - CHECK_NOTNULL(enc, hpack_encoder, max, lim, ha); + CHECK_NOTNULL(enc, hpack_encoder, max, lim, ha, 0); return (enc); } @@ -244,13 +244,13 @@ static struct hpack_encoding unknown_encoding = { static void test_null_alloc(void) { - CHECK_NULL(hp, hpack_decoder, 0, -1, NULL); + CHECK_NULL(hp, hpack_decoder, 0, -1, NULL, 0); } static void test_null_malloc(void) { - CHECK_NULL(hp, hpack_decoder, 0, -1, &null_alloc); + CHECK_NULL(hp, hpack_decoder, 0, -1, &null_alloc, 0); } static void @@ -264,25 +264,25 @@ static void test_alloc_overflow(void) { CHECK_NULL(hp, hpack_decoder, UINT16_MAX + 1, -1, - hpack_default_alloc); + hpack_default_alloc, 0); CHECK_NULL(hp, hpack_decoder, 4096, UINT16_MAX + 1, - hpack_default_alloc); + hpack_default_alloc, 0); } static void test_alloc_underflow(void) { - CHECK_NOTNULL(hp, hpack_decoder, 4096, 2048, hpack_default_alloc); + CHECK_NOTNULL(hp, hpack_decoder, 4096, 2048, hpack_default_alloc, 0); hpack_free(&hp); - CHECK_NOTNULL(hp, hpack_encoder, 4096, 2048, hpack_default_alloc); + CHECK_NOTNULL(hp, hpack_encoder, 4096, 2048, hpack_default_alloc, 0); hpack_free(&hp); } static void test_malloc_failure(void) { - CHECK_NULL(hp, hpack_decoder, 4096, -1, &static_alloc); - CHECK_NULL(hp, hpack_encoder, 0, 4096, &static_alloc); + CHECK_NULL(hp, hpack_decoder, 4096, -1, &static_alloc, 0); + CHECK_NULL(hp, hpack_encoder, 0, 4096, &static_alloc, 0); } static void diff --git a/tst/hpack_mbm.c b/tst/hpack_mbm.c index 13f13e2..21b2a6a 100644 --- a/tst/hpack_mbm.c +++ b/tst/hpack_mbm.c @@ -122,7 +122,7 @@ mbm_setup(void) struct hpack_encoding he; char buf[64]; - hp = hpack_encoder(4096, -1, hpack_default_alloc); + hp = hpack_encoder(4096, -1, hpack_default_alloc, 0); if (hp == NULL) WRONG("hpack_encoder"); From 859dd501a06b0bec5fb17828f01bf5506946ed68 Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 22 Jul 2020 10:55:16 +0200 Subject: [PATCH 2/9] Degraded mode --- inc/hpack.h.in | 9 +++++++++ inc/hpack_priv.h | 3 +++ inc/tbl/hpack_tbl.h | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/inc/hpack.h.in b/inc/hpack.h.in index 3504912..fece624 100644 --- a/inc/hpack.h.in +++ b/inc/hpack.h.in @@ -34,6 +34,15 @@ # include #endif +/* hpack_config */ + +enum hpack_config_e { +#define HPC(f, v, l) \ + HPACK_CFG_##f = v, +#include "tbl/hpack_tbl.h" +#undef HPC +}; + /* hpack_result */ enum hpack_result_e { diff --git a/inc/hpack_priv.h b/inc/hpack_priv.h index 1c18351..d03e484 100644 --- a/inc/hpack_priv.h +++ b/inc/hpack_priv.h @@ -36,6 +36,9 @@ #define HPACK_LIMIT(hp) \ (((hp)->sz.lim >= 0 ? (size_t)(hp)->sz.lim : (hp)->sz.max)) +#define HPC_DEGRADED() \ + (ctx->hp->flags & HPACK_CFG_DEGRADED) + #define CALL(func, ...) \ do { \ if ((func)(__VA_ARGS__) != 0) \ diff --git a/inc/tbl/hpack_tbl.h b/inc/tbl/hpack_tbl.h index ea8d039..1b304ca 100644 --- a/inc/tbl/hpack_tbl.h +++ b/inc/tbl/hpack_tbl.h @@ -227,8 +227,16 @@ HPF(AUT_IDX, 0x80, "\tname and value) is found, either ``TYP_DYN`` or ``TYP_LIT`` are\n" "\tturned into ``TYP_IDX``. If a match is found, *idx* or *nam_idx*\n" "\tis set to non-zero, zero otherwise.\n\n") + #endif /* HPF */ +#ifdef HPC +/* configuration flags */ +HPC(DEGRADED, 0x01, + "\tTODO: write documentation.\n\n") + +#endif /* HPC */ + #ifdef HPP HPP(STR, 7, 0x00) /* Section 5.2 */ HPP(HUF, 7, 0x80) /* Section 5.2 */ From fa5d7ccd49e3453439c23a6313c543f8e7e3e63a Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 22 Jul 2020 19:48:58 +0200 Subject: [PATCH 3/9] Recover from indexing errors --- inc/hpack.h.in | 3 +++ lib/cashpack.map | 2 ++ lib/hpack.c | 4 +++- lib/hpack_tbl.c | 33 +++++++++++++++++++++++++++++---- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/inc/hpack.h.in b/inc/hpack.h.in index fece624..70ddfb5 100644 --- a/inc/hpack.h.in +++ b/inc/hpack.h.in @@ -78,6 +78,9 @@ enum hpack_result_e hpack_trim(struct hpack **); /* hpack_error */ +extern const char *hpack_unknown_name; +extern const char *hpack_unknown_value; + typedef void hpack_dump_f(void *, const char *, ...); const char * hpack_strerror(enum hpack_result_e); diff --git a/lib/cashpack.map b/lib/cashpack.map index 7d46bea..e659fcb 100644 --- a/lib/cashpack.map +++ b/lib/cashpack.map @@ -46,6 +46,8 @@ CASHPACK_0.4 { # variables hpack_default_alloc; + hpack_unknown_name; + hpack_unknown_value; local: *; diff --git a/lib/hpack.c b/lib/hpack.c index 28023a0..a672d6c 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -625,7 +625,9 @@ hpack_decode_field(HPACK_CTX) else CALL(HPT_decode_name, ctx); assert(ctx->buf > ctx->fld.nam); - ctx->fld.nam_sz = (size_t)(ctx->buf - ctx->fld.nam - 1); + if(ctx->fld.nam != hpack_unknown_name) { + ctx->fld.nam_sz = (size_t)(ctx->buf - ctx->fld.nam - 1); + } CALL(HPV_token, ctx, ctx->fld.nam, ctx->fld.nam_sz); ctx->fld.val = ctx->buf; ctx->hp->state.stp = HPACK_STP_VAL_LEN; diff --git a/lib/hpack_tbl.c b/lib/hpack_tbl.c index 3bfa132..5d784bf 100644 --- a/lib/hpack_tbl.c +++ b/lib/hpack_tbl.c @@ -62,6 +62,11 @@ static const struct hpt_field hpt_static[] = { * Tables lookups */ +const char *hpack_unknown_name = "unknown_name"; +const char *hpack_unknown_value = "unknown_value"; + +static size_t HPT_index_silent(HPACK_CTX); + static struct hpt_entry * hpt_dynamic(struct hpack *hp, size_t idx) { @@ -99,6 +104,18 @@ HPT_field(HPACK_CTX, size_t idx, struct hpt_field *hf) } idx -= HPACK_STATIC; + if(HPC_DEGRADED() && idx > ctx->hp->cnt) { + ctx->fld.nam = hpack_unknown_name; + ctx->fld.val = hpack_unknown_value; + ctx->fld.nam_sz = strlen(ctx->fld.nam); + ctx->fld.val_sz = strlen(ctx->fld.val); + while(idx > ctx->hp->cnt) { + HPT_index_silent(ctx); + } + while(idx >= ctx->hp->cnt) { + HPT_index(ctx); + } + } EXPECT(ctx, IDX, idx <= ctx->hp->cnt); he = hpt_dynamic(ctx->hp, idx); @@ -366,8 +383,8 @@ hpt_move_evicted(HPACK_CTX, const char *nam, size_t nam_sz, size_t len) (void)memmove(MOVE(tbl_ptr, len), tbl_ptr, hp->sz.len); } -void -HPT_index(HPACK_CTX) +static size_t +HPT_index_silent(HPACK_CTX) { struct hpack *hp; void *nam_ptr, *val_ptr; @@ -391,7 +408,7 @@ HPT_index(HPACK_CTX) len = HPACK_OVERHEAD + nam_sz + val_sz; if (!hpt_fit(ctx, len)) - return; + return 0; nam_ptr = JUMP(hp->tbl, 0); val_ptr = JUMP(hp->tbl, nam_sz + 1); @@ -412,8 +429,16 @@ HPT_index(HPACK_CTX) hp->tbl->val_sz = (uint16_t)val_sz; hp->sz.len += len; hp->cnt++; + return len; +} - HPC_notify(ctx, HPACK_EVT_INDEX, NULL, len); +void +HPT_index(HPACK_CTX) +{ + size_t len = HPT_index_silent(ctx); + if(len > 0) { + HPC_notify(ctx, HPACK_EVT_INDEX, NULL, len); + } } /********************************************************************** From 720ad9d3a116d8572502f156d982c22be4a4e063 Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 22 Jul 2020 11:44:55 +0200 Subject: [PATCH 4/9] Added events PTR and RECERR to help with error recovery Event PTR and RECERR can be enabled with resp. HPACK_CFG_SEND_PTR and HPACK_CFG_SEND_ERR --- inc/tbl/hpack_tbl.h | 30 +++++++++++++++++++++++++++++- lib/hpack.c | 9 +++++++++ lib/hpack_tbl.c | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/inc/tbl/hpack_tbl.h b/inc/tbl/hpack_tbl.h index 1b304ca..9d0dc35 100644 --- a/inc/tbl/hpack_tbl.h +++ b/inc/tbl/hpack_tbl.h @@ -183,6 +183,17 @@ HPE(TABLE, 7, "the table was updated", "\tA decoder or an encoder sends a TABLE event when a dynamic table\n" "\tupdate is decoded or encoded. The *buf* argument is always\n" "\t``NULL`` and *len* is the new table maximum size.\n\n") + +HPE(PTR, 8, "header line pointer", + "\tA decoder sends a PTR event containing the address pointer of the\n" + "\tstart byte of a header line.\n" + "\tThis event will be emitted only when ``HPACK_CFG_SEND_PTR`` is set.\n\n") + +HPE(RECERR, 9, "recoverable error", + "\tA decoder sends a RECERR event containing the address pointer of\n" + "\tthe byte in error, which may be in the middle of a header line.\n" + "\tThis event will be emitted only when ``HPACK_CFG_SEND_ERR`` is set.\n\n") + #endif /* HPE */ #ifdef HPF @@ -233,7 +244,24 @@ HPF(AUT_IDX, 0x80, #ifdef HPC /* configuration flags */ HPC(DEGRADED, 0x01, - "\tTODO: write documentation.\n\n") + "\tDegraded mode tries to recover from missing indexes in the dynamic\n" + "\ttable. A missing header name will be replaced by ``unknown_name``,\n" + "\tand a missing value will be replaced by ``unknown_value``.\n" + "\t\n\n") + +HPC(SEND_PTR, 0x02, + "\tSends a ``PTR`` event at the start of every header line.\n" + "\tThe address of the header line in the header block will be placed\n" + "\tin the ``const char *buf`` parameter of the callback.\n\n") + +HPC(SEND_ERR, 0x04, + "\tSends a ``RECERR`` event whenever a recoverable error occurs.\n" + "\tThe address of the error in the header block will be placed\n" + "\tin the ``const char *buf`` parameter of the callback.\n" + "\tThis parameter can be used with the ``SEND_PTR`` parameter\n" + "\tto be able to spot and/or extract errored header lines from\n" + "\ta header block.\n" + "\tNote: this is mostly useful in ``DEGRADED`` mode.\n\n") #endif /* HPC */ diff --git a/lib/hpack.c b/lib/hpack.c index a672d6c..73f1994 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -772,6 +772,8 @@ hpack_decode(struct hpack *hp, const struct hpack_decoding *dec) ctx->res = dec->cut ? HPACK_RES_BLK : HPACK_RES_OK; while (ctx->ptr_len > 0) { + if(ctx->hp->flags & HPACK_CFG_SEND_PTR) + HPC_notify(ctx, HPACK_EVT_PTR, ctx->ptr.blk, 0); if (!hp->state.bsy && hp->state.stp == HPACK_STP_FLD_INT) hp->state.typ = *ctx->ptr.blk; if ((hp->state.typ & HPACK_PAT_UPD) != HPACK_PAT_UPD) { @@ -842,6 +844,13 @@ hpack_assert_cb(enum hpack_event_e evt, const char *buf, size_t len, void *priv) assert(buf != NULL); assert(len == strlen(buf)); break; + case HPACK_EVT_PTR: + assert(buf != NULL); + break; + case HPACK_EVT_RECERR: + assert(buf != NULL); + assert(len > 0); + break; case HPACK_EVT_DATA: WRONG("Invalid event"); default: diff --git a/lib/hpack_tbl.c b/lib/hpack_tbl.c index 5d784bf..185b05f 100644 --- a/lib/hpack_tbl.c +++ b/lib/hpack_tbl.c @@ -115,6 +115,8 @@ HPT_field(HPACK_CTX, size_t idx, struct hpt_field *hf) while(idx >= ctx->hp->cnt) { HPT_index(ctx); } + if(ctx->hp->flags & HPACK_CFG_SEND_ERR) + HPC_notify(ctx, HPACK_EVT_RECERR, ctx->ptr.blk, idx); } EXPECT(ctx, IDX, idx <= ctx->hp->cnt); From 05a7ae6aff8ac7c59bc78608c37e828ec19c2fd0 Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 29 Jul 2020 09:48:58 +0200 Subject: [PATCH 5/9] Avoid dynamic table field creation in degraded mode Also avoid copy of sentinel values to be able to use them in event callback. --- lib/hpack_tbl.c | 67 +++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/lib/hpack_tbl.c b/lib/hpack_tbl.c index 185b05f..5dce0b5 100644 --- a/lib/hpack_tbl.c +++ b/lib/hpack_tbl.c @@ -65,8 +65,6 @@ static const struct hpt_field hpt_static[] = { const char *hpack_unknown_name = "unknown_name"; const char *hpack_unknown_value = "unknown_value"; -static size_t HPT_index_silent(HPACK_CTX); - static struct hpt_entry * hpt_dynamic(struct hpack *hp, size_t idx) { @@ -77,7 +75,9 @@ hpt_dynamic(struct hpack *hp, size_t idx) off = 0; assert(idx > 0); - assert(idx <= hp->cnt); + if(idx > hp->cnt) { + return NULL; + } while (1) { (void)memcpy(&tmp, he, HPT_HEADERSZ); @@ -109,18 +109,16 @@ HPT_field(HPACK_CTX, size_t idx, struct hpt_field *hf) ctx->fld.val = hpack_unknown_value; ctx->fld.nam_sz = strlen(ctx->fld.nam); ctx->fld.val_sz = strlen(ctx->fld.val); - while(idx > ctx->hp->cnt) { - HPT_index_silent(ctx); - } - while(idx >= ctx->hp->cnt) { - HPT_index(ctx); - } if(ctx->hp->flags & HPACK_CFG_SEND_ERR) HPC_notify(ctx, HPACK_EVT_RECERR, ctx->ptr.blk, idx); + } else { + EXPECT(ctx, IDX, idx <= ctx->hp->cnt); } - EXPECT(ctx, IDX, idx <= ctx->hp->cnt); he = hpt_dynamic(ctx->hp, idx); + if(HPC_DEGRADED() && he == NULL) { + return (0); + } assert(he != NULL); assert(hf != NULL); (void)memcpy(&tmp, he, HPT_HEADERSZ); @@ -385,8 +383,8 @@ hpt_move_evicted(HPACK_CTX, const char *nam, size_t nam_sz, size_t len) (void)memmove(MOVE(tbl_ptr, len), tbl_ptr, hp->sz.len); } -static size_t -HPT_index_silent(HPACK_CTX) +void +HPT_index(HPACK_CTX) { struct hpack *hp; void *nam_ptr, *val_ptr; @@ -410,7 +408,7 @@ HPT_index_silent(HPACK_CTX) len = HPACK_OVERHEAD + nam_sz + val_sz; if (!hpt_fit(ctx, len)) - return 0; + return; nam_ptr = JUMP(hp->tbl, 0); val_ptr = JUMP(hp->tbl, nam_sz + 1); @@ -431,18 +429,11 @@ HPT_index_silent(HPACK_CTX) hp->tbl->val_sz = (uint16_t)val_sz; hp->sz.len += len; hp->cnt++; - return len; -} - -void -HPT_index(HPACK_CTX) -{ - size_t len = HPT_index_silent(ctx); - if(len > 0) { + if(len > 0) HPC_notify(ctx, HPACK_EVT_INDEX, NULL, len); - } } + /********************************************************************** * Decode */ @@ -455,17 +446,24 @@ HPT_decode(HPACK_CTX, size_t idx) EXPECT(ctx, IDX, idx > 0); (void)memset(&hf, 0, sizeof hf); CALL(HPT_field, ctx, idx, &hf); - assert(hf.nam != NULL); - assert(hf.val != NULL); - assert(hf.nam_sz > 0); - - ctx->fld.nam = ctx->buf; - ctx->fld.nam_sz = hf.nam_sz; - CALL(HPD_puts, ctx, hf.nam, hf.nam_sz); - - ctx->fld.val = ctx->buf; - ctx->fld.val_sz = hf.val_sz; - CALL(HPD_puts, ctx, hf.val, hf.val_sz); + if(HPC_DEGRADED() && hf.nam == NULL) { + ctx->fld.nam = hpack_unknown_name; + ctx->fld.nam_sz = strlen(hpack_unknown_name); + ctx->fld.val = hpack_unknown_value; + ctx->fld.val_sz = strlen(hpack_unknown_value); + } else { + assert(hf.nam != NULL); + assert(hf.val != NULL); + assert(hf.nam_sz > 0); + + ctx->fld.nam = ctx->buf; + ctx->fld.nam_sz = hf.nam_sz; + CALL(HPD_puts, ctx, hf.nam, hf.nam_sz); + + ctx->fld.val = ctx->buf; + ctx->fld.val_sz = hf.val_sz; + CALL(HPD_puts, ctx, hf.val, hf.val_sz); + } HPD_notify(ctx); return (0); @@ -480,6 +478,9 @@ HPT_decode_name(HPACK_CTX) assert(ctx->hp->state.idx != 0); (void)memset(&hf, 0, sizeof hf); CALL(HPT_field, ctx, ctx->hp->state.idx, &hf); + if(HPC_DEGRADED() && hf.nam == NULL) { + return (0); + } assert(hf.nam != NULL); assert(hf.nam_sz > 0); From d638d45879a340e26d9425704bf459c13436961d Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Thu, 23 Jul 2020 16:20:34 +0200 Subject: [PATCH 6/9] Further simplify the bootstrap script --- bootstrap | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bootstrap b/bootstrap index 120d19c..0a45f5a 100755 --- a/bootstrap +++ b/bootstrap @@ -10,12 +10,6 @@ test -n "$ROOT_DIR" test "${LGTM_WORKSPACE:+set}" = set && sed -i '/CASHPACK_ARG_ENABLE..docs/d' configure.ac -if ! command -v libtoolize >/dev/null 2>&1 -then - echo 'libtoolize: command not found, falling back to glibtoolize' >&2 - alias libtoolize=glibtoolize -fi - autoreconf -i "$ROOT_DIR" test "${LGTM_WORKSPACE:+set}" = set && exit From 0c2b6c814a6e791223f6aa2c2a74ce5e6ae0e985 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Thu, 23 Jul 2020 17:05:15 +0200 Subject: [PATCH 7/9] GC duplicate hp symbols in the test suite They were specifically centralized in tst.c to avoid repetition. --- tst/fdecode.c | 2 -- tst/hdecode.c | 2 -- tst/hencode.c | 2 -- tst/ngdecode.c | 2 -- 4 files changed, 8 deletions(-) diff --git a/tst/fdecode.c b/tst/fdecode.c index 9b5115f..c36f86f 100644 --- a/tst/fdecode.c +++ b/tst/fdecode.c @@ -123,8 +123,6 @@ resize_table(void *priv, const void *buf, size_t len, unsigned cut) return (hpack_resize(&priv2->hp, len)); } -struct hpack *hp = NULL; - int main(int argc, char **argv) { diff --git a/tst/hdecode.c b/tst/hdecode.c index b710d47..aa0a2c7 100644 --- a/tst/hdecode.c +++ b/tst/hdecode.c @@ -158,8 +158,6 @@ resize_table(void *priv, const void *buf, size_t len, unsigned cut) return (hpack_resize(&priv2->hp, len)); } -struct hpack *hp = NULL; - int main(int argc, char **argv) { diff --git a/tst/hencode.c b/tst/hencode.c index f854d8a..d5dbf6e 100644 --- a/tst/hencode.c +++ b/tst/hencode.c @@ -274,8 +274,6 @@ parse_commands(struct enc_ctx *ctx) return (parse_commands(ctx)); } -struct hpack *hp = NULL; - int main(int argc, char **argv) { diff --git a/tst/ngdecode.c b/tst/ngdecode.c index 2a2817f..d74e2b2 100644 --- a/tst/ngdecode.c +++ b/tst/ngdecode.c @@ -45,8 +45,6 @@ #include "tst.h" -struct hpack *hp = NULL; /* unused, but needed by tst.c */ - static int print_headers(void *priv, const void *buf, size_t len) { From ea3ffaa44b7a93e63eb05ceae034295f83cfca75 Mon Sep 17 00:00:00 2001 From: David Guerizec Date: Wed, 22 Jul 2020 12:27:09 +0200 Subject: [PATCH 8/9] Introduce a new `hpack_event_id` function This offers a human readable string, convenient for event reporting. Signed-off-by: Dridi Boukelmoune --- inc/hpack.h.in | 2 ++ lib/cashpack.map | 1 + lib/hpack.c | 16 ++++++++++++++++ tst/hpack_arg.c | 14 ++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/inc/hpack.h.in b/inc/hpack.h.in index 70ddfb5..52b5a68 100644 --- a/inc/hpack.h.in +++ b/inc/hpack.h.in @@ -97,6 +97,8 @@ enum hpack_event_e { typedef void hpack_event_f(enum hpack_event_e, const char *, size_t, void *); +const char * hpack_event_id(enum hpack_event_e); + /* hpack_decode */ struct hpack_decoding { diff --git a/lib/cashpack.map b/lib/cashpack.map index e659fcb..403ebc5 100644 --- a/lib/cashpack.map +++ b/lib/cashpack.map @@ -41,6 +41,7 @@ CASHPACK_0.4 { hpack_skip; hpack_static; hpack_strerror; + hpack_event_id; hpack_tables; hpack_trim; diff --git a/lib/hpack.c b/lib/hpack.c index 73f1994..cb1e543 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -431,6 +431,22 @@ hpack_entry(struct hpack *hp, size_t idx, const char **nam, const char **val) return (retval); } +/********************************************************************** + * Events + */ + +const char * +hpack_event_id(enum hpack_event_e evt) +{ + +#define HPE(val, cod, txt, rst) \ + if (evt == cod) \ + return (#val); +#include "tbl/hpack_tbl.h" +#undef HPE + return (NULL); +} + /********************************************************************** * Errors */ diff --git a/tst/hpack_arg.c b/tst/hpack_arg.c index af7a887..af14eff 100644 --- a/tst/hpack_arg.c +++ b/tst/hpack_arg.c @@ -838,6 +838,18 @@ test_dump_unknown(void) hpack_free(&hp); } +static void +test_event_id(void) +{ + const char *str; + +#define HPE(e, v, d, l) \ + CHECK_NOTNULL(str, hpack_event_id, HPACK_EVT_ ## e); +#include "tbl/hpack_tbl.h" +#undef HPE + CHECK_NULL(str, hpack_event_id, UINT16_MAX); +} + /********************************************************************** */ @@ -903,5 +915,7 @@ main(void) test_strerror(); test_dump_unknown(); + test_event_id(); + return (0); } From 6c920df86f0bc208d3ad4d0f054b37d7923233ab Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Thu, 23 Jul 2020 17:17:11 +0200 Subject: [PATCH 9/9] Document `hpack_event_id` Closes #5 --- inc/hpack.h.in | 2 +- man/Makefile.am | 1 + man/cashpack.3.rst.in | 6 ++- man/hpack_alloc.3.rst | 1 + man/hpack_decode.3.rst | 1 + man/hpack_encode.3.rst.in | 1 + man/hpack_error.3.rst.in | 1 + man/hpack_event_id.3.rst | 82 +++++++++++++++++++++++++++++++++++++++ man/hpack_index.3.rst | 1 + 9 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 man/hpack_event_id.3.rst diff --git a/inc/hpack.h.in b/inc/hpack.h.in index 52b5a68..b354a77 100644 --- a/inc/hpack.h.in +++ b/inc/hpack.h.in @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2016-2017 Dridi Boukelmoune + * Copyright (c) 2016-2020 Dridi Boukelmoune * All rights reserved. * * Author: Dridi Boukelmoune diff --git a/man/Makefile.am b/man/Makefile.am index 8966197..c1512b1 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -61,6 +61,7 @@ dist_man_MANS = \ hpack_decode.3 \ hpack_encode.3 \ hpack_error.3 \ + hpack_event_id.3 \ hpack_index.3 \ $(hpack_alloc_links) \ $(hpack_decode_links) \ diff --git a/man/cashpack.3.rst.in b/man/cashpack.3.rst.in index f071f57..df52585 100644 --- a/man/cashpack.3.rst.in +++ b/man/cashpack.3.rst.in @@ -1,4 +1,4 @@ -.. Copyright (c) 2016-2017 Dridi Boukelmoune +.. Copyright (c) 2016-2020 Dridi Boukelmoune .. All rights reserved. .. .. Redistribution and use in source and binary forms, with or without @@ -180,6 +180,9 @@ When dealing with events, unknown values should be ignored. Future versions of cashpack may introduce new events. The values for existing events shall never be changed. +A static textual representation of the event can be obtained with the function +``hpack_event_id()``. + EXAMPLE ======= @@ -239,6 +242,7 @@ SEE ALSO **hpack_encode**\(3), **hpack_encoder**\(3), **hpack_entry**\(3), +**hpack_event_id**\(3), **hpack_free**\(3), **hpack_limit**\(3), **hpack_resize**\(3), diff --git a/man/hpack_alloc.3.rst b/man/hpack_alloc.3.rst index 4eb3886..7a75899 100644 --- a/man/hpack_alloc.3.rst +++ b/man/hpack_alloc.3.rst @@ -193,6 +193,7 @@ SEE ALSO **hpack_dynamic**\(3), **hpack_encode**\(3), **hpack_entry**\(3), +**hpack_event_id**\(3), **hpack_search**\(3), **hpack_skip**\(3), **hpack_static**\(3), diff --git a/man/hpack_decode.3.rst b/man/hpack_decode.3.rst index c1fa88b..8e98d41 100644 --- a/man/hpack_decode.3.rst +++ b/man/hpack_decode.3.rst @@ -301,6 +301,7 @@ SEE ALSO **hpack_encode**\(3), **hpack_encoder**\(3), **hpack_entry**\(3), +**hpack_event_id**\(3), **hpack_free**\(3), **hpack_limit**\(3), **hpack_resize**\(3), diff --git a/man/hpack_encode.3.rst.in b/man/hpack_encode.3.rst.in index 81febc8..bef6119 100644 --- a/man/hpack_encode.3.rst.in +++ b/man/hpack_encode.3.rst.in @@ -278,6 +278,7 @@ SEE ALSO **hpack_dynamic**\(3), **hpack_encoder**\(3), **hpack_entry**\(3), +**hpack_event_id**\(3), **hpack_free**\(3), **hpack_limit**\(3), **hpack_resize**\(3), diff --git a/man/hpack_error.3.rst.in b/man/hpack_error.3.rst.in index 671cecd..c2657aa 100644 --- a/man/hpack_error.3.rst.in +++ b/man/hpack_error.3.rst.in @@ -109,6 +109,7 @@ SEE ALSO **hpack_encode**\(3), **hpack_encoder**\(3), **hpack_entry**\(3), +**hpack_event_id**\(3), **hpack_free**\(3), **hpack_limit**\(3), **hpack_resize**\(3), diff --git a/man/hpack_event_id.3.rst b/man/hpack_event_id.3.rst new file mode 100644 index 0000000..ea1b115 --- /dev/null +++ b/man/hpack_event_id.3.rst @@ -0,0 +1,82 @@ +.. Copyright (c) 2020 Dridi Boukelmoune +.. All rights reserved. +.. +.. Redistribution and use in source and binary forms, with or without +.. modification, are permitted provided that the following conditions +.. are met: +.. 1. Redistributions of source code must retain the above copyright +.. notice, this list of conditions and the following disclaimer. +.. 2. Redistributions in binary form must reproduce the above copyright +.. notice, this list of conditions and the following disclaimer in the +.. documentation and/or other materials provided with the distribution. +.. +.. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.. ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +.. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.. SUCH DAMAGE. + +============== +hpack_event_id +============== + +--------------------------- +turn an event into a string +--------------------------- + +:Manual section: 3 + +SYNOPSIS +======== + +| **#include ** +| **#include ** +| **#include ** +| **#include ** +| +| **enum hpack_event_e;** +| +| **const char * hpack_event_id(enum hpack_event_e** *evt*\ **);** + +DESCRIPTION +=========== + +This is an overview of event functions in cashpack, a stateless event-driven +HPACK codec written in C. + +The ``hpack_event_id()`` function is a thread-safe function that translates an +event code into a human readable string identifier. + +RETURN VALUE +============ + +The ``hpack_event_id()`` function returns a constant string corresponding to +an event enumerator, or ``NULL`` for unknown values. + +SEE ALSO +======== + +**cashpack**\(3), +**hpack_decode**\(3), +**hpack_decode_fields**\(3), +**hpack_decoder**\(3), +**hpack_dump**\(3), +**hpack_dynamic**\(3), +**hpack_encode**\(3), +**hpack_encoder**\(3), +**hpack_entry**\(3), +**hpack_free**\(3), +**hpack_limit**\(3), +**hpack_resize**\(3), +**hpack_search**\(3), +**hpack_skip**\(3), +**hpack_static**\(3), +**hpack_strerror**\(3), +**hpack_tables**\(3), +**hpack_trim**\(3) diff --git a/man/hpack_index.3.rst b/man/hpack_index.3.rst index 2960060..3c064c5 100644 --- a/man/hpack_index.3.rst +++ b/man/hpack_index.3.rst @@ -156,6 +156,7 @@ SEE ALSO **hpack_dump**\(3), **hpack_encode**\(3), **hpack_encoder**\(3), +**hpack_event_id**\(3), **hpack_free**\(3), **hpack_limit**\(3), **hpack_resize**\(3),