lsquic_parse_gquic_common.c revision 6aba801d
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_parse_gquic_common.c -- Parsing functions common to GQUIC
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#include <assert.h>
750aadb33SDmitri Tikhonov#include <errno.h>
850aadb33SDmitri Tikhonov#include <inttypes.h>
950aadb33SDmitri Tikhonov#include <string.h>
1050aadb33SDmitri Tikhonov#include <stdlib.h>
11461e84d8SAmol Deshpande#include <sys/queue.h>
12461e84d8SAmol Deshpande#ifndef WIN32
1350aadb33SDmitri Tikhonov#include <sys/types.h>
14461e84d8SAmol Deshpande#else
15461e84d8SAmol Deshpande#include <vc_compat.h>
16461e84d8SAmol Deshpande#endif
1750aadb33SDmitri Tikhonov
1850aadb33SDmitri Tikhonov#include "lsquic_types.h"
1950aadb33SDmitri Tikhonov#include "lsquic_packet_common.h"
209626cfc2SDmitri Tikhonov#include "lsquic_packet_out.h"
2150aadb33SDmitri Tikhonov#include "lsquic_packet_in.h"
2250aadb33SDmitri Tikhonov#include "lsquic_parse.h"
239626cfc2SDmitri Tikhonov#include "lsquic_parse_common.h"
249626cfc2SDmitri Tikhonov#include "lsquic_version.h"
2550aadb33SDmitri Tikhonov#include "lsquic.h"
2650aadb33SDmitri Tikhonov
2750aadb33SDmitri Tikhonov#define LSQUIC_LOGGER_MODULE LSQLM_PARSE
2850aadb33SDmitri Tikhonov#include "lsquic_logger.h"
2950aadb33SDmitri Tikhonov
3050aadb33SDmitri Tikhonov#define CHECK_SPACE(need, pstart, pend)  \
3150aadb33SDmitri Tikhonov    do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0)
3250aadb33SDmitri Tikhonov
3350aadb33SDmitri Tikhonov/* This partially parses `packet_in' and returns 0 if in case it succeeded and
3450aadb33SDmitri Tikhonov * -1 on failure.
3550aadb33SDmitri Tikhonov *
3650aadb33SDmitri Tikhonov * After this function returns 0, connection ID, nonce, and version fields can
3750aadb33SDmitri Tikhonov * be examined.  To finsh parsing the packet, call version-specific
3850aadb33SDmitri Tikhonov * pf_parse_packet_in_finish() routine.
3950aadb33SDmitri Tikhonov */
4050aadb33SDmitri Tikhonovint
419626cfc2SDmitri Tikhonovlsquic_gquic_parse_packet_in_begin (struct lsquic_packet_in *packet_in,
429626cfc2SDmitri Tikhonov            size_t length, int is_server, struct packin_parse_state *state)
4350aadb33SDmitri Tikhonov{
4450aadb33SDmitri Tikhonov    int nbytes;
4550aadb33SDmitri Tikhonov    enum PACKET_PUBLIC_FLAGS public_flags;
4650aadb33SDmitri Tikhonov    const unsigned char *p = packet_in->pi_data;
4750aadb33SDmitri Tikhonov    const unsigned char *const pend = packet_in->pi_data + length;
4850aadb33SDmitri Tikhonov
4950aadb33SDmitri Tikhonov    CHECK_SPACE(1, p, pend);
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov    public_flags = *p++;
5250aadb33SDmitri Tikhonov
5350aadb33SDmitri Tikhonov    if (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)
5450aadb33SDmitri Tikhonov    {
5550aadb33SDmitri Tikhonov        CHECK_SPACE(8, p, pend);
5650aadb33SDmitri Tikhonov        memcpy(&packet_in->pi_conn_id, p, 8);
5750aadb33SDmitri Tikhonov        packet_in->pi_flags |= PI_CONN_ID;
5850aadb33SDmitri Tikhonov        p += 8;
5950aadb33SDmitri Tikhonov    }
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonov    if (public_flags & PACKET_PUBLIC_FLAGS_VERSION)
6250aadb33SDmitri Tikhonov    {
6350aadb33SDmitri Tikhonov        /* It seems that version negotiation packets sent by Google may have
6450aadb33SDmitri Tikhonov         * NONCE bit set.  Ignore it:
6550aadb33SDmitri Tikhonov         */
6650aadb33SDmitri Tikhonov        public_flags &= ~PACKET_PUBLIC_FLAGS_NONCE;
6750aadb33SDmitri Tikhonov
6850aadb33SDmitri Tikhonov        if (is_server)
6950aadb33SDmitri Tikhonov        {
7050aadb33SDmitri Tikhonov            CHECK_SPACE(4, p, pend);
7150aadb33SDmitri Tikhonov            packet_in->pi_quic_ver = p - packet_in->pi_data;
7250aadb33SDmitri Tikhonov            p += 4;
7350aadb33SDmitri Tikhonov        }
7450aadb33SDmitri Tikhonov        else
7550aadb33SDmitri Tikhonov        {   /* OK, we have a version negotiation packet.  We need to verify
7650aadb33SDmitri Tikhonov             * that it has correct structure.  See Section 4.3 of
7750aadb33SDmitri Tikhonov             * [draft-ietf-quic-transport-00].
7850aadb33SDmitri Tikhonov             */
7950aadb33SDmitri Tikhonov            if ((public_flags & ~(PACKET_PUBLIC_FLAGS_VERSION|
8050aadb33SDmitri Tikhonov                                  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID))
8150aadb33SDmitri Tikhonov                || ((pend - p) & 3))
8250aadb33SDmitri Tikhonov                return -1;
8350aadb33SDmitri Tikhonov            CHECK_SPACE(4, p, pend);
8450aadb33SDmitri Tikhonov            packet_in->pi_quic_ver = p - packet_in->pi_data;
8550aadb33SDmitri Tikhonov            p = pend;
8650aadb33SDmitri Tikhonov        }
8750aadb33SDmitri Tikhonov    }
8850aadb33SDmitri Tikhonov    else
8950aadb33SDmitri Tikhonov    {
9050aadb33SDmitri Tikhonov        /* From [draft-hamilton-quic-transport-protocol-01]:
9150aadb33SDmitri Tikhonov         *    0x40 = MULTIPATH. This bit is reserved for multipath use.
9250aadb33SDmitri Tikhonov         *    0x80 is currently unused, and must be set to 0.
9350aadb33SDmitri Tikhonov         *
9450aadb33SDmitri Tikhonov         * The reference implementation checks that two high bits are not set
9550aadb33SDmitri Tikhonov         * if version flag is not set or if the version is the same.  For our
9650aadb33SDmitri Tikhonov         * purposes, all GQUIC version we support so far have these bits set
9750aadb33SDmitri Tikhonov         * to zero.
9850aadb33SDmitri Tikhonov         */
9950aadb33SDmitri Tikhonov        if (public_flags & (0x80|0x40))
10050aadb33SDmitri Tikhonov            return -1;
10150aadb33SDmitri Tikhonov        packet_in->pi_quic_ver = 0;
10250aadb33SDmitri Tikhonov    }
10350aadb33SDmitri Tikhonov
10450aadb33SDmitri Tikhonov    if (!is_server && (public_flags & PACKET_PUBLIC_FLAGS_NONCE) ==
10550aadb33SDmitri Tikhonov                                            PACKET_PUBLIC_FLAGS_NONCE)
10650aadb33SDmitri Tikhonov    {
10750aadb33SDmitri Tikhonov        CHECK_SPACE(32, p, pend);
10850aadb33SDmitri Tikhonov        packet_in->pi_nonce = p - packet_in->pi_data;
10950aadb33SDmitri Tikhonov        p += 32;
11050aadb33SDmitri Tikhonov    }
11150aadb33SDmitri Tikhonov    else
11250aadb33SDmitri Tikhonov        packet_in->pi_nonce = 0;
11350aadb33SDmitri Tikhonov
11450aadb33SDmitri Tikhonov    state->pps_p = p;
11550aadb33SDmitri Tikhonov
11650aadb33SDmitri Tikhonov    packet_in->pi_packno = 0;
11750aadb33SDmitri Tikhonov    if (0 == (public_flags & (PACKET_PUBLIC_FLAGS_VERSION|PACKET_PUBLIC_FLAGS_RST))
11850aadb33SDmitri Tikhonov        || ((public_flags & PACKET_PUBLIC_FLAGS_VERSION) && is_server))
11950aadb33SDmitri Tikhonov    {
12050aadb33SDmitri Tikhonov        nbytes = twobit_to_1246((public_flags >> 4) & 3);
12150aadb33SDmitri Tikhonov        CHECK_SPACE(nbytes, p, pend);
12250aadb33SDmitri Tikhonov        p += nbytes;
12350aadb33SDmitri Tikhonov        state->pps_nbytes = nbytes;
12450aadb33SDmitri Tikhonov    }
12550aadb33SDmitri Tikhonov    else
12650aadb33SDmitri Tikhonov        state->pps_nbytes = 0;
12750aadb33SDmitri Tikhonov
12850aadb33SDmitri Tikhonov    packet_in->pi_header_sz    = p - packet_in->pi_data;
12950aadb33SDmitri Tikhonov    packet_in->pi_frame_types  = 0;
13050aadb33SDmitri Tikhonov    memset(&packet_in->pi_next, 0, sizeof(packet_in->pi_next));
13150aadb33SDmitri Tikhonov    packet_in->pi_data_sz      = length;
13250aadb33SDmitri Tikhonov    packet_in->pi_refcnt       = 0;
13350aadb33SDmitri Tikhonov    packet_in->pi_received     = 0;
1349626cfc2SDmitri Tikhonov    packet_in->pi_flags       |= PI_GQUIC;
13550aadb33SDmitri Tikhonov
13650aadb33SDmitri Tikhonov    return 0;
13750aadb33SDmitri Tikhonov}
13850aadb33SDmitri Tikhonov
13950aadb33SDmitri Tikhonov
1406aba801dSDmitri Tikhonovstatic const enum quic_frame_type byte2frame_type_Q035_thru_Q039[0x100] =
14150aadb33SDmitri Tikhonov{
14250aadb33SDmitri Tikhonov    [0x00] = QUIC_FRAME_PADDING,
14350aadb33SDmitri Tikhonov    [0x01] = QUIC_FRAME_RST_STREAM,
14450aadb33SDmitri Tikhonov    [0x02] = QUIC_FRAME_CONNECTION_CLOSE,
14550aadb33SDmitri Tikhonov    [0x03] = QUIC_FRAME_GOAWAY,
14650aadb33SDmitri Tikhonov    [0x04] = QUIC_FRAME_WINDOW_UPDATE,
14750aadb33SDmitri Tikhonov    [0x05] = QUIC_FRAME_BLOCKED,
14850aadb33SDmitri Tikhonov    [0x06] = QUIC_FRAME_STOP_WAITING,
14950aadb33SDmitri Tikhonov    [0x07] = QUIC_FRAME_PING,
15050aadb33SDmitri Tikhonov    [0x08] = QUIC_FRAME_INVALID,
15150aadb33SDmitri Tikhonov    [0x09] = QUIC_FRAME_INVALID,
15250aadb33SDmitri Tikhonov    [0x0A] = QUIC_FRAME_INVALID,
15350aadb33SDmitri Tikhonov    [0x0B] = QUIC_FRAME_INVALID,
15450aadb33SDmitri Tikhonov    [0x0C] = QUIC_FRAME_INVALID,
15550aadb33SDmitri Tikhonov    [0x0D] = QUIC_FRAME_INVALID,
15650aadb33SDmitri Tikhonov    [0x0E] = QUIC_FRAME_INVALID,
15750aadb33SDmitri Tikhonov    [0x0F] = QUIC_FRAME_INVALID,
15850aadb33SDmitri Tikhonov    [0x10] = QUIC_FRAME_INVALID,
15950aadb33SDmitri Tikhonov    [0x11] = QUIC_FRAME_INVALID,
16050aadb33SDmitri Tikhonov    [0x12] = QUIC_FRAME_INVALID,
16150aadb33SDmitri Tikhonov    [0x13] = QUIC_FRAME_INVALID,
16250aadb33SDmitri Tikhonov    [0x14] = QUIC_FRAME_INVALID,
16350aadb33SDmitri Tikhonov    [0x15] = QUIC_FRAME_INVALID,
16450aadb33SDmitri Tikhonov    [0x16] = QUIC_FRAME_INVALID,
16550aadb33SDmitri Tikhonov    [0x17] = QUIC_FRAME_INVALID,
16650aadb33SDmitri Tikhonov    [0x18] = QUIC_FRAME_INVALID,
16750aadb33SDmitri Tikhonov    [0x19] = QUIC_FRAME_INVALID,
16850aadb33SDmitri Tikhonov    [0x1A] = QUIC_FRAME_INVALID,
16950aadb33SDmitri Tikhonov    [0x1B] = QUIC_FRAME_INVALID,
17050aadb33SDmitri Tikhonov    [0x1C] = QUIC_FRAME_INVALID,
17150aadb33SDmitri Tikhonov    [0x1D] = QUIC_FRAME_INVALID,
17250aadb33SDmitri Tikhonov    [0x1E] = QUIC_FRAME_INVALID,
17350aadb33SDmitri Tikhonov    [0x1F] = QUIC_FRAME_INVALID,
17450aadb33SDmitri Tikhonov    [0x20] = QUIC_FRAME_INVALID,
17550aadb33SDmitri Tikhonov    [0x21] = QUIC_FRAME_INVALID,
17650aadb33SDmitri Tikhonov    [0x22] = QUIC_FRAME_INVALID,
17750aadb33SDmitri Tikhonov    [0x23] = QUIC_FRAME_INVALID,
17850aadb33SDmitri Tikhonov    [0x24] = QUIC_FRAME_INVALID,
17950aadb33SDmitri Tikhonov    [0x25] = QUIC_FRAME_INVALID,
18050aadb33SDmitri Tikhonov    [0x26] = QUIC_FRAME_INVALID,
18150aadb33SDmitri Tikhonov    [0x27] = QUIC_FRAME_INVALID,
18250aadb33SDmitri Tikhonov    [0x28] = QUIC_FRAME_INVALID,
18350aadb33SDmitri Tikhonov    [0x29] = QUIC_FRAME_INVALID,
18450aadb33SDmitri Tikhonov    [0x2A] = QUIC_FRAME_INVALID,
18550aadb33SDmitri Tikhonov    [0x2B] = QUIC_FRAME_INVALID,
18650aadb33SDmitri Tikhonov    [0x2C] = QUIC_FRAME_INVALID,
18750aadb33SDmitri Tikhonov    [0x2D] = QUIC_FRAME_INVALID,
18850aadb33SDmitri Tikhonov    [0x2E] = QUIC_FRAME_INVALID,
18950aadb33SDmitri Tikhonov    [0x2F] = QUIC_FRAME_INVALID,
19050aadb33SDmitri Tikhonov    [0x30] = QUIC_FRAME_INVALID,
19150aadb33SDmitri Tikhonov    [0x31] = QUIC_FRAME_INVALID,
19250aadb33SDmitri Tikhonov    [0x32] = QUIC_FRAME_INVALID,
19350aadb33SDmitri Tikhonov    [0x33] = QUIC_FRAME_INVALID,
19450aadb33SDmitri Tikhonov    [0x34] = QUIC_FRAME_INVALID,
19550aadb33SDmitri Tikhonov    [0x35] = QUIC_FRAME_INVALID,
19650aadb33SDmitri Tikhonov    [0x36] = QUIC_FRAME_INVALID,
19750aadb33SDmitri Tikhonov    [0x37] = QUIC_FRAME_INVALID,
19850aadb33SDmitri Tikhonov    [0x38] = QUIC_FRAME_INVALID,
19950aadb33SDmitri Tikhonov    [0x39] = QUIC_FRAME_INVALID,
20050aadb33SDmitri Tikhonov    [0x3A] = QUIC_FRAME_INVALID,
20150aadb33SDmitri Tikhonov    [0x3B] = QUIC_FRAME_INVALID,
20250aadb33SDmitri Tikhonov    [0x3C] = QUIC_FRAME_INVALID,
20350aadb33SDmitri Tikhonov    [0x3D] = QUIC_FRAME_INVALID,
20450aadb33SDmitri Tikhonov    [0x3E] = QUIC_FRAME_INVALID,
20550aadb33SDmitri Tikhonov    [0x3F] = QUIC_FRAME_INVALID,
20650aadb33SDmitri Tikhonov    [0x40] = QUIC_FRAME_ACK,
20750aadb33SDmitri Tikhonov    [0x41] = QUIC_FRAME_ACK,
20850aadb33SDmitri Tikhonov    [0x42] = QUIC_FRAME_ACK,
20950aadb33SDmitri Tikhonov    [0x43] = QUIC_FRAME_ACK,
21050aadb33SDmitri Tikhonov    [0x44] = QUIC_FRAME_ACK,
21150aadb33SDmitri Tikhonov    [0x45] = QUIC_FRAME_ACK,
21250aadb33SDmitri Tikhonov    [0x46] = QUIC_FRAME_ACK,
21350aadb33SDmitri Tikhonov    [0x47] = QUIC_FRAME_ACK,
21450aadb33SDmitri Tikhonov    [0x48] = QUIC_FRAME_ACK,
21550aadb33SDmitri Tikhonov    [0x49] = QUIC_FRAME_ACK,
21650aadb33SDmitri Tikhonov    [0x4A] = QUIC_FRAME_ACK,
21750aadb33SDmitri Tikhonov    [0x4B] = QUIC_FRAME_ACK,
21850aadb33SDmitri Tikhonov    [0x4C] = QUIC_FRAME_ACK,
21950aadb33SDmitri Tikhonov    [0x4D] = QUIC_FRAME_ACK,
22050aadb33SDmitri Tikhonov    [0x4E] = QUIC_FRAME_ACK,
22150aadb33SDmitri Tikhonov    [0x4F] = QUIC_FRAME_ACK,
22250aadb33SDmitri Tikhonov    [0x50] = QUIC_FRAME_ACK,
22350aadb33SDmitri Tikhonov    [0x51] = QUIC_FRAME_ACK,
22450aadb33SDmitri Tikhonov    [0x52] = QUIC_FRAME_ACK,
22550aadb33SDmitri Tikhonov    [0x53] = QUIC_FRAME_ACK,
22650aadb33SDmitri Tikhonov    [0x54] = QUIC_FRAME_ACK,
22750aadb33SDmitri Tikhonov    [0x55] = QUIC_FRAME_ACK,
22850aadb33SDmitri Tikhonov    [0x56] = QUIC_FRAME_ACK,
22950aadb33SDmitri Tikhonov    [0x57] = QUIC_FRAME_ACK,
23050aadb33SDmitri Tikhonov    [0x58] = QUIC_FRAME_ACK,
23150aadb33SDmitri Tikhonov    [0x59] = QUIC_FRAME_ACK,
23250aadb33SDmitri Tikhonov    [0x5A] = QUIC_FRAME_ACK,
23350aadb33SDmitri Tikhonov    [0x5B] = QUIC_FRAME_ACK,
23450aadb33SDmitri Tikhonov    [0x5C] = QUIC_FRAME_ACK,
23550aadb33SDmitri Tikhonov    [0x5D] = QUIC_FRAME_ACK,
23650aadb33SDmitri Tikhonov    [0x5E] = QUIC_FRAME_ACK,
23750aadb33SDmitri Tikhonov    [0x5F] = QUIC_FRAME_ACK,
23850aadb33SDmitri Tikhonov    [0x60] = QUIC_FRAME_ACK,
23950aadb33SDmitri Tikhonov    [0x61] = QUIC_FRAME_ACK,
24050aadb33SDmitri Tikhonov    [0x62] = QUIC_FRAME_ACK,
24150aadb33SDmitri Tikhonov    [0x63] = QUIC_FRAME_ACK,
24250aadb33SDmitri Tikhonov    [0x64] = QUIC_FRAME_ACK,
24350aadb33SDmitri Tikhonov    [0x65] = QUIC_FRAME_ACK,
24450aadb33SDmitri Tikhonov    [0x66] = QUIC_FRAME_ACK,
24550aadb33SDmitri Tikhonov    [0x67] = QUIC_FRAME_ACK,
24650aadb33SDmitri Tikhonov    [0x68] = QUIC_FRAME_ACK,
24750aadb33SDmitri Tikhonov    [0x69] = QUIC_FRAME_ACK,
24850aadb33SDmitri Tikhonov    [0x6A] = QUIC_FRAME_ACK,
24950aadb33SDmitri Tikhonov    [0x6B] = QUIC_FRAME_ACK,
25050aadb33SDmitri Tikhonov    [0x6C] = QUIC_FRAME_ACK,
25150aadb33SDmitri Tikhonov    [0x6D] = QUIC_FRAME_ACK,
25250aadb33SDmitri Tikhonov    [0x6E] = QUIC_FRAME_ACK,
25350aadb33SDmitri Tikhonov    [0x6F] = QUIC_FRAME_ACK,
25450aadb33SDmitri Tikhonov    [0x70] = QUIC_FRAME_ACK,
25550aadb33SDmitri Tikhonov    [0x71] = QUIC_FRAME_ACK,
25650aadb33SDmitri Tikhonov    [0x72] = QUIC_FRAME_ACK,
25750aadb33SDmitri Tikhonov    [0x73] = QUIC_FRAME_ACK,
25850aadb33SDmitri Tikhonov    [0x74] = QUIC_FRAME_ACK,
25950aadb33SDmitri Tikhonov    [0x75] = QUIC_FRAME_ACK,
26050aadb33SDmitri Tikhonov    [0x76] = QUIC_FRAME_ACK,
26150aadb33SDmitri Tikhonov    [0x77] = QUIC_FRAME_ACK,
26250aadb33SDmitri Tikhonov    [0x78] = QUIC_FRAME_ACK,
26350aadb33SDmitri Tikhonov    [0x79] = QUIC_FRAME_ACK,
26450aadb33SDmitri Tikhonov    [0x7A] = QUIC_FRAME_ACK,
26550aadb33SDmitri Tikhonov    [0x7B] = QUIC_FRAME_ACK,
26650aadb33SDmitri Tikhonov    [0x7C] = QUIC_FRAME_ACK,
26750aadb33SDmitri Tikhonov    [0x7D] = QUIC_FRAME_ACK,
26850aadb33SDmitri Tikhonov    [0x7E] = QUIC_FRAME_ACK,
26950aadb33SDmitri Tikhonov    [0x7F] = QUIC_FRAME_ACK,
27050aadb33SDmitri Tikhonov    [0x80] = QUIC_FRAME_STREAM,
27150aadb33SDmitri Tikhonov    [0x81] = QUIC_FRAME_STREAM,
27250aadb33SDmitri Tikhonov    [0x82] = QUIC_FRAME_STREAM,
27350aadb33SDmitri Tikhonov    [0x83] = QUIC_FRAME_STREAM,
27450aadb33SDmitri Tikhonov    [0x84] = QUIC_FRAME_STREAM,
27550aadb33SDmitri Tikhonov    [0x85] = QUIC_FRAME_STREAM,
27650aadb33SDmitri Tikhonov    [0x86] = QUIC_FRAME_STREAM,
27750aadb33SDmitri Tikhonov    [0x87] = QUIC_FRAME_STREAM,
27850aadb33SDmitri Tikhonov    [0x88] = QUIC_FRAME_STREAM,
27950aadb33SDmitri Tikhonov    [0x89] = QUIC_FRAME_STREAM,
28050aadb33SDmitri Tikhonov    [0x8A] = QUIC_FRAME_STREAM,
28150aadb33SDmitri Tikhonov    [0x8B] = QUIC_FRAME_STREAM,
28250aadb33SDmitri Tikhonov    [0x8C] = QUIC_FRAME_STREAM,
28350aadb33SDmitri Tikhonov    [0x8D] = QUIC_FRAME_STREAM,
28450aadb33SDmitri Tikhonov    [0x8E] = QUIC_FRAME_STREAM,
28550aadb33SDmitri Tikhonov    [0x8F] = QUIC_FRAME_STREAM,
28650aadb33SDmitri Tikhonov    [0x90] = QUIC_FRAME_STREAM,
28750aadb33SDmitri Tikhonov    [0x91] = QUIC_FRAME_STREAM,
28850aadb33SDmitri Tikhonov    [0x92] = QUIC_FRAME_STREAM,
28950aadb33SDmitri Tikhonov    [0x93] = QUIC_FRAME_STREAM,
29050aadb33SDmitri Tikhonov    [0x94] = QUIC_FRAME_STREAM,
29150aadb33SDmitri Tikhonov    [0x95] = QUIC_FRAME_STREAM,
29250aadb33SDmitri Tikhonov    [0x96] = QUIC_FRAME_STREAM,
29350aadb33SDmitri Tikhonov    [0x97] = QUIC_FRAME_STREAM,
29450aadb33SDmitri Tikhonov    [0x98] = QUIC_FRAME_STREAM,
29550aadb33SDmitri Tikhonov    [0x99] = QUIC_FRAME_STREAM,
29650aadb33SDmitri Tikhonov    [0x9A] = QUIC_FRAME_STREAM,
29750aadb33SDmitri Tikhonov    [0x9B] = QUIC_FRAME_STREAM,
29850aadb33SDmitri Tikhonov    [0x9C] = QUIC_FRAME_STREAM,
29950aadb33SDmitri Tikhonov    [0x9D] = QUIC_FRAME_STREAM,
30050aadb33SDmitri Tikhonov    [0x9E] = QUIC_FRAME_STREAM,
30150aadb33SDmitri Tikhonov    [0x9F] = QUIC_FRAME_STREAM,
30250aadb33SDmitri Tikhonov    [0xA0] = QUIC_FRAME_STREAM,
30350aadb33SDmitri Tikhonov    [0xA1] = QUIC_FRAME_STREAM,
30450aadb33SDmitri Tikhonov    [0xA2] = QUIC_FRAME_STREAM,
30550aadb33SDmitri Tikhonov    [0xA3] = QUIC_FRAME_STREAM,
30650aadb33SDmitri Tikhonov    [0xA4] = QUIC_FRAME_STREAM,
30750aadb33SDmitri Tikhonov    [0xA5] = QUIC_FRAME_STREAM,
30850aadb33SDmitri Tikhonov    [0xA6] = QUIC_FRAME_STREAM,
30950aadb33SDmitri Tikhonov    [0xA7] = QUIC_FRAME_STREAM,
31050aadb33SDmitri Tikhonov    [0xA8] = QUIC_FRAME_STREAM,
31150aadb33SDmitri Tikhonov    [0xA9] = QUIC_FRAME_STREAM,
31250aadb33SDmitri Tikhonov    [0xAA] = QUIC_FRAME_STREAM,
31350aadb33SDmitri Tikhonov    [0xAB] = QUIC_FRAME_STREAM,
31450aadb33SDmitri Tikhonov    [0xAC] = QUIC_FRAME_STREAM,
31550aadb33SDmitri Tikhonov    [0xAD] = QUIC_FRAME_STREAM,
31650aadb33SDmitri Tikhonov    [0xAE] = QUIC_FRAME_STREAM,
31750aadb33SDmitri Tikhonov    [0xAF] = QUIC_FRAME_STREAM,
31850aadb33SDmitri Tikhonov    [0xB0] = QUIC_FRAME_STREAM,
31950aadb33SDmitri Tikhonov    [0xB1] = QUIC_FRAME_STREAM,
32050aadb33SDmitri Tikhonov    [0xB2] = QUIC_FRAME_STREAM,
32150aadb33SDmitri Tikhonov    [0xB3] = QUIC_FRAME_STREAM,
32250aadb33SDmitri Tikhonov    [0xB4] = QUIC_FRAME_STREAM,
32350aadb33SDmitri Tikhonov    [0xB5] = QUIC_FRAME_STREAM,
32450aadb33SDmitri Tikhonov    [0xB6] = QUIC_FRAME_STREAM,
32550aadb33SDmitri Tikhonov    [0xB7] = QUIC_FRAME_STREAM,
32650aadb33SDmitri Tikhonov    [0xB8] = QUIC_FRAME_STREAM,
32750aadb33SDmitri Tikhonov    [0xB9] = QUIC_FRAME_STREAM,
32850aadb33SDmitri Tikhonov    [0xBA] = QUIC_FRAME_STREAM,
32950aadb33SDmitri Tikhonov    [0xBB] = QUIC_FRAME_STREAM,
33050aadb33SDmitri Tikhonov    [0xBC] = QUIC_FRAME_STREAM,
33150aadb33SDmitri Tikhonov    [0xBD] = QUIC_FRAME_STREAM,
33250aadb33SDmitri Tikhonov    [0xBE] = QUIC_FRAME_STREAM,
33350aadb33SDmitri Tikhonov    [0xBF] = QUIC_FRAME_STREAM,
33450aadb33SDmitri Tikhonov    [0xC0] = QUIC_FRAME_STREAM,
33550aadb33SDmitri Tikhonov    [0xC1] = QUIC_FRAME_STREAM,
33650aadb33SDmitri Tikhonov    [0xC2] = QUIC_FRAME_STREAM,
33750aadb33SDmitri Tikhonov    [0xC3] = QUIC_FRAME_STREAM,
33850aadb33SDmitri Tikhonov    [0xC4] = QUIC_FRAME_STREAM,
33950aadb33SDmitri Tikhonov    [0xC5] = QUIC_FRAME_STREAM,
34050aadb33SDmitri Tikhonov    [0xC6] = QUIC_FRAME_STREAM,
34150aadb33SDmitri Tikhonov    [0xC7] = QUIC_FRAME_STREAM,
34250aadb33SDmitri Tikhonov    [0xC8] = QUIC_FRAME_STREAM,
34350aadb33SDmitri Tikhonov    [0xC9] = QUIC_FRAME_STREAM,
34450aadb33SDmitri Tikhonov    [0xCA] = QUIC_FRAME_STREAM,
34550aadb33SDmitri Tikhonov    [0xCB] = QUIC_FRAME_STREAM,
34650aadb33SDmitri Tikhonov    [0xCC] = QUIC_FRAME_STREAM,
34750aadb33SDmitri Tikhonov    [0xCD] = QUIC_FRAME_STREAM,
34850aadb33SDmitri Tikhonov    [0xCE] = QUIC_FRAME_STREAM,
34950aadb33SDmitri Tikhonov    [0xCF] = QUIC_FRAME_STREAM,
35050aadb33SDmitri Tikhonov    [0xD0] = QUIC_FRAME_STREAM,
35150aadb33SDmitri Tikhonov    [0xD1] = QUIC_FRAME_STREAM,
35250aadb33SDmitri Tikhonov    [0xD2] = QUIC_FRAME_STREAM,
35350aadb33SDmitri Tikhonov    [0xD3] = QUIC_FRAME_STREAM,
35450aadb33SDmitri Tikhonov    [0xD4] = QUIC_FRAME_STREAM,
35550aadb33SDmitri Tikhonov    [0xD5] = QUIC_FRAME_STREAM,
35650aadb33SDmitri Tikhonov    [0xD6] = QUIC_FRAME_STREAM,
35750aadb33SDmitri Tikhonov    [0xD7] = QUIC_FRAME_STREAM,
35850aadb33SDmitri Tikhonov    [0xD8] = QUIC_FRAME_STREAM,
35950aadb33SDmitri Tikhonov    [0xD9] = QUIC_FRAME_STREAM,
36050aadb33SDmitri Tikhonov    [0xDA] = QUIC_FRAME_STREAM,
36150aadb33SDmitri Tikhonov    [0xDB] = QUIC_FRAME_STREAM,
36250aadb33SDmitri Tikhonov    [0xDC] = QUIC_FRAME_STREAM,
36350aadb33SDmitri Tikhonov    [0xDD] = QUIC_FRAME_STREAM,
36450aadb33SDmitri Tikhonov    [0xDE] = QUIC_FRAME_STREAM,
36550aadb33SDmitri Tikhonov    [0xDF] = QUIC_FRAME_STREAM,
36650aadb33SDmitri Tikhonov    [0xE0] = QUIC_FRAME_STREAM,
36750aadb33SDmitri Tikhonov    [0xE1] = QUIC_FRAME_STREAM,
36850aadb33SDmitri Tikhonov    [0xE2] = QUIC_FRAME_STREAM,
36950aadb33SDmitri Tikhonov    [0xE3] = QUIC_FRAME_STREAM,
37050aadb33SDmitri Tikhonov    [0xE4] = QUIC_FRAME_STREAM,
37150aadb33SDmitri Tikhonov    [0xE5] = QUIC_FRAME_STREAM,
37250aadb33SDmitri Tikhonov    [0xE6] = QUIC_FRAME_STREAM,
37350aadb33SDmitri Tikhonov    [0xE7] = QUIC_FRAME_STREAM,
37450aadb33SDmitri Tikhonov    [0xE8] = QUIC_FRAME_STREAM,
37550aadb33SDmitri Tikhonov    [0xE9] = QUIC_FRAME_STREAM,
37650aadb33SDmitri Tikhonov    [0xEA] = QUIC_FRAME_STREAM,
37750aadb33SDmitri Tikhonov    [0xEB] = QUIC_FRAME_STREAM,
37850aadb33SDmitri Tikhonov    [0xEC] = QUIC_FRAME_STREAM,
37950aadb33SDmitri Tikhonov    [0xED] = QUIC_FRAME_STREAM,
38050aadb33SDmitri Tikhonov    [0xEE] = QUIC_FRAME_STREAM,
38150aadb33SDmitri Tikhonov    [0xEF] = QUIC_FRAME_STREAM,
38250aadb33SDmitri Tikhonov    [0xF0] = QUIC_FRAME_STREAM,
38350aadb33SDmitri Tikhonov    [0xF1] = QUIC_FRAME_STREAM,
38450aadb33SDmitri Tikhonov    [0xF2] = QUIC_FRAME_STREAM,
38550aadb33SDmitri Tikhonov    [0xF3] = QUIC_FRAME_STREAM,
38650aadb33SDmitri Tikhonov    [0xF4] = QUIC_FRAME_STREAM,
38750aadb33SDmitri Tikhonov    [0xF5] = QUIC_FRAME_STREAM,
38850aadb33SDmitri Tikhonov    [0xF6] = QUIC_FRAME_STREAM,
38950aadb33SDmitri Tikhonov    [0xF7] = QUIC_FRAME_STREAM,
39050aadb33SDmitri Tikhonov    [0xF8] = QUIC_FRAME_STREAM,
39150aadb33SDmitri Tikhonov    [0xF9] = QUIC_FRAME_STREAM,
39250aadb33SDmitri Tikhonov    [0xFA] = QUIC_FRAME_STREAM,
39350aadb33SDmitri Tikhonov    [0xFB] = QUIC_FRAME_STREAM,
39450aadb33SDmitri Tikhonov    [0xFC] = QUIC_FRAME_STREAM,
39550aadb33SDmitri Tikhonov    [0xFD] = QUIC_FRAME_STREAM,
39650aadb33SDmitri Tikhonov    [0xFE] = QUIC_FRAME_STREAM,
39750aadb33SDmitri Tikhonov    [0xFF] = QUIC_FRAME_STREAM,
39850aadb33SDmitri Tikhonov};
39950aadb33SDmitri Tikhonov
40050aadb33SDmitri Tikhonov
4016aba801dSDmitri Tikhonovenum quic_frame_type
40250aadb33SDmitri Tikhonovparse_frame_type_gquic_Q035_thru_Q039 (unsigned char b)
40350aadb33SDmitri Tikhonov{
40450aadb33SDmitri Tikhonov    return byte2frame_type_Q035_thru_Q039[b];
40550aadb33SDmitri Tikhonov}
40650aadb33SDmitri Tikhonov
40750aadb33SDmitri Tikhonov
408c51ce338SDmitri Tikhonovvoid
409c51ce338SDmitri Tikhonovlsquic_turn_on_fin_Q035_thru_Q039 (unsigned char *stream_header)
410c51ce338SDmitri Tikhonov{
411c51ce338SDmitri Tikhonov    /* 1fdoooss */
412c51ce338SDmitri Tikhonov    *stream_header |= 0x40;
413c51ce338SDmitri Tikhonov}
414c51ce338SDmitri Tikhonov
415c51ce338SDmitri Tikhonov
41650aadb33SDmitri Tikhonovsize_t
41750aadb33SDmitri Tikhonovcalc_stream_frame_header_sz_gquic (uint32_t stream_id, uint64_t offset)
41850aadb33SDmitri Tikhonov{
41950aadb33SDmitri Tikhonov    return
42050aadb33SDmitri Tikhonov        /* Type */
42150aadb33SDmitri Tikhonov        1
42250aadb33SDmitri Tikhonov        /* Stream ID length */
42350aadb33SDmitri Tikhonov      + ((stream_id) > 0x0000FF)
42450aadb33SDmitri Tikhonov      + ((stream_id) > 0x00FFFF)
42550aadb33SDmitri Tikhonov      + ((stream_id) > 0xFFFFFF)
42650aadb33SDmitri Tikhonov      + 1
42750aadb33SDmitri Tikhonov        /* Offset length */
42850aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 56))
42950aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 48))
43050aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 40))
43150aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 32))
43250aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 24))
43350aadb33SDmitri Tikhonov      + ((offset) >= (1ULL << 16))
43450aadb33SDmitri Tikhonov      + (((offset) > 0) << 1)
43550aadb33SDmitri Tikhonov        /* Add data length (2) yourself, if necessary */
43650aadb33SDmitri Tikhonov    ;
43750aadb33SDmitri Tikhonov}
43850aadb33SDmitri Tikhonov
43950aadb33SDmitri Tikhonov
44050aadb33SDmitri Tikhonovchar *
44150aadb33SDmitri Tikhonovacki2str (const struct ack_info *acki, size_t *sz)
44250aadb33SDmitri Tikhonov{
44350aadb33SDmitri Tikhonov    size_t off, bufsz, nw;
44450aadb33SDmitri Tikhonov    unsigned n;
44550aadb33SDmitri Tikhonov    char *buf;
44650aadb33SDmitri Tikhonov
44750aadb33SDmitri Tikhonov    bufsz = acki->n_ranges * (3 /* [-] */ + 20 /* ~0ULL */ * 2);
44850aadb33SDmitri Tikhonov    buf = malloc(bufsz);
44950aadb33SDmitri Tikhonov    if (!buf)
45050aadb33SDmitri Tikhonov    {
45150aadb33SDmitri Tikhonov        LSQ_WARN("%s: malloc(%zd) failure: %s", __func__, bufsz,
45250aadb33SDmitri Tikhonov                                                        strerror(errno));
45350aadb33SDmitri Tikhonov        return NULL;
45450aadb33SDmitri Tikhonov    }
45550aadb33SDmitri Tikhonov
45650aadb33SDmitri Tikhonov    off = 0;
45750aadb33SDmitri Tikhonov    for (n = 0; n < acki->n_ranges; ++n)
45850aadb33SDmitri Tikhonov    {
45950aadb33SDmitri Tikhonov        nw = snprintf(buf + off, bufsz - off, "[%"PRIu64"-%"PRIu64"]",
46050aadb33SDmitri Tikhonov                acki->ranges[n].high, acki->ranges[n].low);
46150aadb33SDmitri Tikhonov        if (nw > bufsz - off)
46250aadb33SDmitri Tikhonov            break;
46350aadb33SDmitri Tikhonov        off += nw;
46450aadb33SDmitri Tikhonov    }
46550aadb33SDmitri Tikhonov
46650aadb33SDmitri Tikhonov    *sz = off;
46750aadb33SDmitri Tikhonov    return buf;
46850aadb33SDmitri Tikhonov}
4699626cfc2SDmitri Tikhonov
4709626cfc2SDmitri Tikhonov
4719626cfc2SDmitri Tikhonovsize_t
4729626cfc2SDmitri Tikhonovlsquic_gquic_po_header_sz (enum packet_out_flags flags)
4739626cfc2SDmitri Tikhonov{
4749626cfc2SDmitri Tikhonov    return 1                                                /* Type */
4759626cfc2SDmitri Tikhonov           + (!!(flags & PO_CONN_ID) << 3)                  /* Connection ID */
4769626cfc2SDmitri Tikhonov           + (!!(flags & PO_VERSION) << 2)                  /* Version */
4779626cfc2SDmitri Tikhonov           + (!!(flags & PO_NONCE)   << 5)                  /* Nonce */
4789626cfc2SDmitri Tikhonov           + packno_bits2len((flags >> POBIT_SHIFT) & 0x3)  /* Packet number */
4799626cfc2SDmitri Tikhonov           ;
4809626cfc2SDmitri Tikhonov}
4819626cfc2SDmitri Tikhonov
4829626cfc2SDmitri Tikhonov
4839626cfc2SDmitri Tikhonovsize_t
4849626cfc2SDmitri Tikhonovlsquic_gquic_packout_size (const struct lsquic_conn *conn,
4859626cfc2SDmitri Tikhonov                                const struct lsquic_packet_out *packet_out)
4869626cfc2SDmitri Tikhonov{
4879626cfc2SDmitri Tikhonov    return lsquic_gquic_po_header_sz(packet_out->po_flags)
4889626cfc2SDmitri Tikhonov         + packet_out->po_data_sz
4899626cfc2SDmitri Tikhonov         + QUIC_PACKET_HASH_SZ
4909626cfc2SDmitri Tikhonov         ;
4919626cfc2SDmitri Tikhonov}
4929626cfc2SDmitri Tikhonov
4939626cfc2SDmitri Tikhonov
4949626cfc2SDmitri Tikhonovsize_t
4959626cfc2SDmitri Tikhonovlsquic_gquic_packout_header_size (const struct lsquic_conn *conn,
4969626cfc2SDmitri Tikhonov                                                enum packet_out_flags flags)
4979626cfc2SDmitri Tikhonov{
4989626cfc2SDmitri Tikhonov    return lsquic_gquic_po_header_sz(flags);
4999626cfc2SDmitri Tikhonov}
5009626cfc2SDmitri Tikhonov
5019626cfc2SDmitri Tikhonov
502