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