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