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