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