lsquic_parse_common.c revision afe3d363
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <string.h> 4#include <sys/queue.h> 5#include <sys/types.h> 6 7#include "lsquic.h" 8#include "lsquic_types.h" 9#include "lsquic_int_types.h" 10#include "lsquic_packet_common.h" 11#include "lsquic_packet_in.h" 12#include "lsquic_parse_common.h" 13#include "lsquic_parse.h" 14#include "lsquic_enc_sess.h" 15#include "lsquic_version.h" 16#include "lsquic_qtags.h" 17 18 19static int 20parse_ietf_v1_or_Q046plus_long_begin (struct lsquic_packet_in *packet_in, 21 size_t length, int is_server, unsigned cid_len, 22 struct packin_parse_state *state) 23{ 24 lsquic_ver_tag_t tag; 25 26 if (length >= 5) 27 { 28 memcpy(&tag, packet_in->pi_data + 1, 4); 29 switch (tag) 30 { 31 case TAG('Q', '0', '4', '6'): 32 return lsquic_Q046_parse_packet_in_long_begin(packet_in, length, 33 is_server, cid_len, state); 34 case TAG('Q', '0', '5', '0'): 35 return lsquic_Q050_parse_packet_in_long_begin(packet_in, length, 36 is_server, cid_len, state); 37 default: 38 return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length, 39 is_server, cid_len, state); 40 } 41 } 42 else 43 return -1; 44} 45 46 47static int (* const parse_begin_funcs[32]) (struct lsquic_packet_in *, 48 size_t length, int is_server, unsigned cid_len, 49 struct packin_parse_state *) = 50{ 51 /* Xs vary, Gs are iGnored: */ 52#define PBEL(mask) [(mask) >> 3] 53 /* 1X11 XGGG: */ 54 PBEL(0x80|0x40|0x20|0x10|0x08) = lsquic_Q046_parse_packet_in_long_begin, 55 PBEL(0x80|0x00|0x20|0x10|0x08) = lsquic_Q046_parse_packet_in_long_begin, 56 PBEL(0x80|0x40|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_long_begin, 57 PBEL(0x80|0x00|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_long_begin, 58 /* 1X00 XGGG: */ 59 PBEL(0x80|0x40|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 60 PBEL(0x80|0x00|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 61 PBEL(0x80|0x40|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 62 PBEL(0x80|0x00|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 63 /* 1X01 XGGG: */ 64 PBEL(0x80|0x40|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 65 PBEL(0x80|0x00|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 66 PBEL(0x80|0x40|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 67 PBEL(0x80|0x00|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 68 /* 1X10 XGGG: */ 69 PBEL(0x80|0x40|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 70 PBEL(0x80|0x00|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin, 71 PBEL(0x80|0x40|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 72 PBEL(0x80|0x00|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin, 73 /* 01XX XGGG */ 74 PBEL(0x00|0x40|0x00|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 75 PBEL(0x00|0x40|0x00|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 76 PBEL(0x00|0x40|0x00|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 77 PBEL(0x00|0x40|0x00|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 78 PBEL(0x00|0x40|0x20|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 79 PBEL(0x00|0x40|0x20|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 80 PBEL(0x00|0x40|0x20|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin, 81 PBEL(0x00|0x40|0x20|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin, 82 /* 00XX 0GGG */ 83 PBEL(0x00|0x00|0x00|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin, 84 PBEL(0x00|0x00|0x00|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin, 85 PBEL(0x00|0x00|0x20|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin, 86 PBEL(0x00|0x00|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin, 87 /* 00XX 1GGG */ 88 PBEL(0x00|0x00|0x00|0x00|0x08) = lsquic_gquic_parse_packet_in_begin, 89 PBEL(0x00|0x00|0x00|0x10|0x08) = lsquic_gquic_parse_packet_in_begin, 90 PBEL(0x00|0x00|0x20|0x00|0x08) = lsquic_gquic_parse_packet_in_begin, 91 PBEL(0x00|0x00|0x20|0x10|0x08) = lsquic_gquic_parse_packet_in_begin, 92#undef PBEL 93}; 94 95 96int 97lsquic_parse_packet_in_server_begin (struct lsquic_packet_in *packet_in, 98 size_t length, int is_server_UNUSED, unsigned cid_len, 99 struct packin_parse_state *state) 100{ 101 if (length) 102 return parse_begin_funcs[ packet_in->pi_data[0] >> 3 ]( 103 packet_in, length, 1, cid_len, state); 104 else 105 return -1; 106 107} 108 109 110int 111lsquic_parse_packet_in_begin (lsquic_packet_in_t *packet_in, size_t length, 112 int is_server, unsigned cid_len, struct packin_parse_state *state) 113{ 114 if (length > 0) 115 { 116 switch (packet_in->pi_data[0] & 0xC0) 117 { 118 case 0xC0: 119 case 0x80: 120 return parse_ietf_v1_or_Q046plus_long_begin(packet_in, 121 length, is_server, cid_len, state); 122 case 0x00: 123 return lsquic_gquic_parse_packet_in_begin(packet_in, length, 124 is_server, cid_len, state); 125 default: 126 return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, 127 length, is_server, cid_len, state); 128 } 129 } 130 else 131 return -1; 132} 133 134 135int 136lsquic_ietf_v1_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 137 size_t length, int is_server, unsigned cid_len, 138 struct packin_parse_state *state) 139{ 140 if (length > 0) 141 { 142 if (0 == (packet_in->pi_data[0] & 0x80)) 143 return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 144 is_server, cid_len, state); 145 else 146 return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length, 147 is_server, cid_len, state); 148 } 149 else 150 return -1; 151} 152 153 154int 155lsquic_Q046_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 156 size_t length, int is_server, unsigned cid_len, 157 struct packin_parse_state *state) 158{ 159 assert(!is_server); 160 assert(cid_len == GQUIC_CID_LEN); 161 if (length > 0) 162 { 163 if (0 == (packet_in->pi_data[0] & 0x80)) 164 return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 165 is_server, is_server ? cid_len : 0, state); 166 else 167 return lsquic_Q046_parse_packet_in_long_begin(packet_in, length, 168 is_server, cid_len, state); 169 } 170 else 171 return -1; 172} 173 174 175int 176lsquic_Q050_parse_packet_in_begin (struct lsquic_packet_in *packet_in, 177 size_t length, int is_server, unsigned cid_len, 178 struct packin_parse_state *state) 179{ 180 assert(!is_server); 181 assert(cid_len == GQUIC_CID_LEN); 182 if (length > 0) 183 { 184 if (0 == (packet_in->pi_data[0] & 0x80)) 185 return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length, 186 is_server, is_server ? cid_len : 0, state); 187 else 188 return lsquic_Q050_parse_packet_in_long_begin(packet_in, length, 189 is_server, cid_len, state); 190 } 191 else 192 return -1; 193} 194 195 196/* TODO This function uses the full packet parsing functionality to get at 197 * the CID. This is an overkill and could be optimized -- at the cost of 198 * some code duplication, of course. 199 */ 200int 201lsquic_cid_from_packet (const unsigned char *buf, size_t bufsz, 202 lsquic_cid_t *cid) 203{ 204 struct lsquic_packet_in packet_in; 205 struct packin_parse_state pps; 206 int s; 207 208 packet_in.pi_data = (unsigned char *) buf; 209 s = lsquic_parse_packet_in_server_begin(&packet_in, bufsz, 1, 8, &pps); 210 if (0 == s && (packet_in.pi_flags & PI_CONN_ID)) 211 { 212 *cid = packet_in.pi_dcid; 213 return 0; 214 } 215 else 216 return -1; 217} 218 219 220/* See [draft-ietf-quic-transport-25], Section 12.4 (Table 3) */ 221const enum quic_ft_bit lsquic_legal_frames_by_level[N_ENC_LEVS] = 222{ 223 [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 224 | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE, 225 [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 226 | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 227 | QUIC_FTBIT_BLOCKED 228 | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 229 | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 230 | QUIC_FTBIT_STREAMS_BLOCKED 231 | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 232 | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 233 | QUIC_FTBIT_RETIRE_CONNECTION_ID, 234 [ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 235 | QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE, 236 [ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING 237 | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE 238 | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM 239 | QUIC_FTBIT_BLOCKED 240 | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA 241 | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED 242 | QUIC_FTBIT_STREAMS_BLOCKED 243 | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING 244 | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE 245 | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY 246 | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN 247 | QUIC_FTBIT_TIMESTAMP 248 , 249}; 250