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