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