1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <errno.h>
450aadb33SDmitri Tikhonov#include <stdio.h>
550aadb33SDmitri Tikhonov#include <stdlib.h>
650aadb33SDmitri Tikhonov#include <string.h>
7461e84d8SAmol Deshpande#ifndef WIN32
850aadb33SDmitri Tikhonov#include <unistd.h>
9461e84d8SAmol Deshpande#else
10461e84d8SAmol Deshpande#include <getopt.h>
11461e84d8SAmol Deshpande#endif
1250aadb33SDmitri Tikhonov#include <sys/queue.h>
1350aadb33SDmitri Tikhonov
1450aadb33SDmitri Tikhonov#include "lsquic.h"
1550aadb33SDmitri Tikhonov#include "lsquic_frame_common.h"
16bea64822SDmitri Tikhonov#include "lshpack.h"
1750aadb33SDmitri Tikhonov#include "lsquic_mm.h"
183b55e6aeSDmitri Tikhonov#include "lsquic_int_types.h"
193b55e6aeSDmitri Tikhonov#include "lsquic_conn_flow.h"
203b55e6aeSDmitri Tikhonov#include "lsquic_sfcw.h"
213b55e6aeSDmitri Tikhonov#include "lsquic_rtt.h"
225392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
233b55e6aeSDmitri Tikhonov#include "lsquic_conn.h"
245392f7a3SLiteSpeed Tech#include "lsquic_varint.h"
255392f7a3SLiteSpeed Tech#include "lsquic_hq.h"
263b55e6aeSDmitri Tikhonov#include "lsquic_stream.h"
273b55e6aeSDmitri Tikhonov#include "lsquic_conn_public.h"
2850aadb33SDmitri Tikhonov#include "lsquic_logger.h"
2919f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS
3019f667fbSDmitri Tikhonov#include "lsquic_int_types.h"
3119f667fbSDmitri Tikhonov#include "lsquic_conn.h"
3219f667fbSDmitri Tikhonov#endif
3350aadb33SDmitri Tikhonov
3450aadb33SDmitri Tikhonov#include "lsquic_frame_reader.h"
353b55e6aeSDmitri Tikhonov#include "lsquic_headers.h"
363b55e6aeSDmitri Tikhonov#include "lsquic_http1x_if.h"
3750aadb33SDmitri Tikhonov
3850aadb33SDmitri Tikhonov
3950aadb33SDmitri Tikhonovstruct callback_value   /* What callback returns */
4050aadb33SDmitri Tikhonov{
4150aadb33SDmitri Tikhonov    enum {
4250aadb33SDmitri Tikhonov        CV_HEADERS,
4350aadb33SDmitri Tikhonov        CV_SETTINGS,
4450aadb33SDmitri Tikhonov        CV_PUSH_PROMISE,
4550aadb33SDmitri Tikhonov        CV_PRIORITY,
4650aadb33SDmitri Tikhonov        CV_ERROR,
4750aadb33SDmitri Tikhonov    }                                   type;
4850aadb33SDmitri Tikhonov    unsigned                            stream_off; /* Checked only if not zero */
4950aadb33SDmitri Tikhonov    union {
503b55e6aeSDmitri Tikhonov        struct headers {
513b55e6aeSDmitri Tikhonov            uint32_t                stream_id;
523b55e6aeSDmitri Tikhonov            uint32_t                oth_stream_id;
533b55e6aeSDmitri Tikhonov            unsigned short          weight;
543b55e6aeSDmitri Tikhonov            signed char             exclusive;
553b55e6aeSDmitri Tikhonov            unsigned char           flags;
563b55e6aeSDmitri Tikhonov            unsigned                size;
573b55e6aeSDmitri Tikhonov            unsigned                off;
583b55e6aeSDmitri Tikhonov            char                    buf[0x100];
593b55e6aeSDmitri Tikhonov        }                               headers;
6050aadb33SDmitri Tikhonov        struct {
6150aadb33SDmitri Tikhonov            uint16_t                    id;
6250aadb33SDmitri Tikhonov            uint32_t                    value;
6350aadb33SDmitri Tikhonov        }                               setting;
6450aadb33SDmitri Tikhonov        void                           *push_promise;
6550aadb33SDmitri Tikhonov        struct cv_error {
6650aadb33SDmitri Tikhonov            enum frame_reader_error     code;
675392f7a3SLiteSpeed Tech            lsquic_stream_id_t          stream_id;
6850aadb33SDmitri Tikhonov        }                               error;
6950aadb33SDmitri Tikhonov        struct cv_priority {
705392f7a3SLiteSpeed Tech            lsquic_stream_id_t          stream_id;
7150aadb33SDmitri Tikhonov            int                         exclusive;
725392f7a3SLiteSpeed Tech            lsquic_stream_id_t          dep_stream_id;
7350aadb33SDmitri Tikhonov            unsigned                    weight;
7450aadb33SDmitri Tikhonov        }                               priority;
7550aadb33SDmitri Tikhonov    }                                   u;
7650aadb33SDmitri Tikhonov};
7750aadb33SDmitri Tikhonov
7850aadb33SDmitri Tikhonov
7950aadb33SDmitri Tikhonovvoid
803b55e6aeSDmitri Tikhonovcompare_headers (const struct headers *got_h, const struct headers *exp_h)
8150aadb33SDmitri Tikhonov{
823b55e6aeSDmitri Tikhonov    assert(got_h->stream_id == exp_h->stream_id);
833b55e6aeSDmitri Tikhonov    assert(got_h->oth_stream_id == exp_h->oth_stream_id);
843b55e6aeSDmitri Tikhonov    assert(got_h->weight == exp_h->weight);
853b55e6aeSDmitri Tikhonov    assert(got_h->exclusive == exp_h->exclusive);
863b55e6aeSDmitri Tikhonov    assert(got_h->size == exp_h->size);
873b55e6aeSDmitri Tikhonov    assert(strlen(got_h->buf) == got_h->size);
883b55e6aeSDmitri Tikhonov    assert(got_h->off == exp_h->off);
893b55e6aeSDmitri Tikhonov    assert(got_h->flags == exp_h->flags);
903b55e6aeSDmitri Tikhonov    assert(0 == memcmp(got_h->buf, exp_h->buf, got_h->size));
9150aadb33SDmitri Tikhonov}
9250aadb33SDmitri Tikhonov
9350aadb33SDmitri Tikhonov
9450aadb33SDmitri Tikhonovvoid
953b55e6aeSDmitri Tikhonovcompare_push_promises (const struct headers *got_h, const struct headers *exp_h)
9650aadb33SDmitri Tikhonov{
973b55e6aeSDmitri Tikhonov    assert(got_h->stream_id == exp_h->stream_id);
983b55e6aeSDmitri Tikhonov    assert(got_h->oth_stream_id == exp_h->oth_stream_id);
993b55e6aeSDmitri Tikhonov    assert(got_h->size == exp_h->size);
1003b55e6aeSDmitri Tikhonov    assert(strlen(got_h->buf) == got_h->size);
1013b55e6aeSDmitri Tikhonov    assert(got_h->off == exp_h->off);
1023b55e6aeSDmitri Tikhonov    assert(got_h->flags == exp_h->flags);
1033b55e6aeSDmitri Tikhonov    assert(0 == memcmp(got_h->buf, exp_h->buf, got_h->size));
10450aadb33SDmitri Tikhonov}
10550aadb33SDmitri Tikhonov
10650aadb33SDmitri Tikhonov
10750aadb33SDmitri Tikhonovvoid
10850aadb33SDmitri Tikhonovcompare_priorities (const struct cv_priority *got_prio,
10950aadb33SDmitri Tikhonov                    const struct cv_priority *exp_prio)
11050aadb33SDmitri Tikhonov{
11150aadb33SDmitri Tikhonov    assert(got_prio->stream_id      == exp_prio->stream_id);
11250aadb33SDmitri Tikhonov    assert(got_prio->exclusive      == exp_prio->exclusive);
11350aadb33SDmitri Tikhonov    assert(got_prio->dep_stream_id  == exp_prio->dep_stream_id);
11450aadb33SDmitri Tikhonov    assert(got_prio->weight         == exp_prio->weight);
11550aadb33SDmitri Tikhonov}
11650aadb33SDmitri Tikhonov
11750aadb33SDmitri Tikhonov
11850aadb33SDmitri Tikhonovvoid
11950aadb33SDmitri Tikhonovcompare_errors (const struct cv_error *got_err,
12050aadb33SDmitri Tikhonov                const struct cv_error *exp_err)
12150aadb33SDmitri Tikhonov{
12250aadb33SDmitri Tikhonov    assert(got_err->code == exp_err->code);
12350aadb33SDmitri Tikhonov    assert(got_err->stream_id == exp_err->stream_id);
12450aadb33SDmitri Tikhonov}
12550aadb33SDmitri Tikhonov
12650aadb33SDmitri Tikhonov
12750aadb33SDmitri Tikhonovstatic void
12850aadb33SDmitri Tikhonovcompare_cb_vals (const struct callback_value *got,
12950aadb33SDmitri Tikhonov                 const struct callback_value *exp)
13050aadb33SDmitri Tikhonov{
13150aadb33SDmitri Tikhonov    assert(got->type == exp->type);
13250aadb33SDmitri Tikhonov    if (exp->stream_off)
13350aadb33SDmitri Tikhonov        assert(exp->stream_off == got->stream_off);
13450aadb33SDmitri Tikhonov    switch (got->type)
13550aadb33SDmitri Tikhonov    {
13650aadb33SDmitri Tikhonov    case CV_HEADERS:
1373b55e6aeSDmitri Tikhonov        compare_headers(&got->u.headers, &exp->u.headers);
13850aadb33SDmitri Tikhonov        break;
13950aadb33SDmitri Tikhonov    case CV_PUSH_PROMISE:
1403b55e6aeSDmitri Tikhonov        compare_push_promises(&got->u.headers, &exp->u.headers);
14150aadb33SDmitri Tikhonov        break;
14250aadb33SDmitri Tikhonov    case CV_ERROR:
14350aadb33SDmitri Tikhonov        compare_errors(&got->u.error, &exp->u.error);
14450aadb33SDmitri Tikhonov        break;
14550aadb33SDmitri Tikhonov    case CV_PRIORITY:
14650aadb33SDmitri Tikhonov        compare_priorities(&got->u.priority, &exp->u.priority);
14750aadb33SDmitri Tikhonov        break;
14850aadb33SDmitri Tikhonov    case CV_SETTINGS:
14950aadb33SDmitri Tikhonov        /* TODO */
15050aadb33SDmitri Tikhonov        break;
15150aadb33SDmitri Tikhonov    }
15250aadb33SDmitri Tikhonov}
15350aadb33SDmitri Tikhonov
15450aadb33SDmitri Tikhonov
15550aadb33SDmitri Tikhonovstatic struct {
15650aadb33SDmitri Tikhonov    size_t          in_sz;
15750aadb33SDmitri Tikhonov    size_t          in_off;
15850aadb33SDmitri Tikhonov    size_t          in_max_req_sz;
15950aadb33SDmitri Tikhonov    size_t          in_max_sz;
16050aadb33SDmitri Tikhonov    unsigned char   in_buf[0x1000];
16150aadb33SDmitri Tikhonov} input;
16250aadb33SDmitri Tikhonov
16350aadb33SDmitri Tikhonov
16450aadb33SDmitri Tikhonovstatic struct cb_ctx {
16550aadb33SDmitri Tikhonov    unsigned                n_cb_vals;
16650aadb33SDmitri Tikhonov    struct callback_value   cb_vals[10];
16750aadb33SDmitri Tikhonov} g_cb_ctx;
16850aadb33SDmitri Tikhonov
16950aadb33SDmitri Tikhonov
17050aadb33SDmitri Tikhonovstatic void
17150aadb33SDmitri Tikhonovreset_cb_ctx (struct cb_ctx *cb_ctx)
17250aadb33SDmitri Tikhonov{
17350aadb33SDmitri Tikhonov    cb_ctx->n_cb_vals = 0;
17450aadb33SDmitri Tikhonov    memset(&cb_ctx->cb_vals, 0xA5, sizeof(cb_ctx->cb_vals));
17550aadb33SDmitri Tikhonov}
17650aadb33SDmitri Tikhonov
17750aadb33SDmitri Tikhonov
1783b55e6aeSDmitri Tikhonovstatic void
1793b55e6aeSDmitri Tikhonovcopy_uh_to_headers (const struct uncompressed_headers *uh, struct headers *h)
18050aadb33SDmitri Tikhonov{
1813b55e6aeSDmitri Tikhonov    const struct http1x_headers *h1h = uh->uh_hset;
1823b55e6aeSDmitri Tikhonov    h->flags = uh->uh_flags;
1833b55e6aeSDmitri Tikhonov    h->weight = uh->uh_weight;
1843b55e6aeSDmitri Tikhonov    h->stream_id = uh->uh_stream_id;
1853b55e6aeSDmitri Tikhonov    h->exclusive = uh->uh_exclusive;
1863b55e6aeSDmitri Tikhonov    h->oth_stream_id = uh->uh_oth_stream_id;
1873b55e6aeSDmitri Tikhonov    h->size = h1h->h1h_size;
1883b55e6aeSDmitri Tikhonov    h->off = h1h->h1h_off;
1893b55e6aeSDmitri Tikhonov    memcpy(h->buf, h1h->h1h_buf, h->size);
1903b55e6aeSDmitri Tikhonov    h->buf[h->size] = '\0';
19150aadb33SDmitri Tikhonov}
19250aadb33SDmitri Tikhonov
19350aadb33SDmitri Tikhonov
19450aadb33SDmitri Tikhonovstatic void
19550aadb33SDmitri Tikhonovon_incoming_headers (void *ctx, struct uncompressed_headers *uh)
19650aadb33SDmitri Tikhonov{
19750aadb33SDmitri Tikhonov    struct cb_ctx *cb_ctx = ctx;
19850aadb33SDmitri Tikhonov    assert(cb_ctx == &g_cb_ctx);
19950aadb33SDmitri Tikhonov    unsigned i = cb_ctx->n_cb_vals++;
20050aadb33SDmitri Tikhonov    assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0]));
20150aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].type = CV_HEADERS;
20250aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].stream_off = input.in_off;
2033b55e6aeSDmitri Tikhonov    copy_uh_to_headers(uh, &cb_ctx->cb_vals[i].u.headers);
2043b55e6aeSDmitri Tikhonov    assert(uh->uh_flags & UH_H1H);
2053b55e6aeSDmitri Tikhonov    lsquic_http1x_if->hsi_discard_header_set(uh->uh_hset);
20650aadb33SDmitri Tikhonov    free(uh);
20750aadb33SDmitri Tikhonov}
20850aadb33SDmitri Tikhonov
20950aadb33SDmitri Tikhonov
21050aadb33SDmitri Tikhonovstatic void
21150aadb33SDmitri Tikhonovon_push_promise (void *ctx, struct uncompressed_headers *uh)
21250aadb33SDmitri Tikhonov{
21350aadb33SDmitri Tikhonov    struct cb_ctx *cb_ctx = ctx;
21450aadb33SDmitri Tikhonov    assert(cb_ctx == &g_cb_ctx);
21550aadb33SDmitri Tikhonov    unsigned i = cb_ctx->n_cb_vals++;
21650aadb33SDmitri Tikhonov    assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0]));
21750aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].type = CV_PUSH_PROMISE;
21850aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].stream_off = input.in_off;
2193b55e6aeSDmitri Tikhonov    copy_uh_to_headers(uh, &cb_ctx->cb_vals[i].u.headers);
2203b55e6aeSDmitri Tikhonov    assert(uh->uh_flags & UH_H1H);
2213b55e6aeSDmitri Tikhonov    lsquic_http1x_if->hsi_discard_header_set(uh->uh_hset);
22250aadb33SDmitri Tikhonov    free(uh);
22350aadb33SDmitri Tikhonov}
22450aadb33SDmitri Tikhonov
22550aadb33SDmitri Tikhonov
22650aadb33SDmitri Tikhonovstatic void
2275392f7a3SLiteSpeed Techon_error (void *ctx, lsquic_stream_id_t stream_id, enum frame_reader_error error)
22850aadb33SDmitri Tikhonov{
22950aadb33SDmitri Tikhonov    struct cb_ctx *cb_ctx = ctx;
23050aadb33SDmitri Tikhonov    assert(cb_ctx == &g_cb_ctx);
23150aadb33SDmitri Tikhonov    unsigned i = cb_ctx->n_cb_vals++;
23250aadb33SDmitri Tikhonov    assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0]));
23350aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].type = CV_ERROR;
23450aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.error.stream_id = stream_id;
23550aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.error.code = error;
23650aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].stream_off = input.in_off;
23750aadb33SDmitri Tikhonov}
23850aadb33SDmitri Tikhonov
23950aadb33SDmitri Tikhonov
24050aadb33SDmitri Tikhonovstatic void
24150aadb33SDmitri Tikhonovon_settings (void *ctx, uint16_t id, uint32_t value)
24250aadb33SDmitri Tikhonov{
24350aadb33SDmitri Tikhonov    struct cb_ctx *cb_ctx = ctx;
24450aadb33SDmitri Tikhonov    assert(cb_ctx == &g_cb_ctx);
24550aadb33SDmitri Tikhonov    unsigned i = cb_ctx->n_cb_vals++;
24650aadb33SDmitri Tikhonov    assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0]));
24750aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].type = CV_SETTINGS;
24850aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.setting.id = id;
24950aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.setting.value = value;
25050aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].stream_off = input.in_off;
25150aadb33SDmitri Tikhonov}
25250aadb33SDmitri Tikhonov
25350aadb33SDmitri Tikhonov
25450aadb33SDmitri Tikhonovstatic void
2555392f7a3SLiteSpeed Techon_priority (void *ctx, lsquic_stream_id_t stream_id, int exclusive,
2565392f7a3SLiteSpeed Tech             lsquic_stream_id_t dep_stream_id, unsigned weight)
25750aadb33SDmitri Tikhonov{
25850aadb33SDmitri Tikhonov    struct cb_ctx *cb_ctx = ctx;
25950aadb33SDmitri Tikhonov    assert(cb_ctx == &g_cb_ctx);
26050aadb33SDmitri Tikhonov    unsigned i = cb_ctx->n_cb_vals++;
26150aadb33SDmitri Tikhonov    assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0]));
26250aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].type = CV_PRIORITY;
26350aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.priority.stream_id     = stream_id;
26450aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.priority.exclusive     = exclusive;
26550aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.priority.dep_stream_id = dep_stream_id;
26650aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].u.priority.weight        = weight;
26750aadb33SDmitri Tikhonov    cb_ctx->cb_vals[i].stream_off = input.in_off;
26850aadb33SDmitri Tikhonov}
26950aadb33SDmitri Tikhonov
27050aadb33SDmitri Tikhonov
27150aadb33SDmitri Tikhonovstatic const struct frame_reader_callbacks frame_callbacks = {
27250aadb33SDmitri Tikhonov    .frc_on_headers      = on_incoming_headers,
27350aadb33SDmitri Tikhonov    .frc_on_push_promise = on_push_promise,
27450aadb33SDmitri Tikhonov    .frc_on_settings     = on_settings,
27550aadb33SDmitri Tikhonov    .frc_on_priority     = on_priority,
27650aadb33SDmitri Tikhonov    .frc_on_error        = on_error,
27750aadb33SDmitri Tikhonov};
27850aadb33SDmitri Tikhonov
27950aadb33SDmitri Tikhonov
28050aadb33SDmitri Tikhonovstatic ssize_t
28150aadb33SDmitri Tikhonovread_from_stream (struct lsquic_stream *stream, void *buf, size_t sz)
28250aadb33SDmitri Tikhonov{
28350aadb33SDmitri Tikhonov    if (sz > input.in_max_req_sz)
28450aadb33SDmitri Tikhonov        input.in_max_req_sz = sz;
28550aadb33SDmitri Tikhonov    if (input.in_sz - input.in_off < sz)
28650aadb33SDmitri Tikhonov        sz = input.in_sz - input.in_off;
28750aadb33SDmitri Tikhonov    if (sz > input.in_max_sz)
28850aadb33SDmitri Tikhonov        sz = input.in_max_sz;
28950aadb33SDmitri Tikhonov    memcpy(buf, input.in_buf + input.in_off, sz);
29050aadb33SDmitri Tikhonov    input.in_off += sz;
29150aadb33SDmitri Tikhonov    return sz;
29250aadb33SDmitri Tikhonov}
29350aadb33SDmitri Tikhonov
29450aadb33SDmitri Tikhonov
29550aadb33SDmitri Tikhonovstruct frame_reader_test {
29650aadb33SDmitri Tikhonov    unsigned                        frt_lineno;
29750aadb33SDmitri Tikhonov    /* Input */
29850aadb33SDmitri Tikhonov    enum frame_reader_flags         frt_fr_flags;
29950aadb33SDmitri Tikhonov    unsigned char                   frt_buf[0x100];
30050aadb33SDmitri Tikhonov    unsigned short                  frt_bufsz;
30150aadb33SDmitri Tikhonov    unsigned                        frt_max_headers_sz;
30250aadb33SDmitri Tikhonov    /* Output */
30350aadb33SDmitri Tikhonov    unsigned short                  frt_in_off;
30450aadb33SDmitri Tikhonov    int                             frt_err;      /* True if expecting error */
30550aadb33SDmitri Tikhonov    unsigned                        frt_n_cb_vals;
30650aadb33SDmitri Tikhonov    struct callback_value           frt_cb_vals[10];
30750aadb33SDmitri Tikhonov};
30850aadb33SDmitri Tikhonov
30950aadb33SDmitri Tikhonov
3103b55e6aeSDmitri Tikhonov#define HEADERS(str) .buf = (str), .size = sizeof(str) - 1
31150aadb33SDmitri Tikhonov
31250aadb33SDmitri Tikhonovstatic const struct frame_reader_test tests[] = {
31350aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
31450aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
31550aadb33SDmitri Tikhonov        .frt_buf    = {
31650aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x04,
31750aadb33SDmitri Tikhonov            /* Type: */         0x01,
31850aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
31950aadb33SDmitri Tikhonov                            0x80|           /* <----- This bit must be ignored */
32050aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
32150aadb33SDmitri Tikhonov            /* Block fragment: */
32250aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
32350aadb33SDmitri Tikhonov        },
32450aadb33SDmitri Tikhonov        .frt_bufsz  = 13,
32550aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
32650aadb33SDmitri Tikhonov        .frt_cb_vals = {
32750aadb33SDmitri Tikhonov            {
32850aadb33SDmitri Tikhonov                .type = CV_HEADERS,
3293b55e6aeSDmitri Tikhonov                .u.headers = {
3303b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
3313b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0,
3323b55e6aeSDmitri Tikhonov                    .weight          = 0,
3333b55e6aeSDmitri Tikhonov                    .exclusive       = -1,
3343b55e6aeSDmitri Tikhonov                    .off             = 0,
3353b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
3363b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n\r\n"),
33750aadb33SDmitri Tikhonov                },
33850aadb33SDmitri Tikhonov            },
33950aadb33SDmitri Tikhonov        },
34050aadb33SDmitri Tikhonov    },
34150aadb33SDmitri Tikhonov
34250aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
34350aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
34450aadb33SDmitri Tikhonov        .frt_buf    = {
34550aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x16,
34650aadb33SDmitri Tikhonov            /* Type: */         0x01,
34750aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PADDED,
34850aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
34950aadb33SDmitri Tikhonov            /* Padding length */0x11,
35050aadb33SDmitri Tikhonov            /* Block fragment: */
35150aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
35250aadb33SDmitri Tikhonov            /* Padding: */      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
35350aadb33SDmitri Tikhonov                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
35450aadb33SDmitri Tikhonov                                0xFF,
35550aadb33SDmitri Tikhonov        },
35650aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 1 + 4 + 17,
35750aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
35850aadb33SDmitri Tikhonov        .frt_cb_vals = {
35950aadb33SDmitri Tikhonov            {
36050aadb33SDmitri Tikhonov                .type = CV_HEADERS,
3613b55e6aeSDmitri Tikhonov                .u.headers = {
3623b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
3633b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0,
3643b55e6aeSDmitri Tikhonov                    .weight          = 0,
3653b55e6aeSDmitri Tikhonov                    .exclusive       = -1,
3663b55e6aeSDmitri Tikhonov                    .off             = 0,
3673b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
3683b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n\r\n"),
36950aadb33SDmitri Tikhonov                },
37050aadb33SDmitri Tikhonov            },
37150aadb33SDmitri Tikhonov        },
37250aadb33SDmitri Tikhonov    },
37350aadb33SDmitri Tikhonov
37450aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
37550aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
37650aadb33SDmitri Tikhonov        .frt_buf    = {
37750aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x1B,
37850aadb33SDmitri Tikhonov            /* Type: */         0x01,
37950aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PADDED|HFHF_PRIORITY|
38050aadb33SDmitri Tikhonov                                                            HFHF_END_STREAM,
38150aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
38250aadb33SDmitri Tikhonov            /* Padding length */0x11,
38350aadb33SDmitri Tikhonov            /* Exclusive: */    0x80|
38450aadb33SDmitri Tikhonov            /* Dep Stream Id: */
38550aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
38650aadb33SDmitri Tikhonov            /* Weight: */       0xFF,
38750aadb33SDmitri Tikhonov            /* Block fragment: */
38850aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
38950aadb33SDmitri Tikhonov            /* Padding: */      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
39050aadb33SDmitri Tikhonov                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
39150aadb33SDmitri Tikhonov                                0xFF,
39250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x05,
39350aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_PRIORITY,
39450aadb33SDmitri Tikhonov            /* Flags: */        0x00,
39550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x39,
39650aadb33SDmitri Tikhonov            /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19,
39750aadb33SDmitri Tikhonov            /* Weight: */       0x77,
39850aadb33SDmitri Tikhonov        },
39950aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 1 + 5 + 4 + 17
40050aadb33SDmitri Tikhonov                    + 9 + 5,
40150aadb33SDmitri Tikhonov        .frt_n_cb_vals = 2,
40250aadb33SDmitri Tikhonov        .frt_cb_vals = {
40350aadb33SDmitri Tikhonov            {
40450aadb33SDmitri Tikhonov                .type = CV_HEADERS,
4053b55e6aeSDmitri Tikhonov                .u.headers = {
4063b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
4073b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
4083b55e6aeSDmitri Tikhonov                    .weight          = 0xFF + 1,
4093b55e6aeSDmitri Tikhonov                    .exclusive       = 1,
4103b55e6aeSDmitri Tikhonov                    .off             = 0,
4113b55e6aeSDmitri Tikhonov                    .flags           = UH_FIN | UH_H1H,
4123b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n\r\n"),
41350aadb33SDmitri Tikhonov                },
41450aadb33SDmitri Tikhonov            },
41550aadb33SDmitri Tikhonov            {
41650aadb33SDmitri Tikhonov                .type = CV_PRIORITY,
41750aadb33SDmitri Tikhonov                .u.priority = {
41850aadb33SDmitri Tikhonov                    .stream_id      = 0x39,
41950aadb33SDmitri Tikhonov                    .exclusive      = 1,
42050aadb33SDmitri Tikhonov                    .dep_stream_id  = 0x19,
42150aadb33SDmitri Tikhonov                    .weight         = 0x77 + 1,
42250aadb33SDmitri Tikhonov                },
42350aadb33SDmitri Tikhonov            },
42450aadb33SDmitri Tikhonov        },
42550aadb33SDmitri Tikhonov    },
42650aadb33SDmitri Tikhonov
42750aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
42850aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
42950aadb33SDmitri Tikhonov        .frt_buf    = {
43050aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x09,
43150aadb33SDmitri Tikhonov            /* Type: */         0x01,
43250aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
43350aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
43450aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
43550aadb33SDmitri Tikhonov            /* Dep Stream Id: */
43650aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
43750aadb33SDmitri Tikhonov            /* Weight: */       0x00,
43850aadb33SDmitri Tikhonov            /* Block fragment: */
43950aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
44050aadb33SDmitri Tikhonov        },
44150aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 4,
44250aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
44350aadb33SDmitri Tikhonov        .frt_cb_vals = {
44450aadb33SDmitri Tikhonov            {
44550aadb33SDmitri Tikhonov                .type = CV_HEADERS,
4463b55e6aeSDmitri Tikhonov                .u.headers = {
4473b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
4483b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
4493b55e6aeSDmitri Tikhonov                    .weight          = 1,
4503b55e6aeSDmitri Tikhonov                    .exclusive       = 0,
4513b55e6aeSDmitri Tikhonov                    .off             = 0,
4523b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
4533b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n\r\n"),
45450aadb33SDmitri Tikhonov                },
45550aadb33SDmitri Tikhonov            },
45650aadb33SDmitri Tikhonov        },
45750aadb33SDmitri Tikhonov    },
45850aadb33SDmitri Tikhonov
45950aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
46050aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
46150aadb33SDmitri Tikhonov        .frt_buf    = {
46250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x0E,
46350aadb33SDmitri Tikhonov            /* Type: */         0x01,
46450aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
46550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
46650aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
46750aadb33SDmitri Tikhonov            /* Dep Stream Id: */
46850aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
46950aadb33SDmitri Tikhonov            /* Weight: */       0x00,
47050aadb33SDmitri Tikhonov            /* Block fragment: */
47150aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
47250aadb33SDmitri Tikhonov                                0x60, 0x03, 0x61, 0x3d, 0x62,
47350aadb33SDmitri Tikhonov        },
47450aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 4 + 5,
47550aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
47650aadb33SDmitri Tikhonov        .frt_cb_vals = {
47750aadb33SDmitri Tikhonov            {
47850aadb33SDmitri Tikhonov                .type = CV_HEADERS,
4793b55e6aeSDmitri Tikhonov                .u.headers = {
4803b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
4813b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
4823b55e6aeSDmitri Tikhonov                    .weight          = 1,
4833b55e6aeSDmitri Tikhonov                    .exclusive       = 0,
4843b55e6aeSDmitri Tikhonov                    .off             = 0,
4853b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
4863b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n"
48750aadb33SDmitri Tikhonov                               "Cookie: a=b\r\n\r\n"),
48850aadb33SDmitri Tikhonov                },
48950aadb33SDmitri Tikhonov            },
49050aadb33SDmitri Tikhonov        },
49150aadb33SDmitri Tikhonov    },
49250aadb33SDmitri Tikhonov
49350aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
49450aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
49550aadb33SDmitri Tikhonov        .frt_buf    = {
49650aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x18,
49750aadb33SDmitri Tikhonov            /* Type: */         0x01,
49850aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
49950aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
50050aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
50150aadb33SDmitri Tikhonov            /* Dep Stream Id: */
50250aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
50350aadb33SDmitri Tikhonov            /* Weight: */       0x00,
50450aadb33SDmitri Tikhonov            /* Block fragment: */
50550aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
50650aadb33SDmitri Tikhonov                                0x60, 0x03, 0x61, 0x3d, 0x62,
50750aadb33SDmitri Tikhonov                                0x60, 0x03, 0x63, 0x3d, 0x64,
50850aadb33SDmitri Tikhonov                                0x60, 0x03, 0x65, 0x3d, 0x66,
50950aadb33SDmitri Tikhonov        },
51050aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 4 + 15,
51150aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
51250aadb33SDmitri Tikhonov        .frt_cb_vals = {
51350aadb33SDmitri Tikhonov            {
51450aadb33SDmitri Tikhonov                .type = CV_HEADERS,
5153b55e6aeSDmitri Tikhonov                .u.headers = {
5163b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
5173b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
5183b55e6aeSDmitri Tikhonov                    .weight          = 1,
5193b55e6aeSDmitri Tikhonov                    .exclusive       = 0,
5203b55e6aeSDmitri Tikhonov                    .off             = 0,
5213b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
5223b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n"
52350aadb33SDmitri Tikhonov                               "Cookie: a=b; c=d; e=f\r\n\r\n"),
52450aadb33SDmitri Tikhonov                },
52550aadb33SDmitri Tikhonov            },
52650aadb33SDmitri Tikhonov        },
52750aadb33SDmitri Tikhonov    },
52850aadb33SDmitri Tikhonov
52950aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
53050aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
53150aadb33SDmitri Tikhonov        .frt_buf    = {
53250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x16,
53350aadb33SDmitri Tikhonov            /* Type: */         0x01,
53450aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
53550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
53650aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
53750aadb33SDmitri Tikhonov            /* Dep Stream Id: */
53850aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
53950aadb33SDmitri Tikhonov            /* Weight: */       0x00,
54050aadb33SDmitri Tikhonov            /* Block fragment: */
54150aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2,
54250aadb33SDmitri Tikhonov                                0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4,
54350aadb33SDmitri Tikhonov                                0xff,
54450aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0xEE,
54550aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
54650aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
54750aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
54850aadb33SDmitri Tikhonov            /* Block fragment: */
54950aadb33SDmitri Tikhonov                                'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R',
55050aadb33SDmitri Tikhonov        },
55150aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 17
55250aadb33SDmitri Tikhonov                    + 9 + 0 + 8,
55350aadb33SDmitri Tikhonov        .frt_err = 1,
55450aadb33SDmitri Tikhonov        .frt_in_off = 9 + 5 + 17 + 9,
55550aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
55650aadb33SDmitri Tikhonov        .frt_cb_vals = {
55750aadb33SDmitri Tikhonov            {
55850aadb33SDmitri Tikhonov                .type = CV_HEADERS,
5593b55e6aeSDmitri Tikhonov                .u.headers = {
5603b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
5613b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
5623b55e6aeSDmitri Tikhonov                    .weight          = 1,
5633b55e6aeSDmitri Tikhonov                    .exclusive       = 0,
5643b55e6aeSDmitri Tikhonov                    .off             = 0,
5653b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
5663b55e6aeSDmitri Tikhonov                    HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"),
56750aadb33SDmitri Tikhonov                },
56850aadb33SDmitri Tikhonov            },
56950aadb33SDmitri Tikhonov        },
57050aadb33SDmitri Tikhonov    },
57150aadb33SDmitri Tikhonov
57250aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
57350aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
57450aadb33SDmitri Tikhonov        .frt_buf    = {
57550aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x16,
57650aadb33SDmitri Tikhonov            /* Type: */         0x01,
57750aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
57850aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
57950aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
58050aadb33SDmitri Tikhonov            /* Dep Stream Id: */
58150aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
58250aadb33SDmitri Tikhonov            /* Weight: */       0x00,
58350aadb33SDmitri Tikhonov            /* Block fragment: */
58450aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2,
58550aadb33SDmitri Tikhonov                                0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4,
58650aadb33SDmitri Tikhonov                                0xff,
58750aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0xEE,
58850aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
58950aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
59050aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
59150aadb33SDmitri Tikhonov            /* Block fragment: */
59250aadb33SDmitri Tikhonov                                'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R',
59350aadb33SDmitri Tikhonov        },
59450aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 17
59550aadb33SDmitri Tikhonov                    + 9 + 0 + 8,
59650aadb33SDmitri Tikhonov        .frt_err = 1,
59750aadb33SDmitri Tikhonov        .frt_in_off = 9 + 5 + 17 + 9,
59850aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
59950aadb33SDmitri Tikhonov        .frt_cb_vals = {
60050aadb33SDmitri Tikhonov            {
60150aadb33SDmitri Tikhonov                .type = CV_HEADERS,
6023b55e6aeSDmitri Tikhonov                .u.headers = {
6033b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
6043b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x1234,
6053b55e6aeSDmitri Tikhonov                    .weight          = 1,
6063b55e6aeSDmitri Tikhonov                    .exclusive       = 0,
6073b55e6aeSDmitri Tikhonov                    .off             = 0,
6083b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
6093b55e6aeSDmitri Tikhonov                    HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"),
61050aadb33SDmitri Tikhonov                },
61150aadb33SDmitri Tikhonov            },
61250aadb33SDmitri Tikhonov        },
61350aadb33SDmitri Tikhonov    },
61450aadb33SDmitri Tikhonov
61550aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
61650aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
61750aadb33SDmitri Tikhonov        .frt_buf    = {
61850aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x16,
61950aadb33SDmitri Tikhonov            /* Type: */         0x01,
62050aadb33SDmitri Tikhonov            /* Flags: */        HFHF_PRIORITY,
62150aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
62250aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
62350aadb33SDmitri Tikhonov            /* Dep Stream Id: */
62450aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
62550aadb33SDmitri Tikhonov            /* Weight: */       0x00,
62650aadb33SDmitri Tikhonov            /* Block fragment: */
62750aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2,
62850aadb33SDmitri Tikhonov                                0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4,
62950aadb33SDmitri Tikhonov                                0xff,
63050aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0xEE,
63150aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
63250aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
63350aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0xFF, 0x30, 0x39, /* Stream ID does not match */
63450aadb33SDmitri Tikhonov            /* Block fragment: */
63550aadb33SDmitri Tikhonov                                'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R',
63650aadb33SDmitri Tikhonov        },
63750aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 17
63850aadb33SDmitri Tikhonov                    + 9 + 0 + 8,
63950aadb33SDmitri Tikhonov        .frt_err = 1,
64050aadb33SDmitri Tikhonov        .frt_in_off = 9 + 5 + 17 + 9,
64150aadb33SDmitri Tikhonov        .frt_n_cb_vals = 0,
64250aadb33SDmitri Tikhonov    },
64350aadb33SDmitri Tikhonov
64450aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
64550aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
64650aadb33SDmitri Tikhonov        .frt_buf    = {
64750aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0xEE,
64850aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
64950aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
65050aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
65150aadb33SDmitri Tikhonov            /* Block fragment: */
65250aadb33SDmitri Tikhonov                                'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R',
65350aadb33SDmitri Tikhonov        },
65450aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 8,
65550aadb33SDmitri Tikhonov        .frt_err = 1,
65650aadb33SDmitri Tikhonov        .frt_in_off = 9,
65750aadb33SDmitri Tikhonov        .frt_n_cb_vals = 0,
65850aadb33SDmitri Tikhonov    },
65950aadb33SDmitri Tikhonov
66050aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
66150aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
66250aadb33SDmitri Tikhonov        .frt_buf    = {
66350aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x10,
66450aadb33SDmitri Tikhonov            /* Type: */         0x01,
66550aadb33SDmitri Tikhonov            /* Flags: */        0x00,   /* Note absence of HFHF_END_HEADERS */
66650aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
66750aadb33SDmitri Tikhonov            /* Block fragment:
66850aadb33SDmitri Tikhonov             *   perl hpack.pl :method GET :path / host www.example.com
66950aadb33SDmitri Tikhonov             */
67050aadb33SDmitri Tikhonov                                0x82, 0x84, 0x66, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5,
67150aadb33SDmitri Tikhonov                                0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff,
67250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x08,
67350aadb33SDmitri Tikhonov            /* Type: */         0x01,
67450aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
67550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
67650aadb33SDmitri Tikhonov            /* Block fragment: */
67750aadb33SDmitri Tikhonov                                'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R',
67850aadb33SDmitri Tikhonov        },
67950aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 16
68050aadb33SDmitri Tikhonov                    + 9 + 0 + 8,
68150aadb33SDmitri Tikhonov        .frt_in_off = 9 + 16 + 9,
68250aadb33SDmitri Tikhonov        .frt_err = 1,
68350aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
68450aadb33SDmitri Tikhonov        .frt_cb_vals = {
68550aadb33SDmitri Tikhonov            {
68650aadb33SDmitri Tikhonov                .type = CV_ERROR,
68750aadb33SDmitri Tikhonov                .u.error = {
68850aadb33SDmitri Tikhonov                    .stream_id  = 0x3039,
68950aadb33SDmitri Tikhonov                    .code       = FR_ERR_EXPECTED_CONTIN,
69050aadb33SDmitri Tikhonov                },
69150aadb33SDmitri Tikhonov            },
69250aadb33SDmitri Tikhonov        },
69350aadb33SDmitri Tikhonov    },
69450aadb33SDmitri Tikhonov
69550aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
69650aadb33SDmitri Tikhonov        .frt_fr_flags = FRF_SERVER,
69750aadb33SDmitri Tikhonov        .frt_buf    = {
69850aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x10,
69950aadb33SDmitri Tikhonov            /* Type: */         0x01,
70050aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
70150aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
70250aadb33SDmitri Tikhonov            /* Block fragment:
70350aadb33SDmitri Tikhonov             *   perl hpack.pl :method GET :path / host www.example.com
70450aadb33SDmitri Tikhonov             */
70550aadb33SDmitri Tikhonov                                0x82, 0x84, 0x66, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5,
70650aadb33SDmitri Tikhonov                                0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff,
70750aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x1A,
70850aadb33SDmitri Tikhonov            /* Type: */         0x01,
70950aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
71050aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
71150aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
71250aadb33SDmitri Tikhonov            /* Dep Stream Id: */
71350aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
71450aadb33SDmitri Tikhonov            /* Weight: */       0x00,
71550aadb33SDmitri Tikhonov            /* Block fragment:
71650aadb33SDmitri Tikhonov             *   perl hpack.pl :method GET :path / :scheme http Host www.example.com
71750aadb33SDmitri Tikhonov             */
71850aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x40, 0x83, 0xc6, 0x74, 0x27,
71950aadb33SDmitri Tikhonov                                0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a, 0x6b,
72050aadb33SDmitri Tikhonov                                0xa0, 0xab, 0x90, 0xf4, 0xff,
72150aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x11,
72250aadb33SDmitri Tikhonov            /* Type: */         0x01,
72350aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
72450aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
72550aadb33SDmitri Tikhonov            /* Block fragment: */
72650aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2,
72750aadb33SDmitri Tikhonov                                0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4,
72850aadb33SDmitri Tikhonov                                0xff,
72950aadb33SDmitri Tikhonov        },
73050aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 16
73150aadb33SDmitri Tikhonov                    + 9 + 5 + 21
73250aadb33SDmitri Tikhonov                    + 9 + 0 + 17,
73350aadb33SDmitri Tikhonov        .frt_n_cb_vals = 3,
73450aadb33SDmitri Tikhonov        .frt_cb_vals = {
73550aadb33SDmitri Tikhonov            {
73650aadb33SDmitri Tikhonov                .type = CV_ERROR,
73750aadb33SDmitri Tikhonov                .u.error = {
73850aadb33SDmitri Tikhonov                    .stream_id  = 12345,
739a5fa05f9SDmitri Tikhonov                    .code       = FR_ERR_BAD_HEADER,
74050aadb33SDmitri Tikhonov                },
74150aadb33SDmitri Tikhonov            },
74250aadb33SDmitri Tikhonov            {
74350aadb33SDmitri Tikhonov                .type = CV_ERROR,
74450aadb33SDmitri Tikhonov                .u.error = {
74550aadb33SDmitri Tikhonov                    .stream_id  = 12345,
746a5fa05f9SDmitri Tikhonov                    .code       = FR_ERR_BAD_HEADER,
74750aadb33SDmitri Tikhonov                },
74850aadb33SDmitri Tikhonov            },
74950aadb33SDmitri Tikhonov            {
75050aadb33SDmitri Tikhonov                .type = CV_HEADERS,
7513b55e6aeSDmitri Tikhonov                .u.headers = {
7523b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
7533b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0,
7543b55e6aeSDmitri Tikhonov                    .weight          = 0,
7553b55e6aeSDmitri Tikhonov                    .exclusive       = -1,
7563b55e6aeSDmitri Tikhonov                    .off             = 0,
7573b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
7583b55e6aeSDmitri Tikhonov                    HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"),
75950aadb33SDmitri Tikhonov                },
76050aadb33SDmitri Tikhonov            },
76150aadb33SDmitri Tikhonov        },
76250aadb33SDmitri Tikhonov    },
76350aadb33SDmitri Tikhonov
76450aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
76550aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
76650aadb33SDmitri Tikhonov        .frt_buf    = {
76750aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x15,
76850aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_PUSH_PROMISE,
76950aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
77050aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
77150aadb33SDmitri Tikhonov            /* Dep stream Id: */0x00, 0x12, 0x34, 0x56,
77250aadb33SDmitri Tikhonov            /* Block fragment: */
77350aadb33SDmitri Tikhonov                                0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2,
77450aadb33SDmitri Tikhonov                                0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4,
77550aadb33SDmitri Tikhonov                                0xff,
77650aadb33SDmitri Tikhonov        },
77750aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 0x15,
77850aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
77950aadb33SDmitri Tikhonov        .frt_cb_vals = {
78050aadb33SDmitri Tikhonov            {
78150aadb33SDmitri Tikhonov                .type = CV_PUSH_PROMISE,
7823b55e6aeSDmitri Tikhonov                .u.headers = {
7833b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
7843b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0x123456,
7853b55e6aeSDmitri Tikhonov                    .flags           = UH_PP | UH_H1H,
7863b55e6aeSDmitri Tikhonov                    HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"),
78750aadb33SDmitri Tikhonov                },
78850aadb33SDmitri Tikhonov            },
78950aadb33SDmitri Tikhonov        },
79050aadb33SDmitri Tikhonov    },
79150aadb33SDmitri Tikhonov
79250aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
79350aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
79450aadb33SDmitri Tikhonov        .frt_buf    = {
79550aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x02,
79650aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_HEADERS,
79750aadb33SDmitri Tikhonov            /* Flags: */        0x00,
79850aadb33SDmitri Tikhonov                            0x80|           /* <----- This bit must be ignored */
79950aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
80050aadb33SDmitri Tikhonov            /* Block fragment: */
80150aadb33SDmitri Tikhonov                                0x48, 0x82,
80250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x02,
80350aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
80450aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
80550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
80650aadb33SDmitri Tikhonov            /* Block fragment: */
80750aadb33SDmitri Tikhonov                                0x64, 0x02,
80850aadb33SDmitri Tikhonov        },
80950aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 2 + 9 + 2,
81050aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
81150aadb33SDmitri Tikhonov        .frt_cb_vals = {
81250aadb33SDmitri Tikhonov            {
81350aadb33SDmitri Tikhonov                .type = CV_HEADERS,
8143b55e6aeSDmitri Tikhonov                .u.headers = {
8153b55e6aeSDmitri Tikhonov                    .stream_id       = 12345,
8163b55e6aeSDmitri Tikhonov                    .oth_stream_id   = 0,
8173b55e6aeSDmitri Tikhonov                    .weight          = 0,
8183b55e6aeSDmitri Tikhonov                    .exclusive       = -1,
8193b55e6aeSDmitri Tikhonov                    .off             = 0,
8203b55e6aeSDmitri Tikhonov                    .flags           = UH_H1H,
8213b55e6aeSDmitri Tikhonov                    HEADERS("HTTP/1.1 302 Found\r\n\r\n"),
82250aadb33SDmitri Tikhonov                },
82350aadb33SDmitri Tikhonov            },
82450aadb33SDmitri Tikhonov        },
82550aadb33SDmitri Tikhonov    },
82650aadb33SDmitri Tikhonov
82750aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
82850aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
82950aadb33SDmitri Tikhonov        .frt_buf    = {
83050aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x00,
83150aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
83250aadb33SDmitri Tikhonov            /* Flags: */        0x00,
83350aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
83450aadb33SDmitri Tikhonov        },
83550aadb33SDmitri Tikhonov        .frt_bufsz  = 9,
83650aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
83750aadb33SDmitri Tikhonov        .frt_err = 1,
83850aadb33SDmitri Tikhonov        .frt_cb_vals = {
83950aadb33SDmitri Tikhonov            {
84050aadb33SDmitri Tikhonov                .type = CV_ERROR,
84150aadb33SDmitri Tikhonov                .u.error.code = FR_ERR_INVALID_FRAME_SIZE,
84250aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
84350aadb33SDmitri Tikhonov            },
84450aadb33SDmitri Tikhonov        },
84550aadb33SDmitri Tikhonov    },
84650aadb33SDmitri Tikhonov
84750aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
84850aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
84950aadb33SDmitri Tikhonov        .frt_buf    = {
85050aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x07,
85150aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
85250aadb33SDmitri Tikhonov            /* Flags: */        0x00,
85350aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
85450aadb33SDmitri Tikhonov                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
85550aadb33SDmitri Tikhonov        },
85650aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 7,
85750aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
85850aadb33SDmitri Tikhonov        .frt_err = 1,
85950aadb33SDmitri Tikhonov        .frt_in_off = 9,
86050aadb33SDmitri Tikhonov        .frt_cb_vals = {
86150aadb33SDmitri Tikhonov            {
86250aadb33SDmitri Tikhonov                .type = CV_ERROR,
86350aadb33SDmitri Tikhonov                .u.error.code = FR_ERR_INVALID_FRAME_SIZE,
86450aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
86550aadb33SDmitri Tikhonov            },
86650aadb33SDmitri Tikhonov        },
86750aadb33SDmitri Tikhonov    },
86850aadb33SDmitri Tikhonov
86950aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
87050aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
87150aadb33SDmitri Tikhonov        .frt_buf    = {
87250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x06,
87350aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
87450aadb33SDmitri Tikhonov            /* Flags: */        0x00,
87550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
87650aadb33SDmitri Tikhonov                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
87750aadb33SDmitri Tikhonov        },
87850aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 6,
87950aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
88050aadb33SDmitri Tikhonov        .frt_err = 1,
88150aadb33SDmitri Tikhonov        .frt_in_off = 9,
88250aadb33SDmitri Tikhonov        .frt_cb_vals = {
88350aadb33SDmitri Tikhonov            {
88450aadb33SDmitri Tikhonov                .type = CV_ERROR,
88550aadb33SDmitri Tikhonov                .u.error.code = FR_ERR_NONZERO_STREAM_ID,
88650aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
88750aadb33SDmitri Tikhonov            },
88850aadb33SDmitri Tikhonov        },
88950aadb33SDmitri Tikhonov    },
89050aadb33SDmitri Tikhonov
89150aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
89250aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
89350aadb33SDmitri Tikhonov        .frt_buf    = {
89450aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x0C,
89550aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
89650aadb33SDmitri Tikhonov            /* Flags: */        0x00,
89750aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x00,
89850aadb33SDmitri Tikhonov                                0x00, SETTINGS_INITIAL_WINDOW_SIZE,
89950aadb33SDmitri Tikhonov                                0x01, 0x02, 0x03, 0x04,
90050aadb33SDmitri Tikhonov                                0x00, SETTINGS_HEADER_TABLE_SIZE,
90150aadb33SDmitri Tikhonov                                0x02, 0x03, 0x04, 0x05,
90250aadb33SDmitri Tikhonov        },
90350aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 12,
90450aadb33SDmitri Tikhonov        .frt_n_cb_vals = 2,
90550aadb33SDmitri Tikhonov        .frt_cb_vals = {
90650aadb33SDmitri Tikhonov            {
90750aadb33SDmitri Tikhonov                .type = CV_SETTINGS,
90850aadb33SDmitri Tikhonov                .u.setting.id    = SETTINGS_INITIAL_WINDOW_SIZE,
90950aadb33SDmitri Tikhonov                .u.setting.value = 0x01020304,
91050aadb33SDmitri Tikhonov            },
91150aadb33SDmitri Tikhonov            {
91250aadb33SDmitri Tikhonov                .type = CV_SETTINGS,
91350aadb33SDmitri Tikhonov                .u.setting.id    = SETTINGS_HEADER_TABLE_SIZE,
91450aadb33SDmitri Tikhonov                .u.setting.value = 0x02030405,
91550aadb33SDmitri Tikhonov            },
91650aadb33SDmitri Tikhonov        },
91750aadb33SDmitri Tikhonov    },
91850aadb33SDmitri Tikhonov
91950aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
92050aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
92150aadb33SDmitri Tikhonov        .frt_buf    = {
92250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x09,
92350aadb33SDmitri Tikhonov            /* Type: */         0x01,
92450aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS|HFHF_PRIORITY,
92550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
92650aadb33SDmitri Tikhonov            /* Exclusive: */    0x00|
92750aadb33SDmitri Tikhonov            /* Dep Stream Id: */
92850aadb33SDmitri Tikhonov                                0x00, 0x00, 0x12, 0x34,
92950aadb33SDmitri Tikhonov            /* Weight: */       0x00,
93050aadb33SDmitri Tikhonov            /* Block fragment: */
93150aadb33SDmitri Tikhonov                                0x48, 0x82, 0x64, 0x02,
93250aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x06,
93350aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
93450aadb33SDmitri Tikhonov            /* Flags: */        0x00,
93550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x00,
93650aadb33SDmitri Tikhonov                                0x00, SETTINGS_INITIAL_WINDOW_SIZE,
93750aadb33SDmitri Tikhonov                                0x01, 0x02, 0x03, 0x04,
93850aadb33SDmitri Tikhonov        },
93950aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5 + 4 + 9 + 6,
94050aadb33SDmitri Tikhonov        .frt_max_headers_sz = 10,
94150aadb33SDmitri Tikhonov        .frt_n_cb_vals = 2,
94250aadb33SDmitri Tikhonov        .frt_cb_vals = {
94350aadb33SDmitri Tikhonov            {
94450aadb33SDmitri Tikhonov                .type = CV_ERROR,
94550aadb33SDmitri Tikhonov                .stream_off = 9 + 5 + 4,
946a5fa05f9SDmitri Tikhonov                .u.error.code = FR_ERR_BAD_HEADER,
94750aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
94850aadb33SDmitri Tikhonov            },
94950aadb33SDmitri Tikhonov            {
95050aadb33SDmitri Tikhonov                .type = CV_SETTINGS,
95150aadb33SDmitri Tikhonov                .u.setting.id    = SETTINGS_INITIAL_WINDOW_SIZE,
95250aadb33SDmitri Tikhonov                .u.setting.value = 0x01020304,
95350aadb33SDmitri Tikhonov            },
95450aadb33SDmitri Tikhonov        },
95550aadb33SDmitri Tikhonov    },
95650aadb33SDmitri Tikhonov
95750aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
95850aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
95950aadb33SDmitri Tikhonov        .frt_buf    = {
96050aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x11,
96150aadb33SDmitri Tikhonov            /* Type: */         0x01,
96250aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
96350aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
96450aadb33SDmitri Tikhonov            /* Block fragment: */
96550aadb33SDmitri Tikhonov                                /* 0x11 bytes of no consequence: they are not
96650aadb33SDmitri Tikhonov                                 * parsed.
96750aadb33SDmitri Tikhonov                                 */
96850aadb33SDmitri Tikhonov                                000, 001, 002, 003, 004, 005, 006, 007,
96950aadb33SDmitri Tikhonov                                010, 011, 012, 013, 014, 015, 016, 017,
97050aadb33SDmitri Tikhonov                                020,
97150aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x06,
97250aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
97350aadb33SDmitri Tikhonov            /* Flags: */        0x00,
97450aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x00,
97550aadb33SDmitri Tikhonov                                0x00, SETTINGS_INITIAL_WINDOW_SIZE,
97650aadb33SDmitri Tikhonov                                0x01, 0x02, 0x03, 0x04,
97750aadb33SDmitri Tikhonov        },
97850aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 0x11 + 9 + 6,
97950aadb33SDmitri Tikhonov        .frt_max_headers_sz = 0x10,
98050aadb33SDmitri Tikhonov        .frt_n_cb_vals = 2,
98150aadb33SDmitri Tikhonov        .frt_cb_vals = {
98250aadb33SDmitri Tikhonov            {
98350aadb33SDmitri Tikhonov                .type = CV_ERROR,
98450aadb33SDmitri Tikhonov                .stream_off = 9,
985a5fa05f9SDmitri Tikhonov                .u.error.code = FR_ERR_BAD_HEADER,
98650aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
98750aadb33SDmitri Tikhonov            },
98850aadb33SDmitri Tikhonov            {
98950aadb33SDmitri Tikhonov                .type = CV_SETTINGS,
99050aadb33SDmitri Tikhonov                .u.setting.id    = SETTINGS_INITIAL_WINDOW_SIZE,
99150aadb33SDmitri Tikhonov                .u.setting.value = 0x01020304,
99250aadb33SDmitri Tikhonov            },
99350aadb33SDmitri Tikhonov        },
99450aadb33SDmitri Tikhonov    },
99550aadb33SDmitri Tikhonov
99650aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
99750aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
99850aadb33SDmitri Tikhonov        .frt_buf    = {
99950aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x10,
100050aadb33SDmitri Tikhonov            /* Type: */         0x01,
100150aadb33SDmitri Tikhonov            /* Flags: */        0x00,
100250aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
100350aadb33SDmitri Tikhonov            /* Block fragment: */
100450aadb33SDmitri Tikhonov                                /* 0x10 bytes of no consequence: they are not
100550aadb33SDmitri Tikhonov                                 * parsed.
100650aadb33SDmitri Tikhonov                                 */
100750aadb33SDmitri Tikhonov                                000, 001, 002, 003, 004, 005, 006, 007,
100850aadb33SDmitri Tikhonov                                010, 011, 012, 013, 014, 015, 016, 017,
100950aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x10,
101050aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
101150aadb33SDmitri Tikhonov            /* Flags: */        0x00,
101250aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
101350aadb33SDmitri Tikhonov            /* Block fragment: */
101450aadb33SDmitri Tikhonov                                000, 001, 002, 003, 004, 005, 006, 007,
101550aadb33SDmitri Tikhonov                                010, 011, 012, 013, 014, 015, 016, 017,
101650aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x10,
101750aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_CONTINUATION,
101850aadb33SDmitri Tikhonov            /* Flags: */        HFHF_END_HEADERS,
101950aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x30, 0x39,
102050aadb33SDmitri Tikhonov            /* Block fragment: */
102150aadb33SDmitri Tikhonov                                000, 001, 002, 003, 004, 005, 006, 007,
102250aadb33SDmitri Tikhonov                                010, 011, 012, 013, 014, 015, 016, 017,
102350aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x06,
102450aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_SETTINGS,
102550aadb33SDmitri Tikhonov            /* Flags: */        0x00,
102650aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x00,
102750aadb33SDmitri Tikhonov                                0x00, SETTINGS_INITIAL_WINDOW_SIZE,
102850aadb33SDmitri Tikhonov                                0x01, 0x02, 0x03, 0x04,
102950aadb33SDmitri Tikhonov        },
103050aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 0 + 0x10 + 9 + 0 + 0x10 + 9 + 0 + 0x10 + 9 + 6,
103150aadb33SDmitri Tikhonov        .frt_max_headers_sz = 0x19,
103250aadb33SDmitri Tikhonov        .frt_n_cb_vals = 2,
103350aadb33SDmitri Tikhonov        .frt_cb_vals = {
103450aadb33SDmitri Tikhonov            {
103550aadb33SDmitri Tikhonov                .type = CV_ERROR,
103650aadb33SDmitri Tikhonov                .stream_off = 9 + 0 + 0x10 + 9,
1037a5fa05f9SDmitri Tikhonov                .u.error.code = FR_ERR_BAD_HEADER,
103850aadb33SDmitri Tikhonov                .u.error.stream_id = 12345,
103950aadb33SDmitri Tikhonov            },
104050aadb33SDmitri Tikhonov            {
104150aadb33SDmitri Tikhonov                .type = CV_SETTINGS,
104250aadb33SDmitri Tikhonov                .u.setting.id    = SETTINGS_INITIAL_WINDOW_SIZE,
104350aadb33SDmitri Tikhonov                .u.setting.value = 0x01020304,
104450aadb33SDmitri Tikhonov            },
104550aadb33SDmitri Tikhonov        },
104650aadb33SDmitri Tikhonov    },
104750aadb33SDmitri Tikhonov
104850aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
104950aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
105050aadb33SDmitri Tikhonov        .frt_buf    = {
105150aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00,
105250aadb33SDmitri Tikhonov                                            0x04,  /* <-- wrong payload size */
105350aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_PRIORITY,
105450aadb33SDmitri Tikhonov            /* Flags: */        0x00,
105550aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x39,
105650aadb33SDmitri Tikhonov            /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19,
105750aadb33SDmitri Tikhonov            /* Weight: */       0x77,
105850aadb33SDmitri Tikhonov        },
105950aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5,
106050aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
106150aadb33SDmitri Tikhonov        .frt_err = 1,
106250aadb33SDmitri Tikhonov        .frt_in_off = 9,
106350aadb33SDmitri Tikhonov        .frt_cb_vals = {
106450aadb33SDmitri Tikhonov            {
106550aadb33SDmitri Tikhonov                .type = CV_ERROR,
106650aadb33SDmitri Tikhonov                .stream_off = 9,
106750aadb33SDmitri Tikhonov                .u.error.code = FR_ERR_INVALID_FRAME_SIZE,
106850aadb33SDmitri Tikhonov                .u.error.stream_id = 0x39,
106950aadb33SDmitri Tikhonov            }
107050aadb33SDmitri Tikhonov        },
107150aadb33SDmitri Tikhonov    },
107250aadb33SDmitri Tikhonov
107350aadb33SDmitri Tikhonov    {   .frt_lineno = __LINE__,
107450aadb33SDmitri Tikhonov        .frt_fr_flags = 0,
107550aadb33SDmitri Tikhonov        .frt_buf    = {
107650aadb33SDmitri Tikhonov            /* Length: */       0x00, 0x00, 0x05,
107750aadb33SDmitri Tikhonov            /* Type: */         HTTP_FRAME_PRIORITY,
107850aadb33SDmitri Tikhonov            /* Flags: */        0x00,
107950aadb33SDmitri Tikhonov            /* Stream Id: */    0x00, 0x00, 0x00, 0x00, /* Invalid stream ID */
108050aadb33SDmitri Tikhonov            /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19,
108150aadb33SDmitri Tikhonov            /* Weight: */       0x77,
108250aadb33SDmitri Tikhonov        },
108350aadb33SDmitri Tikhonov        .frt_bufsz  = 9 + 5,
108450aadb33SDmitri Tikhonov        .frt_n_cb_vals = 1,
108550aadb33SDmitri Tikhonov        .frt_err = 1,
108650aadb33SDmitri Tikhonov        .frt_in_off = 9,
108750aadb33SDmitri Tikhonov        .frt_cb_vals = {
108850aadb33SDmitri Tikhonov            {
108950aadb33SDmitri Tikhonov                .type = CV_ERROR,
109050aadb33SDmitri Tikhonov                .stream_off = 9,
109150aadb33SDmitri Tikhonov                .u.error.code = FR_ERR_ZERO_STREAM_ID,
109250aadb33SDmitri Tikhonov                .u.error.stream_id = 0x00,
109350aadb33SDmitri Tikhonov            }
109450aadb33SDmitri Tikhonov        },
109550aadb33SDmitri Tikhonov    },
109650aadb33SDmitri Tikhonov
109750aadb33SDmitri Tikhonov    {
109850aadb33SDmitri Tikhonov        .frt_bufsz  = 0,
109950aadb33SDmitri Tikhonov    },
110050aadb33SDmitri Tikhonov};
110150aadb33SDmitri Tikhonov
110250aadb33SDmitri Tikhonov
110372585dc9SDmitri Tikhonovstatic struct lsquic_stream *
110472585dc9SDmitri Tikhonovmy_get_stream_by_id (struct lsquic_conn *conn, lsquic_stream_id_t stream_id)
110572585dc9SDmitri Tikhonov{
110672585dc9SDmitri Tikhonov    return (void *) my_get_stream_by_id;
110772585dc9SDmitri Tikhonov}
110872585dc9SDmitri Tikhonov
110972585dc9SDmitri Tikhonov
111050aadb33SDmitri Tikhonovstatic void
111150aadb33SDmitri Tikhonovtest_one_frt (const struct frame_reader_test *frt)
111250aadb33SDmitri Tikhonov{
111350aadb33SDmitri Tikhonov    struct lsquic_frame_reader *fr;
111450aadb33SDmitri Tikhonov    unsigned short exp_off;
1115bea64822SDmitri Tikhonov    struct lshpack_dec hdec;
111650aadb33SDmitri Tikhonov    struct lsquic_mm mm;
11173b55e6aeSDmitri Tikhonov    struct lsquic_conn lconn;
11183b55e6aeSDmitri Tikhonov    struct lsquic_conn_public conn_pub;
11193b55e6aeSDmitri Tikhonov    struct lsquic_stream stream;
112050aadb33SDmitri Tikhonov    int s;
112108c45823SDmitri Tikhonov    struct conn_iface my_conn_if;
112250aadb33SDmitri Tikhonov
112319f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS
112419f667fbSDmitri Tikhonov    struct conn_stats conn_stats;
112519f667fbSDmitri Tikhonov    memset(&conn_stats, 0, sizeof(conn_stats));
112619f667fbSDmitri Tikhonov#endif
112719f667fbSDmitri Tikhonov
11283b55e6aeSDmitri Tikhonov    memset(&stream, 0, sizeof(stream));
11293b55e6aeSDmitri Tikhonov    memset(&lconn, 0, sizeof(lconn));
11303b55e6aeSDmitri Tikhonov    memset(&conn_pub, 0, sizeof(conn_pub));
113108c45823SDmitri Tikhonov    memset(&my_conn_if, 0, sizeof(my_conn_if));
113272585dc9SDmitri Tikhonov    my_conn_if.ci_get_stream_by_id = my_get_stream_by_id;
113308c45823SDmitri Tikhonov    lconn.cn_if = &my_conn_if;
11343b55e6aeSDmitri Tikhonov    stream.conn_pub = &conn_pub;
11353b55e6aeSDmitri Tikhonov    conn_pub.lconn = &lconn;
11363b55e6aeSDmitri Tikhonov
113772585dc9SDmitri Tikhonov  top:
113850aadb33SDmitri Tikhonov    lsquic_mm_init(&mm);
1139fb3e20e0SDmitri Tikhonov    lshpack_dec_init(&hdec);
114050aadb33SDmitri Tikhonov    memset(&input, 0, sizeof(input));
114150aadb33SDmitri Tikhonov    memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz);
114250aadb33SDmitri Tikhonov    input.in_sz  = frt->frt_bufsz;
114350aadb33SDmitri Tikhonov
114450aadb33SDmitri Tikhonov    do
114550aadb33SDmitri Tikhonov    {
114650aadb33SDmitri Tikhonov        reset_cb_ctx(&g_cb_ctx);
114750aadb33SDmitri Tikhonov        input.in_off = 0;
114850aadb33SDmitri Tikhonov        ++input.in_max_sz;
114950aadb33SDmitri Tikhonov
115050aadb33SDmitri Tikhonov        fr = lsquic_frame_reader_new(frt->frt_fr_flags, frt->frt_max_headers_sz,
11513b55e6aeSDmitri Tikhonov                &mm, &stream, read_from_stream, &hdec, &frame_callbacks, &g_cb_ctx,
115219f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS
115319f667fbSDmitri Tikhonov                &conn_stats,
115419f667fbSDmitri Tikhonov#endif
11553b55e6aeSDmitri Tikhonov                lsquic_http1x_if, NULL);
115650aadb33SDmitri Tikhonov        do
115750aadb33SDmitri Tikhonov        {
115850aadb33SDmitri Tikhonov            s = lsquic_frame_reader_read(fr);
115950aadb33SDmitri Tikhonov            if (s != 0)
116050aadb33SDmitri Tikhonov                break;
116150aadb33SDmitri Tikhonov        }
116250aadb33SDmitri Tikhonov        while (input.in_off < input.in_sz);
116350aadb33SDmitri Tikhonov
116450aadb33SDmitri Tikhonov        assert(frt->frt_err || 0 == s);
116550aadb33SDmitri Tikhonov
116672585dc9SDmitri Tikhonov        if (my_conn_if.ci_get_stream_by_id)
116772585dc9SDmitri Tikhonov        {
116872585dc9SDmitri Tikhonov            assert(g_cb_ctx.n_cb_vals == frt->frt_n_cb_vals);
116950aadb33SDmitri Tikhonov
117072585dc9SDmitri Tikhonov            unsigned i;
117172585dc9SDmitri Tikhonov            for (i = 0; i < g_cb_ctx.n_cb_vals; ++i)
117272585dc9SDmitri Tikhonov                compare_cb_vals(&g_cb_ctx.cb_vals[i], &frt->frt_cb_vals[i]);
117372585dc9SDmitri Tikhonov        }
117450aadb33SDmitri Tikhonov
117550aadb33SDmitri Tikhonov        exp_off = frt->frt_in_off;
117650aadb33SDmitri Tikhonov        if (!exp_off)
117750aadb33SDmitri Tikhonov            exp_off = frt->frt_bufsz;
117850aadb33SDmitri Tikhonov        assert(input.in_off == exp_off);
117950aadb33SDmitri Tikhonov
118050aadb33SDmitri Tikhonov        lsquic_frame_reader_destroy(fr);
118150aadb33SDmitri Tikhonov    }
118250aadb33SDmitri Tikhonov    while (input.in_max_sz < input.in_max_req_sz);
1183bea64822SDmitri Tikhonov    lshpack_dec_cleanup(&hdec);
118472585dc9SDmitri Tikhonov
118572585dc9SDmitri Tikhonov    if (!(frt->frt_fr_flags & FRF_SERVER) && my_conn_if.ci_get_stream_by_id)
118672585dc9SDmitri Tikhonov    {
118772585dc9SDmitri Tikhonov        /* Do it again, but this time test header block skip logic */
118872585dc9SDmitri Tikhonov        my_conn_if.ci_get_stream_by_id = NULL;
118972585dc9SDmitri Tikhonov        goto top;
119072585dc9SDmitri Tikhonov    }
119172585dc9SDmitri Tikhonov
119250aadb33SDmitri Tikhonov    lsquic_mm_cleanup(&mm);
119350aadb33SDmitri Tikhonov}
119450aadb33SDmitri Tikhonov
119550aadb33SDmitri Tikhonov
119650aadb33SDmitri Tikhonovint
119750aadb33SDmitri Tikhonovmain (int argc, char **argv)
119850aadb33SDmitri Tikhonov{
119950aadb33SDmitri Tikhonov    int opt;
120050aadb33SDmitri Tikhonov
120150aadb33SDmitri Tikhonov    while (-1 != (opt = getopt(argc, argv, "l:")))
120250aadb33SDmitri Tikhonov    {
120350aadb33SDmitri Tikhonov        switch (opt)
120450aadb33SDmitri Tikhonov        {
120550aadb33SDmitri Tikhonov        case 'l':
120650aadb33SDmitri Tikhonov            lsquic_log_to_fstream(stderr, LLTS_NONE);
120750aadb33SDmitri Tikhonov            lsquic_logger_lopt(optarg);
120850aadb33SDmitri Tikhonov            break;
120950aadb33SDmitri Tikhonov        default:
121050aadb33SDmitri Tikhonov            exit(1);
121150aadb33SDmitri Tikhonov        }
121250aadb33SDmitri Tikhonov    }
121350aadb33SDmitri Tikhonov
121450aadb33SDmitri Tikhonov    const struct frame_reader_test *frt;
121550aadb33SDmitri Tikhonov    for (frt = tests; frt->frt_bufsz > 0; ++frt)
121650aadb33SDmitri Tikhonov        test_one_frt(frt);
121750aadb33SDmitri Tikhonov    return 0;
121850aadb33SDmitri Tikhonov}
1219