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