lsquic_mini_conn.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_mini_conn.c -- Mini connection. 4 * 5 * Mini connection is only used in server mode -- this assumption is relied 6 * upon by the code in this file. 7 * 8 * The purpose of this connection is to process incoming handshakes using 9 * minimal amount of resources until we confirm that the client is sending 10 * valid data. Here, we only process Stream 1 data; other packets are 11 * spooled, if necessary. When mini connection is promoted to full 12 * connection, the state, including spooled incoming packets, is transferred 13 * to the full connection. 14 * 15 * Note that mini connections do not retransmit lost packets. This is to 16 * minimize the effect of magnification attacks. Clients like Chrome and 17 * Opera fall back to using TCP if QUIC handshake times out. 18 */ 19 20 21#include <assert.h> 22#include <errno.h> 23#include <inttypes.h> 24#include <limits.h> 25#include <stdlib.h> 26#include <string.h> 27#include <sys/queue.h> 28#include <time.h> 29 30#include "lsquic.h" 31#include "lsquic_int_types.h" 32#include "lsquic_hash.h" 33#include "lsquic_conn.h" 34#include "lsquic_rtt.h" 35#include "lsquic_mini_conn.h" 36#include "lsquic_mm.h" 37#include "lsquic_malo.h" 38#include "lsquic_packet_common.h" 39#include "lsquic_packet_gquic.h" 40#include "lsquic_packet_ietf.h" 41#include "lsquic_packet_in.h" 42#include "lsquic_packet_out.h" 43#include "lsquic_util.h" 44#include "lsquic_str.h" 45#include "lsquic_enc_sess.h" 46#include "lsquic_parse.h" 47#include "lsquic_engine_public.h" 48#include "lsquic_sfcw.h" 49#include "lsquic_varint.h" 50#include "lsquic_hq.h" 51#include "lsquic_stream.h" 52#include "lsquic_rechist.h" 53#include "lsquic_ev_log.h" 54#include "lsquic_qtags.h" 55#include "lsquic_attq.h" 56#include "lsquic_alarmset.h" 57 58#define LSQUIC_LOGGER_MODULE LSQLM_MINI_CONN 59#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&mc->mc_conn) 60#include "lsquic_logger.h" 61 62 63static const struct conn_iface mini_conn_iface_standard; 64static const struct conn_iface mini_conn_iface_standard_Q050; 65 66#if LSQUIC_KEEP_MINICONN_HISTORY 67 68static void 69mchist_append (struct mini_conn *mc, enum miniconn_history_event mh_event) 70{ 71 enum miniconn_history_event prev_event; 72 mchist_idx_t idx; 73 int plus; 74 75 idx = (mc->mc_hist_idx - 1) & MCHIST_MASK; 76 plus = MCHE_PLUS == mc->mc_hist_buf[ idx ]; 77 idx = (idx - plus) & MCHIST_MASK; 78 prev_event = mc->mc_hist_buf[ idx ]; 79 80 if (!(prev_event == mh_event && plus)) 81 { 82 if (prev_event == mh_event) 83 mh_event = MCHE_PLUS; 84 mc->mc_hist_buf[ MCHIST_MASK & mc->mc_hist_idx++ ] = mh_event; 85 } 86} 87 88 89# define MCHIST_APPEND(mc, event) mchist_append(mc, event) 90#else 91# define MCHIST_APPEND(mc, event) 92#endif 93 94static void 95process_deferred_packets (struct mini_conn *mc); 96 97 98/* If this is not true, highest_bit_set() may be broken */ 99typedef char packno_set_is_unsigned_long[ 100 sizeof(unsigned long long) == sizeof(mconn_packno_set_t) ? 1 : -1 ]; 101 102static unsigned 103highest_bit_set (unsigned long long sz) 104{ 105#if __GNUC__ 106 unsigned clz = __builtin_clzll(sz); 107 return 63 - clz; 108#else 109 unsigned long y; 110 unsigned n; 111 n = 64; 112 y = sz >> 32; if (y) { n -= 32; sz = y; } 113 y = sz >> 16; if (y) { n -= 16; sz = y; } 114 y = sz >> 8; if (y) { n -= 8; sz = y; } 115 y = sz >> 4; if (y) { n -= 4; sz = y; } 116 y = sz >> 2; if (y) { n -= 2; sz = y; } 117 y = sz >> 1; if (y) return 63 - n + 2; 118 return 63 - n + sz; 119#endif 120} 121 122 123static unsigned 124lowest_bit_set (unsigned v) 125{ 126#if __GNUC__ 127 return __builtin_ctz(v); 128#else 129 unsigned n; 130 n = 0; 131 if (0 == (v & ((1 << 16) - 1))) { n += 16; v >>= 16; } 132 if (0 == (v & ((1 << 8) - 1))) { n += 8; v >>= 8; } 133 if (0 == (v & ((1 << 4) - 1))) { n += 4; v >>= 4; } 134 if (0 == (v & ((1 << 2) - 1))) { n += 2; v >>= 2; } 135 if (0 == (v & ((1 << 1) - 1))) { n += 1; } 136 return n; 137#endif 138} 139 140 141static int 142is_handshake_stream_id (const struct mini_conn *conn, 143 lsquic_stream_id_t stream_id) 144{ 145 return conn->mc_conn.cn_version < LSQVER_050 && stream_id == 1; 146} 147 148 149static void 150mini_destroy_packet (struct mini_conn *mc, struct lsquic_packet_out *packet_out) 151{ 152 lsquic_packet_out_destroy(packet_out, mc->mc_enpub, 153 mc->mc_path.np_peer_ctx); 154} 155 156 157static int 158packet_in_is_ok (enum lsquic_version version, 159 const struct lsquic_packet_in *packet_in) 160{ 161 size_t min_size; 162 163 if (packet_in->pi_data_sz > GQUIC_MAX_PACKET_SZ) 164 { 165 LSQ_LOG1(LSQ_LOG_DEBUG, "incoming packet too large: %hu bytes", 166 packet_in->pi_data_sz); 167 return 0; 168 } 169 170 if ((1 << version) & LSQUIC_GQUIC_HEADER_VERSIONS) 171 /* This is a very lax number, it allows the server to send 172 * 64 * 200 = 12KB of output (REJ and SHLO). 173 */ 174 min_size = 200; 175 else 176 /* Chrome enforces 1200-byte minimum initial packet limit */ 177 min_size = IQUIC_MIN_INIT_PACKET_SZ; 178 179 if (packet_in->pi_data_sz < min_size) 180 { 181 LSQ_LOG1(LSQ_LOG_DEBUG, "incoming packet too small: %hu bytes", 182 packet_in->pi_data_sz); 183 return 0; 184 } 185 return 1; 186} 187 188 189lsquic_conn_t * 190lsquic_mini_conn_new (struct lsquic_engine_public *enp, 191 const struct lsquic_packet_in *packet_in, 192 enum lsquic_version version) 193{ 194 struct mini_conn *mc; 195 const struct conn_iface *conn_iface; 196 197 if (!packet_in_is_ok(version, packet_in)) 198 return NULL; 199 switch (version) 200 { 201 case LSQVER_050: 202 conn_iface = &mini_conn_iface_standard_Q050; 203 break; 204 default: 205 conn_iface = &mini_conn_iface_standard; 206 break; 207 } 208 209 mc = lsquic_malo_get(enp->enp_mm.malo.mini_conn); 210 if (!mc) 211 { 212 LSQ_LOG1(LSQ_LOG_WARN, "cannot allocate mini connection: %s", 213 strerror(errno)); 214 return NULL; 215 } 216 217 memset(mc, 0, sizeof(*mc)); 218 TAILQ_INIT(&mc->mc_deferred); 219 TAILQ_INIT(&mc->mc_packets_in); 220 TAILQ_INIT(&mc->mc_packets_out); 221 mc->mc_enpub = enp; 222 mc->mc_created = packet_in->pi_received; 223 mc->mc_path.np_pack_size = packet_in->pi_data_sz; 224 mc->mc_conn.cn_cces = mc->mc_cces; 225 mc->mc_conn.cn_cces_mask = 1; 226 mc->mc_conn.cn_n_cces = sizeof(mc->mc_cces) / sizeof(mc->mc_cces[0]); 227 mc->mc_conn.cn_version = version; 228 mc->mc_conn.cn_pf = select_pf_by_ver(version); 229 mc->mc_conn.cn_esf_c = select_esf_common_by_ver(version); 230 mc->mc_conn.cn_esf.g = select_esf_gquic_by_ver(version); 231 mc->mc_conn.cn_cid = packet_in->pi_conn_id; 232 mc->mc_conn.cn_flags = LSCONN_MINI | LSCONN_SERVER; 233 mc->mc_conn.cn_if = conn_iface; 234 LSQ_DEBUG("created mini connection object"); 235 MCHIST_APPEND(mc, MCHE_CREATED); 236 return &mc->mc_conn; 237} 238 239 240static int 241in_acked_range (const struct ack_info *acki, lsquic_packno_t n) /* This is a copy */ 242{ 243 int in_range = 0; 244 unsigned i; 245 for (i = 0; i < acki->n_ranges; ++i) 246 in_range += acki->ranges[i].high >= n 247 && acki->ranges[i].low <= n; 248 return in_range > 0; 249} 250 251 252static void 253take_rtt_sample (struct mini_conn *mc, const lsquic_packet_out_t *packet_out, 254 lsquic_time_t now, lsquic_time_t lack_delta) 255{ 256 assert(packet_out->po_sent); 257 lsquic_time_t measured_rtt = now - packet_out->po_sent; 258 if (lack_delta < measured_rtt) 259 { 260 lsquic_rtt_stats_update(&mc->mc_rtt_stats, measured_rtt, lack_delta); 261 LSQ_DEBUG("srtt: %"PRIu64" usec, var: %"PRIu64, 262 lsquic_rtt_stats_get_srtt(&mc->mc_rtt_stats), 263 lsquic_rtt_stats_get_rttvar(&mc->mc_rtt_stats)); 264 } 265} 266 267 268static unsigned 269process_ack_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 270 const unsigned char *p, size_t len) 271{ 272 int parsed_len; 273 int n_newly_acked; 274 unsigned n; 275 lsquic_packet_out_t *packet_out, *next; 276 struct ack_info *acki; 277 lsquic_packno_t packno; 278 lsquic_time_t warn_time; 279 char buf[200]; 280 281 acki = mc->mc_enpub->enp_mm.acki; 282 parsed_len = mc->mc_conn.cn_pf->pf_parse_ack_frame(p, len, acki, 0); 283 if (parsed_len < 0) 284 return 0; 285 if (empty_ack_frame(acki)) 286 { 287 LSQ_DEBUG("Ignore empty ACK frame"); 288 return parsed_len; 289 } 290 if (packet_in->pi_packno <= mc->mc_max_ack_packno) 291 { 292 LSQ_DEBUG("Ignore old ack (max %u)", mc->mc_max_ack_packno); 293 return parsed_len; 294 } 295 if (packet_in->pi_packno <= UCHAR_MAX) 296 mc->mc_max_ack_packno = packet_in->pi_packno; 297 298 /* Verify ACK frame and update list of acked packet numbers: */ 299 for (n = 0; n < acki->n_ranges; ++n) 300 for (packno = acki->ranges[n].low; packno <= acki->ranges[n].high; 301 ++packno) 302 if (packno > MINICONN_MAX_PACKETS || 303 0 == (MCONN_PACKET_MASK(packno) & mc->mc_sent_packnos)) 304 { 305 warn_time = lsquic_time_now(); 306 if (0 == mc->mc_enpub->enp_last_warning[WT_ACKPARSE_MINI] 307 || mc->mc_enpub->enp_last_warning[WT_ACKPARSE_MINI] 308 + WARNING_INTERVAL < warn_time) 309 { 310 mc->mc_enpub->enp_last_warning[WT_ACKPARSE_MINI] 311 = warn_time; 312 lsquic_hexdump(p, len, buf, sizeof(buf)); 313 LSQ_WARN("packet %"PRIu64" was never sent; ACK " 314 "frame:\n%s", packno, buf); 315 } 316 else 317 LSQ_DEBUG("packet %"PRIu64" was never sent", packno); 318 MCHIST_APPEND(mc, MCHE_UNSENT_ACKED); 319 return 0; 320 } 321 else 322 mc->mc_acked_packnos |= MCONN_PACKET_MASK(packno); 323 324 EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, acki); 325 n_newly_acked = 0; 326 for (packet_out = TAILQ_FIRST(&mc->mc_packets_out); packet_out; 327 packet_out = next) 328 { 329 next = TAILQ_NEXT(packet_out, po_next); 330 if (in_acked_range(acki, packet_out->po_packno)) 331 { 332 ++n_newly_acked; 333 LSQ_DEBUG("Got ACK for packet %"PRIu64, packet_out->po_packno); 334 if (packet_out->po_packno == largest_acked(acki)) 335 take_rtt_sample(mc, packet_out, packet_in->pi_received, 336 acki->lack_delta); 337 TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next); 338 mini_destroy_packet(mc, packet_out); 339 } 340 } 341 342 if (n_newly_acked > 0) 343 mc->mc_hsk_count = 0; 344 345 return parsed_len; 346} 347 348 349static unsigned 350process_blocked_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 351 const unsigned char *p, size_t len) 352{ 353 lsquic_stream_id_t stream_id; 354 int parsed_len; 355 parsed_len = mc->mc_conn.cn_pf->pf_parse_blocked_frame(p, len, &stream_id); 356 if (parsed_len < 0) 357 return 0; 358 EV_LOG_BLOCKED_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id); 359 LSQ_DEBUG("Peer reports stream %"PRIu64" as blocked", stream_id); 360 return parsed_len; 361} 362 363 364static mconn_packno_set_t 365drop_packets_out (struct mini_conn *mc) 366{ 367 struct lsquic_packet_out *packet_out; 368 mconn_packno_set_t in_flight = 0; 369 370 while ((packet_out = TAILQ_FIRST(&mc->mc_packets_out))) 371 { 372 TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next); 373 if (packet_out->po_flags & PO_SENT) 374 in_flight |= MCONN_PACKET_MASK(packet_out->po_packno); 375 mini_destroy_packet(mc, packet_out); 376 } 377 378 return in_flight; 379} 380 381 382static unsigned 383process_connection_close_frame (struct mini_conn *mc, 384 lsquic_packet_in_t *packet_in, const unsigned char *p, size_t len) 385{ 386 uint64_t error_code; 387 uint16_t reason_len; 388 uint8_t reason_off; 389 int parsed_len; 390 391 (void) drop_packets_out(mc); 392 parsed_len = mc->mc_conn.cn_pf->pf_parse_connect_close_frame(p, len, 393 NULL, &error_code, &reason_len, &reason_off); 394 if (parsed_len < 0) 395 return 0; 396 mc->mc_error_code = (uint64_t) error_code; 397 EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, 398 (int) reason_len, (const char *) p + reason_off); 399 if (error_code != 25 /* No recent network activity */ 400 && error_code != 62 /* An active session exists for the given IP */ 401 && error_code != 27 ) /* Write failed with error: -142 (Unknown error)*/ 402 { 403 LSQ_WARN("Received CONNECTION_CLOSE frame (code: %"PRIu64"; reason: %.*s)", 404 error_code, (int) reason_len, (const char *) p + reason_off); 405 } 406 MCHIST_APPEND(mc, MCHE_CONN_CLOSE); 407 return 0; /* This shuts down the connection */ 408} 409 410 411static unsigned 412process_goaway_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 413 const unsigned char *p, size_t len) 414{ 415 lsquic_stream_id_t stream_id; 416 uint32_t error_code; 417 uint16_t reason_length; 418 const char *reason; 419 int parsed_len; 420 parsed_len = mc->mc_conn.cn_pf->pf_parse_goaway_frame(p, len, &error_code, &stream_id, 421 &reason_length, &reason); 422 if (parsed_len < 0) 423 return 0; 424 EV_LOG_GOAWAY_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, stream_id, 425 reason_length, reason); 426 LSQ_DEBUG("received GOAWAY frame, last good stream ID: %"PRIu64", " 427 "error code: 0x%X, reason: `%.*s'", stream_id, error_code, 428 reason_length, reason); 429 if (stream_id != 0) /* This is odd. We warn: */ 430 LSQ_WARN("stream ID is %"PRIu64" in GOAWAY frame", stream_id); 431 mc->mc_conn.cn_flags |= LSCONN_PEER_GOING_AWAY; 432 return parsed_len; 433} 434 435 436static unsigned 437process_invalid_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 438 const unsigned char *p, size_t len) 439{ 440 LSQ_INFO("invalid frame"); 441 MCHIST_APPEND(mc, MCHE_INVALID_FRAME); 442 return 0; 443} 444 445 446static unsigned 447count_zero_bytes (const unsigned char *p, size_t len) 448{ 449 const unsigned char *const end = p + len; 450 while (p < end && 0 == *p) 451 ++p; 452 return len - (end - p); 453} 454 455 456static unsigned 457process_padding_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 458 const unsigned char *p, size_t len) 459{ 460 len = (size_t) count_zero_bytes(p, len); 461 EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len); 462 return len; 463} 464 465 466static unsigned 467process_ping_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 468 const unsigned char *p, size_t len) 469{ 470 EV_LOG_PING_FRAME_IN(LSQUIC_LOG_CONN_ID); 471 return 1; 472} 473 474 475static unsigned 476process_rst_stream_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 477 const unsigned char *p, size_t len) 478{ 479 lsquic_stream_id_t stream_id; 480 uint64_t offset, error_code; 481 int parsed_len; 482 parsed_len = mc->mc_conn.cn_pf->pf_parse_rst_frame(p, len, &stream_id, &offset, &error_code); 483 if (parsed_len < 0) 484 return 0; 485 EV_LOG_RST_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset, 486 error_code); 487 LSQ_DEBUG("Got RST_STREAM; stream: %"PRIu64"; offset: 0x%"PRIX64, stream_id, 488 offset); 489 if (is_handshake_stream_id(mc, stream_id)) 490 { 491 LSQ_INFO("handshake stream reset, closing connection"); 492 return 0; 493 } 494 else 495 return parsed_len; 496} 497 498 499static unsigned 500process_stop_waiting_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 501 const unsigned char *p, size_t len) 502{ 503 lsquic_packno_t least; 504 enum packno_bits bits = lsquic_packet_in_packno_bits(packet_in); 505 int parsed_len; 506 parsed_len = mc->mc_conn.cn_pf->pf_parse_stop_waiting_frame(p, len, packet_in->pi_packno, bits, 507 &least); 508 if (parsed_len < 0) 509 return 0; 510 EV_LOG_STOP_WAITING_FRAME_IN(LSQUIC_LOG_CONN_ID, least); 511 LSQ_DEBUG("Got STOP_WAITING frame, least unacked: %"PRIu64, least); 512 if (least > MINICONN_MAX_PACKETS) 513 return 0; 514 else 515 { 516 mc->mc_cutoff = least; 517 return parsed_len; 518 } 519} 520 521 522static unsigned 523process_stream_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 524 const unsigned char *p, size_t len) 525{ 526 stream_frame_t stream_frame; 527 int parsed_len; 528 parsed_len = mc->mc_conn.cn_pf->pf_parse_stream_frame(p, len, &stream_frame); 529 if (parsed_len < 0) 530 return 0; 531 EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, &stream_frame); 532 LSQ_DEBUG("Got stream frame for stream #%"PRIu64, stream_frame.stream_id); 533 if (is_handshake_stream_id(mc, stream_frame.stream_id)) 534 { 535 if (packet_in->pi_flags & PI_HSK_STREAM) 536 { /* This is not supported for simplicity. The spec recommends 537 * not putting more than one stream frame from the same stream 538 * into a single packet. If this changes and clients actually 539 * do that, we can revisit this code. 540 */ 541 LSQ_INFO("two handshake stream frames in single incoming packet"); 542 MCHIST_APPEND(mc, MCHE_2HSK_1STREAM); 543 return 0; 544 } 545 if (stream_frame.data_frame.df_offset >= mc->mc_read_off) 546 { 547 packet_in->pi_flags |= PI_HSK_STREAM; 548 packet_in->pi_hsk_stream = p - packet_in->pi_data; 549 mc->mc_flags |= MC_HAVE_NEW_HSK; 550 MCHIST_APPEND(mc, MCHE_NEW_HSK); 551 if (0 == stream_frame.data_frame.df_offset) 552 { 553 /* First CHLO message: update maximum packet size */ 554 mc->mc_path.np_pack_size = packet_in->pi_data_sz; 555 LSQ_DEBUG("update packet size to %hu", 556 mc->mc_path.np_pack_size); 557 } 558 } 559 else 560 { 561 LSQ_DEBUG("drop duplicate frame"); 562 MCHIST_APPEND(mc, MCHE_DUP_HSK); 563 } 564 } 565 return parsed_len; 566} 567 568 569static unsigned 570process_crypto_frame (struct mini_conn *mc, struct lsquic_packet_in *packet_in, 571 const unsigned char *p, size_t len) 572{ 573 stream_frame_t stream_frame; 574 int parsed_len; 575 parsed_len = mc->mc_conn.cn_pf->pf_parse_crypto_frame(p, len, 576 &stream_frame); 577 if (parsed_len < 0) 578 return 0; 579 EV_LOG_CRYPTO_FRAME_IN(LSQUIC_LOG_CONN_ID, &stream_frame, 580 lsquic_packet_in_enc_level(packet_in)); 581 LSQ_DEBUG("Got CRYPTO frame at encryption level %s", 582 lsquic_enclev2str[lsquic_packet_in_enc_level(packet_in)]); 583 if (packet_in->pi_flags & PI_HSK_STREAM) 584 { /* This is not supported for simplicity: assume a single CRYPTO frame 585 * per packet. If this changes, we can revisit this code. 586 */ 587 LSQ_INFO("two CRYPTO frames in single incoming packet"); 588 MCHIST_APPEND(mc, MCHE_2HSK_1STREAM); 589 return 0; 590 } 591 if (stream_frame.data_frame.df_offset >= mc->mc_read_off) 592 { 593 packet_in->pi_flags |= PI_HSK_STREAM; 594 packet_in->pi_hsk_stream = p - packet_in->pi_data; 595 mc->mc_flags |= MC_HAVE_NEW_HSK; 596 MCHIST_APPEND(mc, MCHE_NEW_HSK); 597 if (0 == stream_frame.data_frame.df_offset) 598 { 599 /* First CHLO message: update maximum packet size */ 600 mc->mc_path.np_pack_size = packet_in->pi_data_sz 601 /* Q050 and later adjust pi_data_sz of Initial packets during 602 * decryption, here we have to add the tag length back: 603 */ 604 + mc->mc_conn.cn_esf_c->esf_tag_len; 605 LSQ_DEBUG("update packet size to %hu", mc->mc_path.np_pack_size); 606 } 607 } 608 else 609 { 610 LSQ_DEBUG("drop duplicate frame"); 611 MCHIST_APPEND(mc, MCHE_DUP_HSK); 612 } 613 return parsed_len; 614} 615 616 617static unsigned 618process_window_update_frame (struct mini_conn *mc, 619 lsquic_packet_in_t *packet_in, const unsigned char *p, size_t len) 620{ 621 lsquic_stream_id_t stream_id; 622 uint64_t offset; 623 int parsed_len; 624 parsed_len = mc->mc_conn.cn_pf->pf_parse_window_update_frame(p, len, &stream_id, &offset); 625 if (parsed_len < 0) 626 return 0; 627 EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset); 628 if (is_handshake_stream_id(mc, stream_id)) 629 /* This should not happen: why would the client send us WINDOW_UPDATE 630 * on stream 1? 631 */ 632 LSQ_WARN("client sent WINDOW_UPDATE for handshake stream, " 633 "offset %"PRIu64, offset); 634 return parsed_len; 635} 636 637 638typedef unsigned (*process_frame_f)( 639 struct mini_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t); 640 641 642static process_frame_f const process_frames[N_QUIC_FRAMES] = 643{ 644 [QUIC_FRAME_ACK] = process_ack_frame, 645 [QUIC_FRAME_BLOCKED] = process_blocked_frame, 646 [QUIC_FRAME_CONNECTION_CLOSE] = process_connection_close_frame, 647 [QUIC_FRAME_CRYPTO] = process_crypto_frame, 648 [QUIC_FRAME_GOAWAY] = process_goaway_frame, 649 [QUIC_FRAME_INVALID] = process_invalid_frame, 650 [QUIC_FRAME_PADDING] = process_padding_frame, 651 [QUIC_FRAME_PING] = process_ping_frame, 652 [QUIC_FRAME_RST_STREAM] = process_rst_stream_frame, 653 [QUIC_FRAME_STOP_WAITING] = process_stop_waiting_frame, 654 [QUIC_FRAME_STREAM] = process_stream_frame, 655 [QUIC_FRAME_WINDOW_UPDATE] = process_window_update_frame, 656}; 657 658 659static unsigned 660process_packet_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 661 const unsigned char *p, size_t len) 662{ 663 enum quic_frame_type type = mc->mc_conn.cn_pf->pf_parse_frame_type(p, len); 664 packet_in->pi_frame_types |= 1 << type; 665 return process_frames[type](mc, packet_in, p, len); 666} 667 668 669static void 670record_largest_recv (struct mini_conn *mc, lsquic_time_t t) 671{ 672 if (t < mc->mc_created) 673 { 674 LSQ_WARN("largest received predates creation"); 675 return; 676 } 677 t -= mc->mc_created; 678 mc->mc_largest_recv[0] = t; 679 mc->mc_largest_recv[1] = t >> 8; 680 mc->mc_largest_recv[2] = t >> 16; 681 LSQ_DEBUG("recorded largest received timestamp as %"PRIu64" usec since " 682 "creation", t); 683} 684 685 686static enum dec_packin 687conn_decrypt_packet (struct mini_conn *conn, lsquic_packet_in_t *packet_in) 688{ 689 return conn->mc_conn.cn_esf_c->esf_decrypt_packet( 690 conn->mc_conn.cn_enc_session, conn->mc_enpub, 691 &conn->mc_conn, packet_in); 692} 693 694 695/* PRP: Process Regular Packet */ 696enum proc_rp { PRP_KEEP, PRP_DEFER, PRP_DROP, PRP_ERROR, }; 697 698 699static enum proc_rp 700conn_decrypt_packet_or (struct mini_conn *mc, 701 struct lsquic_packet_in *packet_in) 702{ 703 if (DECPI_OK == conn_decrypt_packet(mc, packet_in)) 704 { 705 MCHIST_APPEND(mc, MCHE_DECRYPTED); 706 return PRP_KEEP; 707 } 708 else if (mc->mc_conn.cn_esf.g->esf_have_key_gt_one( 709 mc->mc_conn.cn_enc_session)) 710 { 711 LSQ_INFO("could not decrypt packet: drop"); 712 mc->mc_dropped_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 713 MCHIST_APPEND(mc, MCHE_UNDECR_DROP); 714 return PRP_DROP; 715 } 716 else if ((packet_in->pi_flags & PI_OWN_DATA) || 717 0 == lsquic_conn_copy_and_release_pi_data(&mc->mc_conn, 718 mc->mc_enpub, packet_in)) 719 { 720 assert(packet_in->pi_flags & PI_OWN_DATA); 721 LSQ_INFO("could not decrypt packet: defer"); 722 mc->mc_deferred_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 723 MCHIST_APPEND(mc, MCHE_UNDECR_DEFER); 724 return PRP_DEFER; 725 } 726 else 727 { 728 MCHIST_APPEND(mc, MCHE_ENOMEM); 729 return PRP_ERROR; /* Memory allocation must have failed */ 730 } 731} 732 733 734static enum proc_rp 735process_regular_packet (struct mini_conn *mc, lsquic_packet_in_t *packet_in) 736{ 737 const unsigned char *p, *pend; 738 enum proc_rp prp; 739 unsigned len; 740 741 /* Decrypt packet if necessary */ 742 if (0 == (packet_in->pi_flags & PI_DECRYPTED)) 743 { 744 prp = conn_decrypt_packet_or(mc, packet_in); 745 if (prp != PRP_KEEP) 746 return prp; 747 } 748 749 /* Update receive history before processing the packet: if there is an 750 * error, the connection is terminated and recording this packet number 751 * is helpful when it is printed along with other diagnostics in dtor. 752 */ 753 if (0 == mc->mc_received_packnos || 754 packet_in->pi_packno > highest_bit_set(mc->mc_received_packnos) + 1) 755 record_largest_recv(mc, packet_in->pi_received); 756 mc->mc_received_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 757 758 /* Parse and process frames */ 759 p = packet_in->pi_data + packet_in->pi_header_sz; 760 pend = packet_in->pi_data + packet_in->pi_data_sz; 761 while (p < pend) 762 { 763 len = process_packet_frame(mc, packet_in, p, pend - p); 764 if (len > 0) 765 p += len; 766 else 767 { 768 if (mc->mc_conn.cn_pf->pf_parse_frame_type(p, pend - p) != 769 QUIC_FRAME_CONNECTION_CLOSE) 770 LSQ_WARN("error parsing frame: packno %"PRIu64"; sz: %u; type: " 771 "0x%X", packet_in->pi_packno, packet_in->pi_data_sz, p[0]); 772 MCHIST_APPEND(mc, MCHE_EFRAME); 773 return PRP_ERROR; 774 } 775 } 776 777 mc->mc_flags |= MC_GEN_ACK; 778 779 return PRP_KEEP; 780} 781 782 783struct hsk_chunk 784{ 785 lsquic_packet_in_t *hsk_packet_in; 786 const unsigned char *hsk_data; 787 unsigned hsk_off; 788 unsigned hsk_sz; 789}; 790 791 792static int 793compare_hsk_chunks (const void *ap, const void *bp) 794{ 795 const struct hsk_chunk *a = ap; 796 const struct hsk_chunk *b = bp; 797 return (a->hsk_off > b->hsk_off) - (b->hsk_off > a->hsk_off); 798} 799 800 801struct mini_stream_ctx 802{ 803 const unsigned char *buf; 804 size_t bufsz; 805 size_t off; 806}; 807 808 809static int 810mini_stream_has_data (const struct mini_stream_ctx *ms_ctx) 811{ 812 return ms_ctx->off < ms_ctx->bufsz; 813} 814 815 816static size_t 817mini_stream_read (void *stream, void *buf, size_t len, int *reached_fin) 818{ 819 struct mini_stream_ctx *ms_ctx = stream; 820 size_t avail = ms_ctx->bufsz - ms_ctx->off; 821 if (avail < len) 822 len = avail; 823 memcpy(buf, ms_ctx->buf + ms_ctx->off, len); 824 ms_ctx->off += len; 825 *reached_fin = 0; 826 return len; 827} 828 829 830/* Wrapper to throw out reached_fin */ 831static size_t 832mini_stream_read_for_crypto (void *stream, void *buf, size_t len, int *fin) 833{ 834 size_t retval; 835 int reached_fin; 836 837 retval = mini_stream_read(stream, buf, len, &reached_fin); 838 return retval; 839} 840 841 842static size_t 843mini_stream_size (void *stream) 844{ 845 struct mini_stream_ctx *ms_ctx = stream; 846 size_t avail = ms_ctx->bufsz - ms_ctx->off; 847 return avail; 848} 849 850 851static int 852mini_stream_fin (void *stream) 853{ /* There is never a FIN on the handshake stream */ 854 return 0; 855} 856 857 858static lsquic_packno_t 859next_packno (struct mini_conn *mc) 860{ 861 if (mc->mc_cur_packno < MINICONN_MAX_PACKETS) 862 { 863 return ++mc->mc_cur_packno; 864 } 865 else 866 { 867 if (!(mc->mc_flags & MC_OO_PACKNOS)) 868 { 869 MCHIST_APPEND(mc, MCHE_OUT_OF_PACKNOS); 870 mc->mc_flags |= MC_OO_PACKNOS; 871 LSQ_DEBUG("ran out of outgoing packet numbers"); 872 } 873 return MINICONN_MAX_PACKETS + 1; 874 } 875} 876 877 878static lsquic_packet_out_t * 879allocate_packet_out (struct mini_conn *mc, const unsigned char *nonce) 880{ 881 lsquic_packet_out_t *packet_out; 882 lsquic_packno_t packno; 883 packno = next_packno(mc); 884 if (packno > MINICONN_MAX_PACKETS) 885 { 886 LSQ_DEBUG("ran out of outgoing packet numbers, won't allocate packet"); 887 return NULL; 888 } 889 packet_out = lsquic_packet_out_new(&mc->mc_enpub->enp_mm, NULL, 1, 890 &mc->mc_conn, GQUIC_PACKNO_LEN_1, NULL, nonce, &mc->mc_path, 891 HETY_NOT_SET); 892 if (!packet_out) 893 { 894 LSQ_WARN("could not allocate packet: %s", strerror(errno)); 895 return NULL; 896 } 897 packet_out->po_loss_chain = packet_out; 898 packet_out->po_packno = packno; 899 packet_out->po_flags |= PO_MINI; 900 if (mc->mc_flags & MC_HAVE_SHLO) 901 { 902 packet_out->po_flags |= PO_HELLO; 903 packet_out->po_header_type = HETY_0RTT; 904 } 905 if (mc->mc_conn.cn_version >= LSQVER_050) 906 { 907 if (nonce) 908 packet_out->po_header_type = HETY_0RTT; 909 else 910 packet_out->po_header_type = HETY_INITIAL; 911 } 912 lsquic_packet_out_set_pns(packet_out, PNS_APP); 913 TAILQ_INSERT_TAIL(&mc->mc_packets_out, packet_out, po_next); 914 LSQ_DEBUG("allocated packet #%"PRIu64", nonce: %d", packno, !!nonce); 915 MCHIST_APPEND(mc, MCHE_NEW_PACKET_OUT); 916 EV_LOG_PACKET_CREATED(LSQUIC_LOG_CONN_ID, packet_out); 917 return packet_out; 918} 919 920 921static struct lsquic_packet_out * 922to_packet_pre_Q050 (struct mini_conn *mc, struct mini_stream_ctx *ms_ctx, 923 const unsigned char *nonce) 924{ 925 struct lsquic_packet_out *packet_out; 926 size_t cur_off; 927 int len; 928 929 packet_out = allocate_packet_out(mc, nonce); 930 if (!packet_out) 931 return NULL; 932 cur_off = ms_ctx->off; 933 len = mc->mc_conn.cn_pf->pf_gen_stream_frame( 934 packet_out->po_data + packet_out->po_data_sz, 935 lsquic_packet_out_avail(packet_out), 936 1, mc->mc_write_off, mini_stream_fin(ms_ctx), 937 mini_stream_size(ms_ctx), mini_stream_read, ms_ctx); 938 if (len < 0) 939 { 940 LSQ_WARN("cannot generate STREAM frame (avail: %u)", 941 lsquic_packet_out_avail(packet_out)); 942 return NULL; 943 } 944 mc->mc_write_off += ms_ctx->off - cur_off; 945 EV_LOG_GENERATED_STREAM_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 946 packet_out->po_data + packet_out->po_data_sz, len); 947 packet_out->po_data_sz += len; 948 packet_out->po_frame_types |= 1 << QUIC_FRAME_STREAM; 949 if (0 == lsquic_packet_out_avail(packet_out)) 950 packet_out->po_flags |= PO_STREAM_END; 951 952 return packet_out; 953} 954 955 956static struct lsquic_packet_out * 957to_packet_Q050plus (struct mini_conn *mc, struct mini_stream_ctx *ms_ctx, 958 const unsigned char *nonce) 959{ 960 struct lsquic_packet_out *packet_out; 961 size_t cur_off; 962 int len; 963 964 if (nonce && !(mc->mc_flags & MC_WR_OFF_RESET)) 965 { 966 mc->mc_write_off = 0; 967 mc->mc_flags |= MC_WR_OFF_RESET; 968 } 969 970 packet_out = allocate_packet_out(mc, nonce); 971 if (!packet_out) 972 return NULL; 973 cur_off = ms_ctx->off; 974 len = mc->mc_conn.cn_pf->pf_gen_crypto_frame( 975 packet_out->po_data + packet_out->po_data_sz, 976 lsquic_packet_out_avail(packet_out), 0, mc->mc_write_off, 0, 977 mini_stream_size(ms_ctx), mini_stream_read_for_crypto, ms_ctx); 978 if (len < 0) 979 { 980 LSQ_WARN("cannot generate CRYPTO frame (avail: %u)", 981 lsquic_packet_out_avail(packet_out)); 982 return NULL; 983 } 984 mc->mc_write_off += ms_ctx->off - cur_off; 985 EV_LOG_GENERATED_CRYPTO_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 986 packet_out->po_data + packet_out->po_data_sz, len); 987 packet_out->po_data_sz += len; 988 packet_out->po_frame_types |= 1 << QUIC_FRAME_CRYPTO; 989 990 return packet_out; 991} 992 993 994static int 995packetize_response (struct mini_conn *mc, const unsigned char *buf, 996 size_t bufsz, const unsigned char *nonce) 997{ 998 struct mini_stream_ctx ms_ctx; 999 lsquic_packet_out_t *packet_out; 1000 struct lsquic_packet_out * (*const to_packet) (struct mini_conn *, 1001 struct mini_stream_ctx *, const unsigned char *) 1002 = mc->mc_conn.cn_version < LSQVER_050 1003 ? to_packet_pre_Q050 : to_packet_Q050plus; 1004 1005 LSQ_DEBUG("Packetizing %zd bytes of handshake response", bufsz); 1006 1007 ms_ctx.buf = buf; 1008 ms_ctx.bufsz = bufsz; 1009 ms_ctx.off = 0; 1010 1011 do 1012 { 1013 packet_out = to_packet(mc, &ms_ctx, nonce); 1014 if (!packet_out) 1015 return -1; 1016 } 1017 while (mini_stream_has_data(&ms_ctx)); 1018 1019 /* PAD the last packet with NULs. ACK and STOP_WAITING go into a separate 1020 * packet. 1021 */ 1022 if (lsquic_packet_out_avail(packet_out)) 1023 { 1024 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated PADDING frame %u " 1025 "bytes long", lsquic_packet_out_avail(packet_out)); 1026 memset(packet_out->po_data + packet_out->po_data_sz, 0, 1027 lsquic_packet_out_avail(packet_out)); 1028 packet_out->po_data_sz += lsquic_packet_out_avail(packet_out); 1029 packet_out->po_frame_types |= 1 << QUIC_FRAME_PADDING; 1030 } 1031 1032 return 0; 1033} 1034 1035 1036static int 1037continue_handshake (struct mini_conn *mc) 1038{ 1039 lsquic_packet_in_t *packet_in; 1040 unsigned n_hsk_chunks = 0, n_contig, n, bufsz, off; 1041 int s, rv; 1042 size_t out_len; 1043 enum handshake_error he; 1044 unsigned char *buf_in_16k, *buf_out; 1045 const unsigned char *buf_in; 1046 time_t t; 1047 stream_frame_t frame; 1048 struct hsk_chunk hsk_chunks[MINICONN_MAX_PACKETS], *hsk_chunk; 1049 unsigned char nonce_buf[32]; 1050 int nonce_set = 0; 1051 int (*parse_frame)(const unsigned char *, size_t, struct stream_frame *) 1052 = mc->mc_conn.cn_version < LSQVER_050 1053 ? mc->mc_conn.cn_pf->pf_parse_stream_frame 1054 : mc->mc_conn.cn_pf->pf_parse_crypto_frame; 1055 1056 /* Get handshake stream data from each packet that contains a handshake 1057 * stream frame and place them into `hsk_chunks' array. 1058 */ 1059 TAILQ_FOREACH(packet_in, &mc->mc_packets_in, pi_next) 1060 { 1061 assert(n_hsk_chunks < sizeof(hsk_chunks) / sizeof(hsk_chunks[0])); 1062 if (0 == (packet_in->pi_flags & PI_HSK_STREAM)) 1063 continue; 1064 s = parse_frame(packet_in->pi_data + packet_in->pi_hsk_stream, 1065 packet_in->pi_data_sz - packet_in->pi_hsk_stream, &frame); 1066 if (-1 == s) 1067 { 1068 LSQ_WARN("cannot process hsk stream frame in packet %"PRIu64, 1069 packet_in->pi_packno); 1070 return -1; 1071 } 1072 hsk_chunk = &hsk_chunks[ n_hsk_chunks++ ]; 1073 hsk_chunk->hsk_packet_in = packet_in; 1074 hsk_chunk->hsk_data = frame.data_frame.df_data; 1075 hsk_chunk->hsk_off = frame.data_frame.df_offset; 1076 hsk_chunk->hsk_sz = frame.data_frame.df_size; 1077 } 1078 assert(n_hsk_chunks > 0); 1079 1080 if (n_hsk_chunks > 1) 1081 { 1082 /* Sort handshake stream data */ 1083 qsort(hsk_chunks, n_hsk_chunks, sizeof(hsk_chunks[0]), 1084 compare_hsk_chunks); 1085 /* Figure out how many packets contain handshake stream data in a 1086 * contiguous buffer and how large this data is. 1087 */ 1088 for (n = 1, n_contig = 1, bufsz = hsk_chunks[0].hsk_sz; 1089 n < n_hsk_chunks; ++n) 1090 if (hsk_chunks[n - 1].hsk_off + hsk_chunks[n - 1].hsk_sz == 1091 hsk_chunks[n].hsk_off) 1092 { 1093 ++n_contig; 1094 bufsz += hsk_chunks[n].hsk_sz; 1095 } 1096 else 1097 break; 1098 } 1099 else 1100 { 1101 n_contig = 1; 1102 bufsz = hsk_chunks[0].hsk_sz; 1103 } 1104 1105 /* Handshake handler expects to start reading at a particular offset. 1106 */ 1107 if (hsk_chunks[0].hsk_off != mc->mc_read_off) 1108 { 1109 LSQ_DEBUG("smallest hsk offset is %u, need %hu", 1110 hsk_chunks[0].hsk_off, mc->mc_read_off); 1111 MCHIST_APPEND(mc, MCHE_HELLO_HOLE); 1112 return 0; 1113 } 1114 1115 LSQ_DEBUG("# of contiguous stream frames: %u out of %u; offset: %u; " 1116 "total size: %u", n_contig, n_hsk_chunks, hsk_chunks[0].hsk_off, bufsz); 1117 1118 if (bufsz > 16 * 1024) 1119 { 1120 LSQ_INFO("too much contiguous handshake data (%u bytes); max: %u", 1121 bufsz, 16 * 1024); 1122 MCHIST_APPEND(mc, MCHE_HELLO_TOO_MUCH); 1123 return -1; 1124 } 1125 1126 /* From here on, since we need to clean up, we use `rv' and `goto end' 1127 * to handle error conditions and cleanup. 1128 */ 1129 rv = -1; 1130 if (n_contig > 1) 1131 { 1132 buf_in = buf_in_16k = lsquic_mm_get_16k(&mc->mc_enpub->enp_mm); 1133 if (!buf_in) 1134 { 1135 LSQ_WARN("could not allocate in buffer: %s", strerror(errno)); 1136 buf_out = NULL; 1137 goto end; 1138 } 1139 /* Create a single contiguous buffer to pass to lsquic_enc_session_handle_chlo */ 1140 off = 0; 1141 for (n = 0; n < n_contig; ++n) 1142 { 1143 memcpy(buf_in_16k + off, hsk_chunks[n].hsk_data, 1144 hsk_chunks[n].hsk_sz); 1145 off += hsk_chunks[n].hsk_sz; 1146 } 1147 assert(off == bufsz); 1148 } 1149 else 1150 { 1151 buf_in_16k = NULL; 1152 buf_in = hsk_chunks[0].hsk_data; 1153 } 1154 1155 buf_out = lsquic_mm_get_16k(&mc->mc_enpub->enp_mm); 1156 if (!buf_out) 1157 { 1158 LSQ_WARN("could not allocate out buffer: %s", strerror(errno)); 1159 goto end; 1160 } 1161 out_len = 16 * 1024; 1162 1163 /* Allocate enc_session for the server if first time around: */ 1164 if (!mc->mc_conn.cn_enc_session) 1165 { 1166 mc->mc_conn.cn_enc_session = 1167 mc->mc_conn.cn_esf.g->esf_create_server(&mc->mc_conn, 1168 mc->mc_conn.cn_cid, mc->mc_enpub); 1169 if (!mc->mc_conn.cn_enc_session) 1170 { 1171 LSQ_WARN("cannot create new enc session"); 1172 goto end; 1173 } 1174 MCHIST_APPEND(mc, MCHE_NEW_ENC_SESS); 1175 } 1176 1177 t = time(NULL); 1178 he = mc->mc_conn.cn_esf.g->esf_handle_chlo(mc->mc_conn.cn_enc_session, 1179 mc->mc_conn.cn_version, 1180 buf_in, bufsz, t, NP_PEER_SA(&mc->mc_path), 1181 NP_LOCAL_SA(&mc->mc_path), 1182 buf_out, &out_len, nonce_buf, &nonce_set); 1183 1184 if (HS_SHLO == he) 1185 mc->mc_flags |= MC_HAVE_SHLO; 1186 else 1187 mc->mc_flags &= ~MC_HAVE_SHLO; 1188 1189 MCHIST_APPEND(mc, he == DATA_NOT_ENOUGH ? MCHE_HANDLE_NOT_ENOUGH : 1190 he == HS_SHLO ? MCHE_HANDLE_SHLO : 1191 he == HS_1RTT ? MCHE_HANDLE_1RTT : 1192 he == HS_SREJ ? MCHE_HANDLE_SREJ : 1193 he == HS_ERROR ? MCHE_HANDLE_ERROR : 1194 MCHE_HAHDLE_UNKNOWN); 1195 1196 if ((HS_SHLO == he || HS_1RTT == he) && !mc->mc_rtt_stats.srtt) 1197 { 1198 uint32_t irtt; 1199 if (0 == mc->mc_conn.cn_esf.g->esf_get_peer_setting( 1200 mc->mc_conn.cn_enc_session, QTAG_IRTT, &irtt)) 1201 { 1202 /* Do not allow the client to specify unreasonable values: 1203 * smaller than 10ms or larger than 15s. Per reference 1204 * implementation. 1205 */ 1206 if (irtt > 15 * 1000 * 1000) 1207 irtt = 15 * 1000 * 1000; 1208 else if (irtt < 10 * 1000) 1209 irtt = 10 * 1000; 1210 lsquic_rtt_stats_update(&mc->mc_rtt_stats, irtt, 0); 1211 LSQ_DEBUG("Set initial SRTT to %"PRIu32" usec based on client-" 1212 "supplied IRTT value", irtt); 1213 } 1214 } 1215 1216 switch (he) 1217 { 1218 case DATA_NOT_ENOUGH: 1219 LSQ_DEBUG("lsquic_enc_session_handle_chlo needs more data"); 1220 break; 1221 case HS_SHLO: 1222 mc->mc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE; 1223 mc->mc_flags |= MC_PROMOTE; 1224 LSQ_DEBUG("lsquic_enc_session_handle_chlo returned %d, promote", he); 1225 /* Fall through */ 1226 case HS_1RTT: 1227 assert(out_len > 0); 1228 if (mc->mc_conn.cn_version < LSQVER_046 1229 && !mc->mc_conn.cn_esf.g->esf_get_peer_option( 1230 mc->mc_conn.cn_enc_session, QTAG_NSTP)) 1231 mc->mc_flags |= MC_STOP_WAIT_ON; 1232 if (0 != packetize_response(mc, buf_out, out_len, 1233 nonce_set ? nonce_buf : NULL)) 1234 goto end; 1235 mc->mc_read_off += bufsz; 1236 for (n = 0; n < n_contig; ++n) 1237 hsk_chunks[n].hsk_packet_in->pi_flags &= ~PI_HSK_STREAM; 1238 LSQ_DEBUG("read offset is now %hu", mc->mc_read_off); 1239 break; 1240 default: 1241 LSQ_WARN("unexpected return value from lsquic_enc_session_handle_chlo: %u", he); 1242 /* fallthru */ 1243 case HS_ERROR: 1244#if !LSQUIC_KEEP_ENC_SESS_HISTORY 1245 mc->mc_conn.cn_esf.g->esf_destroy(mc->mc_conn.cn_enc_session); 1246 mc->mc_conn.cn_enc_session = NULL; 1247#endif 1248 mc->mc_flags |= MC_HSK_ERR; 1249 LSQ_INFO("lsquic_enc_session_handle_chlo returned an error (%d)", he); 1250 goto end; 1251 } 1252 1253 rv = 0; 1254 1255 end: 1256 mc->mc_flags &= ~MC_HAVE_SHLO; 1257 if (buf_in_16k) 1258 lsquic_mm_put_16k(&mc->mc_enpub->enp_mm, buf_in_16k); 1259 if (buf_out) 1260 lsquic_mm_put_16k(&mc->mc_enpub->enp_mm, buf_out); 1261 return rv; 1262} 1263 1264 1265struct mini_rechist 1266{ 1267 const struct mini_conn *mc; 1268 mconn_packno_set_t cur_set; 1269 int cur_idx; 1270 struct lsquic_packno_range range; /* We return a pointer to this */ 1271}; 1272 1273 1274static void 1275mini_rechist_init (struct mini_rechist *rechist, const struct mini_conn *mc) 1276{ 1277 rechist->mc = mc; 1278 rechist->cur_set = 0; 1279 rechist->cur_idx = 0; 1280} 1281 1282 1283static lsquic_time_t 1284mini_rechist_largest_recv (void *rechist_ctx) 1285{ 1286 struct mini_rechist *rechist = rechist_ctx; 1287 const struct mini_conn *mc = rechist->mc; 1288 lsquic_time_t delta = mc->mc_largest_recv[0] 1289 + (mc->mc_largest_recv[1] << 8) 1290 + (mc->mc_largest_recv[2] << 16); 1291 LSQ_DEBUG("%s: largest received: %"PRIu64" usec since creation", 1292 __func__, delta); 1293 return mc->mc_created + delta; 1294} 1295 1296 1297static const struct lsquic_packno_range * 1298mini_rechist_next (void *rechist_ctx) 1299{ 1300 struct mini_rechist *rechist = rechist_ctx; 1301 const struct mini_conn *mc = rechist->mc; 1302 mconn_packno_set_t packnos; 1303 int i; 1304 1305 packnos = rechist->cur_set; 1306 if (0 == packnos) 1307 return NULL; 1308 1309 /* There may be a faster way to do this, but for now, we just want 1310 * correctness. 1311 */ 1312 for (i = rechist->cur_idx; i >= 0; --i) 1313 if (packnos & (1ULL << i)) 1314 { 1315 rechist->range.low = i + 1; 1316 rechist->range.high = i + 1; 1317 break; 1318 } 1319 assert(i >= 0); /* We must have hit at least one bit */ 1320 --i; 1321 for ( ; i >= 0 && (packnos & (1ULL << i)); --i) 1322 rechist->range.low = i + 1; 1323 if (i >= 0) 1324 { 1325 rechist->cur_set = packnos & ((1ULL << i) - 1); 1326 rechist->cur_idx = i; 1327 } 1328 else 1329 rechist->cur_set = 0; 1330 LSQ_DEBUG("%s: return [%"PRIu64", %"PRIu64"]", __func__, 1331 rechist->range.low, rechist->range.high); 1332 return &rechist->range; 1333} 1334 1335 1336static const struct lsquic_packno_range * 1337mini_rechist_first (void *rechist_ctx) 1338{ 1339 struct mini_rechist *rechist = rechist_ctx; 1340 rechist->cur_set = rechist->mc->mc_received_packnos; 1341 rechist->cur_idx = highest_bit_set(rechist->cur_set); 1342 return mini_rechist_next(rechist_ctx); 1343} 1344 1345 1346static lsquic_packno_t 1347least_unacked (const struct mini_conn *mc) 1348{ 1349 mconn_packno_set_t unacked; 1350 lsquic_packno_t packno; 1351 unacked = mc->mc_sent_packnos & ~mc->mc_acked_packnos; 1352 if (unacked) 1353 packno = lowest_bit_set(unacked) + 1; 1354 else 1355 packno = highest_bit_set(mc->mc_sent_packnos) + 2; 1356 LSQ_DEBUG("%s: least unacked: %"PRIu64, __func__, packno); 1357 return packno; 1358} 1359 1360 1361static int 1362generate_ack_and_stop_waiting (struct mini_conn *mc, lsquic_time_t now) 1363{ 1364 lsquic_packet_out_t *packet_out; 1365 struct mini_rechist rechist; 1366 int len, not_used_has_missing; 1367 lsquic_packno_t lunack; 1368 1369 /* Chrome's quic_server places ACK and STOP_WAITING frames into a separate 1370 * packet. 1371 */ 1372 packet_out = allocate_packet_out(mc, NULL); 1373 if (!packet_out) 1374 return -1; 1375 1376 /* Generate ACK frame */ 1377 mini_rechist_init(&rechist, mc); 1378 len = mc->mc_conn.cn_pf->pf_gen_ack_frame(packet_out->po_data + packet_out->po_data_sz, 1379 lsquic_packet_out_avail(packet_out), mini_rechist_first, 1380 mini_rechist_next, mini_rechist_largest_recv, &rechist, 1381 now, ¬_used_has_missing, &packet_out->po_ack2ed, NULL); 1382 if (len < 0) 1383 { 1384 LSQ_WARN("could not generate ACK frame"); 1385 return -1; 1386 } 1387 EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 1388 packet_out->po_data + packet_out->po_data_sz, len); 1389 packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK; 1390 packet_out->po_data_sz += len; 1391 packet_out->po_regen_sz += len; 1392 LSQ_DEBUG("wrote ACK frame of size %d", len); 1393 1394 /* Generate STOP_WAITING frame */ 1395 if ((mc->mc_flags & MC_STOP_WAIT_ON) && mc->mc_sent_packnos) 1396 { 1397 lunack = least_unacked(mc); 1398 len = mc->mc_conn.cn_pf->pf_gen_stop_waiting_frame(packet_out->po_data + 1399 packet_out->po_data_sz, 1400 lsquic_packet_out_avail(packet_out), packet_out->po_packno, 1401 lsquic_packet_out_packno_bits(packet_out), lunack); 1402 if (len < 0) 1403 { 1404 LSQ_WARN("could not generate STOP_WAITING frame"); 1405 return -1; 1406 } 1407 packet_out->po_data_sz += len; 1408 packet_out->po_regen_sz += len; 1409 packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING; 1410 LSQ_DEBUG("wrote STOP_WAITING frame of size %d", len); 1411 EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, lunack); 1412 } 1413 else if (mc->mc_flags & MC_STOP_WAIT_ON) 1414 LSQ_DEBUG("nothing sent: no need to generate STOP_WAITING frame"); 1415 1416 mc->mc_flags |= MC_UNSENT_ACK; 1417 return 0; 1418} 1419 1420 1421static int 1422calc_retx_timeout (const struct mini_conn *mc) 1423{ 1424 lsquic_time_t to; 1425 to = lsquic_rtt_stats_get_srtt(&mc->mc_rtt_stats); 1426 if (to) 1427 { 1428 to += to / 2; 1429 if (to < 10000) 1430 to = 10000; 1431 } 1432 else 1433 to = 300000; 1434 return to << mc->mc_hsk_count; 1435} 1436 1437 1438static void 1439return_enc_data (struct mini_conn *mc, struct lsquic_packet_out *packet_out) 1440{ 1441 mc->mc_enpub->enp_pmi->pmi_return(mc->mc_enpub->enp_pmi_ctx, 1442 mc->mc_path.np_peer_ctx, packet_out->po_enc_data, 1443 lsquic_packet_out_ipv6(packet_out)); 1444 packet_out->po_flags &= ~PO_ENCRYPTED; 1445 packet_out->po_enc_data = NULL; 1446} 1447 1448 1449static int 1450repackage_packet (struct mini_conn *mc, lsquic_packet_out_t *packet_out) 1451{ 1452 const lsquic_packno_t oldno = packet_out->po_packno; 1453 const lsquic_packno_t packno = next_packno(mc); 1454 if (packno > MINICONN_MAX_PACKETS) 1455 return -1; 1456 1457 LSQ_DEBUG("Packet %"PRIu64" repackaged for resending as packet %"PRIu64, 1458 oldno, packno); 1459 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "packet %"PRIu64" repackaged for " 1460 "resending as packet %"PRIu64, oldno, packno); 1461 packet_out->po_packno = packno; 1462 packet_out->po_flags &= ~PO_SENT; 1463 if (packet_out->po_flags & PO_ENCRYPTED) 1464 return_enc_data(mc, packet_out); 1465 TAILQ_INSERT_TAIL(&mc->mc_packets_out, packet_out, po_next); 1466 return 0; 1467} 1468 1469 1470static int 1471handle_losses_and_have_unsent (struct mini_conn *mc, lsquic_time_t now) 1472{ 1473 TAILQ_HEAD(, lsquic_packet_out) lost_packets = 1474 TAILQ_HEAD_INITIALIZER(lost_packets); 1475 lsquic_packet_out_t *packet_out, *next; 1476 lsquic_time_t retx_to = 0; 1477 unsigned n_to_send = 0; 1478 1479 for (packet_out = TAILQ_FIRST(&mc->mc_packets_out); packet_out; 1480 packet_out = next) 1481 { 1482 next = TAILQ_NEXT(packet_out, po_next); 1483 if (packet_out->po_flags & PO_SENT) 1484 { 1485 if (0 == retx_to) 1486 retx_to = calc_retx_timeout(mc); 1487 if (packet_out->po_sent + retx_to < now) 1488 { 1489 LSQ_DEBUG("packet %"PRIu64" has been lost (rto: %"PRIu64")", 1490 packet_out->po_packno, retx_to); 1491 TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next); 1492 TAILQ_INSERT_TAIL(&lost_packets, packet_out, po_next); 1493 mc->mc_lost_packnos |= MCONN_PACKET_MASK(packet_out->po_packno); 1494 MCHIST_APPEND(mc, MCHE_PACKET_LOST); 1495 } 1496 } 1497 else 1498 ++n_to_send; 1499 } 1500 1501 mc->mc_hsk_count += !TAILQ_EMPTY(&lost_packets); 1502 1503 while ((packet_out = TAILQ_FIRST(&lost_packets))) 1504 { 1505 TAILQ_REMOVE(&lost_packets, packet_out, po_next); 1506 if ((packet_out->po_frame_types & GQUIC_FRAME_RETRANSMITTABLE_MASK) 1507 && 0 == repackage_packet(mc, packet_out)) 1508 ++n_to_send; 1509 else 1510 mini_destroy_packet(mc, packet_out); 1511 } 1512 1513 return n_to_send > 0; 1514} 1515 1516 1517static int 1518warning_is_warranted (const struct mini_conn *mc) 1519{ 1520 return (mc->mc_flags & (MC_HSK_ERR|MC_OO_PACKNOS)) 1521 || 0x1C /* QUIC_HANDSHAKE_FAILED */ == mc->mc_error_code 1522 || 0x1D /* QUIC_CRYPTO_TAGS_OUT_OF_ORDER */ == mc->mc_error_code 1523 || 0x1E /* QUIC_CRYPTO_TOO_MANY_ENTRIES */ == mc->mc_error_code 1524 || 0x1F /* QUIC_CRYPTO_INVALID_VALUE_LENGTH */ == mc->mc_error_code 1525 || 0x21 /* QUIC_INVALID_CRYPTO_MESSAGE_TYPE */ == mc->mc_error_code 1526 || 0x22 /* QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER */ == mc->mc_error_code 1527 || 0x23 /* QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND */ == mc->mc_error_code 1528 || 0x24 /* QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP */ == mc->mc_error_code 1529 || 0x29 /* QUIC_CRYPTO_TOO_MANY_REJECTS */ == mc->mc_error_code 1530 || 0x2A /* QUIC_PROOF_INVALID */ == mc->mc_error_code 1531 || 0x2B /* QUIC_CRYPTO_DUPLICATE_TAG */ == mc->mc_error_code 1532 || 0x2C /* QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT */ == mc->mc_error_code 1533 || 0x2D /* QUIC_CRYPTO_SERVER_CONFIG_EXPIRED */ == mc->mc_error_code 1534 || 0x35 /* QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED */ == mc->mc_error_code 1535 ; 1536} 1537 1538 1539#if LSQUIC_KEEP_ENC_SESS_HISTORY 1540static void 1541maybe_log_enc_sess_history (const struct mini_conn *mc) 1542{ 1543 char eshist[ESHIST_STR_SIZE]; 1544 enum lsq_log_level log_level; 1545 const char *ua; 1546 1547 if (warning_is_warranted(mc)) 1548 log_level = LSQ_LOG_WARN; 1549 else 1550 log_level = LSQ_LOG_DEBUG; 1551 1552 if (mc->mc_conn.cn_enc_session) 1553 { 1554 mc->mc_conn.cn_esf.g->esf_get_hist(mc->mc_conn.cn_enc_session, eshist); 1555 ua = mc->mc_conn.cn_esf.g->esf_get_ua(mc->mc_conn.cn_enc_session); 1556 LSQ_LOG1(log_level, "enc hist %s; User-Agent: %s", eshist, 1557 ua ? ua : "<not set>"); 1558 } 1559 else 1560 LSQ_LOG1(log_level, "enc session gone: no history to log"); 1561} 1562 1563 1564#endif 1565 1566 1567 1568 1569static int 1570have_packets_to_send (struct mini_conn *mc, lsquic_time_t now) 1571{ 1572 return handle_losses_and_have_unsent(mc, now); 1573} 1574 1575 1576static enum tick_st 1577mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now) 1578{ 1579 struct mini_conn *mc = (struct mini_conn *) lconn; 1580 enum tick_st tick; 1581 1582 ++mc->mc_n_ticks; 1583 1584 if (mc->mc_created + mc->mc_enpub->enp_settings.es_handshake_to < now) 1585 { 1586 LSQ_DEBUG("connection expired: closing"); 1587 tick = TICK_CLOSE; 1588 goto end; 1589 } 1590 1591 if (mc->mc_flags & MC_ERROR) 1592 { 1593 tick = TICK_CLOSE; 1594 goto end; 1595 } 1596 1597 1598 if ((mc->mc_flags & (MC_UNSENT_ACK|MC_GEN_ACK)) == MC_GEN_ACK) 1599 { 1600 if (0 != generate_ack_and_stop_waiting(mc, now)) 1601 { 1602 mc->mc_flags |= MC_ERROR; 1603 tick = TICK_CLOSE; 1604 goto end; 1605 } 1606 else 1607 mc->mc_flags &= ~MC_GEN_ACK; 1608 } 1609 1610 if (have_packets_to_send(mc, now)) 1611 tick = TICK_SEND; 1612 else 1613 tick = TICK_QUIET; 1614 1615 if (mc->mc_flags & MC_PROMOTE) 1616 tick |= TICK_PROMOTE; 1617 1618 end: 1619#if LSQUIC_KEEP_ENC_SESS_HISTORY 1620 if (tick & (TICK_CLOSE|TICK_PROMOTE)) 1621 maybe_log_enc_sess_history(mc); 1622#endif 1623 1624 return tick; 1625} 1626 1627 1628static void 1629process_packet (struct mini_conn *mc, struct lsquic_packet_in *packet_in) 1630{ 1631 switch (process_regular_packet(mc, packet_in)) 1632 { 1633 case PRP_KEEP: 1634 assert(packet_in->pi_flags & PI_OWN_DATA); 1635 lsquic_packet_in_upref(packet_in); 1636 TAILQ_INSERT_TAIL(&mc->mc_packets_in, packet_in, pi_next); 1637 if (mc->mc_flags & MC_HAVE_NEW_HSK) 1638 { 1639 if (0 != continue_handshake(mc)) 1640 mc->mc_flags |= MC_ERROR; 1641 mc->mc_flags &= ~MC_HAVE_NEW_HSK; 1642 } 1643 break; 1644 case PRP_DEFER: 1645 assert(packet_in->pi_flags & PI_OWN_DATA); 1646 lsquic_packet_in_upref(packet_in); 1647 if (mc->mc_n_deferred < MINI_CONN_MAX_DEFERRED) 1648 { 1649 TAILQ_INSERT_TAIL(&mc->mc_deferred, packet_in, pi_next); 1650 ++mc->mc_n_deferred; 1651 } 1652 else 1653 LSQ_DEBUG("won't defer more than %u packets: drop", 1654 MINI_CONN_MAX_DEFERRED); 1655 break; 1656 case PRP_ERROR: 1657 mc->mc_flags |= MC_ERROR; 1658 break; 1659 case PRP_DROP: 1660 break; 1661 } 1662} 1663 1664 1665/* Keep deferred list ordered by packet number, so that we can process all 1666 * of them in a single pass. 1667 */ 1668static void 1669insert_into_deferred (struct mini_conn *mc, lsquic_packet_in_t *new_packet) 1670{ 1671 lsquic_packet_in_t *packet_in; 1672 1673 lsquic_packet_in_upref(new_packet); 1674 1675 TAILQ_FOREACH(packet_in, &mc->mc_deferred, pi_next) 1676 if (packet_in->pi_packno > new_packet->pi_packno) 1677 break; 1678 1679 if (packet_in) 1680 TAILQ_INSERT_BEFORE(packet_in, new_packet, pi_next); 1681 else 1682 TAILQ_INSERT_TAIL(&mc->mc_deferred, new_packet, pi_next); 1683 ++mc->mc_n_deferred; 1684} 1685 1686 1687static void 1688process_deferred_packets (struct mini_conn *mc) 1689{ 1690 lsquic_packet_in_t *last, *packet_in; 1691 int reached_last; 1692 1693 last = TAILQ_LAST(&mc->mc_deferred, head_packet_in); 1694 do 1695 { 1696 packet_in = TAILQ_FIRST(&mc->mc_deferred); 1697 TAILQ_REMOVE(&mc->mc_deferred, packet_in, pi_next); 1698 --mc->mc_n_deferred; 1699 process_packet(mc, packet_in); 1700 reached_last = packet_in == last; 1701 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1702 } 1703 while (!reached_last); 1704} 1705 1706 1707#if LSQUIC_RECORD_INORD_HIST 1708/* FIXME This does not work for Q050, where 0 is a valid packet number. */ 1709/* Packet number is encoded as a sequence of 1-bits and stored in mc_inord_hist 1710 * separated by 0 bits. For example, sequence of packet numbers 3, 2, 1 would 1711 * be encoded as (starting with LSB) 1110110100000000... This is not the most 1712 * space-efficient scheme, but it is simple to implement and should suffice for 1713 * our purposes. 1714 */ 1715static void 1716record_inord_packno (struct mini_conn *mc, lsquic_packno_t packno) 1717{ 1718 int n_avail; 1719 lsquic_packno_t mask; 1720 1721 for ( ; mc->mc_inord_idx < sizeof(mc->mc_inord_hist) / 1722 sizeof(mc->mc_inord_hist[0]); ++mc->mc_inord_idx) 1723 { 1724 if (mc->mc_inord_hist[ mc->mc_inord_idx ]) 1725 n_avail = __builtin_clzll(mc->mc_inord_hist[ mc->mc_inord_idx ]) - 1; 1726 else 1727 n_avail = sizeof(mc->mc_inord_hist[ mc->mc_inord_idx ]) * 8; 1728 if (n_avail >= (int) packno) 1729 { 1730 mask = (1ULL << (int) packno) - 1; 1731 mask <<= sizeof(mc->mc_inord_hist[ mc->mc_inord_idx ]) * 8 - n_avail; 1732 mc->mc_inord_hist[ mc->mc_inord_idx ] |= mask; 1733 return; /* Success */ 1734 } 1735 } 1736} 1737 1738 1739#if __GNUC__ 1740# define ctz __builtin_ctzll 1741#else 1742static unsigned 1743ctz (unsigned long long x) 1744{ 1745 unsigned n = 0; 1746 if (0 == (x & ((1ULL << 32) - 1))) { n += 32; x >>= 32; } 1747 if (0 == (x & ((1ULL << 16) - 1))) { n += 16; x >>= 16; } 1748 if (0 == (x & ((1ULL << 8) - 1))) { n += 8; x >>= 8; } 1749 if (0 == (x & ((1ULL << 4) - 1))) { n += 4; x >>= 4; } 1750 if (0 == (x & ((1ULL << 2) - 1))) { n += 2; x >>= 2; } 1751 if (0 == (x & ((1ULL << 1) - 1))) { n += 1; x >>= 1; } 1752 return n; 1753} 1754 1755 1756#endif 1757 1758 1759static void 1760inord_to_str (const struct mini_conn *mc, char *buf, size_t bufsz) 1761{ 1762 unsigned long long hist; 1763 size_t off; 1764 ssize_t nw; 1765 unsigned n; 1766 int n_trail; 1767 1768 off = 0; 1769 for (n = 0; n < sizeof(mc->mc_inord_hist) / 1770 sizeof(mc->mc_inord_hist[0]); ++n) 1771 { 1772 hist = mc->mc_inord_hist[n]; 1773 while (hist) 1774 { 1775 n_trail = ctz(~hist); 1776 nw = snprintf(buf + off, bufsz - off, 1777 /* No spaces are included on purpose: this makes it a single 1778 * field and thus easy to process log using standard command- 1779 * line tools, such as sork -k, for example. 1780 */ 1781 (off ? ",%d" : "%d"), n_trail); 1782 if ((size_t) nw > bufsz - off || nw < 0) 1783 break; 1784 off += nw; 1785 hist >>= n_trail + 1; 1786 } 1787 } 1788 buf[ bufsz - 1 ] = '\0'; /* CYA */ 1789} 1790 1791 1792#endif 1793 1794 1795static void 1796mini_conn_ci_packet_in (struct lsquic_conn *lconn, 1797 struct lsquic_packet_in *packet_in) 1798{ 1799 struct mini_conn *mc = (struct mini_conn *) lconn; 1800 1801#if LSQUIC_RECORD_INORD_HIST 1802 record_inord_packno(mc, packet_in->pi_packno); 1803#endif 1804#if 0 1805 /* A convenient way to test lsquic_is_valid_hs_packet(): */ 1806 if (!(mc->mc_sent_packnos)) 1807 assert(lsquic_is_valid_hs_packet(NULL, packet_in->pi_data, 1808 packet_in->pi_data_sz)); 1809#endif 1810 1811 if (mc->mc_flags & MC_ERROR) 1812 { 1813 LSQ_DEBUG("error state: ignore packet %"PRIu64, packet_in->pi_packno); 1814 return; 1815 } 1816 1817 if (lsquic_packet_in_is_gquic_prst(packet_in)) 1818 { 1819 LSQ_INFO("received reset packet"); 1820 mc->mc_flags |= MC_ERROR; 1821 MCHIST_APPEND(mc, MCHE_PRST_IN); 1822 return; 1823 } 1824 1825 LSQ_DEBUG("packet in: %"PRIu64, packet_in->pi_packno); 1826 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 1827 1828 1829 /* Check receive history */ 1830 if (0 == packet_in->pi_packno) 1831 { 1832 LSQ_DEBUG("invalid packet number 0"); 1833 mc->mc_flags |= MC_ERROR; 1834 MCHIST_APPEND(mc, MCHE_PACKET0_IN); 1835 return; 1836 } 1837 if (packet_in->pi_packno > MINICONN_MAX_PACKETS) 1838 { 1839 LSQ_DEBUG("packet number %"PRIu64" is too large (max %zd)", 1840 packet_in->pi_packno, MINICONN_MAX_PACKETS); 1841 mc->mc_flags |= MC_ERROR; 1842 MCHIST_APPEND(mc, MCHE_PACKET2LARGE_IN); 1843 return; 1844 } 1845 if (MCONN_PACKET_MASK(packet_in->pi_packno) & mc->mc_received_packnos) 1846 { 1847 LSQ_DEBUG("duplicate packet %"PRIu64", ignoring", packet_in->pi_packno); 1848 MCHIST_APPEND(mc, MCHE_PACKET_DUP_IN); 1849 return; 1850 } 1851 1852 if (TAILQ_EMPTY(&mc->mc_deferred)) 1853 process_packet(mc, packet_in); 1854 else if (mc->mc_n_deferred < MINI_CONN_MAX_DEFERRED) 1855 { 1856 insert_into_deferred(mc, packet_in); 1857 process_deferred_packets(mc); 1858 } 1859 else 1860 LSQ_DEBUG("won't defer more than %u packets: drop", 1861 MINI_CONN_MAX_DEFERRED); 1862} 1863 1864 1865/* Q050 is different is that packet numbers are not known until after the 1866 * packet is decrypted, so we have to follow different logic here. 1867 */ 1868static void 1869mini_conn_ci_Q050_packet_in (struct lsquic_conn *lconn, 1870 struct lsquic_packet_in *packet_in) 1871{ 1872 struct mini_conn *mc = (struct mini_conn *) lconn; 1873 enum proc_rp prp; 1874 1875 if (mc->mc_flags & MC_ERROR) 1876 { 1877 LSQ_DEBUG("error state: ignore packet"); 1878 return; 1879 } 1880 1881 1882 if (!mc->mc_conn.cn_enc_session) 1883 { 1884 mc->mc_conn.cn_enc_session = 1885 mc->mc_conn.cn_esf.g->esf_create_server(&mc->mc_conn, 1886 mc->mc_conn.cn_cid, mc->mc_enpub); 1887 if (!mc->mc_conn.cn_enc_session) 1888 { 1889 LSQ_WARN("cannot create new enc session"); 1890 mc->mc_flags |= MC_ERROR; 1891 return; 1892 } 1893 MCHIST_APPEND(mc, MCHE_NEW_ENC_SESS); 1894 } 1895 1896 assert(!(packet_in->pi_flags & PI_DECRYPTED)); 1897 prp = conn_decrypt_packet_or(mc, packet_in); 1898 switch (prp) 1899 { 1900 case PRP_KEEP: 1901 break; 1902 case PRP_DROP: 1903 return; 1904 case PRP_ERROR: 1905 mc->mc_flags |= MC_ERROR; 1906 return; 1907 default: 1908 if (mc->mc_n_deferred >= MINI_CONN_MAX_DEFERRED) 1909 { 1910 LSQ_DEBUG("won't defer more than %u packets: drop", 1911 MINI_CONN_MAX_DEFERRED); 1912 return; 1913 } 1914 assert(prp == PRP_DEFER); 1915 assert(packet_in->pi_flags & PI_OWN_DATA); 1916 lsquic_packet_in_upref(packet_in); 1917 TAILQ_INSERT_TAIL(&mc->mc_deferred, packet_in, pi_next); 1918 ++mc->mc_n_deferred; 1919 return; 1920 } 1921 1922 assert(prp == PRP_KEEP); 1923 process_packet(mc, packet_in); 1924} 1925 1926 1927static struct lsquic_packet_out * 1928mini_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, 1929 const struct to_coal *to_coal_UNUSED) 1930{ 1931 struct mini_conn *mc = (struct mini_conn *) lconn; 1932 lsquic_packet_out_t *packet_out; 1933 1934 assert(NULL == to_coal_UNUSED); 1935 TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) 1936 { 1937 if (packet_out->po_flags & PO_SENT) 1938 continue; 1939 packet_out->po_flags |= PO_SENT; 1940 LSQ_DEBUG("packet_to_send: %"PRIu64, packet_out->po_packno); 1941 return packet_out; 1942 } 1943 return NULL; 1944} 1945 1946 1947static void 1948mini_conn_ci_packet_sent (struct lsquic_conn *lconn, 1949 struct lsquic_packet_out *packet_out) 1950{ 1951 struct mini_conn *mc = (struct mini_conn *) lconn; 1952 mc->mc_sent_packnos |= MCONN_PACKET_MASK(packet_out->po_packno); 1953 if (packet_out->po_frame_types & (1 << QUIC_FRAME_ACK)) 1954 { 1955 assert(mc->mc_flags & MC_UNSENT_ACK); 1956 mc->mc_flags &= ~MC_UNSENT_ACK; 1957 } 1958 LSQ_DEBUG("%s: packet %"PRIu64" sent", __func__, packet_out->po_packno); 1959 MCHIST_APPEND(mc, MCHE_PACKET_SENT); 1960} 1961 1962 1963static void 1964mini_conn_ci_packet_not_sent (struct lsquic_conn *lconn, 1965 struct lsquic_packet_out *packet_out) 1966{ 1967 struct mini_conn *mc = (struct mini_conn *) lconn; 1968 packet_out->po_flags &= ~PO_SENT; 1969 LSQ_DEBUG("%s: packet %"PRIu64" not sent", __func__, packet_out->po_packno); 1970 MCHIST_APPEND(mc, MCHE_PACKET_DELAYED); 1971} 1972 1973 1974static void 1975mini_conn_ci_destroy (struct lsquic_conn *lconn) 1976{ 1977 assert(!(lconn->cn_flags & LSCONN_HASHED)); 1978 struct mini_conn *mc = (struct mini_conn *) lconn; 1979 lsquic_packet_in_t *packet_in; 1980 mconn_packno_set_t still_deferred = 0, in_flight; 1981 enum lsq_log_level log_level; 1982#if LSQUIC_RECORD_INORD_HIST 1983 char inord_str[0x100]; 1984#endif 1985 while ((packet_in = TAILQ_FIRST(&mc->mc_packets_in))) 1986 { 1987 TAILQ_REMOVE(&mc->mc_packets_in, packet_in, pi_next); 1988 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1989 } 1990 while ((packet_in = TAILQ_FIRST(&mc->mc_deferred))) 1991 { 1992 TAILQ_REMOVE(&mc->mc_deferred, packet_in, pi_next); 1993 --mc->mc_n_deferred; 1994 still_deferred |= MCONN_PACKET_MASK(packet_in->pi_packno); 1995 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1996 } 1997 if (TAILQ_EMPTY(&mc->mc_packets_out)) 1998 in_flight = ~0ull; /* Indicates that packets were dropped before */ 1999 else 2000 in_flight = drop_packets_out(mc); 2001 if (mc->mc_conn.cn_enc_session) 2002 mc->mc_conn.cn_esf.g->esf_destroy(mc->mc_conn.cn_enc_session); 2003 log_level = warning_is_warranted(mc) ? LSQ_LOG_WARN : LSQ_LOG_DEBUG; 2004#if LSQUIC_RECORD_INORD_HIST 2005 if (LSQ_LOG_ENABLED(log_level)) 2006 inord_to_str(mc, inord_str, sizeof(inord_str)); 2007#endif 2008#if LSQUIC_KEEP_MINICONN_HISTORY 2009 const unsigned hist_idx = MCHIST_MASK & mc->mc_hist_idx; 2010 if (MCHE_EMPTY == mc->mc_hist_buf[ hist_idx ]) 2011 LSQ_LOG(log_level, "destroyed. Diagnostics: conn flags: 0x%X, " 2012 "mc flags: 0x%X, " 2013#if LSQUIC_RECORD_INORD_HIST 2014 "incoming-history (trunc: %d) %s, " 2015#endif 2016 "received: %"PRIX64", sent: %"PRIX64", lost: %"PRIX64", " 2017 "deferred: %"PRIX64", still-deferred: %"PRIX64", " 2018 "dropped: %"PRIX64", in-flight: %"PRIX64", acked: %"PRIX64", " 2019 "error_code: 0x%X, ticks: %hu, pack size: %hu, " 2020 "lifetime: %"PRIu64" usec, version: %s, " 2021 "mc hist: %.*s", mc->mc_conn.cn_flags, 2022 mc->mc_flags, 2023#if LSQUIC_RECORD_INORD_HIST 2024 mc->mc_inord_idx >= sizeof(mc->mc_inord_hist) / 2025 sizeof(mc->mc_inord_hist[0]), inord_str, 2026#endif 2027 mc->mc_received_packnos, mc->mc_sent_packnos, mc->mc_lost_packnos, 2028 mc->mc_deferred_packnos, still_deferred, 2029 mc->mc_dropped_packnos, in_flight, mc->mc_acked_packnos, 2030 mc->mc_error_code, mc->mc_n_ticks, mc->mc_path.np_pack_size, 2031 lsquic_time_now() - mc->mc_created, 2032 lsquic_ver2str[mc->mc_conn.cn_version], 2033 (int) hist_idx, mc->mc_hist_buf); 2034 else 2035 LSQ_LOG(log_level, "destroyed. Diagnostics: conn flags: 0x%X, " 2036 "mc flags: 0x%X, " 2037#if LSQUIC_RECORD_INORD_HIST 2038 "incoming-history (trunc: %d) %s, " 2039#endif 2040 "received: %"PRIX64", sent: %"PRIX64", lost: %"PRIX64", " 2041 "deferred: %"PRIX64", still-deferred: %"PRIX64", " 2042 "dropped: %"PRIX64", in-flight: %"PRIX64", acked: %"PRIX64", " 2043 "error_code: 0x%X, ticks: %hu, pack size: %hu, " 2044 "lifetime: %"PRIu64" usec, version: %s, " 2045 "mc hist: %.*s%.*s", mc->mc_conn.cn_flags, 2046 mc->mc_flags, 2047#if LSQUIC_RECORD_INORD_HIST 2048 mc->mc_inord_idx >= sizeof(mc->mc_inord_hist) / 2049 sizeof(mc->mc_inord_hist[0]), inord_str, 2050#endif 2051 mc->mc_received_packnos, mc->mc_sent_packnos, mc->mc_lost_packnos, 2052 mc->mc_deferred_packnos, still_deferred, 2053 mc->mc_dropped_packnos, in_flight, mc->mc_acked_packnos, 2054 mc->mc_error_code, mc->mc_n_ticks, mc->mc_path.np_pack_size, 2055 lsquic_time_now() - mc->mc_created, 2056 lsquic_ver2str[mc->mc_conn.cn_version], 2057 (int) (sizeof(mc->mc_hist_buf) - hist_idx), 2058 mc->mc_hist_buf + hist_idx, (int) hist_idx, mc->mc_hist_buf); 2059#else 2060 if (LSQ_LOG_ENABLED(log_level)) 2061 lsquic_logger_log2(log_level, LSQUIC_LOGGER_MODULE, 2062 LSQUIC_LOG_CONN_ID, 2063 "destroyed. Diagnostics: conn flags: 0x%X, " 2064 "mc flags: 0x%X, " 2065#if LSQUIC_RECORD_INORD_HIST 2066 "incoming-history (trunc: %d) %s, " 2067#endif 2068 "received: %"PRIX64", sent: %"PRIX64", lost: %"PRIX64", " 2069 "deferred: %"PRIX64", still-deferred: %"PRIX64", " 2070 "dropped: %"PRIX64", in-flight: %"PRIX64", acked: %"PRIX64", " 2071 "error_code: 0x%X, ticks: %hu, pack size: %hu, " 2072 "lifetime: %"PRIu64" usec", 2073 mc->mc_conn.cn_flags, 2074 mc->mc_flags, 2075#if LSQUIC_RECORD_INORD_HIST 2076 mc->mc_inord_idx >= sizeof(mc->mc_inord_hist) / 2077 sizeof(mc->mc_inord_hist[0]), inord_str, 2078#endif 2079 mc->mc_received_packnos, mc->mc_sent_packnos, mc->mc_lost_packnos, 2080 mc->mc_deferred_packnos, still_deferred, 2081 mc->mc_dropped_packnos, in_flight, mc->mc_acked_packnos, 2082 mc->mc_error_code, mc->mc_n_ticks, mc->mc_path.np_pack_size, 2083 lsquic_time_now() - mc->mc_created); 2084#endif 2085 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "mini connection destroyed"); 2086 lsquic_malo_put(mc); 2087} 2088 2089 2090static struct lsquic_engine * 2091mini_conn_ci_get_engine (struct lsquic_conn *lconn) 2092{ 2093 struct mini_conn *mc = (struct mini_conn *) lconn; 2094 return mc->mc_enpub->enp_engine; 2095} 2096 2097 2098static void 2099mini_conn_ci_hsk_done (struct lsquic_conn *lconn, enum lsquic_hsk_status status) 2100{ 2101 assert(0); 2102} 2103 2104 2105/* A mini connection is only tickable if it has unsent packets. This can 2106 * occur when packet sending is delayed. 2107 * 2108 * Otherwise, a mini connection is not tickable: Either there are incoming 2109 * packets, in which case, the connection is going to be ticked, or there is 2110 * an alarm pending, in which case it will be handled via the attq. 2111 */ 2112static int 2113mini_conn_ci_is_tickable (struct lsquic_conn *lconn) 2114{ 2115 struct mini_conn *const mc = (struct mini_conn *) lconn; 2116 const struct lsquic_packet_out *packet_out; 2117 2118 if (mc->mc_enpub->enp_flags & ENPUB_CAN_SEND) 2119 TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) 2120 if (!(packet_out->po_flags & PO_SENT)) 2121 return 1; 2122 2123 return 0; 2124} 2125 2126 2127static lsquic_time_t 2128mini_conn_ci_next_tick_time (struct lsquic_conn *lconn, unsigned *why) 2129{ 2130 struct mini_conn *mc = (struct mini_conn *) lconn; 2131 lsquic_packet_out_t *packet_out; 2132 lsquic_time_t exp_time, retx_time; 2133 2134 exp_time = mc->mc_created + mc->mc_enpub->enp_settings.es_handshake_to; 2135 2136 TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) 2137 if (packet_out->po_flags & PO_SENT) 2138 { 2139 retx_time = packet_out->po_sent + calc_retx_timeout(mc); 2140 if (retx_time < exp_time) 2141 { 2142 *why = N_AEWS + AL_RETX_HSK; 2143 return retx_time; 2144 } 2145 else 2146 { 2147 *why = AEW_MINI_EXPIRE; 2148 return exp_time; 2149 } 2150 } 2151 2152 *why = AEW_MINI_EXPIRE; 2153 return exp_time; 2154} 2155 2156 2157static void 2158mini_conn_ci_client_call_on_new (struct lsquic_conn *lconn) 2159{ 2160 assert(0); 2161} 2162 2163 2164static void 2165mini_conn_ci_internal_error (struct lsquic_conn *lconn, 2166 const char *format, ...) 2167{ 2168 struct mini_conn *mc = (struct mini_conn *) lconn; 2169 LSQ_INFO("internal error reported"); 2170 mc->mc_flags |= MC_ERROR; 2171} 2172 2173 2174/* This function should not be called, as this is specific to IETF QUIC */ 2175static void 2176mini_conn_ci_abort_error (struct lsquic_conn *lconn, int is_app, 2177 unsigned error_code, const char *fmt, ...) 2178{ 2179 struct mini_conn *mc = (struct mini_conn *) lconn; 2180 assert(0); 2181 LSQ_WARN("(GQUIC) abort error is called unexpectedly"); 2182 mc->mc_flags |= MC_ERROR; 2183} 2184 2185 2186static void 2187mini_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert) 2188{ 2189 assert(0); 2190} 2191 2192 2193static unsigned char 2194mini_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, 2195 const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 2196{ 2197 struct mini_conn *mc = (struct mini_conn *) lconn; 2198 struct lsquic_packet_out *packet_out; 2199 size_t len; 2200 2201 2202 if (NP_IS_IPv6(&mc->mc_path) != (AF_INET6 == peer_sa->sa_family)) 2203 TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) 2204 if ((packet_out->po_flags & (PO_SENT|PO_ENCRYPTED)) == PO_ENCRYPTED) 2205 return_enc_data(mc, packet_out); 2206 2207 len = local_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) 2208 : sizeof(struct sockaddr_in6); 2209 2210 memcpy(mc->mc_path.np_peer_addr, peer_sa, len); 2211 memcpy(mc->mc_path.np_local_addr, local_sa, len); 2212 mc->mc_path.np_peer_ctx = peer_ctx; 2213 return 0; 2214} 2215 2216 2217static struct network_path * 2218mini_conn_ci_get_path (struct lsquic_conn *lconn, const struct sockaddr *sa) 2219{ 2220 struct mini_conn *mc = (struct mini_conn *) lconn; 2221 2222 return &mc->mc_path; 2223} 2224 2225 2226static const struct conn_iface mini_conn_iface_standard = { 2227 .ci_abort_error = mini_conn_ci_abort_error, 2228 .ci_client_call_on_new = mini_conn_ci_client_call_on_new, 2229 .ci_destroy = mini_conn_ci_destroy, 2230 .ci_get_engine = mini_conn_ci_get_engine, 2231 .ci_get_path = mini_conn_ci_get_path, 2232 .ci_hsk_done = mini_conn_ci_hsk_done, 2233 .ci_internal_error = mini_conn_ci_internal_error, 2234 .ci_is_tickable = mini_conn_ci_is_tickable, 2235 .ci_next_packet_to_send = mini_conn_ci_next_packet_to_send, 2236 .ci_next_tick_time = mini_conn_ci_next_tick_time, 2237 .ci_packet_in = mini_conn_ci_packet_in, 2238 .ci_packet_not_sent = mini_conn_ci_packet_not_sent, 2239 .ci_packet_sent = mini_conn_ci_packet_sent, 2240 .ci_record_addrs = mini_conn_ci_record_addrs, 2241 .ci_tick = mini_conn_ci_tick, 2242 .ci_tls_alert = mini_conn_ci_tls_alert, 2243}; 2244 2245 2246static const struct conn_iface mini_conn_iface_standard_Q050 = { 2247 .ci_abort_error = mini_conn_ci_abort_error, 2248 .ci_client_call_on_new = mini_conn_ci_client_call_on_new, 2249 .ci_destroy = mini_conn_ci_destroy, 2250 .ci_get_engine = mini_conn_ci_get_engine, 2251 .ci_get_path = mini_conn_ci_get_path, 2252 .ci_hsk_done = mini_conn_ci_hsk_done, 2253 .ci_internal_error = mini_conn_ci_internal_error, 2254 .ci_is_tickable = mini_conn_ci_is_tickable, 2255 .ci_next_packet_to_send = mini_conn_ci_next_packet_to_send, 2256 .ci_next_tick_time = mini_conn_ci_next_tick_time, 2257 .ci_packet_in = mini_conn_ci_Q050_packet_in, 2258 .ci_packet_not_sent = mini_conn_ci_packet_not_sent, 2259 .ci_packet_sent = mini_conn_ci_packet_sent, 2260 .ci_record_addrs = mini_conn_ci_record_addrs, 2261 .ci_tick = mini_conn_ci_tick, 2262 .ci_tls_alert = mini_conn_ci_tls_alert, 2263}; 2264 2265 2266typedef char largest_recv_holds_at_least_16_seconds[ 2267 ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) / 1000000 2268 >= 16) ? 1 : -1]; 2269 2270typedef char max_lifespan_smaller_than_largest_recv[ 2271 ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) > 2272 MAX_MINI_CONN_LIFESPAN_IN_USEC) ? 1 : -1]; 2273