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