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