1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech#include <assert.h> 39626cfc2SDmitri Tikhonov#include <string.h> 49626cfc2SDmitri Tikhonov#include <sys/queue.h> 59626cfc2SDmitri Tikhonov#include <sys/types.h> 69626cfc2SDmitri Tikhonov 75392f7a3SLiteSpeed Tech#include "lsquic.h" 89626cfc2SDmitri Tikhonov#include "lsquic_types.h" 99626cfc2SDmitri Tikhonov#include "lsquic_int_types.h" 109626cfc2SDmitri Tikhonov#include "lsquic_packet_common.h" 119626cfc2SDmitri Tikhonov#include "lsquic_packet_in.h" 129626cfc2SDmitri Tikhonov#include "lsquic_parse_common.h" 139626cfc2SDmitri Tikhonov#include "lsquic_parse.h" 145392f7a3SLiteSpeed Tech#include "lsquic_enc_sess.h" 155392f7a3SLiteSpeed Tech#include "lsquic_version.h" 167a8b2eceSDmitri Tikhonov#include "lsquic_qtags.h" 175392f7a3SLiteSpeed Tech 185392f7a3SLiteSpeed Tech 195392f7a3SLiteSpeed Techstatic int 207a8b2eceSDmitri Tikhonovparse_ietf_v1_or_Q046plus_long_begin (struct lsquic_packet_in *packet_in, 215392f7a3SLiteSpeed Tech size_t length, int is_server, unsigned cid_len, 225392f7a3SLiteSpeed Tech struct packin_parse_state *state) 235392f7a3SLiteSpeed Tech{ 245392f7a3SLiteSpeed Tech lsquic_ver_tag_t tag; 255392f7a3SLiteSpeed Tech 265392f7a3SLiteSpeed Tech if (length >= 5) 275392f7a3SLiteSpeed Tech { 285392f7a3SLiteSpeed Tech memcpy(&tag, packet_in->pi_data + 1, 4); 297a8b2eceSDmitri Tikhonov switch (tag) 307a8b2eceSDmitri Tikhonov { 317a8b2eceSDmitri Tikhonov case TAG('Q', '0', '4', '6'): 325392f7a3SLiteSpeed Tech return lsquic_Q046_parse_packet_in_long_begin(packet_in, length, 335392f7a3SLiteSpeed Tech is_server, cid_len, state); 347a8b2eceSDmitri Tikhonov case TAG('Q', '0', '5', '0'): 357a8b2eceSDmitri Tikhonov return lsquic_Q050_parse_packet_in_long_begin(packet_in, length, 367a8b2eceSDmitri Tikhonov is_server, cid_len, state); 377a8b2eceSDmitri Tikhonov default: 385392f7a3SLiteSpeed Tech return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length, 395392f7a3SLiteSpeed Tech is_server, cid_len, state); 407a8b2eceSDmitri Tikhonov } 415392f7a3SLiteSpeed Tech } 425392f7a3SLiteSpeed Tech else 435392f7a3SLiteSpeed Tech return -1; 445392f7a3SLiteSpeed Tech} 455392f7a3SLiteSpeed Tech 465392f7a3SLiteSpeed Tech 475392f7a3SLiteSpeed Techstatic int (* const parse_begin_funcs[32]) (struct lsquic_packet_in *, 485392f7a3SLiteSpeed Tech size_t length, int is_server, unsigned cid_len, 495392f7a3SLiteSpeed Tech struct packin_parse_state *) = 505392f7a3SLiteSpeed Tech{ 515392f7a3SLiteSpeed Tech /* Xs vary, Gs are iGnored: */ 525392f7a3SLiteSpeed Tech#define PBEL(mask) [(mask) >> 3] 535392f7a3SLiteSpeed Tech /* 1X11 XGGG: */ 545392f7a3SLiteSpeed Tech PBEL(0x80|0x40|0x20|0x10|0x08) = lsquic_Q046_parse_packet_in_long_begin, 555392f7a3SLiteSpeed Tech PBEL(0x80|0x00|0x20|0x10|0x08) = lsquic_Q046_parse_packet_in_long_begin, 565392f7a3SLiteSpeed Tech PBEL(0x80|0x40|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_long_begin, 575392f7a3SLiteSpeed Tech PBEL(0x80|0x00|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_long_begin, 585392f7a3SLiteSpeed Tech /* 1X00 XGGG: */ 597a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 607a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 617a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 627a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 635392f7a3SLiteSpeed Tech /* 1X01 XGGG: */ 647a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 657a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 667a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 677a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 685392f7a3SLiteSpeed Tech /* 1X10 XGGG: */ 697a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 707a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 717a8b2eceSDmitri Tikhonov PBEL(0x80|0x40|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 727a8b2eceSDmitri Tikhonov PBEL(0x80|0x00|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 735392f7a3SLiteSpeed Tech /* 01XX XGGG */ 745392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x00|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 755392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x00|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 765392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x00|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 775392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x00|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 785392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x20|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 795392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x20|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 805392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x20|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 815392f7a3SLiteSpeed Tech PBEL(0x00|0x40|0x20|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 825392f7a3SLiteSpeed Tech /* 00XX 0GGG */ 835392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x00|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin, 845392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x00|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin, 855392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x20|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin, 865392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin, 875392f7a3SLiteSpeed Tech /* 00XX 1GGG */ 885392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x00|0x00|0x08) = lsquic_gquic_parse_packet_in_begin, 895392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x00|0x10|0x08) = lsquic_gquic_parse_packet_in_begin, 905392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x20|0x00|0x08) = lsquic_gquic_parse_packet_in_begin, 915392f7a3SLiteSpeed Tech PBEL(0x00|0x00|0x20|0x10|0x08) = lsquic_gquic_parse_packet_in_begin, 925392f7a3SLiteSpeed Tech#undef PBEL 935392f7a3SLiteSpeed Tech}; 949626cfc2SDmitri Tikhonov 959626cfc2SDmitri Tikhonov 969626cfc2SDmitri Tikhonovint 975392f7a3SLiteSpeed Techlsquic_parse_packet_in_server_begin (struct lsquic_packet_in *packet_in, 985392f7a3SLiteSpeed Tech size_t length, int is_server_UNUSED, unsigned cid_len, 995392f7a3SLiteSpeed Tech struct packin_parse_state *state) 1005392f7a3SLiteSpeed Tech{ 1015392f7a3SLiteSpeed Tech if (length) 1025392f7a3SLiteSpeed Tech return parse_begin_funcs[ packet_in->pi_data[0] >> 3 ]( 1035392f7a3SLiteSpeed Tech packet_in, length, 1, cid_len, state); 1045392f7a3SLiteSpeed Tech else 1055392f7a3SLiteSpeed Tech return -1; 1065392f7a3SLiteSpeed Tech 1075392f7a3SLiteSpeed Tech} 1085392f7a3SLiteSpeed Tech 1095392f7a3SLiteSpeed Tech 1105392f7a3SLiteSpeed Techint 1119626cfc2SDmitri Tikhonovlsquic_parse_packet_in_begin (lsquic_packet_in_t *packet_in, size_t length, 1125392f7a3SLiteSpeed Tech int is_server, unsigned cid_len, struct packin_parse_state *state) 1139626cfc2SDmitri Tikhonov{ 1149626cfc2SDmitri Tikhonov if (length > 0) 1159626cfc2SDmitri Tikhonov { 1165392f7a3SLiteSpeed Tech switch (packet_in->pi_data[0] & 0xC0) 1179626cfc2SDmitri Tikhonov { 118c7d81ce1SDmitri Tikhonov case 0xC0: 1195392f7a3SLiteSpeed Tech case 0x80: 1207a8b2eceSDmitri Tikhonov return parse_ietf_v1_or_Q046plus_long_begin(packet_in, 1215392f7a3SLiteSpeed Tech length, is_server, cid_len, state); 1225392f7a3SLiteSpeed Tech case 0x00: 1239626cfc2SDmitri Tikhonov return lsquic_gquic_parse_packet_in_begin(packet_in, length, 1245392f7a3SLiteSpeed Tech is_server, cid_len, state); 1259626cfc2SDmitri Tikhonov default: 1265392f7a3SLiteSpeed Tech return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, 1275392f7a3SLiteSpeed Tech length, is_server, cid_len, state); 1289626cfc2SDmitri Tikhonov } 1299626cfc2SDmitri Tikhonov } 1309626cfc2SDmitri Tikhonov else 1319626cfc2SDmitri Tikhonov return -1; 1329626cfc2SDmitri Tikhonov} 1339626cfc2SDmitri Tikhonov 1349626cfc2SDmitri Tikhonov 1359626cfc2SDmitri Tikhonovint 1365392f7a3SLiteSpeed Techlsquic_ietf_v1_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 1375392f7a3SLiteSpeed Tech size_t length, int is_server, unsigned cid_len, 1385392f7a3SLiteSpeed Tech struct packin_parse_state *state) 1399626cfc2SDmitri Tikhonov{ 1409626cfc2SDmitri Tikhonov if (length > 0) 1419626cfc2SDmitri Tikhonov { 1429626cfc2SDmitri Tikhonov if (0 == (packet_in->pi_data[0] & 0x80)) 1435392f7a3SLiteSpeed Tech return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 1445392f7a3SLiteSpeed Tech is_server, cid_len, state); 1459626cfc2SDmitri Tikhonov else 1465392f7a3SLiteSpeed Tech return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length, 1475392f7a3SLiteSpeed Tech is_server, cid_len, state); 1489626cfc2SDmitri Tikhonov } 1499626cfc2SDmitri Tikhonov else 1509626cfc2SDmitri Tikhonov return -1; 1519626cfc2SDmitri Tikhonov} 1529626cfc2SDmitri Tikhonov 1539626cfc2SDmitri Tikhonov 1545392f7a3SLiteSpeed Techint 1555392f7a3SLiteSpeed Techlsquic_Q046_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 1565392f7a3SLiteSpeed Tech size_t length, int is_server, unsigned cid_len, 1575392f7a3SLiteSpeed Tech struct packin_parse_state *state) 1585392f7a3SLiteSpeed Tech{ 1595392f7a3SLiteSpeed Tech assert(!is_server); 1605392f7a3SLiteSpeed Tech assert(cid_len == GQUIC_CID_LEN); 1615392f7a3SLiteSpeed Tech if (length > 0) 1625392f7a3SLiteSpeed Tech { 1635392f7a3SLiteSpeed Tech if (0 == (packet_in->pi_data[0] & 0x80)) 1645392f7a3SLiteSpeed Tech return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 1655392f7a3SLiteSpeed Tech is_server, is_server ? cid_len : 0, state); 1665392f7a3SLiteSpeed Tech else 1675392f7a3SLiteSpeed Tech return lsquic_Q046_parse_packet_in_long_begin(packet_in, length, 1685392f7a3SLiteSpeed Tech is_server, cid_len, state); 1695392f7a3SLiteSpeed Tech } 1705392f7a3SLiteSpeed Tech else 1715392f7a3SLiteSpeed Tech return -1; 1725392f7a3SLiteSpeed Tech} 1735392f7a3SLiteSpeed Tech 1745392f7a3SLiteSpeed Tech 1757a8b2eceSDmitri Tikhonovint 1767a8b2eceSDmitri Tikhonovlsquic_Q050_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 1777a8b2eceSDmitri Tikhonov size_t length, int is_server, unsigned cid_len, 1787a8b2eceSDmitri Tikhonov struct packin_parse_state *state) 1797a8b2eceSDmitri Tikhonov{ 1807a8b2eceSDmitri Tikhonov assert(!is_server); 1817a8b2eceSDmitri Tikhonov assert(cid_len == GQUIC_CID_LEN); 1827a8b2eceSDmitri Tikhonov if (length > 0) 1837a8b2eceSDmitri Tikhonov { 1847a8b2eceSDmitri Tikhonov if (0 == (packet_in->pi_data[0] & 0x80)) 1857a8b2eceSDmitri Tikhonov return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 1867a8b2eceSDmitri Tikhonov is_server, is_server ? cid_len : 0, state); 1877a8b2eceSDmitri Tikhonov else 1887a8b2eceSDmitri Tikhonov return lsquic_Q050_parse_packet_in_long_begin(packet_in, length, 1897a8b2eceSDmitri Tikhonov is_server, cid_len, state); 1907a8b2eceSDmitri Tikhonov } 1917a8b2eceSDmitri Tikhonov else 1927a8b2eceSDmitri Tikhonov return -1; 1937a8b2eceSDmitri Tikhonov} 1947a8b2eceSDmitri Tikhonov 1957a8b2eceSDmitri Tikhonov 1965392f7a3SLiteSpeed Tech/* TODO This function uses the full packet parsing functionality to get at 1975392f7a3SLiteSpeed Tech * the CID. This is an overkill and could be optimized -- at the cost of 1985392f7a3SLiteSpeed Tech * some code duplication, of course. 1995392f7a3SLiteSpeed Tech */ 2005392f7a3SLiteSpeed Techint 2015392f7a3SLiteSpeed Techlsquic_cid_from_packet (const unsigned char *buf, size_t bufsz, 2025392f7a3SLiteSpeed Tech lsquic_cid_t *cid) 2035392f7a3SLiteSpeed Tech{ 2045392f7a3SLiteSpeed Tech struct lsquic_packet_in packet_in; 2055392f7a3SLiteSpeed Tech struct packin_parse_state pps; 2065392f7a3SLiteSpeed Tech int s; 2075392f7a3SLiteSpeed Tech 2085392f7a3SLiteSpeed Tech packet_in.pi_data = (unsigned char *) buf; 2095392f7a3SLiteSpeed Tech s = lsquic_parse_packet_in_server_begin(&packet_in, bufsz, 1, 8, &pps); 2105392f7a3SLiteSpeed Tech if (0 == s && (packet_in.pi_flags & PI_CONN_ID)) 2115392f7a3SLiteSpeed Tech { 2125392f7a3SLiteSpeed Tech *cid = packet_in.pi_dcid; 2135392f7a3SLiteSpeed Tech return 0; 2145392f7a3SLiteSpeed Tech } 2155392f7a3SLiteSpeed Tech else 2165392f7a3SLiteSpeed Tech return -1; 2175392f7a3SLiteSpeed Tech} 2185392f7a3SLiteSpeed Tech 2195392f7a3SLiteSpeed Tech 220c2faf032SDmitri Tikhonovint 221c2faf032SDmitri Tikhonovlsquic_dcid_from_packet (const unsigned char *buf, size_t bufsz, 222c2faf032SDmitri Tikhonov unsigned server_cid_len, unsigned *cid_len) 223c2faf032SDmitri Tikhonov{ 224c2faf032SDmitri Tikhonov const unsigned char *p; 225c2faf032SDmitri Tikhonov unsigned dcil, scil; 226c2faf032SDmitri Tikhonov 227c2faf032SDmitri Tikhonov if (bufsz < 9) 228c2faf032SDmitri Tikhonov return -1; 229c2faf032SDmitri Tikhonov 230c2faf032SDmitri Tikhonov switch (buf[0] >> 3) 231c2faf032SDmitri Tikhonov { 232c2faf032SDmitri Tikhonov /* Xs vary, Gs are iGnored: */ 233c2faf032SDmitri Tikhonov /* 1X11 XGGG: */ 234c2faf032SDmitri Tikhonov case (0x80|0x40|0x20|0x10|0x08) >> 3: 235c2faf032SDmitri Tikhonov case (0x80|0x00|0x20|0x10|0x08) >> 3: 236c2faf032SDmitri Tikhonov case (0x80|0x40|0x20|0x10|0x00) >> 3: 237c2faf032SDmitri Tikhonov case (0x80|0x00|0x20|0x10|0x00) >> 3: 238c2faf032SDmitri Tikhonov Q046_long: 239c2faf032SDmitri Tikhonov /* lsquic_Q046_parse_packet_in_long_begin */ 240c2faf032SDmitri Tikhonov if (bufsz < 14) 241c2faf032SDmitri Tikhonov return -1; 242c2faf032SDmitri Tikhonov p = buf + 5; 243c2faf032SDmitri Tikhonov dcil = p[0] >> 4; 244c2faf032SDmitri Tikhonov if (dcil) 245c2faf032SDmitri Tikhonov dcil += 3; 246c2faf032SDmitri Tikhonov scil = p[0] & 0xF; 247c2faf032SDmitri Tikhonov if (scil) 248c2faf032SDmitri Tikhonov scil += 3; 249c2faf032SDmitri Tikhonov ++p; 250c2faf032SDmitri Tikhonov if (dcil == GQUIC_CID_LEN && scil == 0) 251c2faf032SDmitri Tikhonov { 252c2faf032SDmitri Tikhonov *cid_len = GQUIC_CID_LEN; 253c2faf032SDmitri Tikhonov return (unsigned) (p - buf); 254c2faf032SDmitri Tikhonov } 255c2faf032SDmitri Tikhonov else 256c2faf032SDmitri Tikhonov return -1; 257c2faf032SDmitri Tikhonov /* 1X00 XGGG: */ 258c2faf032SDmitri Tikhonov /* 259c2faf032SDmitri Tikhonov case (0x80|0x40|0x00|0x00|0x08) >> 3: 260c2faf032SDmitri Tikhonov case (0x80|0x00|0x00|0x00|0x08) >> 3: 261c2faf032SDmitri Tikhonov case (0x80|0x40|0x00|0x00|0x00) >> 3: 262c2faf032SDmitri Tikhonov case (0x80|0x00|0x00|0x00|0x00) >> 3: 263c2faf032SDmitri Tikhonov case (0x80|0x40|0x00|0x10|0x08) >> 3: 264c2faf032SDmitri Tikhonov case (0x80|0x00|0x00|0x10|0x08) >> 3: 265c2faf032SDmitri Tikhonov case (0x80|0x40|0x00|0x10|0x00) >> 3: 266c2faf032SDmitri Tikhonov case (0x80|0x00|0x00|0x10|0x00) >> 3: 267c2faf032SDmitri Tikhonov case (0x80|0x40|0x20|0x00|0x08) >> 3: 268c2faf032SDmitri Tikhonov case (0x80|0x00|0x20|0x00|0x08) >> 3: 269c2faf032SDmitri Tikhonov case (0x80|0x40|0x20|0x00|0x00) >> 3: 270c2faf032SDmitri Tikhonov case (0x80|0x00|0x20|0x00|0x00) >> 3: 271c2faf032SDmitri Tikhonov */ 272c2faf032SDmitri Tikhonov default: 273c2faf032SDmitri Tikhonov /* parse_ietf_v1_or_Q046plus_long_begin */ 274c2faf032SDmitri Tikhonov if (buf[4] == (unsigned) '6') 275c2faf032SDmitri Tikhonov goto Q046_long; 276c2faf032SDmitri Tikhonov /* lsquic_Q050_parse_packet_in_long_begin or 277c2faf032SDmitri Tikhonov lsquic_ietf_v1_parse_packet_in_long_begin */ 278c2faf032SDmitri Tikhonov if (bufsz < 14) 279c2faf032SDmitri Tikhonov return -1; 280c2faf032SDmitri Tikhonov dcil = buf[5]; 281c2faf032SDmitri Tikhonov if (dcil <= MAX_CID_LEN && 6 + dcil < bufsz) 282c2faf032SDmitri Tikhonov { 283c2faf032SDmitri Tikhonov *cid_len = dcil; 284c2faf032SDmitri Tikhonov return 6; 285c2faf032SDmitri Tikhonov } 286c2faf032SDmitri Tikhonov else 287c2faf032SDmitri Tikhonov return -1; 288c2faf032SDmitri Tikhonov /* 01XX XGGG */ 289c2faf032SDmitri Tikhonov case (0x00|0x40|0x00|0x00|0x00) >> 3: 290c2faf032SDmitri Tikhonov case (0x00|0x40|0x00|0x00|0x08) >> 3: 291c2faf032SDmitri Tikhonov case (0x00|0x40|0x00|0x10|0x00) >> 3: 292c2faf032SDmitri Tikhonov case (0x00|0x40|0x00|0x10|0x08) >> 3: 293c2faf032SDmitri Tikhonov case (0x00|0x40|0x20|0x00|0x00) >> 3: 294c2faf032SDmitri Tikhonov case (0x00|0x40|0x20|0x00|0x08) >> 3: 295c2faf032SDmitri Tikhonov case (0x00|0x40|0x20|0x10|0x00) >> 3: 296c2faf032SDmitri Tikhonov case (0x00|0x40|0x20|0x10|0x08) >> 3: 297c2faf032SDmitri Tikhonov /* lsquic_ietf_v1_parse_packet_in_short_begin */ 298c2faf032SDmitri Tikhonov if (1 + server_cid_len <= bufsz) 299c2faf032SDmitri Tikhonov { 300c2faf032SDmitri Tikhonov *cid_len = server_cid_len; 301c2faf032SDmitri Tikhonov return 1; 302c2faf032SDmitri Tikhonov } 303c2faf032SDmitri Tikhonov else 304c2faf032SDmitri Tikhonov return -1; 305c2faf032SDmitri Tikhonov /* 00XX 0GGG */ 306c2faf032SDmitri Tikhonov case (0x00|0x00|0x00|0x00|0x00) >> 3: 307c2faf032SDmitri Tikhonov case (0x00|0x00|0x00|0x10|0x00) >> 3: 308c2faf032SDmitri Tikhonov case (0x00|0x00|0x20|0x00|0x00) >> 3: 309c2faf032SDmitri Tikhonov case (0x00|0x00|0x20|0x10|0x00) >> 3: 310c2faf032SDmitri Tikhonov /* lsquic_Q046_parse_packet_in_short_begin */ 311c2faf032SDmitri Tikhonov if (1 + server_cid_len <= bufsz && (buf[0] & 0x40)) 312c2faf032SDmitri Tikhonov { 313c2faf032SDmitri Tikhonov *cid_len = server_cid_len; 314c2faf032SDmitri Tikhonov return 1; 315c2faf032SDmitri Tikhonov } 316c2faf032SDmitri Tikhonov else 317c2faf032SDmitri Tikhonov return -1; 318c2faf032SDmitri Tikhonov /* 00XX 1GGG */ 319c2faf032SDmitri Tikhonov case (0x00|0x00|0x00|0x00|0x08) >> 3: 320c2faf032SDmitri Tikhonov case (0x00|0x00|0x00|0x10|0x08) >> 3: 321c2faf032SDmitri Tikhonov case (0x00|0x00|0x20|0x00|0x08) >> 3: 322c2faf032SDmitri Tikhonov case (0x00|0x00|0x20|0x10|0x08) >> 3: 323c2faf032SDmitri Tikhonov /* lsquic_gquic_parse_packet_in_begin */ 324c2faf032SDmitri Tikhonov if (1 + GQUIC_CID_LEN <= bufsz 325c2faf032SDmitri Tikhonov && (buf[0] & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)) 326c2faf032SDmitri Tikhonov { 327c2faf032SDmitri Tikhonov *cid_len = server_cid_len; 328c2faf032SDmitri Tikhonov return 1; 329c2faf032SDmitri Tikhonov } 330c2faf032SDmitri Tikhonov else 331c2faf032SDmitri Tikhonov return -1; 332c2faf032SDmitri Tikhonov } 333c2faf032SDmitri Tikhonov} 334c2faf032SDmitri Tikhonov 335c2faf032SDmitri Tikhonov 336fb73393fSDmitri Tikhonov/* See [draft-ietf-quic-transport-28], Section 12.4 (Table 3) */ 337fb73393fSDmitri Tikhonovconst enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] = 3385392f7a3SLiteSpeed Tech{ 33926e8f082SDmitri Tikhonov [LSQVER_I001] = { 340b1a7c3f9SDmitri Tikhonov [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 341b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE, 342b1a7c3f9SDmitri Tikhonov [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 343b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 3444051ae3aSDmitri Tikhonov | QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE 3454051ae3aSDmitri Tikhonov | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 3464051ae3aSDmitri Tikhonov | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 3474051ae3aSDmitri Tikhonov | QUIC_FTBIT_STREAMS_BLOCKED 3484051ae3aSDmitri Tikhonov | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 34926e8f082SDmitri Tikhonov | QUIC_FTBIT_PATH_CHALLENGE 350b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 3514051ae3aSDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID, 3524051ae3aSDmitri Tikhonov [ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 3534051ae3aSDmitri Tikhonov | QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE, 3544051ae3aSDmitri Tikhonov [ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 3554051ae3aSDmitri Tikhonov | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE 3564051ae3aSDmitri Tikhonov | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 3574051ae3aSDmitri Tikhonov | QUIC_FTBIT_BLOCKED 3584051ae3aSDmitri Tikhonov | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 3594051ae3aSDmitri Tikhonov | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 3604051ae3aSDmitri Tikhonov | QUIC_FTBIT_STREAMS_BLOCKED 3614051ae3aSDmitri Tikhonov | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 3624051ae3aSDmitri Tikhonov | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 3634051ae3aSDmitri Tikhonov | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY 3644051ae3aSDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN 3654051ae3aSDmitri Tikhonov | QUIC_FTBIT_TIMESTAMP 366b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 3674051ae3aSDmitri Tikhonov , 3684051ae3aSDmitri Tikhonov }, 36926e8f082SDmitri Tikhonov [LSQVER_ID29] = { 370fb73393fSDmitri Tikhonov [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 371fb73393fSDmitri Tikhonov | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE, 372fb73393fSDmitri Tikhonov [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 373fb73393fSDmitri Tikhonov | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 374fb73393fSDmitri Tikhonov | QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE 375fb73393fSDmitri Tikhonov | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 376fb73393fSDmitri Tikhonov | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 377fb73393fSDmitri Tikhonov | QUIC_FTBIT_STREAMS_BLOCKED 378fb73393fSDmitri Tikhonov | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 379fb73393fSDmitri Tikhonov | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 38026e8f082SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 381fb73393fSDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID, 382fb73393fSDmitri Tikhonov [ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 383fb73393fSDmitri Tikhonov | QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE, 384fb73393fSDmitri Tikhonov [ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 385fb73393fSDmitri Tikhonov | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE 386fb73393fSDmitri Tikhonov | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 387fb73393fSDmitri Tikhonov | QUIC_FTBIT_BLOCKED 388fb73393fSDmitri Tikhonov | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 389fb73393fSDmitri Tikhonov | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 390fb73393fSDmitri Tikhonov | QUIC_FTBIT_STREAMS_BLOCKED 391fb73393fSDmitri Tikhonov | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 392fb73393fSDmitri Tikhonov | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 393fb73393fSDmitri Tikhonov | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY 394fb73393fSDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN 395fb73393fSDmitri Tikhonov | QUIC_FTBIT_TIMESTAMP 39626e8f082SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 397fb73393fSDmitri Tikhonov , 398fb73393fSDmitri Tikhonov }, 399fb73393fSDmitri Tikhonov [LSQVER_ID27] = { 4005392f7a3SLiteSpeed Tech [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 4015392f7a3SLiteSpeed Tech | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE, 4025392f7a3SLiteSpeed Tech [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 4035392f7a3SLiteSpeed Tech | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 4045392f7a3SLiteSpeed Tech | QUIC_FTBIT_BLOCKED 4055392f7a3SLiteSpeed Tech | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 4065392f7a3SLiteSpeed Tech | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 4075392f7a3SLiteSpeed Tech | QUIC_FTBIT_STREAMS_BLOCKED 4085392f7a3SLiteSpeed Tech | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 4095392f7a3SLiteSpeed Tech | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 410b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID 411b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 412b1a7c3f9SDmitri Tikhonov , 4135392f7a3SLiteSpeed Tech [ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 4145392f7a3SLiteSpeed Tech | QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE, 4155392f7a3SLiteSpeed Tech [ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 4165392f7a3SLiteSpeed Tech | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE 4175392f7a3SLiteSpeed Tech | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 4185392f7a3SLiteSpeed Tech | QUIC_FTBIT_BLOCKED 4195392f7a3SLiteSpeed Tech | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 4205392f7a3SLiteSpeed Tech | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 4215392f7a3SLiteSpeed Tech | QUIC_FTBIT_STREAMS_BLOCKED 4225392f7a3SLiteSpeed Tech | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 4235392f7a3SLiteSpeed Tech | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 424feca77f5SDmitri Tikhonov | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY 425afe3d363SDmitri Tikhonov | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN 426afe3d363SDmitri Tikhonov | QUIC_FTBIT_TIMESTAMP 427b1a7c3f9SDmitri Tikhonov | QUIC_FTBIT_DATAGRAM 428afe3d363SDmitri Tikhonov , 429fb73393fSDmitri Tikhonov }, 4305392f7a3SLiteSpeed Tech}; 431