lsquic_parse_Q050.c revision feca77f5
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_parse_Q050.c -- Parsing functions specific to GQUIC Q050
4 */
5
6#include <assert.h>
7#include <errno.h>
8#include <inttypes.h>
9#include <string.h>
10#include <sys/queue.h>
11#ifndef WIN32
12#include <sys/types.h>
13#else
14#include <vc_compat.h>
15#endif
16
17#include "lsquic_types.h"
18#include "lsquic_int_types.h"
19#include "lsquic_packet_common.h"
20#include "lsquic_packet_in.h"
21#include "lsquic_packet_out.h"
22#include "lsquic_parse.h"
23#include "lsquic_parse_common.h"
24#include "lsquic_version.h"
25#include "lsquic.h"
26#include "lsquic_parse_gquic_be.h"
27#include "lsquic_parse_ietf.h"
28#include "lsquic_byteswap.h"
29#include "lsquic_hash.h"
30#include "lsquic_conn.h"
31#include "lsquic_varint.h"
32#include "lsquic_enc_sess.h"
33
34#define LSQUIC_LOGGER_MODULE LSQLM_PARSE
35#include "lsquic_logger.h"
36
37
38/* [draft-ietf-quic-transport-24] Section-17.2 */
39static const enum header_type bits2ht[4] =
40{
41    [0] = HETY_INITIAL,
42    [1] = HETY_0RTT,
43    [2] = HETY_HANDSHAKE,
44    [3] = HETY_RETRY,
45};
46
47
48int
49lsquic_Q050_parse_packet_in_long_begin (struct lsquic_packet_in *packet_in,
50                size_t length, int is_server, unsigned cid_len,
51                struct packin_parse_state *state)
52{
53    const unsigned char *p = packet_in->pi_data;
54    const unsigned char *const end = p + length;
55    lsquic_ver_tag_t tag;
56    enum header_type header_type;
57    unsigned dcil, scil, odcil;
58    int verneg, r;
59    unsigned char first_byte;
60    uint64_t payload_len, token_len;
61
62    if (length < 6)
63        return -1;
64    first_byte = *p++;
65
66    memcpy(&tag, p, 4);
67    p += 4;
68    verneg = 0 == tag;
69    if (!verneg)
70        header_type = bits2ht[ (first_byte >> 4) & 3 ];
71    else
72        header_type = HETY_VERNEG;
73
74    packet_in->pi_header_type = header_type;
75
76    dcil = *p++;
77    if (p + dcil >= end || dcil > MAX_CID_LEN)
78        return -1;
79    if (dcil)
80    {
81        memcpy(packet_in->pi_dcid.idbuf, p, dcil);
82        packet_in->pi_flags |= PI_CONN_ID;
83        p += dcil;
84        packet_in->pi_dcid.len = dcil;
85    }
86
87    scil = *p++;
88    if (p + scil > end || scil > MAX_CID_LEN)
89        return -1;
90    if (scil)
91    {
92        memcpy(packet_in->pi_dcid.idbuf, p, scil);
93        packet_in->pi_flags |= PI_CONN_ID;
94        p += scil;
95        packet_in->pi_dcid.len = scil;
96    }
97
98    if (is_server)
99    {
100        if (scil)
101            return -1;
102    }
103    else
104        if (dcil)
105            return -1;
106
107    switch (header_type)
108    {
109    case HETY_INITIAL:
110        r = vint_read(p, end, &token_len);
111        if (r < 0)
112            return -1;
113        if (token_len && !is_server)
114        {
115            /* From [draft-ietf-quic-transport-14]:
116             *
117             *  Token Length:  A variable-length integer specifying the
118             *  length of the Token field, in bytes.  This value is zero
119             *  if no token is present.  Initial packets sent by the
120             *  server MUST set the Token Length field to zero; clients
121             *  that receive an Initial packet with a non-zero Token
122             *  Length field MUST either discard the packet or generate
123             *  a connection error of type PROTOCOL_VIOLATION.
124             */
125            return -1;
126        }
127        p += r;
128        if (token_len)
129        {
130            if (token_len >=
131                        1ull << (sizeof(packet_in->pi_token_size) * 8))
132                return -1;
133            if (p + token_len > end)
134                return -1;
135            packet_in->pi_token = p - packet_in->pi_data;
136            packet_in->pi_token_size = token_len;
137            p += token_len;
138        }
139        /* fall-through */
140    case HETY_HANDSHAKE:
141    case HETY_0RTT:
142        if (p >= end)
143            return -1;
144        r = vint_read(p, end, &payload_len);
145        if (r < 0)
146            return -1;
147        p += r;
148        if (p - packet_in->pi_data + payload_len > length)
149            return -1;
150        length = p - packet_in->pi_data + payload_len;
151        if (end - p < 4)
152            return -1;
153        state->pps_p      = p - r;
154        state->pps_nbytes = r;
155        packet_in->pi_quic_ver = 1;
156        break;
157    case HETY_RETRY:
158        if (p >= end)
159            return -1;
160        odcil = *p++;
161        if (p + odcil > end || odcil > MAX_CID_LEN)
162            return -1;
163        packet_in->pi_odcid_len = odcil;
164        packet_in->pi_odcid = p - packet_in->pi_data;
165        p += odcil;
166        packet_in->pi_token = p - packet_in->pi_data;
167        packet_in->pi_token_size = end - p;
168        p = end;
169        length = end - packet_in->pi_data;
170        state->pps_p      = NULL;
171        state->pps_nbytes = 0;
172        packet_in->pi_quic_ver = 1;
173        break;
174    default:
175        assert(header_type == HETY_VERNEG);
176        if (p >= end || (3 & (uintptr_t) (end - p)))
177            return -1;
178        packet_in->pi_quic_ver = p - packet_in->pi_data;
179        p = end;
180        state->pps_p      = NULL;
181        state->pps_nbytes = 0;
182        break;
183    }
184
185    packet_in->pi_header_sz     = p - packet_in->pi_data;
186    packet_in->pi_data_sz       = length;
187    packet_in->pi_nonce         = 0;
188    packet_in->pi_refcnt        = 0;
189    packet_in->pi_frame_types   = 0;
190    memset(&packet_in->pi_next, 0, sizeof(packet_in->pi_next));
191    packet_in->pi_refcnt        = 0;
192    packet_in->pi_received      = 0;
193
194    /* Packet number is set to an invalid value.  The packet number must
195     * be decrypted, which happens later.
196     */
197    packet_in->pi_packno        = 1ULL << 62;
198
199    return 0;
200}
201
202
203
204
205static unsigned
206gquic_Q050_packno_bits2len (enum packno_bits bits)
207{
208    return bits + 1;
209}
210
211#define iquic_packno_bits2len gquic_Q050_packno_bits2len
212
213
214static enum packno_bits
215gquic_Q050_calc_packno_bits (lsquic_packno_t packno,
216                    lsquic_packno_t least_unacked, uint64_t n_in_flight)
217{
218    uint64_t delta;
219    unsigned bits;
220
221    delta = packno - least_unacked;
222    if (n_in_flight > delta)
223        delta = n_in_flight;
224
225    delta *= 4;
226    bits = (delta >= (1ULL <<  8))
227         + (delta >= (1ULL << 16))
228         + (delta >= (1ULL << 24))
229         ;
230
231    return bits;
232}
233
234
235static unsigned
236write_packno (unsigned char *p, lsquic_packno_t packno, enum packno_bits bits)
237{
238    unsigned char *const begin = p;
239
240    switch (bits)
241    {
242    case IQUIC_PACKNO_LEN_4:
243        *p++ = packno >> 24;
244        /* fall-through */
245    case IQUIC_PACKNO_LEN_3:
246        *p++ = packno >> 16;
247        /* fall-through */
248    case IQUIC_PACKNO_LEN_2:
249        *p++ = packno >> 8;
250        /* fall-through */
251    default:
252        *p++ = packno;
253    }
254
255    return p - begin;
256}
257
258
259static int
260gen_short_pkt_header (const struct lsquic_conn *lconn,
261            const struct lsquic_packet_out *packet_out, unsigned char *buf,
262                                                                size_t bufsz)
263{
264    unsigned packno_len, need;
265    enum packno_bits bits;
266
267    bits = lsquic_packet_out_packno_bits(packet_out);
268    packno_len = iquic_packno_bits2len(bits);
269
270    if (lconn->cn_flags & LSCONN_SERVER)
271        need = 1 + packno_len;
272    else
273        need = 1 + 8 /* CID */ + packno_len;
274
275    if (need > bufsz)
276        return -1;
277
278    *buf++ = 0x40 | bits;
279
280    if (0 == (lconn->cn_flags & LSCONN_SERVER))
281    {
282        memcpy(buf, lconn->cn_cid.idbuf, 8);
283        buf += 8;
284    }
285
286    (void) write_packno(buf, packet_out->po_packno, bits);
287
288    return need;
289}
290
291
292static size_t
293gquic_Q050_packout_header_size_long_by_flags (const struct lsquic_conn *lconn,
294                                                    enum packet_out_flags flags)
295{
296    size_t sz;
297    enum packno_bits packno_bits;
298
299    packno_bits = (flags >> POBIT_SHIFT) & 0x3;
300
301    sz = 1 /* Type */
302       + 4 /* Version */
303       + 1 /* DCIL */
304       + 1 /* SCIL */
305       + lconn->cn_cid.len
306       + 1 /* Token length: only use for Initial packets, while token is never
307            * set in this version.
308            */
309       + (flags & PO_NONCE ? DNONC_LENGTH : 0)
310       + 2 /* Always use two bytes to encode payload length */
311       + iquic_packno_bits2len(packno_bits)
312       ;
313
314    return sz;
315}
316
317
318/* [draft-ietf-quic-transport-17] Section-17.2 */
319static const unsigned char header_type_to_bin[] = {
320    [HETY_INITIAL]      = 0x0,
321    [HETY_0RTT]         = 0x1,
322    [HETY_HANDSHAKE]    = 0x2,
323    [HETY_RETRY]        = 0x3,
324};
325
326
327static size_t
328gquic_Q050_packout_header_size_long_by_packet (const struct lsquic_conn *lconn,
329                                    const struct lsquic_packet_out *packet_out)
330{
331    size_t sz;
332    enum packno_bits packno_bits;
333
334    packno_bits = lsquic_packet_out_packno_bits(packet_out);
335
336    sz = 1 /* Type */
337       + 4 /* Version */
338       + 1 /* DCIL */
339       + 1 /* SCIL */
340       + lconn->cn_cid.len
341         /* Token is never sent, but token length byte is used */
342       + (packet_out->po_header_type == HETY_INITIAL)
343       + 2 /* Always use two bytes to encode payload length */
344       + iquic_packno_bits2len(packno_bits)
345       + (packet_out->po_nonce ? DNONC_LENGTH : 0)
346       ;
347
348    return sz;
349}
350
351
352static void
353gquic_Q050_packno_info (const struct lsquic_conn *lconn,
354        const struct lsquic_packet_out *packet_out, unsigned *packno_off,
355        unsigned *packno_len)
356{
357    unsigned token_len; /* Need intermediate value to quiet compiler warning */
358
359    if (packet_out->po_header_type == HETY_NOT_SET)
360        *packno_off = 1 +
361            (lconn->cn_flags & LSCONN_SERVER ? 0 : 8);
362    else
363        *packno_off = 1
364                    + 4
365                    + 1
366                    + 1
367                    + lconn->cn_cid.len
368                    + (packet_out->po_header_type == HETY_INITIAL ?
369                        (token_len = packet_out->po_token_len,
370                            (1 << vint_val2bits(token_len)) + token_len) : 0)
371                    + 2;
372    *packno_len = iquic_packno_bits2len(
373        lsquic_packet_out_packno_bits(packet_out));
374}
375
376
377static int
378gquic_Q050_gen_long_pkt_header (const struct lsquic_conn *lconn,
379            const struct lsquic_packet_out *packet_out, unsigned char *buf,
380                                                                size_t bufsz)
381{
382    enum packno_bits packno_bits;
383    lsquic_ver_tag_t ver_tag;
384    unsigned token_len, payload_len, bits;
385    unsigned char *p;
386    size_t need;
387
388    need = gquic_Q050_packout_header_size_long_by_packet(lconn, packet_out);
389    if (need > bufsz)
390    {
391        errno = EINVAL;
392        return -1;
393    }
394
395    packno_bits = lsquic_packet_out_packno_bits(packet_out);
396    p = buf;
397    *p++ = 0x80 | 0x40
398         | (header_type_to_bin[ packet_out->po_header_type ] << 4)
399         | packno_bits;
400    ver_tag = lsquic_ver2tag(lconn->cn_version);
401    memcpy(p, &ver_tag, sizeof(ver_tag));
402    p += sizeof(ver_tag);
403
404    if (lconn->cn_flags & LSCONN_SERVER)
405    {
406        *p++ = 0;
407        *p++ = lconn->cn_cid.len;
408        memcpy(p, lconn->cn_cid.idbuf, lconn->cn_cid.len);
409        p += lconn->cn_cid.len;
410    }
411    else
412    {
413        *p++ = lconn->cn_cid.len;
414        memcpy(p, lconn->cn_cid.idbuf, lconn->cn_cid.len);
415        p += lconn->cn_cid.len;
416        *p++ = 0;
417    }
418
419    if (HETY_INITIAL == packet_out->po_header_type)
420    {
421        token_len = packet_out->po_token_len;
422        bits = vint_val2bits(token_len);
423        vint_write(p, token_len, bits, 1 << bits);
424        p += 1 << bits;
425        memcpy(p, packet_out->po_token, token_len);
426        p += token_len;
427    }
428
429    payload_len = packet_out->po_data_sz
430                + lconn->cn_esf_c->esf_tag_len
431                + iquic_packno_bits2len(packno_bits);
432    if (packet_out->po_nonce)
433        payload_len += DNONC_LENGTH;
434    bits = 1;   /* Always use two bytes to encode payload length */
435    vint_write(p, payload_len, bits, 1 << bits);
436    p += 1 << bits;
437    p += write_packno(p, packet_out->po_packno, packno_bits);
438
439    if (packet_out->po_nonce)
440    {
441        memcpy(p, packet_out->po_nonce, DNONC_LENGTH);
442        p += DNONC_LENGTH;
443    }
444
445    assert(need == (size_t) (p - buf));
446    return p - buf;
447}
448
449
450static int
451gquic_Q050_gen_reg_pkt_header (const struct lsquic_conn *lconn,
452            const struct lsquic_packet_out *packet_out, unsigned char *buf,
453                                                                size_t bufsz)
454{
455    if (0 == (packet_out->po_flags & PO_LONGHEAD))
456        return gen_short_pkt_header(lconn, packet_out, buf, bufsz);
457    else
458        return gquic_Q050_gen_long_pkt_header(lconn, packet_out, buf, bufsz);
459}
460
461
462static size_t
463gquic_Q050_packout_header_size_short (const struct lsquic_conn *lconn,
464                                                enum packet_out_flags flags)
465{
466    enum packno_bits bits;
467    size_t sz;
468
469    bits = (flags >> POBIT_SHIFT) & 0x3;
470    sz = 1; /* Type */
471    sz += (lconn->cn_flags & LSCONN_SERVER) ? 0 : 8;
472    sz += iquic_packno_bits2len(bits);
473
474    return sz;
475}
476
477
478static size_t
479gquic_Q050_packout_max_header_size (const struct lsquic_conn *lconn,
480                        enum packet_out_flags flags, size_t dcid_len_unused)
481{
482    if (lconn->cn_flags & LSCONN_SERVER)
483    {
484        if (0 == (flags & PO_LONGHEAD))
485            return gquic_Q050_packout_header_size_short(lconn, flags);
486        else
487            return gquic_Q050_packout_header_size_long_by_flags(lconn, flags);
488    }
489    else
490    {
491        if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
492            return gquic_Q050_packout_header_size_short(lconn, flags);
493        else
494            return gquic_Q050_packout_header_size_long_by_flags(lconn, flags);
495    }
496}
497
498
499static size_t
500gquic_Q050_packout_size (const struct lsquic_conn *lconn,
501                                const struct lsquic_packet_out *packet_out)
502{
503    size_t sz;
504
505    if ((lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
506                                && packet_out->po_header_type == HETY_NOT_SET)
507        sz = gquic_Q050_packout_header_size_short(lconn, packet_out->po_flags);
508    else
509        sz = gquic_Q050_packout_header_size_long_by_packet(lconn, packet_out);
510
511    sz += packet_out->po_data_sz;
512    sz += lconn->cn_esf_c->esf_tag_len;
513
514    return sz;
515}
516
517
518void
519gquic_Q050_parse_packet_in_finish (struct lsquic_packet_in *packet_in,
520                                            struct packin_parse_state *state)
521{
522}
523
524
525/* Same as Q046 plus CRYPTO frame at slot 8 */
526static const enum quic_frame_type byte2frame_type_Q050[0x100] =
527{
528    [0x00] = QUIC_FRAME_PADDING,
529    [0x01] = QUIC_FRAME_RST_STREAM,
530    [0x02] = QUIC_FRAME_CONNECTION_CLOSE,
531    [0x03] = QUIC_FRAME_GOAWAY,
532    [0x04] = QUIC_FRAME_WINDOW_UPDATE,
533    [0x05] = QUIC_FRAME_BLOCKED,
534    [0x06] = QUIC_FRAME_STOP_WAITING,
535    [0x07] = QUIC_FRAME_PING,
536    [0x08] = QUIC_FRAME_CRYPTO,
537    [0x09] = QUIC_FRAME_INVALID,
538    [0x0A] = QUIC_FRAME_INVALID,
539    [0x0B] = QUIC_FRAME_INVALID,
540    [0x0C] = QUIC_FRAME_INVALID,
541    [0x0D] = QUIC_FRAME_INVALID,
542    [0x0E] = QUIC_FRAME_INVALID,
543    [0x0F] = QUIC_FRAME_INVALID,
544    [0x10] = QUIC_FRAME_INVALID,
545    [0x11] = QUIC_FRAME_INVALID,
546    [0x12] = QUIC_FRAME_INVALID,
547    [0x13] = QUIC_FRAME_INVALID,
548    [0x14] = QUIC_FRAME_INVALID,
549    [0x15] = QUIC_FRAME_INVALID,
550    [0x16] = QUIC_FRAME_INVALID,
551    [0x17] = QUIC_FRAME_INVALID,
552    [0x18] = QUIC_FRAME_INVALID,
553    [0x19] = QUIC_FRAME_INVALID,
554    [0x1A] = QUIC_FRAME_INVALID,
555    [0x1B] = QUIC_FRAME_INVALID,
556    [0x1C] = QUIC_FRAME_INVALID,
557    [0x1D] = QUIC_FRAME_INVALID,
558    [0x1E] = QUIC_FRAME_INVALID,
559    [0x1F] = QUIC_FRAME_INVALID,
560    [0x20] = QUIC_FRAME_INVALID,
561    [0x21] = QUIC_FRAME_INVALID,
562    [0x22] = QUIC_FRAME_INVALID,
563    [0x23] = QUIC_FRAME_INVALID,
564    [0x24] = QUIC_FRAME_INVALID,
565    [0x25] = QUIC_FRAME_INVALID,
566    [0x26] = QUIC_FRAME_INVALID,
567    [0x27] = QUIC_FRAME_INVALID,
568    [0x28] = QUIC_FRAME_INVALID,
569    [0x29] = QUIC_FRAME_INVALID,
570    [0x2A] = QUIC_FRAME_INVALID,
571    [0x2B] = QUIC_FRAME_INVALID,
572    [0x2C] = QUIC_FRAME_INVALID,
573    [0x2D] = QUIC_FRAME_INVALID,
574    [0x2E] = QUIC_FRAME_INVALID,
575    [0x2F] = QUIC_FRAME_INVALID,
576    [0x30] = QUIC_FRAME_INVALID,
577    [0x31] = QUIC_FRAME_INVALID,
578    [0x32] = QUIC_FRAME_INVALID,
579    [0x33] = QUIC_FRAME_INVALID,
580    [0x34] = QUIC_FRAME_INVALID,
581    [0x35] = QUIC_FRAME_INVALID,
582    [0x36] = QUIC_FRAME_INVALID,
583    [0x37] = QUIC_FRAME_INVALID,
584    [0x38] = QUIC_FRAME_INVALID,
585    [0x39] = QUIC_FRAME_INVALID,
586    [0x3A] = QUIC_FRAME_INVALID,
587    [0x3B] = QUIC_FRAME_INVALID,
588    [0x3C] = QUIC_FRAME_INVALID,
589    [0x3D] = QUIC_FRAME_INVALID,
590    [0x3E] = QUIC_FRAME_INVALID,
591    [0x3F] = QUIC_FRAME_INVALID,
592    [0x40] = QUIC_FRAME_ACK,
593    [0x41] = QUIC_FRAME_ACK,
594    [0x42] = QUIC_FRAME_ACK,
595    [0x43] = QUIC_FRAME_ACK,
596    [0x44] = QUIC_FRAME_ACK,
597    [0x45] = QUIC_FRAME_ACK,
598    [0x46] = QUIC_FRAME_ACK,
599    [0x47] = QUIC_FRAME_ACK,
600    [0x48] = QUIC_FRAME_ACK,
601    [0x49] = QUIC_FRAME_ACK,
602    [0x4A] = QUIC_FRAME_ACK,
603    [0x4B] = QUIC_FRAME_ACK,
604    [0x4C] = QUIC_FRAME_ACK,
605    [0x4D] = QUIC_FRAME_ACK,
606    [0x4E] = QUIC_FRAME_ACK,
607    [0x4F] = QUIC_FRAME_ACK,
608    [0x50] = QUIC_FRAME_ACK,
609    [0x51] = QUIC_FRAME_ACK,
610    [0x52] = QUIC_FRAME_ACK,
611    [0x53] = QUIC_FRAME_ACK,
612    [0x54] = QUIC_FRAME_ACK,
613    [0x55] = QUIC_FRAME_ACK,
614    [0x56] = QUIC_FRAME_ACK,
615    [0x57] = QUIC_FRAME_ACK,
616    [0x58] = QUIC_FRAME_ACK,
617    [0x59] = QUIC_FRAME_ACK,
618    [0x5A] = QUIC_FRAME_ACK,
619    [0x5B] = QUIC_FRAME_ACK,
620    [0x5C] = QUIC_FRAME_ACK,
621    [0x5D] = QUIC_FRAME_ACK,
622    [0x5E] = QUIC_FRAME_ACK,
623    [0x5F] = QUIC_FRAME_ACK,
624    [0x60] = QUIC_FRAME_ACK,
625    [0x61] = QUIC_FRAME_ACK,
626    [0x62] = QUIC_FRAME_ACK,
627    [0x63] = QUIC_FRAME_ACK,
628    [0x64] = QUIC_FRAME_ACK,
629    [0x65] = QUIC_FRAME_ACK,
630    [0x66] = QUIC_FRAME_ACK,
631    [0x67] = QUIC_FRAME_ACK,
632    [0x68] = QUIC_FRAME_ACK,
633    [0x69] = QUIC_FRAME_ACK,
634    [0x6A] = QUIC_FRAME_ACK,
635    [0x6B] = QUIC_FRAME_ACK,
636    [0x6C] = QUIC_FRAME_ACK,
637    [0x6D] = QUIC_FRAME_ACK,
638    [0x6E] = QUIC_FRAME_ACK,
639    [0x6F] = QUIC_FRAME_ACK,
640    [0x70] = QUIC_FRAME_ACK,
641    [0x71] = QUIC_FRAME_ACK,
642    [0x72] = QUIC_FRAME_ACK,
643    [0x73] = QUIC_FRAME_ACK,
644    [0x74] = QUIC_FRAME_ACK,
645    [0x75] = QUIC_FRAME_ACK,
646    [0x76] = QUIC_FRAME_ACK,
647    [0x77] = QUIC_FRAME_ACK,
648    [0x78] = QUIC_FRAME_ACK,
649    [0x79] = QUIC_FRAME_ACK,
650    [0x7A] = QUIC_FRAME_ACK,
651    [0x7B] = QUIC_FRAME_ACK,
652    [0x7C] = QUIC_FRAME_ACK,
653    [0x7D] = QUIC_FRAME_ACK,
654    [0x7E] = QUIC_FRAME_ACK,
655    [0x7F] = QUIC_FRAME_ACK,
656    [0x80] = QUIC_FRAME_STREAM,
657    [0x81] = QUIC_FRAME_STREAM,
658    [0x82] = QUIC_FRAME_STREAM,
659    [0x83] = QUIC_FRAME_STREAM,
660    [0x84] = QUIC_FRAME_STREAM,
661    [0x85] = QUIC_FRAME_STREAM,
662    [0x86] = QUIC_FRAME_STREAM,
663    [0x87] = QUIC_FRAME_STREAM,
664    [0x88] = QUIC_FRAME_STREAM,
665    [0x89] = QUIC_FRAME_STREAM,
666    [0x8A] = QUIC_FRAME_STREAM,
667    [0x8B] = QUIC_FRAME_STREAM,
668    [0x8C] = QUIC_FRAME_STREAM,
669    [0x8D] = QUIC_FRAME_STREAM,
670    [0x8E] = QUIC_FRAME_STREAM,
671    [0x8F] = QUIC_FRAME_STREAM,
672    [0x90] = QUIC_FRAME_STREAM,
673    [0x91] = QUIC_FRAME_STREAM,
674    [0x92] = QUIC_FRAME_STREAM,
675    [0x93] = QUIC_FRAME_STREAM,
676    [0x94] = QUIC_FRAME_STREAM,
677    [0x95] = QUIC_FRAME_STREAM,
678    [0x96] = QUIC_FRAME_STREAM,
679    [0x97] = QUIC_FRAME_STREAM,
680    [0x98] = QUIC_FRAME_STREAM,
681    [0x99] = QUIC_FRAME_STREAM,
682    [0x9A] = QUIC_FRAME_STREAM,
683    [0x9B] = QUIC_FRAME_STREAM,
684    [0x9C] = QUIC_FRAME_STREAM,
685    [0x9D] = QUIC_FRAME_STREAM,
686    [0x9E] = QUIC_FRAME_STREAM,
687    [0x9F] = QUIC_FRAME_STREAM,
688    [0xA0] = QUIC_FRAME_STREAM,
689    [0xA1] = QUIC_FRAME_STREAM,
690    [0xA2] = QUIC_FRAME_STREAM,
691    [0xA3] = QUIC_FRAME_STREAM,
692    [0xA4] = QUIC_FRAME_STREAM,
693    [0xA5] = QUIC_FRAME_STREAM,
694    [0xA6] = QUIC_FRAME_STREAM,
695    [0xA7] = QUIC_FRAME_STREAM,
696    [0xA8] = QUIC_FRAME_STREAM,
697    [0xA9] = QUIC_FRAME_STREAM,
698    [0xAA] = QUIC_FRAME_STREAM,
699    [0xAB] = QUIC_FRAME_STREAM,
700    [0xAC] = QUIC_FRAME_STREAM,
701    [0xAD] = QUIC_FRAME_STREAM,
702    [0xAE] = QUIC_FRAME_STREAM,
703    [0xAF] = QUIC_FRAME_STREAM,
704    [0xB0] = QUIC_FRAME_STREAM,
705    [0xB1] = QUIC_FRAME_STREAM,
706    [0xB2] = QUIC_FRAME_STREAM,
707    [0xB3] = QUIC_FRAME_STREAM,
708    [0xB4] = QUIC_FRAME_STREAM,
709    [0xB5] = QUIC_FRAME_STREAM,
710    [0xB6] = QUIC_FRAME_STREAM,
711    [0xB7] = QUIC_FRAME_STREAM,
712    [0xB8] = QUIC_FRAME_STREAM,
713    [0xB9] = QUIC_FRAME_STREAM,
714    [0xBA] = QUIC_FRAME_STREAM,
715    [0xBB] = QUIC_FRAME_STREAM,
716    [0xBC] = QUIC_FRAME_STREAM,
717    [0xBD] = QUIC_FRAME_STREAM,
718    [0xBE] = QUIC_FRAME_STREAM,
719    [0xBF] = QUIC_FRAME_STREAM,
720    [0xC0] = QUIC_FRAME_STREAM,
721    [0xC1] = QUIC_FRAME_STREAM,
722    [0xC2] = QUIC_FRAME_STREAM,
723    [0xC3] = QUIC_FRAME_STREAM,
724    [0xC4] = QUIC_FRAME_STREAM,
725    [0xC5] = QUIC_FRAME_STREAM,
726    [0xC6] = QUIC_FRAME_STREAM,
727    [0xC7] = QUIC_FRAME_STREAM,
728    [0xC8] = QUIC_FRAME_STREAM,
729    [0xC9] = QUIC_FRAME_STREAM,
730    [0xCA] = QUIC_FRAME_STREAM,
731    [0xCB] = QUIC_FRAME_STREAM,
732    [0xCC] = QUIC_FRAME_STREAM,
733    [0xCD] = QUIC_FRAME_STREAM,
734    [0xCE] = QUIC_FRAME_STREAM,
735    [0xCF] = QUIC_FRAME_STREAM,
736    [0xD0] = QUIC_FRAME_STREAM,
737    [0xD1] = QUIC_FRAME_STREAM,
738    [0xD2] = QUIC_FRAME_STREAM,
739    [0xD3] = QUIC_FRAME_STREAM,
740    [0xD4] = QUIC_FRAME_STREAM,
741    [0xD5] = QUIC_FRAME_STREAM,
742    [0xD6] = QUIC_FRAME_STREAM,
743    [0xD7] = QUIC_FRAME_STREAM,
744    [0xD8] = QUIC_FRAME_STREAM,
745    [0xD9] = QUIC_FRAME_STREAM,
746    [0xDA] = QUIC_FRAME_STREAM,
747    [0xDB] = QUIC_FRAME_STREAM,
748    [0xDC] = QUIC_FRAME_STREAM,
749    [0xDD] = QUIC_FRAME_STREAM,
750    [0xDE] = QUIC_FRAME_STREAM,
751    [0xDF] = QUIC_FRAME_STREAM,
752    [0xE0] = QUIC_FRAME_STREAM,
753    [0xE1] = QUIC_FRAME_STREAM,
754    [0xE2] = QUIC_FRAME_STREAM,
755    [0xE3] = QUIC_FRAME_STREAM,
756    [0xE4] = QUIC_FRAME_STREAM,
757    [0xE5] = QUIC_FRAME_STREAM,
758    [0xE6] = QUIC_FRAME_STREAM,
759    [0xE7] = QUIC_FRAME_STREAM,
760    [0xE8] = QUIC_FRAME_STREAM,
761    [0xE9] = QUIC_FRAME_STREAM,
762    [0xEA] = QUIC_FRAME_STREAM,
763    [0xEB] = QUIC_FRAME_STREAM,
764    [0xEC] = QUIC_FRAME_STREAM,
765    [0xED] = QUIC_FRAME_STREAM,
766    [0xEE] = QUIC_FRAME_STREAM,
767    [0xEF] = QUIC_FRAME_STREAM,
768    [0xF0] = QUIC_FRAME_STREAM,
769    [0xF1] = QUIC_FRAME_STREAM,
770    [0xF2] = QUIC_FRAME_STREAM,
771    [0xF3] = QUIC_FRAME_STREAM,
772    [0xF4] = QUIC_FRAME_STREAM,
773    [0xF5] = QUIC_FRAME_STREAM,
774    [0xF6] = QUIC_FRAME_STREAM,
775    [0xF7] = QUIC_FRAME_STREAM,
776    [0xF8] = QUIC_FRAME_STREAM,
777    [0xF9] = QUIC_FRAME_STREAM,
778    [0xFA] = QUIC_FRAME_STREAM,
779    [0xFB] = QUIC_FRAME_STREAM,
780    [0xFC] = QUIC_FRAME_STREAM,
781    [0xFD] = QUIC_FRAME_STREAM,
782    [0xFE] = QUIC_FRAME_STREAM,
783    [0xFF] = QUIC_FRAME_STREAM,
784};
785
786
787static enum quic_frame_type
788gquic_Q050_parse_frame_type (const unsigned char *buf, size_t len)
789{
790    if (len > 0)
791        return byte2frame_type_Q050[buf[0]];
792    else
793        return QUIC_FRAME_INVALID;
794}
795
796
797static int
798gquic_Q050_gen_crypto_frame (unsigned char *buf, size_t buf_len,
799        uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream)
800{
801    return lsquic_ietf_v1_gen_crypto_frame(buf, 0x8, buf_len, offset,
802                                                size, gcf_read, stream);
803}
804
805
806static int
807gquic_Q050_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
808                                            struct stream_frame *stream_frame)
809{
810    if (rem_packet_sz > 0)
811    {
812        assert(0x08 == buf[0]);
813        return lsquic_ietf_v1_parse_crypto_frame(buf, rem_packet_sz,
814                                                            stream_frame);
815    }
816    else
817        return -1;
818}
819
820
821static size_t
822gquic_Q050_calc_crypto_frame_header_sz (uint64_t offset, unsigned data_sz)
823{
824    return 1    /* Frame type */
825         + (1 << vint_val2bits(offset))
826         + (1 << vint_val2bits(data_sz))
827         ;
828}
829
830
831/* No simple PRST for Q050 */
832static ssize_t
833gquic_Q050_generate_simple_prst (const lsquic_cid_t *cidp, unsigned char *buf,
834                                                                size_t buf_sz)
835{
836    return -1;
837}
838
839
840static unsigned
841gquic_Q050_handshake_done_frame_size (void)
842{
843    return 0;
844}
845
846
847static int
848gquic_Q050_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
849{
850    return -1;
851}
852
853
854static int
855gquic_Q050_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
856{
857    return -1;
858}
859
860
861const struct parse_funcs lsquic_parse_funcs_gquic_Q050 =
862{
863    .pf_gen_reg_pkt_header            =  gquic_Q050_gen_reg_pkt_header,
864    .pf_parse_packet_in_finish        =  gquic_Q050_parse_packet_in_finish,
865    .pf_gen_stream_frame              =  gquic_be_gen_stream_frame,
866    .pf_calc_stream_frame_header_sz   =  calc_stream_frame_header_sz_gquic,
867    .pf_parse_stream_frame            =  gquic_be_parse_stream_frame,
868    .pf_parse_ack_frame               =  gquic_be_parse_ack_frame,
869    .pf_gen_ack_frame                 =  gquic_be_gen_ack_frame,
870    .pf_gen_stop_waiting_frame        =  gquic_be_gen_stop_waiting_frame,
871    .pf_parse_stop_waiting_frame      =  gquic_be_parse_stop_waiting_frame,
872    .pf_skip_stop_waiting_frame       =  gquic_be_skip_stop_waiting_frame,
873    .pf_gen_window_update_frame       =  gquic_be_gen_window_update_frame,
874    .pf_parse_window_update_frame     =  gquic_be_parse_window_update_frame,
875    .pf_gen_blocked_frame             =  gquic_be_gen_blocked_frame,
876    .pf_parse_blocked_frame           =  gquic_be_parse_blocked_frame,
877    .pf_gen_rst_frame                 =  gquic_be_gen_rst_frame,
878    .pf_parse_rst_frame               =  gquic_be_parse_rst_frame,
879    .pf_connect_close_frame_size      =  gquic_be_connect_close_frame_size,
880    .pf_gen_connect_close_frame       =  gquic_be_gen_connect_close_frame,
881    .pf_parse_connect_close_frame     =  gquic_be_parse_connect_close_frame,
882    .pf_gen_goaway_frame              =  gquic_be_gen_goaway_frame,
883    .pf_parse_goaway_frame            =  gquic_be_parse_goaway_frame,
884    .pf_gen_ping_frame                =  gquic_be_gen_ping_frame,
885#ifndef NDEBUG
886    .pf_write_float_time16            =  gquic_be_write_float_time16,
887    .pf_read_float_time16             =  gquic_be_read_float_time16,
888#endif
889    .pf_generate_simple_prst          =  gquic_Q050_generate_simple_prst,
890    .pf_parse_frame_type              =  gquic_Q050_parse_frame_type,
891    .pf_turn_on_fin                   =  lsquic_turn_on_fin_Q035_thru_Q046,
892    .pf_packout_size                  =  gquic_Q050_packout_size,
893    .pf_packout_max_header_size       =  gquic_Q050_packout_max_header_size,
894    .pf_calc_packno_bits              =  gquic_Q050_calc_packno_bits,
895    .pf_packno_bits2len               =  gquic_Q050_packno_bits2len,
896    .pf_gen_crypto_frame              =  gquic_Q050_gen_crypto_frame,
897    .pf_parse_crypto_frame            =  gquic_Q050_parse_crypto_frame,
898    .pf_packno_info                   =  gquic_Q050_packno_info,
899    .pf_calc_crypto_frame_header_sz   =  gquic_Q050_calc_crypto_frame_header_sz,
900    .pf_gen_handshake_done_frame      =  gquic_Q050_gen_handshake_done_frame,
901    .pf_parse_handshake_done_frame    =  gquic_Q050_parse_handshake_done_frame,
902    .pf_handshake_done_frame_size     =  gquic_Q050_handshake_done_frame_size,
903};
904