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