lsquic_trans_params.c revision 1bdb91d1
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 default: return INT_MAX; 55 } 56} 57 58 59static const unsigned short enum_2_tpi_val[LAST_TPI + 1] = 60{ 61 [TPI_ORIGINAL_CONNECTION_ID] = 0x0, 62 [TPI_MAX_IDLE_TIMEOUT] = 0x1, 63 [TPI_STATELESS_RESET_TOKEN] = 0x2, 64 [TPI_MAX_PACKET_SIZE] = 0x3, 65 [TPI_INIT_MAX_DATA] = 0x4, 66 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = 0x5, 67 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = 0x6, 68 [TPI_INIT_MAX_STREAM_DATA_UNI] = 0x7, 69 [TPI_INIT_MAX_STREAMS_BIDI] = 0x8, 70 [TPI_INIT_MAX_STREAMS_UNI] = 0x9, 71 [TPI_ACK_DELAY_EXPONENT] = 0xA, 72 [TPI_MAX_ACK_DELAY] = 0xB, 73 [TPI_DISABLE_ACTIVE_MIGRATION] = 0xC, 74 [TPI_PREFERRED_ADDRESS] = 0xD, 75 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = 0xE, 76#if LSQUIC_TEST_QUANTUM_READINESS 77 [TPI_QUANTUM_READINESS] = 0xC37, 78#endif 79 [TPI_LOSS_BITS] = 0x1057, 80}; 81 82 83static const char * const tpi2str[LAST_TPI + 1] = 84{ 85 [TPI_ORIGINAL_CONNECTION_ID] = "original_connection_id", 86 [TPI_MAX_IDLE_TIMEOUT] = "max_idle_timeout", 87 [TPI_STATELESS_RESET_TOKEN] = "stateless_reset_token", 88 [TPI_MAX_PACKET_SIZE] = "max_packet_size", 89 [TPI_INIT_MAX_DATA] = "init_max_data", 90 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = "init_max_stream_data_bidi_local", 91 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = "init_max_stream_data_bidi_remote", 92 [TPI_INIT_MAX_STREAM_DATA_UNI] = "init_max_stream_data_uni", 93 [TPI_INIT_MAX_STREAMS_BIDI] = "init_max_streams_bidi", 94 [TPI_INIT_MAX_STREAMS_UNI] = "init_max_streams_uni", 95 [TPI_ACK_DELAY_EXPONENT] = "ack_delay_exponent", 96 [TPI_MAX_ACK_DELAY] = "max_ack_delay", 97 [TPI_DISABLE_ACTIVE_MIGRATION] = "disable_active_migration", 98 [TPI_PREFERRED_ADDRESS] = "preferred_address", 99 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = "active_connection_id_limit", 100#if LSQUIC_TEST_QUANTUM_READINESS 101 [TPI_QUANTUM_READINESS] = "quantum_readiness", 102#endif 103 [TPI_LOSS_BITS] = "loss_bits", 104}; 105 106 107static const uint64_t def_vals[MAX_NUM_WITH_DEF_TPI + 1] = 108{ 109 [TPI_MAX_PACKET_SIZE] = TP_DEF_MAX_PACKET_SIZE, 110 [TPI_ACK_DELAY_EXPONENT] = TP_DEF_ACK_DELAY_EXP, 111 [TPI_INIT_MAX_STREAMS_UNI] = TP_DEF_INIT_MAX_STREAMS_UNI, 112 [TPI_INIT_MAX_STREAMS_BIDI] = TP_DEF_INIT_MAX_STREAMS_BIDI, 113 [TPI_INIT_MAX_DATA] = TP_DEF_INIT_MAX_DATA, 114 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL, 115 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE, 116 [TPI_INIT_MAX_STREAM_DATA_UNI] = TP_DEF_INIT_MAX_STREAM_DATA_UNI, 117 [TPI_MAX_IDLE_TIMEOUT] = TP_DEF_MAX_IDLE_TIMEOUT, 118 [TPI_MAX_ACK_DELAY] = TP_DEF_MAX_ACK_DELAY, 119 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = TP_DEF_ACTIVE_CONNECTION_ID_LIMIT, 120}; 121 122 123static const uint64_t max_vals[MAX_NUMERIC_TPI + 1] = 124{ 125 [TPI_MAX_PACKET_SIZE] = VINT_MAX_VALUE, 126 [TPI_ACK_DELAY_EXPONENT] = VINT_MAX_VALUE, 127 [TPI_INIT_MAX_STREAMS_UNI] = VINT_MAX_VALUE, 128 [TPI_INIT_MAX_STREAMS_BIDI] = VINT_MAX_VALUE, 129 [TPI_INIT_MAX_DATA] = VINT_MAX_VALUE, 130 [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = VINT_MAX_VALUE, 131 [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = VINT_MAX_VALUE, 132 [TPI_INIT_MAX_STREAM_DATA_UNI] = VINT_MAX_VALUE, 133 [TPI_MAX_IDLE_TIMEOUT] = VINT_MAX_VALUE, 134 [TPI_MAX_ACK_DELAY] = TP_MAX_MAX_ACK_DELAY, 135 [TPI_ACTIVE_CONNECTION_ID_LIMIT] = VINT_MAX_VALUE, 136 [TPI_LOSS_BITS] = 1, 137}; 138 139 140static size_t 141preferred_address_size (const struct transport_params *params) 142{ 143 return sizeof(params->tp_preferred_address.ipv4_addr) 144 + sizeof(params->tp_preferred_address.ipv4_port) 145 + sizeof(params->tp_preferred_address.ipv6_addr) 146 + sizeof(params->tp_preferred_address.ipv6_port) 147 + 1 + params->tp_preferred_address.cid.len 148 + sizeof(params->tp_preferred_address.srst) 149 ; 150} 151 152 153int 154lsquic_tp_has_pref_ipv4 (const struct transport_params *params) 155{ 156 return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS)) 157 && params->tp_preferred_address.ipv4_port 158 && !lsquic_is_zero(params->tp_preferred_address.ipv4_addr, 159 sizeof(params->tp_preferred_address.ipv4_addr)); 160} 161 162 163int 164lsquic_tp_has_pref_ipv6 (const struct transport_params *params) 165{ 166 return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS)) 167 && params->tp_preferred_address.ipv6_port 168 && !lsquic_is_zero(params->tp_preferred_address.ipv6_addr, 169 sizeof(params->tp_preferred_address.ipv6_addr)); 170} 171 172 173int 174lsquic_tp_encode (const struct transport_params *params, int is_server, 175 unsigned char *const buf, size_t bufsz) 176{ 177 unsigned char *p; 178 size_t need = 2; 179 uint16_t u16; 180 enum transport_param_id tpi; 181 unsigned set; 182 unsigned bits[MAX_NUMERIC_TPI + 1]; 183 184 set = params->tp_set; /* Will turn bits off for default values */ 185 186 if (is_server) 187 { 188 if (set & (1 << TPI_ORIGINAL_CONNECTION_ID)) 189 need += 4 + params->tp_original_cid.len; 190 if (set & (1 << TPI_STATELESS_RESET_TOKEN)) 191 need += 4 + sizeof(params->tp_stateless_reset_token); 192 if (set & (1 << TPI_PREFERRED_ADDRESS)) 193 need += 4 + preferred_address_size(params); 194 } 195#if LSQUIC_TEST_QUANTUM_READINESS 196 else if (set & (1 << TPI_QUANTUM_READINESS)) 197 need += 4 + QUANTUM_READY_SZ; 198#endif 199 200 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 201 if (set & (1 << tpi)) 202 { 203 if (tpi > MAX_NUM_WITH_DEF_TPI 204 || params->tp_numerics[tpi] != def_vals[tpi]) 205 { 206 if (params->tp_numerics[tpi] <= max_vals[tpi]) 207 { 208 bits[tpi] = vint_val2bits(params->tp_numerics[tpi]); 209 need += 4 + (1 << bits[tpi]); 210 } 211 else 212 { 213 LSQ_DEBUG("numeric value is too large (%"PRIu64" vs maximum " 214 "of %"PRIu64")", params->tp_numerics[tpi], 215 max_vals[tpi]); 216 return -1; 217 } 218 } 219 else 220 set &= ~(1 << tpi); /* Don't write default value */ 221 } 222 223 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 224 if (set & (1 << tpi)) 225 need += 4 + 0; 226 227 if (need > bufsz || need > UINT16_MAX) 228 { 229 errno = ENOBUFS; 230 return -1; 231 } 232 233 p = buf; 234 235#define WRITE_TO_P(src, len) do { \ 236 memcpy(p, src, len); \ 237 p += len; \ 238} while (0) 239 240#if __BYTE_ORDER == __LITTLE_ENDIAN 241#define WRITE_UINT_TO_P(val, width) do { \ 242 u##width = bswap_##width(val); \ 243 WRITE_TO_P(&u##width, sizeof(u##width)); \ 244} while (0) 245#else 246#define WRITE_UINT_TO_P(val, width) do { \ 247 u##width = val; \ 248 WRITE_TO_P(&u##width, sizeof(u##width)); \ 249} while (0) 250#endif 251 252#define WRITE_PARAM_TO_P(tpidx, tpval, width) do { \ 253 WRITE_UINT_TO_P(tpidx, 16); \ 254 WRITE_UINT_TO_P(width / 8, 16); \ 255 if (width > 8) \ 256 WRITE_UINT_TO_P(tpval, width); \ 257 else if (width) \ 258 *p++ = tpval; \ 259} while (0) 260 261 WRITE_UINT_TO_P(need - 2 + buf - p, 16); 262 263 for (tpi = 0; tpi <= LAST_TPI; ++tpi) 264 if (set & (1 << tpi)) 265 { 266 WRITE_UINT_TO_P(enum_2_tpi_val[tpi], 16); 267 switch (tpi) 268 { 269 case TPI_MAX_IDLE_TIMEOUT: 270 case TPI_MAX_PACKET_SIZE: 271 case TPI_INIT_MAX_DATA: 272 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 273 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 274 case TPI_INIT_MAX_STREAM_DATA_UNI: 275 case TPI_INIT_MAX_STREAMS_BIDI: 276 case TPI_INIT_MAX_STREAMS_UNI: 277 case TPI_ACK_DELAY_EXPONENT: 278 case TPI_MAX_ACK_DELAY: 279 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 280 case TPI_LOSS_BITS: 281 WRITE_UINT_TO_P(1 << bits[tpi], 16); 282 vint_write(p, params->tp_numerics[tpi], bits[tpi], 283 1 << bits[tpi]); 284 p += 1 << bits[tpi]; 285 break; 286 case TPI_ORIGINAL_CONNECTION_ID: 287 WRITE_UINT_TO_P(params->tp_original_cid.len, 16); 288 WRITE_TO_P(params->tp_original_cid.idbuf, 289 params->tp_original_cid.len); 290 break; 291 case TPI_STATELESS_RESET_TOKEN: 292 WRITE_UINT_TO_P(sizeof(params->tp_stateless_reset_token), 16); 293 WRITE_TO_P(params->tp_stateless_reset_token, 294 sizeof(params->tp_stateless_reset_token)); 295 break; 296 case TPI_PREFERRED_ADDRESS: 297 WRITE_UINT_TO_P(preferred_address_size(params), 16); 298 WRITE_TO_P(¶ms->tp_preferred_address.ipv4_addr, 299 sizeof(params->tp_preferred_address.ipv4_addr)); 300 WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16); 301 WRITE_TO_P(¶ms->tp_preferred_address.ipv6_addr, 302 sizeof(params->tp_preferred_address.ipv6_addr)); 303 WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16); 304 *p++ = params->tp_preferred_address.cid.len; 305 WRITE_TO_P(params->tp_preferred_address.cid.idbuf, 306 params->tp_preferred_address.cid.len); 307 WRITE_TO_P(params->tp_preferred_address.srst, 308 sizeof(params->tp_preferred_address.srst)); 309 break; 310 case TPI_DISABLE_ACTIVE_MIGRATION: 311 WRITE_UINT_TO_P(0, 16); 312 break; 313#if LSQUIC_TEST_QUANTUM_READINESS 314 case TPI_QUANTUM_READINESS: 315 WRITE_UINT_TO_P(QUANTUM_READY_SZ, 16); 316 memset(p, 'Q', QUANTUM_READY_SZ); 317 p += QUANTUM_READY_SZ; 318 break; 319#endif 320 } 321 } 322 323 assert(buf + need == p); 324 return (int) (p - buf); 325 326#undef WRITE_TO_P 327#undef WRITE_UINT_TO_P 328} 329 330 331int 332lsquic_tp_decode (const unsigned char *const buf, size_t bufsz, 333 int is_server, 334 struct transport_params *params) 335{ 336 const unsigned char *p, *end, *q; 337 uint16_t len, param_id, tlen; 338 enum transport_param_id tpi; 339 unsigned set_of_ids; 340 int s; 341 342 p = buf; 343 end = buf + bufsz; 344 345 *params = TP_INITIALIZER(); 346 347 if (end - p < 2) 348 return -1; 349 READ_UINT(len, 16, p, 2); 350 p += 2; 351 if (len > end - p) 352 return -1; 353 end = p + len; 354 355#define EXPECT_LEN(expected_len) do { \ 356 if (expected_len != len) \ 357 return -1; \ 358} while (0) 359 360#define EXPECT_AT_LEAST(expected_len) do { \ 361 if ((expected_len) > (uintptr_t) (p + len - q)) \ 362 return -1; \ 363} while (0) 364 365 set_of_ids = 0; 366 while (p + 4 <= end) 367 { 368 READ_UINT(param_id, 16, p, 2); 369 p += 2; 370 READ_UINT(len, 16, p, 2); 371 p += 2; 372 if (len > end - p) 373 return -1; 374 tpi = tpi_val_2_enum(param_id); 375 if (tpi <= LAST_TPI) 376 { 377 if (set_of_ids & (1 << tpi)) 378 return -1; 379 set_of_ids |= 1 << tpi; 380 } 381 switch (tpi) 382 { 383 case TPI_MAX_IDLE_TIMEOUT: 384 case TPI_MAX_PACKET_SIZE: 385 case TPI_INIT_MAX_DATA: 386 case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL: 387 case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE: 388 case TPI_INIT_MAX_STREAM_DATA_UNI: 389 case TPI_INIT_MAX_STREAMS_BIDI: 390 case TPI_INIT_MAX_STREAMS_UNI: 391 case TPI_ACK_DELAY_EXPONENT: 392 case TPI_MAX_ACK_DELAY: 393 case TPI_ACTIVE_CONNECTION_ID_LIMIT: 394 case TPI_LOSS_BITS: 395 switch (len) 396 { 397 case 1: 398 case 2: 399 case 4: 400 case 8: 401 s = vint_read(p, p + len, ¶ms->tp_numerics[tpi]); 402 if (s == len) 403 { 404 if (params->tp_numerics[tpi] > max_vals[tpi]) 405 { 406 LSQ_DEBUG("numeric value of parameter 0x%X is too " 407 "large (%"PRIu64" vs maximum of %"PRIu64, 408 param_id, params->tp_numerics[tpi], max_vals[tpi]); 409 return -1; 410 } 411 break; 412 } 413 else 414 { 415 LSQ_DEBUG("cannot read the value of numeric transport " 416 "param %u of length %u", param_id, len); 417 return -1; 418 } 419 default: 420 LSQ_DEBUG("invalid length=%u for numeric transport " 421 "parameter 0x%X", len, param_id); 422 return -1; 423 } 424 break; 425 case TPI_DISABLE_ACTIVE_MIGRATION: 426 EXPECT_LEN(0); 427 break; 428 case TPI_STATELESS_RESET_TOKEN: 429 /* Client MUST not include reset token, 430 * see [draft-ietf-quic-transport-11], Section 6.4.1 431 */ 432 if (!is_server) 433 return -1; 434 EXPECT_LEN(sizeof(params->tp_stateless_reset_token)); 435 memcpy(params->tp_stateless_reset_token, p, 436 sizeof(params->tp_stateless_reset_token)); 437 break; 438 case TPI_ORIGINAL_CONNECTION_ID: 439 /* Client MUST not original connecti ID, 440 * see [draft-ietf-quic-transport-15], Section 6.6.1 441 */ 442 if (!is_server) 443 return -1; 444 if (len > MAX_CID_LEN) 445 return -1; 446 memcpy(params->tp_original_cid.idbuf, p, len); 447 params->tp_original_cid.len = len; 448 break; 449 case TPI_PREFERRED_ADDRESS: 450 /* Client MUST not include preferred address, 451 * see [draft-ietf-quic-transport-12], Section 6.4.1 452 */ 453 if (!is_server) 454 return -1; 455 q = p; 456 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr)); 457 memcpy(params->tp_preferred_address.ipv4_addr, q, 458 sizeof(params->tp_preferred_address.ipv4_addr)); 459 q += sizeof(params->tp_preferred_address.ipv4_addr); 460 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port)); 461 READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2); 462 q += 2; 463 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr)); 464 memcpy(params->tp_preferred_address.ipv6_addr, q, 465 sizeof(params->tp_preferred_address.ipv6_addr)); 466 q += sizeof(params->tp_preferred_address.ipv6_addr); 467 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port)); 468 READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2); 469 q += 2; 470 EXPECT_AT_LEAST(1); 471 tlen = *q; 472 q += 1; 473 if (tlen < 4 || tlen > MAX_CID_LEN) 474 { 475 LSQ_DEBUG("preferred server address contains invalid " 476 "CID length of %"PRIu16" bytes", tlen); 477 return -1; 478 } 479 EXPECT_AT_LEAST(tlen); 480 memcpy(params->tp_preferred_address.cid.idbuf, q, tlen); 481 params->tp_preferred_address.cid.len = tlen; 482 q += tlen; 483 EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst)); 484 memcpy(params->tp_preferred_address.srst, q, 485 sizeof(params->tp_preferred_address.srst)); 486 q += sizeof(params->tp_preferred_address.srst); 487 if (q != p + len) 488 return -1; 489 break; 490 default: 491 /* Do nothing: skip this transport parameter */ 492 break; 493 } 494 p += len; 495 if (tpi <= LAST_TPI) 496 { 497 params->tp_set |= 1 << tpi; 498 params->tp_decoded |= 1 << tpi; 499 } 500 } 501 502 if (p != end) 503 return -1; 504 505 return (int) (end - buf); 506#undef EXPECT_LEN 507} 508 509 510void 511lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz) 512{ 513 char *const end = buf + sz; 514 int nw; 515 enum transport_param_id tpi; 516 char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1]; 517 char addr_str[INET6_ADDRSTRLEN]; 518 519 for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi) 520 if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)) 521 { 522 nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64, 523 (buf + sz > end) << 1, "; ", tpi2str[tpi], 524 params->tp_numerics[tpi]); 525 buf += nw; 526 if (buf >= end) 527 return; 528 } 529 for (; tpi <= MAX_EMPTY_TPI; ++tpi) 530 if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)) 531 { 532 nw = snprintf(buf, end - buf, "%.*s%s", 533 (buf + sz > end) << 1, "; ", tpi2str[tpi]); 534 buf += nw; 535 if (buf >= end) 536 return; 537 } 538#if LSQUIC_TEST_QUANTUM_READINESS 539 if (params->tp_set & (1 << TPI_QUANTUM_READINESS)) 540 { 541 nw = snprintf(buf, end - buf, "%.*s%s", 542 (buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]); 543 buf += nw; 544 if (buf >= end) 545 return; 546 } 547#endif 548 if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN)) 549 { 550 lsquic_hexstr(params->tp_stateless_reset_token, 551 sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str)); 552 nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str); 553 buf += nw; 554 if (buf >= end) 555 return; 556 } 557 if (params->tp_set & (1 << TPI_ORIGINAL_CONNECTION_ID)) 558 { 559 char cidbuf_[MAX_CID_LEN * 2 + 1]; 560 nw = snprintf(buf, end - buf, "; original DCID (ODCID): %"CID_FMT, 561 CID_BITS(¶ms->tp_original_cid)); 562 buf += nw; 563 if (buf >= end) 564 return; 565 } 566 if (lsquic_tp_has_pref_ipv4(params)) 567 { 568 if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr, 569 addr_str, sizeof(addr_str))) 570 { 571 nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u", 572 addr_str, params->tp_preferred_address.ipv4_port); 573 buf += nw; 574 if (buf >= end) 575 return; 576 } 577 } 578 if (lsquic_tp_has_pref_ipv6(params)) 579 { 580 if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr, 581 addr_str, sizeof(addr_str))) 582 { 583 nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u", 584 addr_str, params->tp_preferred_address.ipv6_port); 585 buf += nw; 586 if (buf >= end) 587 return; 588 } 589 } 590} 591