lsquic_parse_ietf_v1.c revision fb3e20e0
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_parse_ietf_v1.c -- Parsing functions specific to IETF QUIC v1
4 */
5
6#include <assert.h>
7#include <inttypes.h>
8#include <errno.h>
9#include <stddef.h>
10#include <string.h>
11#include <sys/queue.h>
12#ifndef WIN32
13#include <sys/types.h>
14#else
15#include <vc_compat.h>
16#endif
17
18#include "lsquic_types.h"
19#include "lsquic_int_types.h"
20#include "lsquic_sizes.h"
21#include "lsquic_packet_common.h"
22#include "lsquic_packet_ietf.h"
23#include "lsquic_packet_in.h"
24#include "lsquic_packet_out.h"
25#include "lsquic_parse.h"
26#include "lsquic_parse_common.h"
27#include "lsquic_sfcw.h"
28#include "lsquic_varint.h"
29#include "lsquic_hq.h"
30#include "lsquic_hash.h"
31#include "lsquic_stream.h"
32#include "lsquic_mm.h"
33#include "lsquic_malo.h"
34#include "lsquic_version.h"
35#include "lsquic.h"
36#include "lsquic_byteswap.h"
37#include "lsquic_conn.h"
38#include "lsquic_enc_sess.h"
39#include "lsquic_trans_params.h"
40#include "lsquic_parse_ietf.h"
41#include "lsquic_qtags.h"
42
43#define LSQUIC_LOGGER_MODULE LSQLM_PARSE
44#include "lsquic_logger.h"
45
46#define CHECK_SPACE(need, pstart, pend)  \
47    do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0)
48
49#define FRAME_TYPE_ACK_FREQUENCY    0xAF
50#define FRAME_TYPE_TIMESTAMP        0x2F5
51
52static int
53ietf_v1_gen_one_varint (unsigned char *, size_t, unsigned char, uint64_t);
54
55static int
56ietf_v1_gen_two_varints (unsigned char *, size_t, unsigned char, uint64_t[2]);
57
58static void
59ietf_v1_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
60                                            struct packin_parse_state *state)
61{
62    /* Packet number is set to an invalid value.  The packet number must
63     * be decrypted, which happens later.
64     */
65    packet_in->pi_packno        = 1ULL << 62;
66}
67
68
69/* Note: token size is not accounted for */
70static size_t
71ietf_v1_packout_header_size_long_by_flags (const struct lsquic_conn *lconn,
72                enum header_type header_type, enum packet_out_flags flags,
73                size_t dcid_len)
74{
75    size_t sz;
76    enum packno_bits packno_bits;
77
78    packno_bits = (flags >> POBIT_SHIFT) & 0x3;
79
80    sz = 1 /* Type */
81       + 4 /* Version */
82       + 1 /* DCIL */
83       + dcid_len
84       + 1 /* SCIL */
85       + CN_SCID(lconn)->len
86       + (header_type == HETY_INITIAL)  /* Token length */
87       + 2 /* Always use two bytes to encode payload length */
88       + iquic_packno_bits2len(packno_bits)
89       ;
90
91    return sz;
92}
93
94
95static size_t
96ietf_v1_packout_header_size_long_by_packet (const struct lsquic_conn *lconn,
97                                const struct lsquic_packet_out *packet_out)
98{
99    size_t sz;
100    unsigned token_len; /* Need intermediate value to quiet compiler warning */
101    enum packno_bits packno_bits;
102
103    packno_bits = lsquic_packet_out_packno_bits(packet_out);
104
105    sz = 1 /* Type */
106       + 4 /* Version */
107       + 1 /* DCIL */
108       + packet_out->po_path->np_dcid.len
109       + 1 /* SCIL */
110       + CN_SCID(lconn)->len
111       + (packet_out->po_header_type == HETY_INITIAL ?
112            (token_len = packet_out->po_token_len,
113                (1 << vint_val2bits(token_len)) + token_len) : 0)
114       + 2 /* Always use two bytes to encode payload length */
115       + iquic_packno_bits2len(packno_bits)
116       ;
117
118    return sz;
119}
120
121
122static size_t
123ietf_v1_packout_header_size_short (const struct lsquic_conn *lconn,
124                                enum packet_out_flags flags, size_t dcid_len)
125{
126    enum packno_bits bits;
127    size_t sz;
128
129    bits = (flags >> POBIT_SHIFT) & 0x3;
130    sz = 1 /* Type */
131       + (flags & PO_CONN_ID ? dcid_len : 0)
132       + iquic_packno_bits2len(bits)
133       ;
134
135    return sz;
136}
137
138
139static size_t
140ietf_v1_packout_max_header_size (const struct lsquic_conn *lconn,
141                                enum packet_out_flags flags, size_t dcid_len)
142{
143    if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
144        return ietf_v1_packout_header_size_short(lconn, flags, dcid_len);
145    else if (lconn->cn_flags & LSCONN_SERVER)
146        /* Server does not set the token in its Initial packet header: set
147         * the packet type to something else in order not to overestimate
148         * header size.
149         */
150        return ietf_v1_packout_header_size_long_by_flags(lconn, HETY_HANDSHAKE,
151                                                            flags, dcid_len);
152    else
153        return ietf_v1_packout_header_size_long_by_flags(lconn, HETY_INITIAL,
154                                                            flags, dcid_len);
155}
156
157
158/* [draft-ietf-quic-transport-17] Section-17.2 */
159static const unsigned char header_type_to_bin[] = {
160    [HETY_INITIAL]      = 0x0,
161    [HETY_0RTT]         = 0x1,
162    [HETY_HANDSHAKE]    = 0x2,
163    [HETY_RETRY]        = 0x3,
164};
165
166
167static unsigned
168write_packno (unsigned char *p, lsquic_packno_t packno,
169                                                enum packno_bits bits)
170{
171    unsigned char *const begin = p;
172
173    switch (bits)
174    {
175    case IQUIC_PACKNO_LEN_4:
176        *p++ = packno >> 24;
177        /* fall through */
178    case IQUIC_PACKNO_LEN_3:
179        *p++ = packno >> 16;
180        /* fall through */
181    case IQUIC_PACKNO_LEN_2:
182        *p++ = packno >> 8;
183        /* fall through */
184    default:
185        *p++ = packno;
186    }
187
188    return p - begin;
189}
190
191
192static int
193gen_long_pkt_header (const struct lsquic_conn *lconn,
194            const struct lsquic_packet_out *packet_out, unsigned char *buf,
195                                                                size_t bufsz)
196{
197    unsigned payload_len, bits;
198    enum packno_bits packno_bits;
199    lsquic_ver_tag_t ver_tag;
200    unsigned char *p;
201    unsigned token_len;
202    size_t need;
203
204    need = ietf_v1_packout_header_size_long_by_packet(lconn, packet_out);
205    if (need > bufsz)
206    {
207        errno = EINVAL;
208        return -1;
209    }
210
211    packno_bits = lsquic_packet_out_packno_bits(packet_out);
212    p = buf;
213    *p++ = 0xC0
214         | ( header_type_to_bin[ packet_out->po_header_type ] << 4)
215         | packno_bits
216         ;
217    ver_tag = lsquic_ver2tag(lconn->cn_version);
218    memcpy(p, &ver_tag, sizeof(ver_tag));
219    p += sizeof(ver_tag);
220
221    *p++ = packet_out->po_path->np_dcid.len;
222    memcpy(p, packet_out->po_path->np_dcid.idbuf, packet_out->po_path->np_dcid.len);
223    p += packet_out->po_path->np_dcid.len;
224    *p++ = CN_SCID(lconn)->len;
225    memcpy(p, CN_SCID(lconn)->idbuf, CN_SCID(lconn)->len);
226    p +=  CN_SCID(lconn)->len;
227
228    if (HETY_INITIAL == packet_out->po_header_type)
229    {
230        token_len = packet_out->po_token_len;
231        bits = vint_val2bits(token_len);
232        vint_write(p, token_len, bits, 1 << bits);
233        p += 1 << bits;
234        memcpy(p, packet_out->po_token, token_len);
235        p += token_len;
236    }
237
238    payload_len = packet_out->po_data_sz
239                + lconn->cn_esf_c->esf_tag_len
240                + iquic_packno_bits2len(packno_bits);
241    bits = 1;   /* Always use two bytes to encode payload length */
242    vint_write(p, payload_len, bits, 1 << bits);
243    p += 1 << bits;
244
245    p += write_packno(p, packet_out->po_packno, packno_bits);
246
247    return p - buf;
248}
249
250
251static int
252gen_short_pkt_header (const struct lsquic_conn *lconn,
253            const struct lsquic_packet_out *packet_out, unsigned char *buf,
254                                                                size_t bufsz)
255{
256    unsigned packno_len, cid_len, need;
257    enum packno_bits packno_bits;
258
259    packno_bits = lsquic_packet_out_packno_bits(packet_out);
260    packno_len = iquic_packno_bits2len(packno_bits);
261    cid_len = packet_out->po_flags & PO_CONN_ID ? packet_out->po_path->np_dcid.len : 0;
262
263    need = 1 + cid_len + packno_len;
264    if (need > bufsz)
265        return -1;
266
267    buf[0] = 0x40
268           | (lsquic_packet_out_spin_bit(packet_out) << 5)
269           | (lsquic_packet_out_square_bit(packet_out) << 4)
270           | (lsquic_packet_out_loss_bit(packet_out) << 3)
271           | (lsquic_packet_out_kp(packet_out) << 2)
272           | packno_bits
273           ;
274
275    if (cid_len)
276        memcpy(buf + 1, packet_out->po_path->np_dcid.idbuf, cid_len);
277
278    (void) write_packno(buf + 1 + cid_len, packet_out->po_packno, packno_bits);
279
280    return need;
281}
282
283
284static int
285ietf_v1_gen_reg_pkt_header (const struct lsquic_conn *lconn,
286            const struct lsquic_packet_out *packet_out, unsigned char *buf,
287                                                                size_t bufsz)
288{
289    if (packet_out->po_header_type == HETY_NOT_SET)
290        return gen_short_pkt_header(lconn, packet_out, buf, bufsz);
291    else
292        return gen_long_pkt_header(lconn, packet_out, buf, bufsz);
293}
294
295
296static void
297ietf_v1_packno_info (const struct lsquic_conn *lconn,
298        const struct lsquic_packet_out *packet_out, unsigned *packno_off,
299        unsigned *packno_len)
300{
301    unsigned token_len; /* Need intermediate value to quiet compiler warning */
302
303    if (packet_out->po_header_type == HETY_NOT_SET)
304        *packno_off = 1 +
305            (packet_out->po_flags & PO_CONN_ID ? packet_out->po_path->np_dcid.len : 0);
306    else
307        *packno_off = 1
308                    + 4
309                    + 1
310                    + packet_out->po_path->np_dcid.len
311                    + 1
312                    + CN_SCID(lconn)->len
313                    + (packet_out->po_header_type == HETY_INITIAL ?
314                        (token_len = packet_out->po_token_len,
315                            (1 << vint_val2bits(token_len)) + token_len) : 0)
316                    + 2;
317    *packno_len = iquic_packno_bits2len(
318        lsquic_packet_out_packno_bits(packet_out));
319}
320
321
322static size_t
323ietf_v1_packout_size (const struct lsquic_conn *lconn,
324                                const struct lsquic_packet_out *packet_out)
325{
326    size_t sz;
327
328    if ((lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
329                                && packet_out->po_header_type == HETY_NOT_SET)
330        sz = ietf_v1_packout_header_size_short(lconn, packet_out->po_flags,
331                                            packet_out->po_path->np_dcid.len);
332    else
333        sz = ietf_v1_packout_header_size_long_by_packet(lconn, packet_out);
334
335    sz += packet_out->po_data_sz;
336    sz += lconn->cn_esf_c->esf_tag_len;
337
338    return sz;
339}
340
341
342static int
343ietf_v1_gen_stream_frame (unsigned char *buf, size_t buf_len,
344        lsquic_stream_id_t stream_id, uint64_t offset, int fin, size_t size,
345        gsf_read_f gsf_read, void *stream)
346{
347    /* 0b00001XXX
348     *  0x4     OFF
349     *  0x2     LEN
350     *  0x1     FIN
351     */
352    unsigned sbits, obits, dbits;
353    unsigned slen, olen, dlen;
354    unsigned char *p = buf + 1;
355
356#if _MSC_VER
357    obits = 0, dbits = 0;
358#endif
359
360    assert(!!fin ^ !!size);
361
362    /* We do not check that stream_id, offset, and size are smaller
363     * than 2^62: this is not necessary, as this code will never generate
364     * this many stream IDs, nor will it even transfer this much data.
365     * The size is limited by our own code.
366     */
367
368    sbits = vint_val2bits(stream_id);
369    slen = 1 << sbits;
370    if (offset)
371    {
372        obits = vint_val2bits(offset);
373        olen = 1 << obits;
374    }
375    else
376        olen = 0;
377
378    if (!fin)
379    {
380        unsigned n_avail;
381        size_t nr;
382
383        n_avail = buf_len - (p + slen + olen - buf);
384
385        /* If we cannot fill remaining buffer, we need to include data
386         * length.
387         */
388        if (size < n_avail)
389        {
390            dbits = vint_val2bits(size);
391            dlen = 1 << dbits;
392            n_avail -= dlen;
393            if (size > n_avail)
394                size = n_avail;
395        }
396        else
397        {
398            dlen = 0;
399            size = n_avail;
400        }
401
402        CHECK_STREAM_SPACE(1 + olen + slen + dlen +
403            + 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
404
405        vint_write(p, stream_id, sbits, slen);
406        p += slen;
407
408        if (olen)
409            vint_write(p, offset, obits, olen);
410        p += olen;
411
412        /* Read as much as we can */
413        nr = gsf_read(stream, p + dlen, size, &fin);
414        assert(nr != 0);
415        assert(nr <= size);
416
417        if (dlen)
418            vint_write(p, nr, dbits, dlen);
419
420        p += dlen + nr;
421    }
422    else
423    {
424        dlen = 1 + slen + olen < buf_len;
425        CHECK_STREAM_SPACE(1 + slen + olen + dlen, buf, buf + buf_len);
426        vint_write(p, stream_id, sbits, slen);
427        p += slen;
428        if (olen)
429            vint_write(p, offset, obits, olen);
430        p += olen;
431        if (dlen)
432            *p++ = 0;
433    }
434
435    buf[0] = 0x08
436           | (!!olen << 2)
437           | (!!dlen << 1)
438           | (!!fin  << 0)
439           ;
440    return p - buf;
441}
442
443
444int
445lsquic_ietf_v1_gen_crypto_frame (unsigned char *buf, unsigned char first_byte,
446            size_t buf_len, uint64_t offset, size_t size, gcf_read_f gcf_read,
447            void *stream)
448{
449    unsigned char *const end = buf + buf_len;
450    unsigned char *p;
451    unsigned obits, dbits;
452    unsigned olen, dlen;
453    size_t nr, n_avail;
454
455    obits = vint_val2bits(offset);
456    olen = 1 << obits;
457    dbits = vint_val2bits(size);
458    dlen = 1 << dbits;
459
460    CHECK_SPACE(1 + olen + dlen
461        + (dlen > 0) /* We need to write at least 1 byte */, buf, end);
462
463    n_avail = end - buf - 1 - olen - dlen;
464    if (n_avail < size)
465        size = n_avail;
466
467    p = buf;
468    *p++ = first_byte;
469
470    vint_write(p, offset, obits, olen);
471    p += olen;
472
473    nr = gcf_read(stream, p + dlen, size);
474    assert(nr != 0);    /* This indicates error in the caller */
475    assert(nr <= size); /* This also indicates an error in the caller */
476
477    vint_write(p, nr, dbits, dlen);
478    p += dlen + nr;
479
480    return p - buf;
481}
482
483
484static int
485ietf_v1_gen_crypto_frame (unsigned char *buf, size_t buf_len,
486        uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream)
487{
488    return lsquic_ietf_v1_gen_crypto_frame(buf, 0x6, buf_len, offset,
489                                                size, gcf_read, stream);
490}
491
492
493/* return parsed (used) buffer length */
494static int
495ietf_v1_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
496                                        struct stream_frame *stream_frame)
497{
498    /* 0b00001XXX
499     *  0x4     OFF
500     *  0x2     LEN
501     *  0x1     FIN
502     */
503    const unsigned char *const pend = buf + rem_packet_sz;
504    const unsigned char *p = buf;
505    lsquic_stream_id_t stream_id;
506    uint64_t offset, data_sz;
507    int r;
508
509    CHECK_SPACE(1, p, pend);
510    const char type = *p++;
511
512    r = vint_read(p, pend, &stream_id);
513    if (r < 0)
514        return -1;
515    p += r;
516
517    if (type & 0x4)
518    {
519        r = vint_read(p, pend, &offset);
520        if (r < 0)
521            return -1;
522        p += r;
523    }
524    else
525        offset = 0;
526
527    if (type & 0x2)
528    {
529        r = vint_read(p, pend, &data_sz);
530        if (r < 0)
531            return -1;
532        p += r;
533        CHECK_SPACE(data_sz, p, pend);
534    }
535    else
536        data_sz = pend - p;
537
538    /* Largest offset cannot exceed this value and we MUST detect this error */
539    if (VINT_MAX_VALUE - offset < data_sz)
540        return -1;
541
542    stream_frame->stream_id             = stream_id;
543    stream_frame->data_frame.df_fin     = type & 0x1;
544    stream_frame->data_frame.df_offset  = offset;
545    stream_frame->data_frame.df_size    = data_sz;
546    stream_frame->data_frame.df_data    = p;
547    stream_frame->data_frame.df_read_off= 0;
548    stream_frame->packet_in             = NULL;
549
550    assert(p <= pend);
551
552    return p + data_sz - (unsigned char *) buf;
553}
554
555
556int
557lsquic_ietf_v1_parse_crypto_frame (const unsigned char *buf,
558                    size_t rem_packet_sz, struct stream_frame *stream_frame)
559{
560    const unsigned char *const pend = buf + rem_packet_sz;
561    const unsigned char *p = buf;
562    uint64_t offset, data_sz;
563    int r;
564
565    CHECK_SPACE(1, p, pend);
566
567    ++p;
568
569    r = vint_read(p, pend, &offset);
570    if (r < 0)
571        return -1;
572    p += r;
573
574    r = vint_read(p, pend, &data_sz);
575    if (r < 0)
576        return -1;
577    p += r;
578    CHECK_SPACE(data_sz, p, pend);
579
580    /* Largest offset cannot exceed this value and we MUST detect this error */
581    if (VINT_MAX_VALUE - offset < data_sz)
582        return -1;
583
584    stream_frame->stream_id             = ~0ULL;    /* Unset */
585    stream_frame->data_frame.df_fin     = 0;
586    stream_frame->data_frame.df_offset  = offset;
587    stream_frame->data_frame.df_size    = data_sz;
588    stream_frame->data_frame.df_data    = p;
589    stream_frame->data_frame.df_read_off= 0;
590    stream_frame->packet_in             = NULL;
591
592    assert(p <= pend);
593
594    return p + data_sz - (unsigned char *) buf;
595}
596
597
598static int
599ietf_v1_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
600                                        struct stream_frame *stream_frame)
601{
602    if (rem_packet_sz > 0)
603    {
604        assert(0x06 == buf[0]);
605        return lsquic_ietf_v1_parse_crypto_frame(buf, rem_packet_sz,
606                                                            stream_frame);
607    }
608    else
609        return -1;
610}
611
612
613#if __GNUC__
614#   define UNLIKELY(cond) __builtin_expect(cond, 0)
615#else
616#   define UNLIKELY(cond) cond
617#endif
618
619
620/* Bits 10 (2) is ECT(0); * bits 01 (1) is ECT(1). */
621static const int ecnmap[4] = { 0, 2, 1, 3, };
622
623
624static int
625ietf_v1_parse_ack_frame (const unsigned char *const buf, size_t buf_len,
626                                            struct ack_info *ack, uint8_t exp)
627{
628    const unsigned char *p = buf;
629    const unsigned char *const end = buf + buf_len;
630    uint64_t block_count, gap, block;
631    enum ecn ecn;
632    unsigned i;
633    int r;
634
635    ++p;
636    r = vint_read(p, end, &ack->ranges[0].high);
637    if (UNLIKELY(r < 0))
638        return -1;
639    p += r;
640    r = vint_read(p, end, &ack->lack_delta);
641    if (UNLIKELY(r < 0))
642        return -1;
643    p += r;
644    ack->lack_delta <<= exp;
645    r = vint_read(p, end, &block_count);
646    if (UNLIKELY(r < 0))
647        return -1;
648    p += r;
649    r = vint_read(p, end, &block);
650    if (UNLIKELY(r < 0))
651        return -1;
652    ack->ranges[0].low = ack->ranges[0].high - block;
653    if (UNLIKELY(ack->ranges[0].high < ack->ranges[0].low))
654        return -1;
655    p += r;
656
657    for (i = 1; i <= block_count; ++i)
658    {
659        r = vint_read(p, end, &gap);
660        if (UNLIKELY(r < 0))
661            return -1;
662        p += r;
663        r = vint_read(p, end, &block);
664        if (UNLIKELY(r < 0))
665            return -1;
666        p += r;
667        if (i < sizeof(ack->ranges) / sizeof(ack->ranges[0]))
668        {
669            ack->ranges[i].high = ack->ranges[i - 1].low - gap - 2;
670            ack->ranges[i].low  = ack->ranges[i].high - block;
671            if (UNLIKELY(ack->ranges[i].high >= ack->ranges[i - 1].low
672                         || ack->ranges[i].high < ack->ranges[i].low))
673                return -1;
674        }
675    }
676
677    if (i < sizeof(ack->ranges) / sizeof(ack->ranges[0]))
678    {
679        ack->flags = 0;
680        ack->n_ranges = block_count + 1;
681    }
682    else
683    {
684        ack->flags = AI_TRUNCATED;
685        ack->n_ranges = sizeof(ack->ranges) / sizeof(ack->ranges[0]);
686    }
687
688
689    if (0x03 == buf[0])
690    {
691        for (ecn = 1; ecn <= 3; ++ecn)
692        {
693            r = vint_read(p, end, &ack->ecn_counts[ecnmap[ecn]]);
694            if (UNLIKELY(r < 0))
695                return -1;
696            p += r;
697        }
698        ack->flags |= AI_ECN;
699    }
700
701    return p - buf;
702}
703
704
705static unsigned
706ietf_v1_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
707                                                            uint64_t final_size)
708{
709    return 1                        /* Type */
710         + vint_size(stream_id)   /* Stream ID (i) */
711         + vint_size(error_code)  /* Application Error Code (i) */
712         + vint_size(final_size); /* Final Size (i) */
713}
714
715
716static int
717ietf_v1_gen_rst_frame (unsigned char *buf, size_t buf_len,
718        lsquic_stream_id_t stream_id, uint64_t error_code, uint64_t final_size)
719{
720    unsigned vbits;
721    unsigned char *p;
722
723    if (buf_len < ietf_v1_rst_frame_size(stream_id, error_code, final_size))
724        return -1;
725    p = buf;
726
727    *p++ = 0x04;
728    /* Stream ID (i) */
729    vbits = vint_val2bits(stream_id);
730    vint_write(p, stream_id, vbits, 1 << vbits);
731    p += 1 << vbits;
732
733    /* Application Error Code (i) */
734    vbits = vint_val2bits(error_code);
735    vint_write(p, error_code, vbits, 1 << vbits);
736    p += 1 << vbits;
737
738    /* Final Size (i) */
739    vbits = vint_val2bits(final_size);
740    vint_write(p, final_size, vbits, 1 << vbits);
741    p += 1 << vbits;
742
743    return p - buf;
744}
745
746
747static int
748ietf_v1_parse_rst_frame (const unsigned char *buf, size_t buf_len,
749    lsquic_stream_id_t *stream_id_p, uint64_t *final_size_p, uint64_t *error_code_p)
750{
751    const unsigned char *p = buf + 1;
752    const unsigned char *const end = buf + buf_len;
753    uint64_t stream_id, final_size, error_code;
754    int r;
755
756    /* Stream ID (i) */
757    r = vint_read(p, end, &stream_id);
758    if (r < 0)
759        return r;
760    p += r;
761
762    /* Application Error Code (i) */
763    r = vint_read(p, end, &error_code);
764    if (r < 0)
765        return r;
766    p += r;
767
768    /* Final Size (i) */
769    r = vint_read(p, end, &final_size);
770    if (r < 0)
771        return r;
772    p += r;
773
774    *stream_id_p = stream_id;
775    *final_size_p = final_size;
776    *error_code_p = error_code;
777
778    return p - buf;
779}
780
781
782static int
783ietf_v1_parse_stop_sending_frame (const unsigned char *buf, size_t buf_len,
784                        lsquic_stream_id_t *stream_id, uint64_t *error_code)
785{
786    const unsigned char *p = buf + 1;
787    const unsigned char *const end = buf + buf_len;
788    int r;
789
790    r = vint_read(p, end, stream_id);
791    if (r < 0)
792        return r;
793    p += r;
794
795    r = vint_read(p, end, error_code);
796    if (r < 0)
797        return r;
798    p += r;
799
800    return p - buf;
801}
802
803
804static int
805ietf_v1_gen_stop_sending_frame (unsigned char *buf, size_t len,
806                            lsquic_stream_id_t stream_id, uint64_t error_code)
807{
808    return ietf_v1_gen_two_varints(buf, len, 0x05, (uint64_t[]){ stream_id,
809                                                                error_code, });
810}
811
812
813static unsigned
814ietf_v1_stop_sending_frame_size (lsquic_stream_id_t val, uint64_t error_code)
815{
816    return 1 + vint_size(val) + vint_size(error_code);
817}
818
819
820static int
821ietf_v1_parse_new_token_frame (const unsigned char *buf, size_t buf_len,
822                            const unsigned char **token, size_t *token_size_p)
823{
824    uint64_t token_size;
825    const unsigned char *p = buf + 1;
826    const unsigned char *const end = buf + buf_len;
827    int r;
828
829    r = vint_read(p, end, &token_size);
830    if (r < 0)
831        return r;
832    p += r;
833
834    if (p + token_size > end)
835        return -1;
836    *token = p;
837    p += token_size;
838    *token_size_p = token_size;
839
840    return p - buf;
841}
842
843
844static int
845ietf_v1_gen_ping_frame (unsigned char *buf, int buf_len)
846{
847    if (buf_len > 0)
848    {
849        buf[0] = 0x01;
850        return 1;
851    }
852    else
853        return -1;
854}
855
856
857static size_t
858ietf_v1_connect_close_frame_size (int app_error, unsigned error_code,
859                                unsigned frame_type, size_t reason_len)
860{
861    return 1                                                         /* Type */
862         + (1 << vint_val2bits(error_code))                    /* Error code */
863         + (app_error ? 0 : 1 << vint_val2bits(frame_type))    /* Frame type */
864         + (1 << vint_val2bits(reason_len))          /* Reason Phrase Length */
865         + reason_len
866         ;
867}
868
869
870static int
871ietf_v1_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
872    int app_error, unsigned error_code, const char *reason, int reason_len)
873{
874    size_t needed;
875    unsigned bits_error, bits_reason;
876    unsigned char *p;
877
878    assert(!!reason == !!reason_len);
879
880    bits_reason = vint_val2bits(reason_len);
881    bits_error = vint_val2bits(error_code);
882    needed = 1 /* Type */ + (1 << bits_error)
883           + (app_error ? 0 : 1) /* Frame type */
884        /* TODO: frame type instead of just zero */
885           + (1 << bits_reason) + reason_len;
886
887    if (buf_len < needed)
888        return -1;
889
890    p = buf;
891    *p = 0x1C + !!app_error;
892    ++p;
893    vint_write(p, error_code, bits_error, 1 << bits_error);
894    p += 1 << bits_error;
895    if (!app_error)
896        *p++ = 0;   /* Frame type */ /* TODO */
897    vint_write(p, reason_len, bits_reason, 1 << bits_reason);
898    p += 1 << bits_reason;
899    if (reason_len)
900    {
901        memcpy(p, reason, reason_len);
902        p += reason_len;
903    }
904
905    assert((unsigned) (p - buf) == needed);
906    return p - buf;
907}
908
909
910static int
911ietf_v1_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
912        int *app_error_p, uint64_t *error_code, uint16_t *reason_len,
913        uint8_t *reason_offset)
914{
915    const unsigned char *const pend = buf + buf_len;
916    const unsigned char *p = buf + 1;
917    uint64_t len;
918    ptrdiff_t off;
919    int app_error, r;
920
921    r = vint_read(p, pend, error_code);
922    if (r < 0)
923        return -1;
924    p += r;
925
926    app_error = buf[0] == 0x1D;
927    if (!app_error)
928    {
929        r = vint_read(p, pend, &len);
930        if (r < 0)
931            return -1;
932        p += r;
933    }
934
935    r = vint_read(p, pend, &len);
936    if (r < 0)
937        return -1;
938    if (len > UINT16_MAX)
939        return -1;
940    p += r;
941
942    off = p - buf;
943    if (buf_len < off + len)
944        return -2;
945
946    *app_error_p = app_error;
947    *reason_len = len;
948    *reason_offset = off;
949    return off + len;
950}
951
952
953/* Returns number of bytes written or -1 on failure */
954/* This function makes an assumption that there is at least one range */
955static int
956ietf_v1_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
957        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
958        gaf_rechist_largest_recv_f rechist_largest_recv,
959        void *rechist, lsquic_time_t now, int *has_missing,
960        lsquic_packno_t *largest_received, const uint64_t *ecn_counts)
961{
962    unsigned char *block_count_p, *p = outbuf;
963    unsigned char *const end = p + outbuf_sz;
964    lsquic_time_t time_diff;
965    lsquic_packno_t packno_diff, gap, prev_low, maxno, rsize;
966    size_t sz;
967    const struct lsquic_packno_range *range;
968    unsigned a, b, c, addl_ack_blocks, ecn_needs;
969    unsigned bits[4];
970    enum ecn ecn;
971
972#define AVAIL() (end - p)
973
974#define CHECKOUT(sz) do {                                               \
975    if ((intptr_t) (sz) > AVAIL()) {                                    \
976        errno = ENOBUFS;                                                \
977        return -1;                                                      \
978    }                                                                   \
979} while (0)
980
981    range = rechist_first(rechist);
982    if (!range)
983    {
984        errno = EINVAL;
985        return -1;
986    }
987    // LSQ_DEBUG("range [%"PRIu64" - %"PRIu64"]", range->high, range->low);
988
989    time_diff = now - rechist_largest_recv(rechist);
990    time_diff >>= TP_DEF_ACK_DELAY_EXP;
991
992    maxno = range->high;
993    packno_diff = maxno - range->low;
994
995    a = vint_val2bits(maxno);
996    b = vint_val2bits(time_diff);
997    c = vint_val2bits(packno_diff);
998    sz = 1          /* Type */
999       + (1 << a)   /* Largest Acknowledged */
1000       + (1 << b)   /* ACK Delay */
1001       + 1          /* ACK Block Count */
1002       + (1 << c)   /* ACK Blocks */
1003       ;
1004
1005    CHECKOUT(sz);
1006
1007    if (ecn_counts)
1008    {
1009        for (ecn = 1; ecn <= 3; ++ecn)
1010            bits[ecn] = vint_val2bits(ecn_counts[ecn]);
1011        ecn_needs = (1 << bits[1]) + (1 << bits[2]) + (1 << bits[3]);
1012    }
1013    else
1014        ecn_needs = 0;
1015
1016    *p = 0x02 + !!ecn_counts;
1017    ++p;
1018
1019    vint_write(p, maxno, a, 1 << a);
1020    p += 1 << a;
1021    vint_write(p, time_diff, b, 1 << b);
1022    p += 1 << b;
1023    block_count_p = p;
1024    p += 1; /* Initial guess that we have fewer than 64 additional ACK Blocks */
1025    vint_write(p, packno_diff, c, 1 << c);
1026    p += 1 << c;
1027
1028    prev_low = range->low;
1029    addl_ack_blocks = 0;
1030    while ((range = rechist_next(rechist)))
1031    {
1032        // LSQ_DEBUG("range [%"PRIu64" - %"PRIu64"]", range->high, range->low);
1033        gap = prev_low - range->high - 1;
1034        rsize = range->high - range->low;
1035        a = vint_val2bits(gap - 1);
1036        b = vint_val2bits(rsize);
1037        if (ecn_needs + (1 << a) + (1 << b) > (unsigned)AVAIL())
1038            break;
1039        if (addl_ack_blocks == VINT_MAX_ONE_BYTE)
1040        {
1041            memmove(block_count_p + 2, block_count_p + 1,
1042                                                p - block_count_p - 1);
1043            ++p;
1044        }
1045        vint_write(p, gap - 1, a, 1 << a);
1046        p += 1 << a;
1047        vint_write(p, rsize, b, 1 << b);
1048        p += 1 << b;
1049        ++addl_ack_blocks;
1050        prev_low = range->low;
1051    }
1052
1053    /* Here we assume that addl_ack_blocks < (1 << 14), which is a safe
1054     * assumption to make.
1055     */
1056    vint_write(block_count_p, addl_ack_blocks,
1057                        addl_ack_blocks > VINT_MAX_ONE_BYTE,
1058                        1 + (addl_ack_blocks > VINT_MAX_ONE_BYTE));
1059
1060    if (ecn_counts)
1061    {
1062        assert(ecn_needs <= (unsigned)AVAIL());
1063        for (ecn = 1; ecn <= 3; ++ecn)
1064        {
1065            vint_write(p, ecn_counts[ecnmap[ecn]], bits[ecnmap[ecn]], 1 << bits[ecnmap[ecn]]);
1066            p += 1 << bits[ecnmap[ecn]];
1067        }
1068    }
1069
1070    *has_missing = addl_ack_blocks > 0;
1071    *largest_received = maxno;
1072    return p - (unsigned char *) outbuf;
1073
1074#undef CHECKOUT
1075#undef AVAIL
1076}
1077
1078
1079static size_t
1080ietf_v1_calc_stream_frame_header_sz (lsquic_stream_id_t stream_id,
1081                                            uint64_t offset, unsigned data_sz)
1082{
1083    if (offset)
1084        return 1
1085            + (1 << vint_val2bits(stream_id))
1086            + (1 << vint_val2bits(data_sz))
1087            + (1 << vint_val2bits(offset));
1088    else
1089        return 1
1090            + (1 << vint_val2bits(data_sz))
1091            + (1 << vint_val2bits(stream_id));
1092}
1093
1094
1095/* [draft-ietf-quic-transport-24] Section 19.6 */
1096static size_t
1097ietf_v1_calc_crypto_frame_header_sz (uint64_t offset, unsigned data_sz)
1098{
1099    return 1    /* Frame type */
1100         + (1 << vint_val2bits(offset))
1101         + (1 << vint_val2bits(data_sz))
1102         ;
1103}
1104
1105
1106static enum quic_frame_type
1107ietf_v1_parse_frame_type (const unsigned char *buf, size_t len)
1108{
1109    uint64_t val;
1110    int s;
1111
1112    if (len > 0 && buf[0] < 0x40)
1113        return lsquic_iquic_byte2type[buf[0]];
1114
1115    s = vint_read(buf, buf + len, &val);
1116    if (s > 0 && (unsigned) s == (1u << vint_val2bits(val)))
1117        switch (val)
1118        {
1119        case FRAME_TYPE_ACK_FREQUENCY:  return QUIC_FRAME_ACK_FREQUENCY;
1120        case FRAME_TYPE_TIMESTAMP:      return QUIC_FRAME_TIMESTAMP;
1121        default:    break;
1122        }
1123
1124    return QUIC_FRAME_INVALID;
1125}
1126
1127
1128static unsigned
1129ietf_v1_path_chal_frame_size (void)
1130{
1131    return 1 + sizeof(uint64_t);
1132}
1133
1134
1135static int
1136ietf_v1_gen_path_chal_frame (unsigned char *buf, size_t len, uint64_t chal)
1137{
1138    if (len >= 1 + sizeof(chal))
1139    {
1140        *buf = 0x1A;
1141        memcpy(buf + 1, &chal, sizeof(chal));
1142        return 1 + sizeof(chal);
1143    }
1144    else
1145        return -1;
1146}
1147
1148
1149static int
1150ietf_v1_parse_path_chal_frame (const unsigned char *buf, size_t len,
1151                                                            uint64_t *chal)
1152{
1153    if (len >= 9)
1154    {
1155        memcpy(chal, buf + 1, 8);
1156        return 9;
1157    }
1158    else
1159        return -1;
1160}
1161
1162
1163static unsigned
1164ietf_v1_path_resp_frame_size (void)
1165{
1166    return 1 + sizeof(uint64_t);
1167}
1168
1169
1170static int
1171ietf_v1_gen_path_resp_frame (unsigned char *buf, size_t len, uint64_t resp)
1172{
1173    if (len >= 1 + sizeof(resp))
1174    {
1175        *buf = 0x1B;
1176        memcpy(buf + 1, &resp, sizeof(resp));
1177        return 1 + sizeof(resp);
1178    }
1179    else
1180        return -1;
1181}
1182
1183
1184static int
1185ietf_v1_parse_path_resp_frame (const unsigned char *buf, size_t len,
1186                                                            uint64_t *resp)
1187{
1188    return ietf_v1_parse_path_chal_frame(buf, len, resp);
1189}
1190
1191
1192static void
1193ietf_v1_turn_on_fin (unsigned char *stream_frame_header)
1194{
1195    *stream_frame_header |= 1;
1196}
1197
1198
1199static unsigned
1200ietf_v1_packno_bits2len (enum packno_bits bits)
1201{
1202    return iquic_packno_bits2len(bits);
1203}
1204
1205
1206static enum packno_bits
1207ietf_v1_calc_packno_bits (lsquic_packno_t packno,
1208                    lsquic_packno_t least_unacked, uint64_t n_in_flight)
1209{
1210    uint64_t delta;
1211    unsigned bits;
1212
1213    delta = packno - least_unacked;
1214    if (n_in_flight > delta)
1215        delta = n_in_flight;
1216
1217    delta *= 4;
1218    bits = (delta >= (1ULL <<  8))
1219         + (delta >= (1ULL << 16))
1220         + (delta >= (1ULL << 24))
1221         ;
1222
1223    return bits;
1224}
1225
1226
1227static int
1228ietf_v1_parse_one_varint (const unsigned char *buf, size_t len, uint64_t *val)
1229{
1230    int s;
1231
1232    s = vint_read(buf + 1, buf + len, val);
1233    if (s >= 0)
1234        return 1 + s;
1235    else
1236        return s;
1237}
1238
1239
1240static int
1241ietf_v1_gen_one_varint (unsigned char *buf, size_t len,
1242                                        unsigned char type, uint64_t val)
1243{
1244    unsigned vbits;
1245    unsigned char *p;
1246
1247    vbits = vint_val2bits(val);
1248
1249    if (1u + (1u << vbits) > len)
1250        return -1;
1251
1252    p = buf;
1253    *p++ = type;
1254    vint_write(p, val, vbits, 1 << vbits);
1255    p += 1 << vbits;
1256
1257    return p - buf;
1258}
1259
1260
1261static int
1262ietf_v1_gen_blocked_frame (unsigned char *buf, size_t buf_len, uint64_t off)
1263{
1264    return ietf_v1_gen_one_varint(buf, buf_len, 0x14, off);
1265}
1266
1267
1268static int
1269ietf_v1_parse_blocked_frame (const unsigned char *buf, size_t sz, uint64_t *off)
1270{
1271    return ietf_v1_parse_one_varint(buf, sz, off);
1272}
1273
1274
1275static unsigned
1276ietf_v1_blocked_frame_size (uint64_t off)
1277{
1278    return 1 + vint_size(off);
1279}
1280
1281
1282static int
1283ietf_v1_parse_max_data (const unsigned char *buf, size_t len, uint64_t *val)
1284{
1285    return ietf_v1_parse_one_varint(buf, len, val);
1286}
1287
1288
1289static int
1290ietf_v1_gen_max_data_frame (unsigned char *buf, size_t len, uint64_t val)
1291{
1292    return ietf_v1_gen_one_varint(buf, len, 0x10, val);
1293}
1294
1295
1296static unsigned
1297ietf_v1_max_data_frame_size (uint64_t val)
1298{
1299    return 1 + vint_size(val);
1300}
1301
1302
1303static int
1304ietf_v1_parse_retire_cid_frame (const unsigned char *buf, size_t len,
1305                                                                uint64_t *val)
1306{
1307    return ietf_v1_parse_one_varint(buf, len, val);
1308}
1309
1310
1311static int
1312ietf_v1_gen_retire_cid_frame (unsigned char *buf, size_t len, uint64_t val)
1313{
1314    return ietf_v1_gen_one_varint(buf, len, 0x19, val);
1315}
1316
1317
1318static size_t
1319ietf_v1_retire_cid_frame_size (uint64_t val)
1320{
1321    return 1 + vint_size(val);
1322}
1323
1324
1325static int
1326ietf_v1_parse_new_conn_id (const unsigned char *buf, size_t len,
1327                        uint64_t *seqno, uint64_t *retire_prior_to,
1328                        lsquic_cid_t *cid, const unsigned char **reset_token)
1329{
1330    const unsigned char *p = buf + 1;
1331    const unsigned char *const end = buf + len;
1332    unsigned char cid_len;
1333    int s;
1334
1335    s = vint_read(p, end, seqno);
1336    if (s < 0)
1337        return s;
1338    p += s;
1339
1340    s = vint_read(p, end, retire_prior_to);
1341    if (s < 0)
1342        return s;
1343    p += s;
1344
1345    if (p >= end)
1346        return -1;
1347
1348    cid_len = *p++;
1349    if (cid_len == 0 || cid_len > MAX_CID_LEN)
1350        return -2;
1351
1352    if ((unsigned) (end - p) < cid_len + IQUIC_SRESET_TOKEN_SZ)
1353        return -1;
1354    cid->len = cid_len;
1355    memcpy(cid->idbuf, p, cid_len);
1356    p += cid_len;
1357    if (reset_token)
1358        *reset_token = p;
1359    p += IQUIC_SRESET_TOKEN_SZ;
1360
1361    return p - buf;
1362}
1363
1364
1365/* Size of a frame that contains two varints */
1366static unsigned
1367ietf_v1_two_varints_size (uint64_t vals[2])
1368{
1369    unsigned vbits[2];
1370
1371    vbits[0] = vint_val2bits(vals[0]);
1372    vbits[1] = vint_val2bits(vals[1]);
1373    return 1u + (1u << vbits[0]) + (1u << vbits[1]);
1374}
1375
1376
1377static int
1378ietf_v1_gen_two_varints (unsigned char *buf, size_t len,
1379                                    unsigned char type, uint64_t vals[2])
1380{
1381    unsigned vbits[2];
1382    unsigned char *p;
1383
1384    vbits[0] = vint_val2bits(vals[0]);
1385    vbits[1] = vint_val2bits(vals[1]);
1386
1387    if (1u + (1u << vbits[0]) + (1u << vbits[1]) > len)
1388        return -1;
1389
1390    p = buf;
1391    *p++ = type;
1392    vint_write(p, vals[0], vbits[0], 1 << vbits[0]);
1393    p += 1 << vbits[0];
1394    vint_write(p, vals[1], vbits[1], 1 << vbits[1]);
1395    p += 1 << vbits[1];
1396
1397    return p - buf;
1398}
1399
1400
1401static int
1402ietf_v1_parse_two_varints (const unsigned char *buf, size_t len, uint64_t *vals[2])
1403{
1404    const unsigned char *p = buf;
1405    const unsigned char *const end = p + len;
1406    int s;
1407
1408    if (len < 2)
1409        return -1;
1410
1411    ++p;    /* Type */
1412
1413    s = vint_read(p, end, vals[0]);
1414    if (s < 0)
1415        return s;
1416    p += s;
1417
1418    s = vint_read(p, end, vals[1]);
1419    if (s < 0)
1420        return s;
1421    p += s;
1422
1423    return p - buf;
1424}
1425
1426
1427/* vals[0] is the frame type */
1428static unsigned
1429ietf_v1_frame_with_varints_size (unsigned n, uint64_t vals[])
1430{
1431    unsigned vbits, size;
1432
1433    assert(n > 0);
1434    vbits = vint_val2bits(vals[0]);
1435    size = 1 << vbits;
1436    while (--n)
1437    {
1438        vbits = vint_val2bits(vals[n]);
1439        size += 1 << vbits;
1440    }
1441
1442    return size;
1443}
1444
1445
1446/* vals[0] is the frame type */
1447static int
1448ietf_v1_gen_frame_with_varints (unsigned char *buf, size_t len,
1449                                    unsigned count, uint64_t vals[])
1450{
1451    unsigned vbits, n;
1452    unsigned char *p;
1453
1454    if (ietf_v1_frame_with_varints_size(count, vals) > len)
1455        return -1;
1456
1457    p = buf;
1458    for (n = 0; n < count; ++n)
1459    {
1460        vbits = vint_val2bits(vals[n]);
1461        vint_write(p, vals[n], vbits, 1 << vbits);
1462        p += 1 << vbits;
1463    }
1464
1465    return p - buf;
1466}
1467
1468
1469/* Frame type is checked when frame type is parsed.  The only use here is
1470 * to calculate skip length.
1471 */
1472static int
1473ietf_v1_parse_frame_with_varints (const unsigned char *buf, size_t len,
1474            const uint64_t frame_type, unsigned count, uint64_t *vals[])
1475{
1476    const unsigned char *p = buf;
1477    const unsigned char *const end = p + len;
1478    unsigned vbits, n;
1479    int s;
1480
1481    vbits = vint_val2bits(frame_type);
1482    p += 1 << vbits;
1483
1484    for (n = 0; n < count; ++n)
1485    {
1486        s = vint_read(p, end, vals[n]);
1487        if (s < 0)
1488            return s;
1489        p += s;
1490    }
1491
1492    return p - buf;
1493}
1494
1495
1496
1497static int
1498ietf_v1_parse_stream_blocked_frame (const unsigned char *buf, size_t len,
1499                            lsquic_stream_id_t *stream_id, uint64_t *offset)
1500{
1501    return ietf_v1_parse_two_varints(buf, len,
1502                                       (uint64_t *[]) { stream_id, offset, });
1503}
1504
1505
1506static unsigned
1507ietf_v1_stream_blocked_frame_size (lsquic_stream_id_t stream_id, uint64_t off)
1508{
1509    return ietf_v1_two_varints_size((uint64_t []) { stream_id, off, });
1510}
1511
1512
1513static int
1514ietf_v1_gen_streams_blocked_frame (unsigned char *buf, size_t len,
1515                                    enum stream_dir sd, uint64_t limit)
1516{
1517    return ietf_v1_gen_one_varint(buf, len, 0x16 + (sd == SD_UNI), limit);
1518}
1519
1520
1521static int
1522ietf_v1_parse_streams_blocked_frame (const unsigned char *buf, size_t len,
1523                                    enum stream_dir *sd, uint64_t *limit)
1524{
1525    int s;
1526
1527    s = ietf_v1_parse_one_varint(buf, len, limit);
1528    if (s > 0)
1529    {
1530        if (buf[0] == 0x16)
1531            *sd = SD_BIDI;
1532        else
1533            *sd = SD_UNI;
1534    }
1535    return s;
1536}
1537
1538
1539static unsigned
1540ietf_v1_streams_blocked_frame_size (uint64_t limit)
1541{
1542    return 1 + vint_size(limit);
1543}
1544
1545
1546static int
1547ietf_v1_gen_stream_blocked_frame (unsigned char *buf, size_t len,
1548                                    lsquic_stream_id_t stream_id, uint64_t off)
1549{
1550    return ietf_v1_gen_two_varints(buf, len, 0x15, (uint64_t[]){ stream_id, off, });
1551}
1552
1553
1554static int
1555ietf_v1_gen_max_stream_data_frame (unsigned char *buf, size_t len,
1556                                    lsquic_stream_id_t stream_id, uint64_t off)
1557{
1558    return ietf_v1_gen_two_varints(buf, len, 0x11, (uint64_t[]){ stream_id, off, });
1559}
1560
1561
1562static unsigned
1563ietf_v1_max_stream_data_frame_size (lsquic_stream_id_t stream_id, uint64_t off)
1564{
1565    return ietf_v1_two_varints_size((uint64_t []) { stream_id, off, });
1566}
1567
1568
1569
1570static int
1571ietf_v1_parse_max_stream_data_frame (const unsigned char *buf, size_t len,
1572                                lsquic_stream_id_t *stream_id, uint64_t *off)
1573{
1574    return ietf_v1_parse_two_varints(buf, len, (uint64_t *[]){ stream_id, off, });
1575}
1576
1577
1578static int
1579ietf_v1_parse_max_streams_frame (const unsigned char *buf, size_t len,
1580                                    enum stream_dir *sd, uint64_t *max_streams)
1581{
1582    int s;
1583
1584    s = ietf_v1_parse_one_varint(buf, len, max_streams);
1585    if (s > 0)
1586        *sd = buf[0] == 0x12 ? SD_BIDI : SD_UNI;
1587    return s;
1588}
1589
1590
1591static int
1592ietf_v1_gen_max_streams_frame (unsigned char *buf, size_t len,
1593                                    enum stream_dir sd, uint64_t limit)
1594{
1595    return ietf_v1_gen_one_varint(buf, len, 0x12 + (sd == SD_UNI), limit);
1596}
1597
1598
1599static unsigned
1600ietf_v1_max_streams_frame_size (uint64_t limit)
1601{
1602    return 1 + vint_size(limit);
1603}
1604
1605
1606static size_t
1607ietf_v1_new_token_frame_size (size_t token_sz)
1608{
1609    unsigned bits;
1610
1611    bits = vint_val2bits(token_sz);
1612    return 1 + (1 << bits) + token_sz;
1613}
1614
1615
1616static int
1617ietf_v1_gen_new_token_frame (unsigned char *buf, size_t buf_sz,
1618                                const unsigned char *token, size_t token_sz)
1619{
1620    unsigned char *p;
1621    unsigned bits;
1622
1623    bits = vint_val2bits(token_sz);
1624    if (buf_sz < 1 + (1 << bits) + token_sz)
1625    {
1626        errno = ENOBUFS;
1627        return -1;
1628    }
1629
1630    p = buf;
1631    *p++ = 0x07;
1632    vint_write(p, token_sz, bits, 1 << bits);
1633    p += 1 << bits;
1634    memcpy(p, token, token_sz);
1635    p += token_sz;
1636
1637    return p - buf;
1638}
1639
1640
1641static size_t
1642ietf_v1_new_connection_id_frame_size (unsigned seqno, unsigned scid_len)
1643{
1644    unsigned bits;
1645
1646    bits = vint_val2bits(seqno);
1647    return 1                /* Frame Type */
1648         + (1 << bits)      /* Sequence Number */
1649         + 1                /* Retire Prior To (we always set it to zero */
1650         + 1                /* CID length */
1651         + scid_len
1652         + IQUIC_SRESET_TOKEN_SZ;
1653}
1654
1655
1656static int
1657ietf_v1_gen_new_connection_id_frame (unsigned char *buf, size_t buf_sz,
1658            unsigned seqno, const struct lsquic_cid *cid,
1659            const unsigned char *token, size_t token_sz)
1660{
1661    unsigned char *p;
1662    unsigned bits;
1663
1664    if (buf_sz < ietf_v1_new_connection_id_frame_size(seqno, cid->len))
1665        return -1;
1666
1667    p = buf;
1668    *p++ = 0x18;
1669    bits = vint_val2bits(seqno);
1670    vint_write(p, seqno, bits, 1 << bits);
1671    p += 1 << bits;
1672    *p++ = 0;   /* Retire Prior To */
1673    *p++ = cid->len;
1674    memcpy(p, cid->idbuf, cid->len);
1675    p += cid->len;
1676    memcpy(p, token, token_sz);
1677    p += token_sz;
1678
1679    return p - buf;
1680}
1681
1682
1683/* [draft-ietf-quic-transport-17] Section-17.2 */
1684static const enum header_type bits2ht[4] =
1685{
1686    [0] = HETY_INITIAL,
1687    [1] = HETY_0RTT,
1688    [2] = HETY_HANDSHAKE,
1689    [3] = HETY_RETRY,
1690};
1691
1692
1693int
1694lsquic_ietf_v1_parse_packet_in_long_begin (struct lsquic_packet_in *packet_in,
1695                size_t length, int is_server, unsigned cid_len,
1696                struct packin_parse_state *state)
1697{
1698    const unsigned char *p = packet_in->pi_data;
1699    const unsigned char *const end = p + length;
1700    lsquic_ver_tag_t tag;
1701    enum header_type header_type;
1702    unsigned dcil, scil;
1703    int verneg, r;
1704    unsigned char first_byte;
1705    uint64_t payload_len, token_len;
1706
1707    if (length < 6)
1708        return -1;
1709    first_byte = *p++;
1710
1711    memcpy(&tag, p, 4);
1712    p += 4;
1713    verneg = 0 == tag;
1714    if (!verneg)
1715        header_type = bits2ht[ (first_byte >> 4) & 3 ];
1716    else
1717        header_type = HETY_VERNEG;
1718
1719    packet_in->pi_header_type = header_type;
1720
1721    dcil = *p++;
1722    if (p + dcil >= end || dcil > MAX_CID_LEN)
1723        return -1;
1724    if (dcil)
1725    {
1726        memcpy(packet_in->pi_dcid.idbuf, p, dcil);
1727        packet_in->pi_flags |= PI_CONN_ID;
1728        p += dcil;
1729    }
1730    packet_in->pi_dcid.len = dcil;
1731
1732    scil = *p++;
1733    if (p + scil > end || scil > MAX_CID_LEN)
1734        return -1;
1735    if (scil)
1736    {
1737        packet_in->pi_scid_off = p - packet_in->pi_data;
1738        p += scil;
1739    }
1740    packet_in->pi_scid_len = scil;
1741
1742    switch (header_type)
1743    {
1744    case HETY_INITIAL:
1745        if (is_server && dcil < MIN_INITIAL_DCID_LEN)
1746            return -1;
1747        r = vint_read(p, end, &token_len);
1748        if (r < 0)
1749            return -1;
1750        if (token_len && !is_server)
1751        {
1752            /* From [draft-ietf-quic-transport-14]:
1753             *
1754             *  Token Length:  A variable-length integer specifying the
1755             *  length of the Token field, in bytes.  This value is zero
1756             *  if no token is present.  Initial packets sent by the
1757             *  server MUST set the Token Length field to zero; clients
1758             *  that receive an Initial packet with a non-zero Token
1759             *  Length field MUST either discard the packet or generate
1760             *  a connection error of type PROTOCOL_VIOLATION.
1761             */
1762            return -1;
1763        }
1764        p += r;
1765        if (token_len)
1766        {
1767            if (token_len >=
1768                        1ull << (sizeof(packet_in->pi_token_size) * 8))
1769                return -1;
1770            if (p + token_len > end)
1771                return -1;
1772            packet_in->pi_token = p - packet_in->pi_data;
1773            packet_in->pi_token_size = token_len;
1774            p += token_len;
1775        }
1776        /* fall-through */
1777    case HETY_HANDSHAKE:
1778    case HETY_0RTT:
1779        if (p >= end)
1780            return -1;
1781        r = vint_read(p, end, &payload_len);
1782        if (r < 0)
1783            return -1;
1784        p += r;
1785        if (p - packet_in->pi_data + payload_len > length)
1786            return -1;
1787        length = p - packet_in->pi_data + payload_len;
1788        if (end - p < 4)
1789            return -1;
1790        state->pps_p      = p - r;
1791        state->pps_nbytes = r;
1792        packet_in->pi_quic_ver = 1;
1793        break;
1794    case HETY_RETRY:
1795        if (p >= end)
1796            return -1;
1797        if (p
1798            /* [draft-ietf-quic-transport-25] Section 17.2.5 says that "a
1799             * client MUST discard a Retry packet with a zero-length Retry
1800             * Token field."  We might as well do it here.
1801             */
1802            + 1
1803            /* Integrity tag length: */
1804            + 16 > end)
1805                return -1;
1806        packet_in->pi_token = p - packet_in->pi_data;
1807        packet_in->pi_token_size = end - p - 16;
1808        /* Tag validation happens later */
1809        p = end;
1810        length = end - packet_in->pi_data;
1811        state->pps_p      = NULL;
1812        state->pps_nbytes = 0;
1813        packet_in->pi_quic_ver = 1;
1814        break;
1815    default:
1816        assert(header_type == HETY_VERNEG);
1817        if (p >= end || (3 & (uintptr_t) (end - p)))
1818            return -1;
1819        packet_in->pi_quic_ver = p - packet_in->pi_data;
1820        p = end;
1821        state->pps_p      = NULL;
1822        state->pps_nbytes = 0;
1823        break;
1824    }
1825
1826    packet_in->pi_header_sz     = p - packet_in->pi_data;
1827    packet_in->pi_data_sz       = length;
1828    packet_in->pi_nonce         = 0;
1829    packet_in->pi_refcnt        = 0;
1830    packet_in->pi_frame_types   = 0;
1831    memset(&packet_in->pi_next, 0, sizeof(packet_in->pi_next));
1832    packet_in->pi_refcnt        = 0;
1833    packet_in->pi_received      = 0;
1834
1835    /* Packet number is set to an invalid value.  The packet number must
1836     * be decrypted, which happens later.
1837     */
1838    packet_in->pi_packno        = 1ULL << 62;
1839
1840    return 0;
1841}
1842
1843
1844/* Is this a valid Initial packet?  We take the perspective of the server. */
1845int
1846lsquic_is_valid_ietf_v1_or_Q046plus_hs_packet (const unsigned char *buf,
1847                                        size_t length, lsquic_ver_tag_t *tagp)
1848{
1849    const unsigned char *p = buf;
1850    const unsigned char *const end = p + length;
1851    lsquic_ver_tag_t tag;
1852    enum header_type header_type;
1853    unsigned dcil, scil;
1854    int r;
1855    unsigned char first_byte;
1856    uint64_t payload_len, token_len, packet_len;
1857
1858    if (length < 6)
1859        return 0;
1860    first_byte = *p++;
1861
1862    header_type = bits2ht[ (first_byte >> 4) & 3 ];
1863    if (header_type != HETY_INITIAL)
1864        return 0;
1865
1866    memcpy(&tag, p, 4);
1867    p += 4;
1868    switch (tag)
1869    {
1870    case 0:
1871        return 0;       /* Client never sends version negotiation packets */
1872    case TAG('Q', '0', '4', '6'):
1873        dcil = p[0] >> 4;
1874        if (dcil)
1875            dcil += 3;
1876        scil = p[0] & 0xF;
1877        if (scil)
1878            scil += 3;
1879        ++p;
1880
1881        if (!(dcil == GQUIC_CID_LEN && scil == 0))
1882            return 0;
1883
1884        packet_len = first_byte & 3;
1885
1886        if (end - p < (ptrdiff_t) (dcil + scil + packet_len))
1887            return 0;
1888        break;
1889    case TAG('Q', '0', '5', '0'):
1890        dcil = *p++;
1891        if (dcil != 8)
1892            return 0;
1893        if (p + dcil + 1 >= end)
1894            return 0;
1895        p += dcil;
1896        scil = *p++;
1897        if (scil != 0)
1898            return 0;
1899        goto read_token;
1900    default:
1901        dcil = *p++;
1902        if (dcil < MIN_INITIAL_DCID_LEN || dcil > MAX_CID_LEN)
1903            return 0;
1904        if (p + dcil >= end)
1905            return 0;
1906        p += dcil;
1907        scil = *p++;
1908        if (p + scil > end || scil > MAX_CID_LEN)
1909            return 0;
1910        p += scil;
1911  read_token:
1912        r = vint_read(p, end, &token_len);
1913        if (r < 0)
1914            return 0;
1915        p += r;
1916        p += token_len;
1917        if (p >= end)
1918            return 0;
1919        r = vint_read(p, end, &payload_len);
1920        if (r < 0)
1921            return 0;
1922        p += r;
1923        if (p - buf + payload_len > length)
1924            return 0;
1925        if (end - p < 4)
1926            return 0;
1927    }
1928
1929    *tagp = tag;
1930    return 1;
1931}
1932
1933
1934int
1935lsquic_ietf_v1_parse_packet_in_short_begin (struct lsquic_packet_in *packet_in,
1936                size_t length, int is_server, unsigned cid_len,
1937                struct packin_parse_state *state)
1938{
1939    unsigned char byte;
1940    unsigned header_sz;
1941
1942    /* By the time this function has been called, we know length is non-zero */
1943    byte = packet_in->pi_data[0];
1944
1945    /* [draft-ietf-quic-transport-17] Section 17.3 */
1946    /* 01SRRKPP */
1947
1948    if (cid_len)
1949    {
1950        header_sz = 1 + cid_len;
1951        if (length < header_sz)
1952            return -1;
1953        memcpy(packet_in->pi_dcid.idbuf, packet_in->pi_data + 1, cid_len);
1954        packet_in->pi_dcid.len = cid_len;
1955        packet_in->pi_flags |= PI_CONN_ID;
1956    }
1957    else
1958        header_sz = 1;
1959
1960    packet_in->pi_flags |= ((byte & 0x20) > 0) << PIBIT_SPIN_SHIFT;
1961    packet_in->pi_flags |= (byte & 3) << PIBIT_BITS_SHIFT;
1962
1963    packet_in->pi_header_sz     = header_sz;
1964    packet_in->pi_data_sz       = length;
1965    packet_in->pi_quic_ver      = 0;
1966    packet_in->pi_nonce         = 0;
1967    packet_in->pi_refcnt        = 0;
1968    packet_in->pi_frame_types   = 0;
1969    memset(&packet_in->pi_next, 0, sizeof(packet_in->pi_next));
1970    packet_in->pi_refcnt        = 0;
1971    packet_in->pi_received      = 0;
1972
1973    /* This is so that Q046 works, ID-18 code does not use it */
1974    state->pps_p                = packet_in->pi_data + header_sz;
1975    state->pps_nbytes           = 1 + (byte & 3);
1976
1977    return 0;
1978}
1979
1980
1981#if __GNUC__
1982#   define popcount __builtin_popcount
1983#else
1984static int
1985popcount (unsigned v)
1986{
1987    int count, i;
1988    for (i = 0, count = 0; i < sizeof(v) * 8; ++i)
1989        if (v & (1 << i))
1990            ++count;
1991    return count;
1992}
1993#endif
1994
1995
1996int
1997lsquic_ietf_v1_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
1998         const lsquic_cid_t *scid, const lsquic_cid_t *dcid, unsigned versions,
1999         uint8_t rand)
2000{
2001    size_t need;
2002    int r;
2003
2004    need = 1 /* Type */ + 4 /* Version */ + 1 /* DCIL */
2005                + dcid->len + 1 /* SCIL */ + scid->len + popcount(versions) * 4;
2006
2007    if (need > bufsz)
2008        return -1;
2009
2010    *buf++ = 0x80 | 0x40 | rand;
2011    memset(buf, 0, 4);
2012    buf += 4;
2013
2014    /* From [draft-ietf-quic-transport-22], Section 17.2.1:
2015     *
2016     *  The server MUST include the value from the Source Connection ID field
2017     *  of the packet it receives in the Destination Connection ID field.
2018     *  The value for Source Connection ID MUST be copied from the
2019     *  Destination Connection ID of the received packet, which is initially
2020     *  randomly selected by a client.  Echoing both connection IDs gives
2021     *  clients some assurance that the server received the packet and that
2022     *  the Version Negotiation packet was not generated by an off-path
2023     *  attacker.
2024     */
2025
2026    *buf++ = dcid->len;
2027    memcpy(buf, dcid->idbuf, dcid->len);
2028    buf += dcid->len;
2029    *buf++ = scid->len;
2030    memcpy(buf, scid->idbuf, scid->len);
2031    buf += scid->len;
2032
2033    r = lsquic_gen_ver_tags(buf, bufsz - 1 - 4 - 2 - dcid->len - scid->len,
2034                                                                    versions);
2035    if (r < 0)
2036        return -1;
2037    assert((unsigned) r == popcount(versions) * 4u);
2038
2039    return need;
2040}
2041
2042
2043static int
2044ietf_v1_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
2045{
2046    if (buf_len > 0)
2047    {
2048        *buf = 0x1E;
2049        return 1;
2050    }
2051    else
2052        return -1;
2053}
2054
2055
2056static int
2057ietf_v1_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
2058{
2059    assert(buf[0] == 0x1E);
2060    assert(buf_len > 0);
2061    return 1;
2062}
2063
2064
2065static int
2066ietf_v1_gen_ack_frequency_frame (unsigned char *buf, size_t buf_len,
2067    uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad)
2068{
2069    return ietf_v1_gen_frame_with_varints(buf, buf_len, 4,
2070        (uint64_t[]){ FRAME_TYPE_ACK_FREQUENCY, seqno, pack_tol, upd_mad });
2071}
2072
2073
2074static int
2075ietf_v1_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
2076    uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad)
2077{
2078    return ietf_v1_parse_frame_with_varints(buf, buf_len,
2079                FRAME_TYPE_ACK_FREQUENCY,
2080                3, (uint64_t *[]) { seqno, pack_tol, upd_mad });
2081}
2082
2083
2084static unsigned
2085ietf_v1_ack_frequency_frame_size (uint64_t seqno, uint64_t pack_tol,
2086    uint64_t upd_mad)
2087{
2088    return ietf_v1_frame_with_varints_size(4,
2089            (uint64_t[]){ FRAME_TYPE_ACK_FREQUENCY, seqno, pack_tol, upd_mad });
2090}
2091
2092
2093static unsigned
2094ietf_v1_handshake_done_frame_size (void)
2095{
2096    return 1;
2097}
2098
2099
2100static int
2101ietf_v1_gen_timestamp_frame (unsigned char *buf, size_t buf_len,
2102                                                            uint64_t timestamp)
2103{
2104    return ietf_v1_gen_frame_with_varints(buf, buf_len, 2,
2105                            (uint64_t[]){ FRAME_TYPE_TIMESTAMP, timestamp });
2106}
2107
2108
2109static int
2110ietf_v1_parse_timestamp_frame (const unsigned char *buf, size_t buf_len,
2111                                                            uint64_t *timestamp)
2112{
2113    return ietf_v1_parse_frame_with_varints(buf, buf_len,
2114                FRAME_TYPE_TIMESTAMP, 1, (uint64_t *[]) { timestamp });
2115}
2116
2117
2118const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
2119{
2120    .pf_gen_reg_pkt_header            =  ietf_v1_gen_reg_pkt_header,
2121    .pf_parse_packet_in_finish        =  ietf_v1_parse_packet_in_finish,
2122    .pf_gen_stream_frame              =  ietf_v1_gen_stream_frame,
2123    .pf_calc_stream_frame_header_sz   =  ietf_v1_calc_stream_frame_header_sz,
2124    .pf_parse_stream_frame            =  ietf_v1_parse_stream_frame,
2125    .pf_parse_ack_frame               =  ietf_v1_parse_ack_frame,
2126    .pf_gen_ack_frame                 =  ietf_v1_gen_ack_frame,
2127    .pf_gen_blocked_frame             =  ietf_v1_gen_blocked_frame,
2128    .pf_parse_blocked_frame           =  ietf_v1_parse_blocked_frame,
2129    .pf_blocked_frame_size            =  ietf_v1_blocked_frame_size,
2130    .pf_rst_frame_size                =  ietf_v1_rst_frame_size,
2131    .pf_gen_rst_frame                 =  ietf_v1_gen_rst_frame,
2132    .pf_parse_rst_frame               =  ietf_v1_parse_rst_frame,
2133    .pf_connect_close_frame_size      =  ietf_v1_connect_close_frame_size,
2134    .pf_gen_connect_close_frame       =  ietf_v1_gen_connect_close_frame,
2135    .pf_parse_connect_close_frame     =  ietf_v1_parse_connect_close_frame,
2136    .pf_gen_ping_frame                =  ietf_v1_gen_ping_frame,
2137    .pf_parse_frame_type              =  ietf_v1_parse_frame_type,
2138    .pf_turn_on_fin                   =  ietf_v1_turn_on_fin,
2139    .pf_packout_size                  =  ietf_v1_packout_size,
2140    .pf_packout_max_header_size       =  ietf_v1_packout_max_header_size,
2141    .pf_path_chal_frame_size          =  ietf_v1_path_chal_frame_size,
2142    .pf_parse_path_chal_frame         =  ietf_v1_parse_path_chal_frame,
2143    .pf_gen_path_chal_frame           =  ietf_v1_gen_path_chal_frame,
2144    .pf_path_resp_frame_size          =  ietf_v1_path_resp_frame_size,
2145    .pf_gen_path_resp_frame           =  ietf_v1_gen_path_resp_frame,
2146    .pf_parse_path_resp_frame         =  ietf_v1_parse_path_resp_frame,
2147    .pf_calc_packno_bits              =  ietf_v1_calc_packno_bits,
2148    .pf_packno_bits2len               =  ietf_v1_packno_bits2len,
2149    .pf_packno_info                   =  ietf_v1_packno_info,
2150    .pf_gen_crypto_frame              =  ietf_v1_gen_crypto_frame,
2151    .pf_parse_crypto_frame            =  ietf_v1_parse_crypto_frame,
2152    .pf_calc_crypto_frame_header_sz   =  ietf_v1_calc_crypto_frame_header_sz,
2153    .pf_parse_max_data                =  ietf_v1_parse_max_data,
2154    .pf_gen_max_data_frame            =  ietf_v1_gen_max_data_frame,
2155    .pf_max_data_frame_size           =  ietf_v1_max_data_frame_size,
2156    .pf_parse_new_conn_id             =  ietf_v1_parse_new_conn_id,
2157    .pf_gen_stream_blocked_frame      =  ietf_v1_gen_stream_blocked_frame,
2158    .pf_parse_stream_blocked_frame    =  ietf_v1_parse_stream_blocked_frame,
2159    .pf_stream_blocked_frame_size     =  ietf_v1_stream_blocked_frame_size,
2160    .pf_gen_max_stream_data_frame     =  ietf_v1_gen_max_stream_data_frame,
2161    .pf_parse_max_stream_data_frame   =  ietf_v1_parse_max_stream_data_frame,
2162    .pf_max_stream_data_frame_size    =  ietf_v1_max_stream_data_frame_size,
2163    .pf_parse_stop_sending_frame      =  ietf_v1_parse_stop_sending_frame,
2164    .pf_gen_stop_sending_frame        =  ietf_v1_gen_stop_sending_frame,
2165    .pf_stop_sending_frame_size       =  ietf_v1_stop_sending_frame_size,
2166    .pf_parse_new_token_frame         =  ietf_v1_parse_new_token_frame,
2167    .pf_new_connection_id_frame_size  =  ietf_v1_new_connection_id_frame_size,
2168    .pf_gen_new_connection_id_frame   =  ietf_v1_gen_new_connection_id_frame,
2169    .pf_new_token_frame_size          =  ietf_v1_new_token_frame_size,
2170    .pf_gen_new_token_frame           =  ietf_v1_gen_new_token_frame,
2171    .pf_parse_retire_cid_frame        =  ietf_v1_parse_retire_cid_frame,
2172    .pf_gen_retire_cid_frame          =  ietf_v1_gen_retire_cid_frame,
2173    .pf_retire_cid_frame_size         =  ietf_v1_retire_cid_frame_size,
2174    .pf_gen_streams_blocked_frame     =  ietf_v1_gen_streams_blocked_frame,
2175    .pf_parse_streams_blocked_frame   =  ietf_v1_parse_streams_blocked_frame,
2176    .pf_streams_blocked_frame_size    =  ietf_v1_streams_blocked_frame_size,
2177    .pf_gen_max_streams_frame         =  ietf_v1_gen_max_streams_frame,
2178    .pf_parse_max_streams_frame       =  ietf_v1_parse_max_streams_frame,
2179    .pf_max_streams_frame_size        =  ietf_v1_max_streams_frame_size,
2180    .pf_gen_handshake_done_frame      =  ietf_v1_gen_handshake_done_frame,
2181    .pf_parse_handshake_done_frame    =  ietf_v1_parse_handshake_done_frame,
2182    .pf_handshake_done_frame_size     =  ietf_v1_handshake_done_frame_size,
2183    .pf_gen_ack_frequency_frame       =  ietf_v1_gen_ack_frequency_frame,
2184    .pf_parse_ack_frequency_frame     =  ietf_v1_parse_ack_frequency_frame,
2185    .pf_ack_frequency_frame_size      =  ietf_v1_ack_frequency_frame_size,
2186    .pf_gen_timestamp_frame           =  ietf_v1_gen_timestamp_frame,
2187    .pf_parse_timestamp_frame         =  ietf_v1_parse_timestamp_frame,
2188};
2189