lsquic_parse_iquic_common.c revision 229fce07
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <stddef.h> 3#include <stdint.h> 4#include <string.h> 5#include <sys/queue.h> 6#include <sys/types.h> 7 8#include <openssl/rand.h> 9 10#include "lsquic_types.h" 11#include "lsquic_int_types.h" 12#include "lsquic_packet_common.h" 13#include "lsquic_packet_in.h" 14#include "lsquic_parse_common.h" 15#include "lsquic_parse.h" 16#include "lsquic_version.h" 17#include "lsquic.h" 18#include "lsquic_logger.h" 19#include "lsquic_byteswap.h" 20#include "lsquic_str.h" 21#include "lsquic_handshake.h" 22 23 24static const enum header_type bin_2_header_type[0x100] = 25{ 26 [0x80 | 0x7F] = HETY_INITIAL, 27 [0x80 | 0x7E] = HETY_RETRY, 28 [0x80 | 0x7D] = HETY_HANDSHAKE, 29 [0x80 | 0x7C] = HETY_0RTT, 30}; 31 32 33int 34lsquic_iquic_parse_packet_in_long_begin (lsquic_packet_in_t *packet_in, 35 size_t length, int is_server, struct packin_parse_state *state) 36{ 37 const unsigned char *p = packet_in->pi_data; 38 const unsigned char *const end = p + length; 39 lsquic_ver_tag_t tag; 40 enum header_type header_type; 41 unsigned dcil, scil; 42 int verneg; 43 unsigned char first_byte; 44 const unsigned cid_len = 8; 45 46 if (length < 6) 47 return -1; 48 first_byte = *p++; 49 50 memcpy(&tag, p, 4); 51 p += 4; 52 verneg = 0 == tag; 53 if (!verneg) 54 { 55 header_type = bin_2_header_type[ first_byte ]; 56 if (!header_type) 57 return -1; 58 } 59 else 60 header_type = HETY_VERNEG; 61 62 packet_in->pi_header_type = header_type; 63 64 dcil = p[0] >> 4; 65 if (dcil) 66 dcil += 3; 67 scil = p[0] & 0xF; 68 if (scil) 69 scil += 3; 70 ++p; 71 72 /* Chromium comments state that the client sends packets with destination 73 * CID of 8 bytes and source CID of 0 bytes and the server does it the 74 * other way around. 75 * 76 * XXX When IETF branch is merged, this check for Q044 will have to be 77 * moved to the pf_parse_packet_in_finish(). 78 */ 79 if (is_server) 80 { 81 if (!(dcil == cid_len && scil == 0)) 82 return -1; 83 } 84 else 85 { 86 if (!(dcil == 0 && scil == cid_len)) 87 return -1; 88 } 89 90 const unsigned packet_len = 4; 91 /* XXX This checks both packet length or the first version of the version 92 * array in a version negotiation packet. This is because the sizes of 93 * the packet number field and the version tag are the same. The check 94 * will probably have to be split in the future. 95 */ 96 if (end - p < (ptrdiff_t) (dcil + scil + packet_len)) 97 return -1; 98 99 memcpy(&packet_in->pi_conn_id, p, cid_len); 100 p += cid_len; 101 packet_in->pi_flags |= PI_CONN_ID; 102 103 packet_in->pi_packno = 0; 104 105 if (!verneg) 106 { 107 state->pps_p = p; 108 state->pps_nbytes = packet_len; 109 p += packet_len; 110 packet_in->pi_quic_ver = 1; 111 if (is_server || HETY_0RTT != header_type) 112 packet_in->pi_nonce = 0; 113 else 114 { 115 packet_in->pi_nonce = p - packet_in->pi_data; 116 p += 32; 117 } 118 } 119 else 120 { 121 if ((end - p) & 3) 122 return -1; 123 state->pps_p = NULL; 124 state->pps_nbytes = 0; 125 packet_in->pi_quic_ver = p - packet_in->pi_data; 126 p = packet_in->pi_data + length; 127 packet_in->pi_nonce = 0; 128 } 129 130 packet_in->pi_header_sz = p - packet_in->pi_data; 131 packet_in->pi_frame_types = 0; 132 packet_in->pi_data_sz = length; 133 packet_in->pi_refcnt = 0; 134 packet_in->pi_received = 0; 135 136 return 0; 137} 138 139 140int 141lsquic_iquic_parse_packet_in_short_begin (lsquic_packet_in_t *packet_in, 142 size_t length, int is_server, struct packin_parse_state *state) 143{ 144 const unsigned char *p = packet_in->pi_data; 145 const unsigned char *const pend = packet_in->pi_data + length; 146 unsigned cid_len = 8; /* XXX this will need to be passed in */ 147 unsigned packet_len; 148 149 if ((*p & 0x30) != 0x30 || (*p & 3) == 3) 150 return -1; 151 152 packet_len = 1 << (*p & 3); 153 if (pend - p < (ptrdiff_t) (1 + cid_len + packet_len)) 154 return -1; 155 156 ++p; 157 158 if (is_server) 159 { 160 memcpy(&packet_in->pi_conn_id, p, cid_len); 161 p += cid_len; 162 packet_in->pi_flags |= PI_CONN_ID; 163 } 164 165 /* We could read in the packet number here, but we choose to do it in 166 * the finish() call instead. 167 */ 168 packet_in->pi_packno = 0; 169 state->pps_p = p; 170 state->pps_nbytes = packet_len; 171 p += packet_len; 172 173 packet_in->pi_header_type = HETY_NOT_SET; 174 packet_in->pi_quic_ver = 0; 175 packet_in->pi_nonce = 0; 176 packet_in->pi_header_sz = p - packet_in->pi_data; 177 packet_in->pi_frame_types = 0; 178 packet_in->pi_data_sz = length; 179 packet_in->pi_refcnt = 0; 180 packet_in->pi_received = 0; 181 182 return 0; 183} 184 185 186