Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/recover #6

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 17 additions & 3 deletions inc/hpack.h.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2016-2017 Dridi Boukelmoune
* Copyright (c) 2016-2020 Dridi Boukelmoune
* All rights reserved.
*
* Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Expand Down Expand Up @@ -34,6 +34,15 @@
# include <unistd.h>
#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 {
Expand All @@ -59,8 +68,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);
Expand All @@ -69,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);
Expand All @@ -85,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 {
Expand Down
4 changes: 4 additions & 0 deletions inc/hpack_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -197,6 +200,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;
Expand Down
36 changes: 36 additions & 0 deletions inc/tbl/hpack_tbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -227,8 +238,33 @@ 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,
"\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 */

#ifdef HPP
HPP(STR, 7, 0x00) /* Section 5.2 */
HPP(HUF, 7, 0x80) /* Section 5.2 */
Expand Down
3 changes: 3 additions & 0 deletions lib/cashpack.map
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ CASHPACK_0.4 {
hpack_skip;
hpack_static;
hpack_strerror;
hpack_event_id;
hpack_tables;
hpack_trim;

# variables
hpack_default_alloc;
hpack_unknown_name;
hpack_unknown_value;

local:
*;
Expand Down
40 changes: 34 additions & 6 deletions lib/hpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -430,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
*/
Expand Down Expand Up @@ -624,7 +641,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;
Expand Down Expand Up @@ -769,6 +788,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) {
Expand Down Expand Up @@ -839,6 +860,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:
Expand Down
58 changes: 43 additions & 15 deletions lib/hpack_tbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ static const struct hpt_field hpt_static[] = {
* Tables lookups
*/

const char *hpack_unknown_name = "unknown_name";
const char *hpack_unknown_value = "unknown_value";

static struct hpt_entry *
hpt_dynamic(struct hpack *hp, size_t idx)
{
Expand All @@ -72,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);
Expand All @@ -99,9 +104,21 @@ HPT_field(HPACK_CTX, size_t idx, struct hpt_field *hf)
}

idx -= HPACK_STATIC;
EXPECT(ctx, IDX, idx <= ctx->hp->cnt);
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);
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);
}

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);
Expand Down Expand Up @@ -412,10 +429,11 @@ HPT_index(HPACK_CTX)
hp->tbl->val_sz = (uint16_t)val_sz;
hp->sz.len += len;
hp->cnt++;

HPC_notify(ctx, HPACK_EVT_INDEX, NULL, len);
if(len > 0)
HPC_notify(ctx, HPACK_EVT_INDEX, NULL, len);
}


/**********************************************************************
* Decode
*/
Expand All @@ -428,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);
Expand All @@ -453,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);

Expand Down
1 change: 1 addition & 0 deletions man/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
2 changes: 1 addition & 1 deletion man/cashdumb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion man/cashdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading