lsquic_trans_params.c revision f38b395a
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_trans_params.c 4 */ 5 6#include <assert.h> 7#include <errno.h> 8#include <inttypes.h> 9#include <limits.h> 10#include <stddef.h> 11#include <stdint.h> 12#include <string.h> 13 14#ifndef WIN32 15#include <arpa/inet.h> 16#include <sys/socket.h> 17#else 18#include "vc_compat.h" 19#include "Ws2tcpip.h" 20#endif 21 22#include "lsquic_byteswap.h" 23#include "lsquic_int_types.h" 24#include "lsquic_types.h" 25#include "lsquic_version.h" 26#include "lsquic_sizes.h" 27#include "lsquic_trans_params.h" 28#include "lsquic_util.h" 29#include "lsquic_varint.h" 30 31#define LSQUIC_LOGGER_MODULE LSQLM_TRAPA 32#include "lsquic_logger.h" 33 34 35static enum transport_param_id 36tpi_val_2_enum (uint64_t tpi_val) 37{ 38 switch (tpi_val) 39 { 40 case 0: return TPI_ORIGINAL_DEST_CID; 41 case 1: return TPI_MAX_IDLE_TIMEOUT; 42 case 2: return TPI_STATELESS_RESET_TOKEN; 43 case 3: return TPI_MAX_UDP_PAYLOAD_SIZE; 44 case 4: return TPI_INIT_MAX_DATA; 45 case 5: return TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL; 46 case 6: return TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE; 47 case 7: return TPI_INIT_MAX_STREAM_DATA_UNI; 48 case 8: return TPI_INIT_MAX_STREAMS_BIDI; 49 case 9: return TPI_INIT_MAX_STREAMS_UNI; 50 case 10: return TPI_ACK_DELAY_EXPONENT; 51 case 11: return TPI_MAX_ACK_DELAY; 52 case 12: return TPI_DISABLE_ACTIVE_MIGRATION; 53 case 13: return TPI_PREFERRED_ADDRESS; 54 case 14: return TPI_ACTIVE_CONNECTION_ID_LIMIT; 55 case 15: return TPI_INITIAL_SOURCE_CID; 56 case 16: return TPI_RETRY_SOURCE_CID; 57 case 0x20: return TPI_MAX_DATAGRAM_FRAME_SIZE; 58#if LSQUIC_TEST_QUANTUM_READINESS 59 case 0xC37: return TPI_QUANTUM_READINESS; 60#endif 61 case 0x1057: return TPI_LOSS_BITS; 62 case 0x2AB2: return TPI_GREASE_QUIC_BIT; 63 case 0xDE1A: return TPI_MIN_ACK_DELAY; 64 case 0xFF02DE1A:return TPI_MIN_ACK_DELAY_02; 65 case 0x7158: return TPI_TIMESTAMPS; 66 default: return INT_MAX; 67 } 68} 69 70 71static const unsigned enum_2_tpi_val[LAST_TPI + 1] = 72{ 73 [TPI_ORIGINAL_DEST_CID] = 0x0, 74 [TPI_MAX_IDLE_TIMEOUT] = 0x1, 75 [TPI_STATELESS_RESET_TOKEN] = 0x2, 76 [TPI_MAX_UDP_PAYLOAD_SIZE] = 0x3, 77 [TPI_INIT_MAX_DATA] = 0x4, 78 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = 0x5, 79 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = 0x6, 80 [TPI_INIT_MAX_STREAM_DATA_UNI] = 0x7, 81 [TPI_INIT_MAX_STREAMS_BIDI] = 0x8, 82 [TPI_INIT_MAX_STREAMS_UNI] = 0x9, 83 [TPI_ACK_DELAY_EXPONENT] = 0xA, 84 [TPI_MAX_ACK_DELAY] = 0xB, 85 [TPI_DISABLE_ACTIVE_MIGRATION] = 0xC, 86 [TPI_PREFERRED_ADDRESS] = 0xD, 87 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = 0xE, 88 [TPI_INITIAL_SOURCE_CID] = 0xF, 89 [TPI_RETRY_SOURCE_CID] = 0x10, 90 [TPI_MAX_DATAGRAM_FRAME_SIZE] = 0x20, 91#if LSQUIC_TEST_QUANTUM_READINESS 92 [TPI_QUANTUM_READINESS] = 0xC37, 93#endif 94 [TPI_LOSS_BITS] = 0x1057, 95 [TPI_MIN_ACK_DELAY] = 0xDE1A, 96 [TPI_MIN_ACK_DELAY_02] = 0xFF02DE1A, 97 [TPI_TIMESTAMPS] = 0x7158, 98 [TPI_GREASE_QUIC_BIT] = 0x2AB2, 99}; 100 101 102const char * const lsquic_tpi2str[LAST_TPI + 1] = 103{ 104 [TPI_ORIGINAL_DEST_CID] = "original_destination_connection_id", 105 [TPI_MAX_IDLE_TIMEOUT] = "max_idle_timeout", 106 [TPI_STATELESS_RESET_TOKEN] = "stateless_reset_token", 107 [TPI_MAX_UDP_PAYLOAD_SIZE] = "max_udp_payload_size", 108 [TPI_INIT_MAX_DATA] = "init_max_data", 109 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = "init_max_stream_data_bidi_local", 110 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = "init_max_stream_data_bidi_remote", 111 [TPI_INIT_MAX_STREAM_DATA_UNI] = "init_max_stream_data_uni", 112 [TPI_INIT_MAX_STREAMS_BIDI] = "init_max_streams_bidi", 113 [TPI_INIT_MAX_STREAMS_UNI] = "init_max_streams_uni", 114 [TPI_ACK_DELAY_EXPONENT] = "ack_delay_exponent", 115 [TPI_MAX_ACK_DELAY] = "max_ack_delay", 116 [TPI_DISABLE_ACTIVE_MIGRATION] = "disable_active_migration", 117 [TPI_PREFERRED_ADDRESS] = "preferred_address", 118 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = "active_connection_id_limit", 119 [TPI_INITIAL_SOURCE_CID] = "initial_source_connection_id", 120 [TPI_RETRY_SOURCE_CID] = "retry_source_connection_id", 121 [TPI_MAX_DATAGRAM_FRAME_SIZE] = "max_datagram_frame_size", 122#if LSQUIC_TEST_QUANTUM_READINESS 123 [TPI_QUANTUM_READINESS] = "quantum_readiness", 124#endif 125 [TPI_LOSS_BITS] = "loss_bits", 126 [TPI_MIN_ACK_DELAY] = "min_ack_delay", 127 [TPI_MIN_ACK_DELAY_02] = "min_ack_delay_02", 128 [TPI_TIMESTAMPS] = "timestamps", 129 [TPI_GREASE_QUIC_BIT] = "grease_quic_bit", 130}; 131#define tpi2str lsquic_tpi2str 132 133 134static const uint64_t def_vals[MAX_NUM_WITH_DEF_TPI + 1] = 135{ 136 [TPI_MAX_UDP_PAYLOAD_SIZE] = TP_DEF_MAX_UDP_PAYLOAD_SIZE, 137 [TPI_ACK_DELAY_EXPONENT] = TP_DEF_ACK_DELAY_EXP, 138 [TPI_INIT_MAX_STREAMS_UNI] = TP_DEF_INIT_MAX_STREAMS_UNI, 139 [TPI_INIT_MAX_STREAMS_BIDI] = TP_DEF_INIT_MAX_STREAMS_BIDI, 140 [TPI_INIT_MAX_DATA] = TP_DEF_INIT_MAX_DATA, 141 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL, 142 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE, 143 [TPI_INIT_MAX_STREAM_DATA_UNI] = TP_DEF_INIT_MAX_STREAM_DATA_UNI, 144 [TPI_MAX_IDLE_TIMEOUT] = TP_DEF_MAX_IDLE_TIMEOUT, 145 [TPI_MAX_ACK_DELAY] = TP_DEF_MAX_ACK_DELAY, 146 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = TP_DEF_ACTIVE_CONNECTION_ID_LIMIT, 147}; 148 149 150static const uint64_t max_vals[MAX_NUMERIC_TPI + 1] = 151{ 152 /* We don't enforce the maximum practical UDP payload value of 65527, as 153 * it is not required by the spec and is not necessary. 154 */ 155 [TPI_MAX_UDP_PAYLOAD_SIZE] = VINT_MAX_VALUE, 156 [TPI_ACK_DELAY_EXPONENT] = VINT_MAX_VALUE, 157 [TPI_INIT_MAX_STREAMS_UNI] = 1ull << 60, 158 [TPI_INIT_MAX_STREAMS_BIDI] = 1ull << 60, 159 [TPI_INIT_MAX_DATA] = VINT_MAX_VALUE, 160 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = VINT_MAX_VALUE, 161 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = VINT_MAX_VALUE, 162 [TPI_INIT_MAX_STREAM_DATA_UNI] = VINT_MAX_VALUE, 163 [TPI_MAX_IDLE_TIMEOUT] = VINT_MAX_VALUE, 164 [TPI_MAX_ACK_DELAY] = TP_MAX_MAX_ACK_DELAY, 165 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = VINT_MAX_VALUE, 166 [TPI_LOSS_BITS] = 1, 167 [TPI_MIN_ACK_DELAY] = (1u << 24) - 1u, 168 [TPI_MIN_ACK_DELAY_02] = (1u << 24) - 1u, 169 [TPI_TIMESTAMPS] = TS_WANT_THEM|TS_GENERATE_THEM, 170 [TPI_MAX_DATAGRAM_FRAME_SIZE] = VINT_MAX_VALUE, 171}; 172 173 174static const uint64_t min_vals[MAX_NUMERIC_TPI + 1] = 175{ 176 /* On the other hand, we do enforce the lower bound. */ 177 [TPI_MAX_UDP_PAYLOAD_SIZE] = 1200, 178 [TPI_MIN_ACK_DELAY] = 1, 179 [TPI_MIN_ACK_DELAY_02] = 1, 180 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = 2, 181 [TPI_TIMESTAMPS] = TS_WANT_THEM, 182}; 183 184 185static size_t 186preferred_address_size (const struct transport_params *params) 187{ 188 return sizeof(params->tp_preferred_address.ipv4_addr) 189 + sizeof(params->tp_preferred_address.ipv4_port) 190 + sizeof(params->tp_preferred_address.ipv6_addr) 191 + sizeof(params->tp_preferred_address.ipv6_port) 192 + 1 + params->tp_preferred_address.cid.len 193 + sizeof(params->tp_preferred_address.srst) 194 ; 195} 196 197 198int 199lsquic_tp_has_pref_ipv4 (const struct transport_params *params) 200{ 201 return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS)) 202 && params->tp_preferred_address.ipv4_port 203 && !lsquic_is_zero(params->tp_preferred_address.ipv4_addr, 204 sizeof(params->tp_preferred_address.ipv4_addr)); 205} 206 207 208int 209lsquic_tp_has_pref_ipv6 (const struct transport_params *params) 210{ 211 return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS)) 212 && params->tp_preferred_address.ipv6_port 213 && !lsquic_is_zero(params->tp_preferred_address.ipv6_addr, 214 sizeof(params->tp_preferred_address.ipv6_addr)); 215} 216 217 218#if LSQUIC_TEST_QUANTUM_READINESS 219#include <stdlib.h> 220size_t 221lsquic_tp_get_quantum_sz (void) 222{ 223 const char *str; 224 225 str = getenv("LSQUIC_QUANTUM_SZ"); 226 if (str) 227 return atoi(str); 228 else 229 /* https://github.com/quicwg/base-drafts/wiki/Quantum-Readiness-test */ 230 return 1200; 231} 232#endif 233 234 235static size_t 236update_cid_bits (unsigned bits[][3], enum transport_param_id tpi, 237 const lsquic_cid_t *cid) 238{ 239 bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]); 240#if __GNUC__ 241#pragma GCC diagnostic ignored "-Wunknown-pragmas" 242#if __clang__ 243#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" 244#else 245#pragma GCC diagnostic ignored "-Wtype-limits" 246#endif 247#endif 248 bits[tpi][1] = vint_val2bits(cid->len); 249#if __GNUC__ 250#pragma GCC diagnostic pop 251#pragma GCC diagnostic pop 252#endif 253 return (1u << bits[tpi][0]) + (1u << bits[tpi][1]) + cid->len; 254} 255 256 257int 258lsquic_tp_encode (const struct transport_params *params, int is_server, 259 unsigned char *const buf, size_t bufsz) 260{ 261 unsigned char *p; 262 size_t need; 263 uint16_t u16; 264 enum transport_param_id tpi; 265 unsigned set; 266 unsigned bits[LAST_TPI + 1][3 /* ID, length, value */]; 267#if LSQUIC_TEST_QUANTUM_READINESS 268 const size_t quantum_sz = lsquic_tp_get_quantum_sz(); 269#endif 270 271 need = 0; 272 set = params->tp_set; /* Will turn bits off for default values */ 273 274 if (set & (1 << TPI_INITIAL_SOURCE_CID)) 275 need += update_cid_bits(bits, TPI_INITIAL_SOURCE_CID, 276 ¶ms->tp_initial_source_cid); 277 if (is_server) 278 { 279 if (set & (1 << TPI_ORIGINAL_DEST_CID)) 280 need += update_cid_bits(bits, TPI_ORIGINAL_DEST_CID, 281 ¶ms->tp_original_dest_cid); 282 if (set & (1 << TPI_RETRY_SOURCE_CID)) 283 need += update_cid_bits(bits, TPI_RETRY_SOURCE_CID, 284 ¶ms->tp_retry_source_cid); 285 if (set & (1 << TPI_STATELESS_RESET_TOKEN)) 286 { 287 bits[TPI_STATELESS_RESET_TOKEN][0] 288 = vint_val2bits(enum_2_tpi_val[TPI_STATELESS_RESET_TOKEN]); 289 bits[TPI_STATELESS_RESET_TOKEN][1] 290 = vint_val2bits(sizeof(params->tp_stateless_reset_token)); 291 need += (1 << bits[TPI_STATELESS_RESET_TOKEN][0]) 292 + (1 << bits[TPI_STATELESS_RESET_TOKEN][1]) 293 + sizeof(params->tp_stateless_reset_token); 294 } 295 if (set & (1 << TPI_PREFERRED_ADDRESS)) 296 { 297 bits[TPI_PREFERRED_ADDRESS][0] 298 = vint_val2bits(enum_2_tpi_val[TPI_PREFERRED_ADDRESS]); 299 bits[TPI_PREFERRED_ADDRESS][1] = vint_val2bits( 300 preferred_address_size(params)); 301 need += (1 << bits[TPI_PREFERRED_ADDRESS][0]) 302 + (1 << bits[TPI_PREFERRED_ADDRESS][1]) 303 + preferred_address_size(params); 304 } 305 } 306#if LSQUIC_TEST_QUANTUM_READINESS 307 if (set & (1 << TPI_QUANTUM_READINESS)) 308 { 309 bits[TPI_QUANTUM_READINESS][0] 310 = vint_val2bits(enum_2_tpi_val[TPI_QUANTUM_READINESS]); 311 bits[TPI_QUANTUM_READINESS][1] = vint_val2bits(quantum_sz); 312 need += (1 << bits[TPI_QUANTUM_READINESS][0]) 313 + (1 << bits[TPI_QUANTUM_READINESS][1]) 314 + quantum_sz; 315 } 316#endif 317 318 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 319 if (set & (1 << tpi)) 320 { 321 if (tpi > MAX_NUM_WITH_DEF_TPI 322 || params->tp_numerics[tpi] != def_vals[tpi]) 323 { 324 if (params->tp_numerics[tpi] >= min_vals[tpi] 325 && params->tp_numerics[tpi] <= max_vals[tpi]) 326 { 327 bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]); 328 bits[tpi][2] = vint_val2bits(params->tp_numerics[tpi]); 329 bits[tpi][1] = vint_val2bits(bits[tpi][2]); 330 need += (1 << bits[tpi][0]) 331 + (1 << bits[tpi][1]) 332 + (1 << bits[tpi][2]); 333 } 334 else if (params->tp_numerics[tpi] > max_vals[tpi]) 335 { 336 LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs " 337 "maximum of %"PRIu64")", tpi2str[tpi], 338 params->tp_numerics[tpi], max_vals[tpi]); 339 return -1; 340 } 341 else 342 { 343 LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs " 344 "minimum " "of %"PRIu64")", 345 tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]); 346 return -1; 347 } 348 } 349 else 350 set &= ~(1 << tpi); /* Don't write default value */ 351 } 352 353 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 354 if (set & (1 << tpi)) 355 { 356 bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]); 357 need += (1 << bits[tpi][0]) + 1 /* Zero length byte */; 358 } 359 360 if (need > bufsz || need > UINT16_MAX) 361 { 362 errno = ENOBUFS; 363 return -1; 364 } 365 366 p = buf; 367 368#define WRITE_TO_P(src, len) do { \ 369 memcpy(p, src, len); \ 370 p += len; \ 371} while (0) 372 373#if __BYTE_ORDER == __LITTLE_ENDIAN 374#define WRITE_UINT_TO_P(val, width) do { \ 375 u##width = bswap_##width(val); \ 376 WRITE_TO_P(&u##width, sizeof(u##width)); \ 377} while (0) 378#else 379#define WRITE_UINT_TO_P(val, width) do { \ 380 u##width = val; \ 381 WRITE_TO_P(&u##width, sizeof(u##width)); \ 382} while (0) 383#endif 384 385 for (tpi = 0; tpi <= LAST_TPI; ++tpi) 386 if (set & (1 << tpi)) 387 { 388 vint_write(p, enum_2_tpi_val[tpi], bits[tpi][0], 389 1 << bits[tpi][0]); 390 p += 1 << bits[tpi][0]; 391 switch (tpi) 392 { 393 case TPI_MAX_IDLE_TIMEOUT: 394 case TPI_MAX_UDP_PAYLOAD_SIZE: 395 case TPI_INIT_MAX_DATA: 396 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 397 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 398 case TPI_INIT_MAX_STREAM_DATA_UNI: 399 case TPI_INIT_MAX_STREAMS_BIDI: 400 case TPI_INIT_MAX_STREAMS_UNI: 401 case TPI_ACK_DELAY_EXPONENT: 402 case TPI_MAX_ACK_DELAY: 403 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 404 case TPI_LOSS_BITS: 405 case TPI_MIN_ACK_DELAY: 406 case TPI_MIN_ACK_DELAY_02: 407 case TPI_TIMESTAMPS: 408 case TPI_MAX_DATAGRAM_FRAME_SIZE: 409 vint_write(p, 1 << bits[tpi][2], bits[tpi][1], 410 1 << bits[tpi][1]); 411 p += 1 << bits[tpi][1]; 412 vint_write(p, params->tp_numerics[tpi], bits[tpi][2], 413 1 << bits[tpi][2]); 414 p += 1 << bits[tpi][2]; 415 break; 416 case TPI_ORIGINAL_DEST_CID: 417 case TPI_INITIAL_SOURCE_CID: 418 case TPI_RETRY_SOURCE_CID: 419 vint_write(p, params->tp_cids[TP_CID_IDX(tpi)].len, bits[tpi][1], 420 1 << bits[tpi][1]); 421 p += 1 << bits[tpi][1]; 422 WRITE_TO_P(params->tp_cids[TP_CID_IDX(tpi)].idbuf, 423 params->tp_cids[TP_CID_IDX(tpi)].len); 424 break; 425 case TPI_STATELESS_RESET_TOKEN: 426 vint_write(p, sizeof(params->tp_stateless_reset_token), 427 bits[tpi][1], 1 << bits[tpi][1]); 428 p += 1 << bits[tpi][1]; 429 WRITE_TO_P(params->tp_stateless_reset_token, 430 sizeof(params->tp_stateless_reset_token)); 431 break; 432 case TPI_PREFERRED_ADDRESS: 433 vint_write(p, preferred_address_size(params), 434 bits[tpi][1], 1 << bits[tpi][1]); 435 p += 1 << bits[tpi][1]; 436 WRITE_TO_P(¶ms->tp_preferred_address.ipv4_addr, 437 sizeof(params->tp_preferred_address.ipv4_addr)); 438 WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16); 439 WRITE_TO_P(¶ms->tp_preferred_address.ipv6_addr, 440 sizeof(params->tp_preferred_address.ipv6_addr)); 441 WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16); 442 *p++ = params->tp_preferred_address.cid.len; 443 WRITE_TO_P(params->tp_preferred_address.cid.idbuf, 444 params->tp_preferred_address.cid.len); 445 WRITE_TO_P(params->tp_preferred_address.srst, 446 sizeof(params->tp_preferred_address.srst)); 447 break; 448 case TPI_DISABLE_ACTIVE_MIGRATION: 449 case TPI_GREASE_QUIC_BIT: 450 *p++ = 0; 451 break; 452#if LSQUIC_TEST_QUANTUM_READINESS 453 case TPI_QUANTUM_READINESS: 454 LSQ_DEBUG("encoded %zd bytes of quantum readiness", quantum_sz); 455 vint_write(p, quantum_sz, bits[tpi][1], 1 << bits[tpi][1]); 456 p += 1 << bits[tpi][1]; 457 memset(p, 'Q', quantum_sz); 458 p += quantum_sz; 459 break; 460#endif 461 } 462 } 463 464 assert(buf + need == p); 465 return (int) (p - buf); 466 467#undef WRITE_TO_P 468#undef WRITE_UINT_TO_P 469} 470 471 472int 473lsquic_tp_decode (const unsigned char *const buf, size_t bufsz, 474 int is_server, 475 struct transport_params *params) 476{ 477 const unsigned char *p, *end, *q; 478 uint64_t len, param_id; 479 uint16_t tlen; 480 enum transport_param_id tpi; 481 unsigned set_of_ids; 482 int s; 483 484 p = buf; 485 end = buf + bufsz; 486 487 *params = TP_INITIALIZER(); 488 489#define EXPECT_LEN(expected_len) do { \ 490 if (expected_len != len) \ 491 return -1; \ 492} while (0) 493 494#define EXPECT_AT_LEAST(expected_len) do { \ 495 if ((expected_len) > (uintptr_t) (p + len - q)) \ 496 return -1; \ 497} while (0) 498 499 set_of_ids = 0; 500 while (p < end) 501 { 502 s = vint_read(p, end, ¶m_id); 503 if (s < 0) 504 return -1; 505 LSQ_DEBUG("read TP 0x%"PRIX64, param_id); 506 p += s; 507 s = vint_read(p, end, &len); 508 if (s < 0) 509 return -1; 510 p += s; 511 if ((ptrdiff_t) len > end - p) 512 return -1; 513 tpi = tpi_val_2_enum(param_id); 514 if (tpi <= LAST_TPI) 515 { 516 if (set_of_ids & (1 << tpi)) 517 return -1; 518 set_of_ids |= 1 << tpi; 519 } 520 switch (tpi) 521 { 522 case TPI_MAX_IDLE_TIMEOUT: 523 case TPI_MAX_UDP_PAYLOAD_SIZE: 524 case TPI_INIT_MAX_DATA: 525 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 526 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 527 case TPI_INIT_MAX_STREAM_DATA_UNI: 528 case TPI_INIT_MAX_STREAMS_BIDI: 529 case TPI_INIT_MAX_STREAMS_UNI: 530 case TPI_ACK_DELAY_EXPONENT: 531 case TPI_MAX_ACK_DELAY: 532 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 533 case TPI_LOSS_BITS: 534 case TPI_MIN_ACK_DELAY: 535 case TPI_MIN_ACK_DELAY_02: 536 case TPI_TIMESTAMPS: 537 case TPI_MAX_DATAGRAM_FRAME_SIZE: 538 switch (len) 539 { 540 case 1: 541 case 2: 542 case 4: 543 case 8: 544 s = vint_read(p, p + len, ¶ms->tp_numerics[tpi]); 545 if (s == (int) len) 546 { 547 if (params->tp_numerics[tpi] > max_vals[tpi]) 548 { 549 LSQ_DEBUG("numeric value of %s is too large " 550 "(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi], 551 params->tp_numerics[tpi], max_vals[tpi]); 552 return -1; 553 } 554 else if (params->tp_numerics[tpi] < min_vals[tpi]) 555 { 556 LSQ_DEBUG("numeric value of %s is too small " 557 "(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi], 558 params->tp_numerics[tpi], min_vals[tpi]); 559 return -1; 560 } 561 break; 562 } 563 else 564 { 565 LSQ_DEBUG("cannot read the value of numeric transport " 566 "param %s of length %"PRIu64, tpi2str[tpi], len); 567 return -1; 568 } 569 default: 570 LSQ_DEBUG("invalid length=%"PRIu64" for numeric transport " 571 "parameter %s", len, tpi2str[tpi]); 572 return -1; 573 } 574 break; 575 case TPI_DISABLE_ACTIVE_MIGRATION: 576 case TPI_GREASE_QUIC_BIT: 577 EXPECT_LEN(0); 578 break; 579 case TPI_STATELESS_RESET_TOKEN: 580 /* Client MUST not include reset token, 581 * see [draft-ietf-quic-transport-11], Section 6.4.1 582 */ 583 if (!is_server) 584 return -1; 585 EXPECT_LEN(sizeof(params->tp_stateless_reset_token)); 586 memcpy(params->tp_stateless_reset_token, p, 587 sizeof(params->tp_stateless_reset_token)); 588 break; 589 case TPI_ORIGINAL_DEST_CID: 590 case TPI_RETRY_SOURCE_CID: 591 /* [draft-ietf-quic-transport-28] Section 18.2: 592 " A client MUST NOT include any server-only transport parameter: 593 " original_destination_connection_id, preferred_address, 594 " retry_source_connection_id, or stateless_reset_token. 595 */ 596 if (!is_server) 597 return -1; 598 /* fallthru */ 599 case TPI_INITIAL_SOURCE_CID: 600 if (len > MAX_CID_LEN) 601 return -1; 602 memcpy(params->tp_cids[TP_CID_IDX(tpi)].idbuf, p, len); 603 params->tp_cids[TP_CID_IDX(tpi)].len = len; 604 break; 605 case TPI_PREFERRED_ADDRESS: 606 /* Client MUST not include preferred address, 607 * see [draft-ietf-quic-transport-12], Section 6.4.1 608 */ 609 if (!is_server) 610 return -1; 611 q = p; 612 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr)); 613 memcpy(params->tp_preferred_address.ipv4_addr, q, 614 sizeof(params->tp_preferred_address.ipv4_addr)); 615 q += sizeof(params->tp_preferred_address.ipv4_addr); 616 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port)); 617 READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2); 618 q += 2; 619 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr)); 620 memcpy(params->tp_preferred_address.ipv6_addr, q, 621 sizeof(params->tp_preferred_address.ipv6_addr)); 622 q += sizeof(params->tp_preferred_address.ipv6_addr); 623 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port)); 624 READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2); 625 q += 2; 626 EXPECT_AT_LEAST(1); 627 tlen = *q; 628 q += 1; 629 if (tlen > MAX_CID_LEN) 630 { 631 LSQ_DEBUG("preferred server address contains invalid " 632 "CID length of %"PRIu16" bytes", tlen); 633 return -1; 634 } 635 EXPECT_AT_LEAST(tlen); 636 memcpy(params->tp_preferred_address.cid.idbuf, q, tlen); 637 params->tp_preferred_address.cid.len = tlen; 638 q += tlen; 639 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst)); 640 memcpy(params->tp_preferred_address.srst, q, 641 sizeof(params->tp_preferred_address.srst)); 642 q += sizeof(params->tp_preferred_address.srst); 643 if (q != p + len) 644 return -1; 645 break; 646 default: 647 /* Do nothing: skip this transport parameter */ 648 break; 649 } 650 p += len; 651 if (tpi <= LAST_TPI) 652 { 653 params->tp_set |= 1 << tpi; 654 params->tp_decoded |= 1 << tpi; 655 } 656 } 657 658 if (p != end) 659 return -1; 660 661 if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY)) 662 && params->tp_numerics[TPI_MIN_ACK_DELAY] 663 > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000) 664 { 665 LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than " 666 "max_ack_delay (%"PRIu64" ms)", 667 params->tp_numerics[TPI_MIN_ACK_DELAY], 668 params->tp_numerics[TPI_MAX_ACK_DELAY]); 669 return -1; 670 } 671 672 if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY_02)) 673 && params->tp_numerics[TPI_MIN_ACK_DELAY_02] 674 > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000) 675 { 676 LSQ_DEBUG("min_ack_delay_02 (%"PRIu64" usec) is larger than " 677 "max_ack_delay (%"PRIu64" ms)", 678 params->tp_numerics[TPI_MIN_ACK_DELAY_02], 679 params->tp_numerics[TPI_MAX_ACK_DELAY]); 680 return -1; 681 } 682 683 return (int) (end - buf); 684#undef EXPECT_LEN 685} 686 687 688void 689lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz) 690{ 691 char *const end = buf + sz; 692 int nw; 693 enum transport_param_id tpi; 694 char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1]; 695 char addr_str[INET6_ADDRSTRLEN]; 696 697 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 698 if (params->tp_set & (1 << tpi)) 699 { 700 nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64, 701 (buf + sz > end) << 1, "; ", tpi2str[tpi], 702 params->tp_numerics[tpi]); 703 buf += nw; 704 if (buf >= end) 705 return; 706 } 707 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 708 if (params->tp_set & (1 << tpi)) 709 { 710 nw = snprintf(buf, end - buf, "%.*s%s", 711 (buf + sz > end) << 1, "; ", tpi2str[tpi]); 712 buf += nw; 713 if (buf >= end) 714 return; 715 } 716#if LSQUIC_TEST_QUANTUM_READINESS 717 if (params->tp_set & (1 << TPI_QUANTUM_READINESS)) 718 { 719 nw = snprintf(buf, end - buf, "%.*s%s", 720 (buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]); 721 buf += nw; 722 if (buf >= end) 723 return; 724 } 725#endif 726 if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN)) 727 { 728 lsquic_hexstr(params->tp_stateless_reset_token, 729 sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str)); 730 nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str); 731 buf += nw; 732 if (buf >= end) 733 return; 734 } 735 for (tpi = FIRST_TP_CID; tpi <= LAST_TP_CID; ++tpi) 736 if (params->tp_set & (1 << tpi)) 737 { 738 char cidbuf_[MAX_CID_LEN * 2 + 1]; 739 nw = snprintf(buf, end - buf, "; %s: %"CID_FMT, tpi2str[tpi], 740 CID_BITS(¶ms->tp_cids[TP_CID_IDX(tpi)])); 741 buf += nw; 742 if (buf >= end) 743 return; 744 } 745 if (lsquic_tp_has_pref_ipv4(params)) 746 { 747 if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr, 748 addr_str, sizeof(addr_str))) 749 { 750 nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u", 751 addr_str, params->tp_preferred_address.ipv4_port); 752 buf += nw; 753 if (buf >= end) 754 return; 755 } 756 } 757 if (lsquic_tp_has_pref_ipv6(params)) 758 { 759 if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr, 760 addr_str, sizeof(addr_str))) 761 { 762 nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u", 763 addr_str, params->tp_preferred_address.ipv6_port); 764 buf += nw; 765 if (buf >= end) 766 return; 767 } 768 } 769} 770 771 772int 773lsquic_tp_encode_27 (const struct transport_params *params, int is_server, 774 unsigned char *const buf, size_t bufsz) 775{ 776 unsigned char *p; 777 size_t need; 778 uint16_t u16; 779 enum transport_param_id tpi; 780 unsigned set; 781 unsigned bits[LAST_TPI + 1][3 /* ID, length, value */]; 782#if LSQUIC_TEST_QUANTUM_READINESS 783 const size_t quantum_sz = lsquic_tp_get_quantum_sz(); 784#endif 785 786 need = 0; 787 set = params->tp_set; /* Will turn bits off for default values */ 788 789 if (is_server) 790 { 791 if (set & (1 << TPI_ORIGINAL_DEST_CID)) 792 { 793 bits[TPI_ORIGINAL_DEST_CID][0] 794 = vint_val2bits(enum_2_tpi_val[TPI_ORIGINAL_DEST_CID]); 795#if __GNUC__ 796#pragma GCC diagnostic ignored "-Wunknown-pragmas" 797#if __clang__ 798#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" 799#else 800#pragma GCC diagnostic ignored "-Wtype-limits" 801#endif 802#endif 803 bits[TPI_ORIGINAL_DEST_CID][1] 804 = vint_val2bits(params->tp_original_dest_cid.len); 805#if __GNUC__ 806#pragma GCC diagnostic pop 807#pragma GCC diagnostic pop 808#endif 809 need += (1 << bits[TPI_ORIGINAL_DEST_CID][0]) 810 + (1 << bits[TPI_ORIGINAL_DEST_CID][1]) 811 + params->tp_original_dest_cid.len; 812 } 813 if (set & (1 << TPI_STATELESS_RESET_TOKEN)) 814 { 815 bits[TPI_STATELESS_RESET_TOKEN][0] 816 = vint_val2bits(enum_2_tpi_val[TPI_STATELESS_RESET_TOKEN]); 817 bits[TPI_STATELESS_RESET_TOKEN][1] 818 = vint_val2bits(sizeof(params->tp_stateless_reset_token)); 819 need += (1 << bits[TPI_STATELESS_RESET_TOKEN][0]) 820 + (1 << bits[TPI_STATELESS_RESET_TOKEN][1]) 821 + sizeof(params->tp_stateless_reset_token); 822 } 823 if (set & (1 << TPI_PREFERRED_ADDRESS)) 824 { 825 bits[TPI_PREFERRED_ADDRESS][0] 826 = vint_val2bits(enum_2_tpi_val[TPI_PREFERRED_ADDRESS]); 827 bits[TPI_PREFERRED_ADDRESS][1] = vint_val2bits( 828 preferred_address_size(params)); 829 need += (1 << bits[TPI_PREFERRED_ADDRESS][0]) 830 + (1 << bits[TPI_PREFERRED_ADDRESS][1]) 831 + preferred_address_size(params); 832 } 833 } 834#if LSQUIC_TEST_QUANTUM_READINESS 835 else if (set & (1 << TPI_QUANTUM_READINESS)) 836 { 837 bits[TPI_QUANTUM_READINESS][0] 838 = vint_val2bits(enum_2_tpi_val[TPI_QUANTUM_READINESS]); 839 bits[TPI_QUANTUM_READINESS][1] = vint_val2bits(quantum_sz); 840 need += (1 << bits[TPI_QUANTUM_READINESS][0]) 841 + (1 << bits[TPI_QUANTUM_READINESS][1]) 842 + quantum_sz; 843 } 844#endif 845 846 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 847 if (set & (1 << tpi)) 848 { 849 if (tpi > MAX_NUM_WITH_DEF_TPI 850 || params->tp_numerics[tpi] != def_vals[tpi]) 851 { 852 if (params->tp_numerics[tpi] >= min_vals[tpi] 853 && params->tp_numerics[tpi] <= max_vals[tpi]) 854 { 855 bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]); 856 bits[tpi][2] = vint_val2bits(params->tp_numerics[tpi]); 857 bits[tpi][1] = vint_val2bits(bits[tpi][2]); 858 need += (1 << bits[tpi][0]) 859 + (1 << bits[tpi][1]) 860 + (1 << bits[tpi][2]); 861 } 862 else if (params->tp_numerics[tpi] > max_vals[tpi]) 863 { 864 LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs " 865 "maximum of %"PRIu64")", tpi2str[tpi], 866 params->tp_numerics[tpi], max_vals[tpi]); 867 return -1; 868 } 869 else 870 { 871 LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs " 872 "minimum " "of %"PRIu64")", 873 tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]); 874 return -1; 875 } 876 } 877 else 878 set &= ~(1 << tpi); /* Don't write default value */ 879 } 880 881 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 882 if (set & (1 << tpi)) 883 { 884 bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]); 885 need += (1 << bits[tpi][0]) + 1 /* Zero length byte */; 886 } 887 888 if (need > bufsz || need > UINT16_MAX) 889 { 890 errno = ENOBUFS; 891 return -1; 892 } 893 894 p = buf; 895 896#define WRITE_TO_P(src, len) do { \ 897 memcpy(p, src, len); \ 898 p += len; \ 899} while (0) 900 901#if __BYTE_ORDER == __LITTLE_ENDIAN 902#define WRITE_UINT_TO_P(val, width) do { \ 903 u##width = bswap_##width(val); \ 904 WRITE_TO_P(&u##width, sizeof(u##width)); \ 905} while (0) 906#else 907#define WRITE_UINT_TO_P(val, width) do { \ 908 u##width = val; \ 909 WRITE_TO_P(&u##width, sizeof(u##width)); \ 910} while (0) 911#endif 912 913 for (tpi = 0; tpi <= LAST_TPI; ++tpi) 914 if (set & (1 << tpi)) 915 { 916 vint_write(p, enum_2_tpi_val[tpi], bits[tpi][0], 917 1 << bits[tpi][0]); 918 p += 1 << bits[tpi][0]; 919 switch (tpi) 920 { 921 case TPI_MAX_IDLE_TIMEOUT: 922 case TPI_MAX_UDP_PAYLOAD_SIZE: 923 case TPI_INIT_MAX_DATA: 924 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 925 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 926 case TPI_INIT_MAX_STREAM_DATA_UNI: 927 case TPI_INIT_MAX_STREAMS_BIDI: 928 case TPI_INIT_MAX_STREAMS_UNI: 929 case TPI_ACK_DELAY_EXPONENT: 930 case TPI_MAX_ACK_DELAY: 931 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 932 case TPI_LOSS_BITS: 933 case TPI_MIN_ACK_DELAY: 934 case TPI_MIN_ACK_DELAY_02: 935 case TPI_TIMESTAMPS: 936 case TPI_MAX_DATAGRAM_FRAME_SIZE: 937 vint_write(p, 1 << bits[tpi][2], bits[tpi][1], 938 1 << bits[tpi][1]); 939 p += 1 << bits[tpi][1]; 940 vint_write(p, params->tp_numerics[tpi], bits[tpi][2], 941 1 << bits[tpi][2]); 942 p += 1 << bits[tpi][2]; 943 break; 944 case TPI_INITIAL_SOURCE_CID: 945 case TPI_RETRY_SOURCE_CID: 946 assert(0); 947 return -1; 948 case TPI_ORIGINAL_DEST_CID: 949 vint_write(p, params->tp_original_dest_cid.len, bits[tpi][1], 950 1 << bits[tpi][1]); 951 p += 1 << bits[tpi][1]; 952 WRITE_TO_P(params->tp_original_dest_cid.idbuf, 953 params->tp_original_dest_cid.len); 954 break; 955 case TPI_STATELESS_RESET_TOKEN: 956 vint_write(p, sizeof(params->tp_stateless_reset_token), 957 bits[tpi][1], 1 << bits[tpi][1]); 958 p += 1 << bits[tpi][1]; 959 WRITE_TO_P(params->tp_stateless_reset_token, 960 sizeof(params->tp_stateless_reset_token)); 961 break; 962 case TPI_PREFERRED_ADDRESS: 963 vint_write(p, preferred_address_size(params), 964 bits[tpi][1], 1 << bits[tpi][1]); 965 p += 1 << bits[tpi][1]; 966 WRITE_TO_P(¶ms->tp_preferred_address.ipv4_addr, 967 sizeof(params->tp_preferred_address.ipv4_addr)); 968 WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16); 969 WRITE_TO_P(¶ms->tp_preferred_address.ipv6_addr, 970 sizeof(params->tp_preferred_address.ipv6_addr)); 971 WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16); 972 *p++ = params->tp_preferred_address.cid.len; 973 WRITE_TO_P(params->tp_preferred_address.cid.idbuf, 974 params->tp_preferred_address.cid.len); 975 WRITE_TO_P(params->tp_preferred_address.srst, 976 sizeof(params->tp_preferred_address.srst)); 977 break; 978 case TPI_DISABLE_ACTIVE_MIGRATION: 979 case TPI_GREASE_QUIC_BIT: 980 *p++ = 0; 981 break; 982#if LSQUIC_TEST_QUANTUM_READINESS 983 case TPI_QUANTUM_READINESS: 984 LSQ_DEBUG("encoded %zd bytes of quantum readiness", quantum_sz); 985 vint_write(p, quantum_sz, bits[tpi][1], 1 << bits[tpi][1]); 986 p += 1 << bits[tpi][1]; 987 memset(p, 'Q', quantum_sz); 988 p += quantum_sz; 989 break; 990#endif 991 } 992 } 993 994 assert(buf + need == p); 995 return (int) (p - buf); 996 997#undef WRITE_TO_P 998#undef WRITE_UINT_TO_P 999} 1000 1001 1002int 1003lsquic_tp_decode_27 (const unsigned char *const buf, size_t bufsz, 1004 int is_server, 1005 struct transport_params *params) 1006{ 1007 const unsigned char *p, *end, *q; 1008 uint64_t len, param_id; 1009 uint16_t tlen; 1010 enum transport_param_id tpi; 1011 unsigned set_of_ids; 1012 int s; 1013 1014 p = buf; 1015 end = buf + bufsz; 1016 1017 *params = TP_INITIALIZER(); 1018 1019#define EXPECT_LEN(expected_len) do { \ 1020 if (expected_len != len) \ 1021 return -1; \ 1022} while (0) 1023 1024#define EXPECT_AT_LEAST(expected_len) do { \ 1025 if ((expected_len) > (uintptr_t) (p + len - q)) \ 1026 return -1; \ 1027} while (0) 1028 1029 set_of_ids = 0; 1030 while (p < end) 1031 { 1032 s = vint_read(p, end, ¶m_id); 1033 if (s < 0) 1034 return -1; 1035 p += s; 1036 s = vint_read(p, end, &len); 1037 if (s < 0) 1038 return -1; 1039 p += s; 1040 if ((ptrdiff_t) len > end - p) 1041 return -1; 1042 tpi = tpi_val_2_enum(param_id); 1043 if (tpi <= LAST_TPI) 1044 { 1045 if (set_of_ids & (1 << tpi)) 1046 return -1; 1047 set_of_ids |= 1 << tpi; 1048 } 1049 switch (tpi) 1050 { 1051 case TPI_MAX_IDLE_TIMEOUT: 1052 case TPI_MAX_UDP_PAYLOAD_SIZE: 1053 case TPI_INIT_MAX_DATA: 1054 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 1055 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 1056 case TPI_INIT_MAX_STREAM_DATA_UNI: 1057 case TPI_INIT_MAX_STREAMS_BIDI: 1058 case TPI_INIT_MAX_STREAMS_UNI: 1059 case TPI_ACK_DELAY_EXPONENT: 1060 case TPI_MAX_ACK_DELAY: 1061 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 1062 case TPI_LOSS_BITS: 1063 case TPI_MIN_ACK_DELAY: 1064 case TPI_MIN_ACK_DELAY_02: 1065 case TPI_TIMESTAMPS: 1066 case TPI_MAX_DATAGRAM_FRAME_SIZE: 1067 switch (len) 1068 { 1069 case 1: 1070 case 2: 1071 case 4: 1072 case 8: 1073 s = vint_read(p, p + len, ¶ms->tp_numerics[tpi]); 1074 if (s == (int) len) 1075 { 1076 if (params->tp_numerics[tpi] > max_vals[tpi]) 1077 { 1078 LSQ_DEBUG("numeric value of %s is too large " 1079 "(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi], 1080 params->tp_numerics[tpi], max_vals[tpi]); 1081 return -1; 1082 } 1083 else if (params->tp_numerics[tpi] < min_vals[tpi]) 1084 { 1085 LSQ_DEBUG("numeric value of %s is too small " 1086 "(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi], 1087 params->tp_numerics[tpi], min_vals[tpi]); 1088 return -1; 1089 } 1090 break; 1091 } 1092 else 1093 { 1094 LSQ_DEBUG("cannot read the value of numeric transport " 1095 "param %s of length %"PRIu64, tpi2str[tpi], len); 1096 return -1; 1097 } 1098 default: 1099 LSQ_DEBUG("invalid length=%"PRIu64" for numeric transport " 1100 "parameter %s", len, tpi2str[tpi]); 1101 return -1; 1102 } 1103 break; 1104 case TPI_DISABLE_ACTIVE_MIGRATION: 1105 EXPECT_LEN(0); 1106 break; 1107 case TPI_STATELESS_RESET_TOKEN: 1108 /* Client MUST not include reset token, 1109 * see [draft-ietf-quic-transport-11], Section 6.4.1 1110 */ 1111 if (!is_server) 1112 return -1; 1113 EXPECT_LEN(sizeof(params->tp_stateless_reset_token)); 1114 memcpy(params->tp_stateless_reset_token, p, 1115 sizeof(params->tp_stateless_reset_token)); 1116 break; 1117 case TPI_ORIGINAL_DEST_CID: 1118 /* Client MUST not original connecti ID, 1119 * see [draft-ietf-quic-transport-15], Section 6.6.1 1120 */ 1121 if (!is_server) 1122 return -1; 1123 if (len > MAX_CID_LEN) 1124 return -1; 1125 memcpy(params->tp_original_dest_cid.idbuf, p, len); 1126 params->tp_original_dest_cid.len = len; 1127 break; 1128 case TPI_PREFERRED_ADDRESS: 1129 /* Client MUST not include preferred address, 1130 * see [draft-ietf-quic-transport-12], Section 6.4.1 1131 */ 1132 if (!is_server) 1133 return -1; 1134 q = p; 1135 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr)); 1136 memcpy(params->tp_preferred_address.ipv4_addr, q, 1137 sizeof(params->tp_preferred_address.ipv4_addr)); 1138 q += sizeof(params->tp_preferred_address.ipv4_addr); 1139 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port)); 1140 READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2); 1141 q += 2; 1142 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr)); 1143 memcpy(params->tp_preferred_address.ipv6_addr, q, 1144 sizeof(params->tp_preferred_address.ipv6_addr)); 1145 q += sizeof(params->tp_preferred_address.ipv6_addr); 1146 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port)); 1147 READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2); 1148 q += 2; 1149 EXPECT_AT_LEAST(1); 1150 tlen = *q; 1151 q += 1; 1152 if (tlen > MAX_CID_LEN) 1153 { 1154 LSQ_DEBUG("preferred server address contains invalid " 1155 "CID length of %"PRIu16" bytes", tlen); 1156 return -1; 1157 } 1158 EXPECT_AT_LEAST(tlen); 1159 memcpy(params->tp_preferred_address.cid.idbuf, q, tlen); 1160 params->tp_preferred_address.cid.len = tlen; 1161 q += tlen; 1162 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst)); 1163 memcpy(params->tp_preferred_address.srst, q, 1164 sizeof(params->tp_preferred_address.srst)); 1165 q += sizeof(params->tp_preferred_address.srst); 1166 if (q != p + len) 1167 return -1; 1168 break; 1169 default: 1170 /* Do nothing: skip this transport parameter */ 1171 break; 1172 } 1173 p += len; 1174 if (tpi <= LAST_TPI) 1175 { 1176 params->tp_set |= 1 << tpi; 1177 params->tp_decoded |= 1 << tpi; 1178 } 1179 } 1180 1181 if (p != end) 1182 return -1; 1183 1184 if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY)) 1185 && params->tp_numerics[TPI_MIN_ACK_DELAY] 1186 > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000) 1187 { 1188 LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than " 1189 "max_ack_delay (%"PRIu64" ms)", 1190 params->tp_numerics[TPI_MIN_ACK_DELAY], 1191 params->tp_numerics[TPI_MAX_ACK_DELAY]); 1192 return -1; 1193 } 1194 1195 if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY_02)) 1196 && params->tp_numerics[TPI_MIN_ACK_DELAY_02] 1197 > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000) 1198 { 1199 LSQ_DEBUG("min_ack_delay_02 (%"PRIu64" usec) is larger than " 1200 "max_ack_delay (%"PRIu64" ms)", 1201 params->tp_numerics[TPI_MIN_ACK_DELAY_02], 1202 params->tp_numerics[TPI_MAX_ACK_DELAY]); 1203 return -1; 1204 } 1205 1206 return (int) (end - buf); 1207#undef EXPECT_LEN 1208} 1209 1210 1211void 1212lsquic_tp_to_str_27 (const struct transport_params *params, char *buf, size_t sz) 1213{ 1214 char *const end = buf + sz; 1215 int nw; 1216 enum transport_param_id tpi; 1217 char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1]; 1218 char addr_str[INET6_ADDRSTRLEN]; 1219 1220 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 1221 if (params->tp_set & (1 << tpi)) 1222 { 1223 nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64, 1224 (buf + sz > end) << 1, "; ", tpi2str[tpi], 1225 params->tp_numerics[tpi]); 1226 buf += nw; 1227 if (buf >= end) 1228 return; 1229 } 1230 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 1231 if (params->tp_set & (1 << tpi)) 1232 { 1233 nw = snprintf(buf, end - buf, "%.*s%s", 1234 (buf + sz > end) << 1, "; ", tpi2str[tpi]); 1235 buf += nw; 1236 if (buf >= end) 1237 return; 1238 } 1239#if LSQUIC_TEST_QUANTUM_READINESS 1240 if (params->tp_set & (1 << TPI_QUANTUM_READINESS)) 1241 { 1242 nw = snprintf(buf, end - buf, "%.*s%s", 1243 (buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]); 1244 buf += nw; 1245 if (buf >= end) 1246 return; 1247 } 1248#endif 1249 if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN)) 1250 { 1251 lsquic_hexstr(params->tp_stateless_reset_token, 1252 sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str)); 1253 nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str); 1254 buf += nw; 1255 if (buf >= end) 1256 return; 1257 } 1258 if (params->tp_set & (1 << TPI_ORIGINAL_DEST_CID)) 1259 { 1260 char cidbuf_[MAX_CID_LEN * 2 + 1]; 1261 nw = snprintf(buf, end - buf, "; original DCID (ODCID): %"CID_FMT, 1262 CID_BITS(¶ms->tp_original_dest_cid)); 1263 buf += nw; 1264 if (buf >= end) 1265 return; 1266 } 1267 if (lsquic_tp_has_pref_ipv4(params)) 1268 { 1269 if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr, 1270 addr_str, sizeof(addr_str))) 1271 { 1272 nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u", 1273 addr_str, params->tp_preferred_address.ipv4_port); 1274 buf += nw; 1275 if (buf >= end) 1276 return; 1277 } 1278 } 1279 if (lsquic_tp_has_pref_ipv6(params)) 1280 { 1281 if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr, 1282 addr_str, sizeof(addr_str))) 1283 { 1284 nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u", 1285 addr_str, params->tp_preferred_address.ipv6_port); 1286 buf += nw; 1287 if (buf >= end) 1288 return; 1289 } 1290 } 1291} 1292