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