lsquic_mini_conn.c revision 7a8b2ece
1/* Copyright (c) 2017 - 2019 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_in.h" 39#include "lsquic_packet_out.h" 40#include "lsquic_util.h" 41#include "lsquic_str.h" 42#include "lsquic_enc_sess.h" 43#include "lsquic_parse.h" 44#include "lsquic_engine_public.h" 45#include "lsquic_sfcw.h" 46#include "lsquic_varint.h" 47#include "lsquic_hq.h" 48#include "lsquic_varint.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#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 64static const struct conn_iface mini_conn_iface_disable_handshake; 65#endif 66 67#if LSQUIC_KEEP_MINICONN_HISTORY 68 69static void 70mchist_append (struct mini_conn *mc, enum miniconn_history_event mh_event) 71{ 72 enum miniconn_history_event prev_event; 73 mchist_idx_t idx; 74 int plus; 75 76 idx = (mc->mc_hist_idx - 1) & MCHIST_MASK; 77 plus = MCHE_PLUS == mc->mc_hist_buf[ idx ]; 78 idx = (idx - plus) & MCHIST_MASK; 79 prev_event = mc->mc_hist_buf[ idx ]; 80 81 if (!(prev_event == mh_event && plus)) 82 { 83 if (prev_event == mh_event) 84 mh_event = MCHE_PLUS; 85 mc->mc_hist_buf[ MCHIST_MASK & mc->mc_hist_idx++ ] = mh_event; 86 } 87} 88 89 90# define MCHIST_APPEND(mc, event) mchist_append(mc, event) 91#else 92# define MCHIST_APPEND(mc, event) 93#endif 94 95static void 96process_deferred_packets (struct mini_conn *mc); 97 98 99/* If this is not true, highest_bit_set() may be broken */ 100typedef char packno_set_is_unsigned_long[ 101 (sizeof(unsigned long long) == sizeof(mconn_packno_set_t)) - 1]; 102 103static unsigned 104highest_bit_set (unsigned long long sz) 105{ 106#if __GNUC__ 107 unsigned clz = __builtin_clzll(sz); 108 return 63 - clz; 109#else 110 unsigned long y; 111 unsigned n; 112 n = 64; 113 y = sz >> 32; if (y) { n -= 32; sz = y; } 114 y = sz >> 16; if (y) { n -= 16; sz = y; } 115 y = sz >> 8; if (y) { n -= 8; sz = y; } 116 y = sz >> 4; if (y) { n -= 4; sz = y; } 117 y = sz >> 2; if (y) { n -= 2; sz = y; } 118 y = sz >> 1; if (y) return 63 - n + 2; 119 return 63 - n + sz; 120#endif 121} 122 123 124static unsigned 125lowest_bit_set (unsigned v) 126{ 127#if __GNUC__ 128 return __builtin_ctz(v); 129#else 130 unsigned n; 131 n = 0; 132 if (0 == (v & ((1 << 16) - 1))) { n += 16; v >>= 16; } 133 if (0 == (v & ((1 << 8) - 1))) { n += 8; v >>= 8; } 134 if (0 == (v & ((1 << 4) - 1))) { n += 4; v >>= 4; } 135 if (0 == (v & ((1 << 2) - 1))) { n += 2; v >>= 2; } 136 if (0 == (v & ((1 << 1) - 1))) { n += 1; } 137 return n; 138#endif 139} 140 141 142static int 143is_handshake_stream_id (const struct mini_conn *conn, 144 lsquic_stream_id_t stream_id) 145{ 146 return conn->mc_conn.cn_version < LSQVER_050 && stream_id == 1; 147} 148 149 150static void 151mini_destroy_packet (struct mini_conn *mc, struct lsquic_packet_out *packet_out) 152{ 153 lsquic_packet_out_destroy(packet_out, mc->mc_enpub, 154 mc->mc_path.np_peer_ctx); 155} 156 157 158static int 159packet_in_is_ok (const struct lsquic_packet_in *packet_in) 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 if (packet_in->pi_data_sz < 200) /* TODO: 64 packets now */ 168 { /* mini connection is limited to 32 packets, yet it must send out REJ 169 * and SHLO, which are about 4 KB combined. 170 */ 171 LSQ_LOG1(LSQ_LOG_DEBUG, "incoming packet too small: %hu bytes", 172 packet_in->pi_data_sz); 173 return 0; 174 } 175 return 1; 176} 177 178 179lsquic_conn_t * 180mini_conn_new (struct lsquic_engine_public *enp, 181 const struct lsquic_packet_in *packet_in, 182 enum lsquic_version version) 183{ 184 struct mini_conn *mc; 185 const struct conn_iface *conn_iface; 186 187#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 188 if (getenv("LSQUIC_DISABLE_HANDSHAKE")) 189 conn_iface = &mini_conn_iface_disable_handshake; 190 else 191#endif 192 { 193 if (!packet_in_is_ok(packet_in)) 194 return NULL; 195 switch (version) 196 { 197 case LSQVER_050: 198 conn_iface = &mini_conn_iface_standard_Q050; 199 break; 200 default: 201 conn_iface = &mini_conn_iface_standard; 202 break; 203 } 204 } 205 206 mc = lsquic_malo_get(enp->enp_mm.malo.mini_conn); 207 if (!mc) 208 { 209 LSQ_LOG1(LSQ_LOG_WARN, "cannot allocate mini connection: %s", 210 strerror(errno)); 211 return NULL; 212 } 213 214 memset(mc, 0, sizeof(*mc)); 215 TAILQ_INIT(&mc->mc_deferred); 216 TAILQ_INIT(&mc->mc_packets_in); 217 TAILQ_INIT(&mc->mc_packets_out); 218 mc->mc_enpub = enp; 219 mc->mc_created = packet_in->pi_received; 220#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 221 if (conn_iface == &mini_conn_iface_disable_handshake) 222 mc->mc_path.np_pack_size = 1370; 223 else 224#endif 225 mc->mc_path.np_pack_size = packet_in->pi_data_sz; 226 mc->mc_conn.cn_cces = mc->mc_cces; 227 mc->mc_conn.cn_cces_mask = 1; 228 mc->mc_conn.cn_n_cces = sizeof(mc->mc_cces) / sizeof(mc->mc_cces[0]); 229 mc->mc_conn.cn_version = version; 230 mc->mc_conn.cn_pf = select_pf_by_ver(version); 231 mc->mc_conn.cn_esf_c = select_esf_common_by_ver(version); 232 mc->mc_conn.cn_esf.g = select_esf_gquic_by_ver(version); 233 mc->mc_conn.cn_cid = packet_in->pi_conn_id; 234 mc->mc_conn.cn_flags = LSCONN_MINI | LSCONN_SERVER; 235 mc->mc_conn.cn_if = conn_iface; 236 LSQ_DEBUG("created mini connection object"); 237 MCHIST_APPEND(mc, MCHE_CREATED); 238 return &mc->mc_conn; 239} 240 241 242static int 243in_acked_range (const struct ack_info *acki, lsquic_packno_t n) /* This is a copy */ 244{ 245 int in_range = 0; 246 unsigned i; 247 for (i = 0; i < acki->n_ranges; ++i) 248 in_range += acki->ranges[i].high >= n 249 && acki->ranges[i].low <= n; 250 return in_range > 0; 251} 252 253 254static void 255take_rtt_sample (struct mini_conn *mc, const lsquic_packet_out_t *packet_out, 256 lsquic_time_t now, lsquic_time_t lack_delta) 257{ 258 assert(packet_out->po_sent); 259 lsquic_time_t measured_rtt = now - packet_out->po_sent; 260 if (lack_delta < measured_rtt) 261 { 262 lsquic_rtt_stats_update(&mc->mc_rtt_stats, measured_rtt, lack_delta); 263 LSQ_DEBUG("srtt: %"PRIu64" usec, var: %"PRIu64, 264 lsquic_rtt_stats_get_srtt(&mc->mc_rtt_stats), 265 lsquic_rtt_stats_get_rttvar(&mc->mc_rtt_stats)); 266 } 267} 268 269 270static unsigned 271process_ack_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 272 const unsigned char *p, size_t len) 273{ 274 int parsed_len; 275 int n_newly_acked; 276 unsigned n; 277 lsquic_packet_out_t *packet_out, *next; 278 struct ack_info *acki; 279 lsquic_packno_t packno; 280 lsquic_time_t warn_time; 281 char buf[200]; 282 283 acki = mc->mc_enpub->enp_mm.acki; 284 parsed_len = mc->mc_conn.cn_pf->pf_parse_ack_frame(p, len, acki, 0); 285 if (parsed_len < 0) 286 return 0; 287 if (empty_ack_frame(acki)) 288 { 289 LSQ_DEBUG("Ignore empty ACK frame"); 290 return parsed_len; 291 } 292 if (packet_in->pi_packno <= mc->mc_max_ack_packno) 293 { 294 LSQ_DEBUG("Ignore old ack (max %u)", mc->mc_max_ack_packno); 295 return parsed_len; 296 } 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 /* First CHLO message: update maximum packet size */ 553 mc->mc_path.np_pack_size = packet_in->pi_data_sz; 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 handshake stream 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 /* First CHLO message: update maximum packet size */ 595 mc->mc_path.np_pack_size = packet_in->pi_data_sz; 596 } 597 else 598 { 599 LSQ_DEBUG("drop duplicate frame"); 600 MCHIST_APPEND(mc, MCHE_DUP_HSK); 601 } 602 return parsed_len; 603} 604 605 606static unsigned 607process_window_update_frame (struct mini_conn *mc, 608 lsquic_packet_in_t *packet_in, const unsigned char *p, size_t len) 609{ 610 lsquic_stream_id_t stream_id; 611 uint64_t offset; 612 int parsed_len; 613 parsed_len = mc->mc_conn.cn_pf->pf_parse_window_update_frame(p, len, &stream_id, &offset); 614 if (parsed_len < 0) 615 return 0; 616 EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset); 617 if (is_handshake_stream_id(mc, stream_id)) 618 /* This should not happen: why would the client send us WINDOW_UPDATE 619 * on stream 1? 620 */ 621 LSQ_WARN("client sent WINDOW_UPDATE for handshake stream, " 622 "offset %"PRIu64, offset); 623 return parsed_len; 624} 625 626 627typedef unsigned (*process_frame_f)( 628 struct mini_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t); 629 630 631static process_frame_f const process_frames[N_QUIC_FRAMES] = 632{ 633 [QUIC_FRAME_ACK] = process_ack_frame, 634 [QUIC_FRAME_BLOCKED] = process_blocked_frame, 635 [QUIC_FRAME_CONNECTION_CLOSE] = process_connection_close_frame, 636 [QUIC_FRAME_CRYPTO] = process_crypto_frame, 637 [QUIC_FRAME_GOAWAY] = process_goaway_frame, 638 [QUIC_FRAME_INVALID] = process_invalid_frame, 639 [QUIC_FRAME_PADDING] = process_padding_frame, 640 [QUIC_FRAME_PING] = process_ping_frame, 641 [QUIC_FRAME_RST_STREAM] = process_rst_stream_frame, 642 [QUIC_FRAME_STOP_WAITING] = process_stop_waiting_frame, 643 [QUIC_FRAME_STREAM] = process_stream_frame, 644 [QUIC_FRAME_WINDOW_UPDATE] = process_window_update_frame, 645}; 646 647 648static unsigned 649process_packet_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in, 650 const unsigned char *p, size_t len) 651{ 652 enum quic_frame_type type = mc->mc_conn.cn_pf->pf_parse_frame_type(p[0]); 653 packet_in->pi_frame_types |= 1 << type; 654 return process_frames[type](mc, packet_in, p, len); 655} 656 657 658static void 659record_largest_recv (struct mini_conn *mc, lsquic_time_t t) 660{ 661 if (t < mc->mc_created) 662 { 663 LSQ_WARN("largest received predates creation"); 664 return; 665 } 666 t -= mc->mc_created; 667 mc->mc_largest_recv[0] = t; 668 mc->mc_largest_recv[1] = t >> 8; 669 mc->mc_largest_recv[2] = t >> 16; 670 LSQ_DEBUG("recorded largest received timestamp as %"PRIu64" usec since " 671 "creation", t); 672} 673 674 675static enum dec_packin 676conn_decrypt_packet (struct mini_conn *conn, lsquic_packet_in_t *packet_in) 677{ 678#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 679 if (getenv("LSQUIC_DISABLE_HANDSHAKE")) 680 { 681 (void) lsquic_conn_copy_and_release_pi_data(&conn->mc_conn, 682 conn->mc_enpub, packet_in); 683 packet_in->pi_flags |= PI_DECRYPTED; 684 return 0; 685 } 686 else 687#endif 688 return conn->mc_conn.cn_esf_c->esf_decrypt_packet( 689 conn->mc_conn.cn_enc_session, conn->mc_enpub, 690 &conn->mc_conn, packet_in); 691} 692 693 694/* PRP: Process Regular Packet */ 695enum proc_rp { PRP_KEEP, PRP_DEFER, PRP_DROP, PRP_ERROR, }; 696 697 698static enum proc_rp 699conn_decrypt_packet_or (struct mini_conn *mc, 700 struct lsquic_packet_in *packet_in) 701{ 702 if (DECPI_OK == conn_decrypt_packet(mc, packet_in)) 703 { 704 MCHIST_APPEND(mc, MCHE_DECRYPTED); 705 return PRP_KEEP; 706 } 707 else if (mc->mc_conn.cn_esf.g->esf_have_key_gt_one( 708 mc->mc_conn.cn_enc_session)) 709 { 710 LSQ_INFO("could not decrypt packet: drop"); 711 mc->mc_dropped_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 712 MCHIST_APPEND(mc, MCHE_UNDECR_DROP); 713 return PRP_DROP; 714 } 715 else if ((packet_in->pi_flags & PI_OWN_DATA) || 716 0 == lsquic_conn_copy_and_release_pi_data(&mc->mc_conn, 717 mc->mc_enpub, packet_in)) 718 { 719 assert(packet_in->pi_flags & PI_OWN_DATA); 720 LSQ_INFO("could not decrypt packet: defer"); 721 mc->mc_deferred_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 722 MCHIST_APPEND(mc, MCHE_UNDECR_DEFER); 723 return PRP_DEFER; 724 } 725 else 726 { 727 MCHIST_APPEND(mc, MCHE_ENOMEM); 728 return PRP_ERROR; /* Memory allocation must have failed */ 729 } 730} 731 732 733static enum proc_rp 734process_regular_packet (struct mini_conn *mc, lsquic_packet_in_t *packet_in) 735{ 736 const unsigned char *p, *pend; 737 enum proc_rp prp; 738 unsigned len; 739 740 /* Decrypt packet if necessary */ 741 if (0 == (packet_in->pi_flags & PI_DECRYPTED)) 742 { 743 prp = conn_decrypt_packet_or(mc, packet_in); 744 if (prp != PRP_KEEP) 745 return prp; 746 } 747 748 /* Update receive history before processing the packet: if there is an 749 * error, the connection is terminated and recording this packet number 750 * is helpful when it is printed along with other diagnostics in dtor. 751 */ 752 if (0 == mc->mc_received_packnos || 753 packet_in->pi_packno > highest_bit_set(mc->mc_received_packnos) + 1) 754 record_largest_recv(mc, packet_in->pi_received); 755 mc->mc_received_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 756 757 /* Parse and process frames */ 758 p = packet_in->pi_data + packet_in->pi_header_sz; 759 pend = packet_in->pi_data + packet_in->pi_data_sz; 760 while (p < pend) 761 { 762 len = process_packet_frame(mc, packet_in, p, pend - p); 763 if (len > 0) 764 p += len; 765 else 766 { 767 if (mc->mc_conn.cn_pf->pf_parse_frame_type(p[0]) != 768 QUIC_FRAME_CONNECTION_CLOSE) 769 LSQ_WARN("error parsing frame: packno %"PRIu64"; sz: %u; type: " 770 "0x%X", packet_in->pi_packno, packet_in->pi_data_sz, p[0]); 771 MCHIST_APPEND(mc, MCHE_EFRAME); 772 return PRP_ERROR; 773 } 774 } 775 776 mc->mc_flags |= MC_GEN_ACK; 777 778 return PRP_KEEP; 779} 780 781 782struct hsk_chunk 783{ 784 lsquic_packet_in_t *hsk_packet_in; 785 const unsigned char *hsk_data; 786 unsigned hsk_off; 787 unsigned hsk_sz; 788}; 789 790 791static int 792compare_hsk_chunks (const void *ap, const void *bp) 793{ 794 const struct hsk_chunk *a = ap; 795 const struct hsk_chunk *b = bp; 796 return (a->hsk_off > b->hsk_off) - (b->hsk_off > a->hsk_off); 797} 798 799 800struct mini_stream_ctx 801{ 802 const unsigned char *buf; 803 size_t bufsz; 804 size_t off; 805}; 806 807 808static int 809mini_stream_has_data (const struct mini_stream_ctx *ms_ctx) 810{ 811 return ms_ctx->off < ms_ctx->bufsz; 812} 813 814 815static size_t 816mini_stream_read (void *stream, void *buf, size_t len, int *reached_fin) 817{ 818 struct mini_stream_ctx *ms_ctx = stream; 819 size_t avail = ms_ctx->bufsz - ms_ctx->off; 820 if (avail < len) 821 len = avail; 822 memcpy(buf, ms_ctx->buf + ms_ctx->off, len); 823 ms_ctx->off += len; 824 *reached_fin = 0; 825 return len; 826} 827 828 829/* Wrapper to throw out reached_fin */ 830static size_t 831mini_stream_read_for_crypto (void *stream, void *buf, size_t len) 832{ 833 size_t retval; 834 int reached_fin; 835 836 retval = mini_stream_read(stream, buf, len, &reached_fin); 837 return retval; 838} 839 840 841static size_t 842mini_stream_size (void *stream) 843{ 844 struct mini_stream_ctx *ms_ctx = stream; 845 size_t avail = ms_ctx->bufsz - ms_ctx->off; 846 return avail; 847} 848 849 850static int 851mini_stream_fin (void *stream) 852{ /* There is never a FIN on the handshake stream */ 853 return 0; 854} 855 856 857static lsquic_packno_t 858next_packno (struct mini_conn *mc) 859{ 860 if (mc->mc_cur_packno < MINICONN_MAX_PACKETS) 861 { 862 return ++mc->mc_cur_packno; 863 } 864 else 865 { 866 if (!(mc->mc_flags & MC_OO_PACKNOS)) 867 { 868 MCHIST_APPEND(mc, MCHE_OUT_OF_PACKNOS); 869 mc->mc_flags |= MC_OO_PACKNOS; 870 LSQ_DEBUG("ran out of outgoing packet numbers"); 871 } 872 return MINICONN_MAX_PACKETS + 1; 873 } 874} 875 876 877static lsquic_packet_out_t * 878allocate_packet_out (struct mini_conn *mc, const unsigned char *nonce) 879{ 880 lsquic_packet_out_t *packet_out; 881 lsquic_packno_t packno; 882 packno = next_packno(mc); 883 if (packno > MINICONN_MAX_PACKETS) 884 { 885 LSQ_DEBUG("ran out of outgoing packet numbers, won't allocate packet"); 886 return NULL; 887 } 888 packet_out = lsquic_packet_out_new(&mc->mc_enpub->enp_mm, NULL, 1, 889 &mc->mc_conn, GQUIC_PACKNO_LEN_1, NULL, nonce, &mc->mc_path); 890 if (!packet_out) 891 { 892 LSQ_WARN("could not allocate packet: %s", strerror(errno)); 893 return NULL; 894 } 895 packet_out->po_loss_chain = packet_out; 896 packet_out->po_packno = packno; 897 packet_out->po_flags |= PO_MINI; 898 if (mc->mc_flags & MC_HAVE_SHLO) 899 { 900 packet_out->po_flags |= PO_HELLO; 901 packet_out->po_header_type = HETY_0RTT; 902 } 903 if (mc->mc_conn.cn_version >= LSQVER_050) 904 { 905 if (nonce) 906 packet_out->po_header_type = HETY_0RTT; 907 else 908 packet_out->po_header_type = HETY_INITIAL; 909 } 910 lsquic_packet_out_set_pns(packet_out, PNS_APP); 911 TAILQ_INSERT_TAIL(&mc->mc_packets_out, packet_out, po_next); 912 LSQ_DEBUG("allocated packet #%"PRIu64", nonce: %d", packno, !!nonce); 913 MCHIST_APPEND(mc, MCHE_NEW_PACKET_OUT); 914 EV_LOG_PACKET_CREATED(LSQUIC_LOG_CONN_ID, packet_out); 915 return packet_out; 916} 917 918 919static struct lsquic_packet_out * 920to_packet_pre_Q050 (struct mini_conn *mc, struct mini_stream_ctx *ms_ctx, 921 const unsigned char *nonce) 922{ 923 struct lsquic_packet_out *packet_out; 924 size_t cur_off; 925 int len; 926 927 packet_out = allocate_packet_out(mc, nonce); 928 if (!packet_out) 929 return NULL; 930 cur_off = ms_ctx->off; 931 len = mc->mc_conn.cn_pf->pf_gen_stream_frame( 932 packet_out->po_data + packet_out->po_data_sz, 933 lsquic_packet_out_avail(packet_out), 934 1, mc->mc_write_off, mini_stream_fin(ms_ctx), 935 mini_stream_size(ms_ctx), mini_stream_read, ms_ctx); 936 if (len < 0) 937 { 938 LSQ_WARN("cannot generate STREAM frame (avail: %u)", 939 lsquic_packet_out_avail(packet_out)); 940 return NULL; 941 } 942 mc->mc_write_off += ms_ctx->off - cur_off; 943 EV_LOG_GENERATED_STREAM_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 944 packet_out->po_data + packet_out->po_data_sz, len); 945 packet_out->po_data_sz += len; 946 packet_out->po_frame_types |= 1 << QUIC_FRAME_STREAM; 947 if (0 == lsquic_packet_out_avail(packet_out)) 948 packet_out->po_flags |= PO_STREAM_END; 949 950 return packet_out; 951} 952 953 954static struct lsquic_packet_out * 955to_packet_Q050plus (struct mini_conn *mc, struct mini_stream_ctx *ms_ctx, 956 const unsigned char *nonce) 957{ 958 struct lsquic_packet_out *packet_out; 959 size_t cur_off; 960 int len; 961 962 if (nonce && !(mc->mc_flags & MC_WR_OFF_RESET)) 963 { 964 mc->mc_write_off = 0; 965 mc->mc_flags |= MC_WR_OFF_RESET; 966 } 967 968 packet_out = allocate_packet_out(mc, nonce); 969 if (!packet_out) 970 return NULL; 971 cur_off = ms_ctx->off; 972 len = mc->mc_conn.cn_pf->pf_gen_crypto_frame( 973 packet_out->po_data + packet_out->po_data_sz, 974 lsquic_packet_out_avail(packet_out), mc->mc_write_off, 975 mini_stream_size(ms_ctx), mini_stream_read_for_crypto, ms_ctx); 976 if (len < 0) 977 { 978 LSQ_WARN("cannot generate CRYPTO frame (avail: %u)", 979 lsquic_packet_out_avail(packet_out)); 980 return NULL; 981 } 982 mc->mc_write_off += ms_ctx->off - cur_off; 983 EV_LOG_GENERATED_CRYPTO_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 984 packet_out->po_data + packet_out->po_data_sz, len); 985 packet_out->po_data_sz += len; 986 packet_out->po_frame_types |= 1 << QUIC_FRAME_CRYPTO; 987 988 return packet_out; 989} 990 991 992static int 993packetize_response (struct mini_conn *mc, const unsigned char *buf, 994 size_t bufsz, const unsigned char *nonce) 995{ 996 struct mini_stream_ctx ms_ctx; 997 lsquic_packet_out_t *packet_out; 998 struct lsquic_packet_out * (*const to_packet) (struct mini_conn *, 999 struct mini_stream_ctx *, const unsigned char *) 1000 = mc->mc_conn.cn_version < LSQVER_050 1001 ? to_packet_pre_Q050 : to_packet_Q050plus; 1002 1003 LSQ_DEBUG("Packetizing %zd bytes of handshake response", bufsz); 1004 1005 ms_ctx.buf = buf; 1006 ms_ctx.bufsz = bufsz; 1007 ms_ctx.off = 0; 1008 1009 do 1010 { 1011 packet_out = to_packet(mc, &ms_ctx, nonce); 1012 if (!packet_out) 1013 return -1; 1014 } 1015 while (mini_stream_has_data(&ms_ctx)); 1016 1017 /* PAD the last packet with NULs. ACK and STOP_WAITING go into a separate 1018 * packet. 1019 */ 1020 if (lsquic_packet_out_avail(packet_out)) 1021 { 1022 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated PADDING frame %u " 1023 "bytes long", lsquic_packet_out_avail(packet_out)); 1024 memset(packet_out->po_data + packet_out->po_data_sz, 0, 1025 lsquic_packet_out_avail(packet_out)); 1026 packet_out->po_data_sz += lsquic_packet_out_avail(packet_out); 1027 packet_out->po_frame_types |= 1 << QUIC_FRAME_PADDING; 1028 } 1029 1030 return 0; 1031} 1032 1033 1034static int 1035continue_handshake (struct mini_conn *mc) 1036{ 1037 lsquic_packet_in_t *packet_in; 1038 unsigned n_hsk_chunks = 0, n_contig, n, bufsz, off; 1039 int s, rv; 1040 size_t out_len; 1041 enum handshake_error he; 1042 unsigned char *buf_in_16k, *buf_out; 1043 const unsigned char *buf_in; 1044 time_t t; 1045 stream_frame_t frame; 1046 struct hsk_chunk hsk_chunks[MINICONN_MAX_PACKETS], *hsk_chunk; 1047 unsigned char nonce_buf[32]; 1048 int nonce_set = 0; 1049 int (*parse_frame)(const unsigned char *, size_t, struct stream_frame *) 1050 = mc->mc_conn.cn_version < LSQVER_050 1051 ? mc->mc_conn.cn_pf->pf_parse_stream_frame 1052 : mc->mc_conn.cn_pf->pf_parse_crypto_frame; 1053 1054 /* Get handshake stream data from each packet that contains a handshake 1055 * stream frame and place them into `hsk_chunks' array. 1056 */ 1057 TAILQ_FOREACH(packet_in, &mc->mc_packets_in, pi_next) 1058 { 1059 assert(n_hsk_chunks < sizeof(hsk_chunks) / sizeof(hsk_chunks[0])); 1060 if (0 == (packet_in->pi_flags & PI_HSK_STREAM)) 1061 continue; 1062 s = parse_frame(packet_in->pi_data + packet_in->pi_hsk_stream, 1063 packet_in->pi_data_sz - packet_in->pi_hsk_stream, &frame); 1064 if (-1 == s) 1065 { 1066 LSQ_WARN("cannot process hsk stream frame in packet %"PRIu64, 1067 packet_in->pi_packno); 1068 return -1; 1069 } 1070 hsk_chunk = &hsk_chunks[ n_hsk_chunks++ ]; 1071 hsk_chunk->hsk_packet_in = packet_in; 1072 hsk_chunk->hsk_data = frame.data_frame.df_data; 1073 hsk_chunk->hsk_off = frame.data_frame.df_offset; 1074 hsk_chunk->hsk_sz = frame.data_frame.df_size; 1075 } 1076 assert(n_hsk_chunks > 0); 1077 1078 if (n_hsk_chunks > 1) 1079 { 1080 /* Sort handshake stream data */ 1081 qsort(hsk_chunks, n_hsk_chunks, sizeof(hsk_chunks[0]), 1082 compare_hsk_chunks); 1083 /* Figure out how many packets contain handshake stream data in a 1084 * contiguous buffer and how large this data is. 1085 */ 1086 for (n = 1, n_contig = 1, bufsz = hsk_chunks[0].hsk_sz; 1087 n < n_hsk_chunks; ++n) 1088 if (hsk_chunks[n - 1].hsk_off + hsk_chunks[n - 1].hsk_sz == 1089 hsk_chunks[n].hsk_off) 1090 { 1091 ++n_contig; 1092 bufsz += hsk_chunks[n].hsk_sz; 1093 } 1094 else 1095 break; 1096 } 1097 else 1098 { 1099 n_contig = 1; 1100 bufsz = hsk_chunks[0].hsk_sz; 1101 } 1102 1103 /* Handshake handler expects to start reading at a particular offset. 1104 */ 1105 if (hsk_chunks[0].hsk_off != mc->mc_read_off) 1106 { 1107 LSQ_DEBUG("smallest hsk offset is %u, need %hu", 1108 hsk_chunks[0].hsk_off, mc->mc_read_off); 1109 MCHIST_APPEND(mc, MCHE_HELLO_HOLE); 1110 return 0; 1111 } 1112 1113 LSQ_DEBUG("# of contiguous stream frames: %u out of %u; offset: %u; " 1114 "total size: %u", n_contig, n_hsk_chunks, hsk_chunks[0].hsk_off, bufsz); 1115 1116 if (bufsz > 16 * 1024) 1117 { 1118 LSQ_INFO("too much contiguous handshake data (%u bytes); max: %u", 1119 bufsz, 16 * 1024); 1120 MCHIST_APPEND(mc, MCHE_HELLO_TOO_MUCH); 1121 return -1; 1122 } 1123 1124 /* From here on, since we need to clean up, we use `rv' and `goto end' 1125 * to handle error conditions and cleanup. 1126 */ 1127 rv = -1; 1128 if (n_contig > 1) 1129 { 1130 buf_in = buf_in_16k = lsquic_mm_get_16k(&mc->mc_enpub->enp_mm); 1131 if (!buf_in) 1132 { 1133 LSQ_WARN("could not allocate in buffer: %s", strerror(errno)); 1134 buf_out = NULL; 1135 goto end; 1136 } 1137 /* Create a single contiguous buffer to pass to lsquic_enc_session_handle_chlo */ 1138 off = 0; 1139 for (n = 0; n < n_contig; ++n) 1140 { 1141 memcpy(buf_in_16k + off, hsk_chunks[n].hsk_data, 1142 hsk_chunks[n].hsk_sz); 1143 off += hsk_chunks[n].hsk_sz; 1144 } 1145 assert(off == bufsz); 1146 } 1147 else 1148 { 1149 buf_in_16k = NULL; 1150 buf_in = hsk_chunks[0].hsk_data; 1151 } 1152 1153 buf_out = lsquic_mm_get_16k(&mc->mc_enpub->enp_mm); 1154 if (!buf_out) 1155 { 1156 LSQ_WARN("could not allocate out buffer: %s", strerror(errno)); 1157 goto end; 1158 } 1159 out_len = 16 * 1024; 1160 1161 /* Allocate enc_session for the server if first time around: */ 1162 if (!mc->mc_conn.cn_enc_session) 1163 { 1164 mc->mc_conn.cn_enc_session = 1165 mc->mc_conn.cn_esf.g->esf_create_server(&mc->mc_conn, 1166 mc->mc_conn.cn_cid, mc->mc_enpub); 1167 if (!mc->mc_conn.cn_enc_session) 1168 { 1169 LSQ_WARN("cannot create new enc session"); 1170 goto end; 1171 } 1172 MCHIST_APPEND(mc, MCHE_NEW_ENC_SESS); 1173 } 1174 1175 t = time(NULL); 1176 he = mc->mc_conn.cn_esf.g->esf_handle_chlo(mc->mc_conn.cn_enc_session, 1177 mc->mc_conn.cn_version, 1178 buf_in, bufsz, t, NP_PEER_SA(&mc->mc_path), 1179 NP_LOCAL_SA(&mc->mc_path), 1180 buf_out, &out_len, nonce_buf, &nonce_set); 1181 1182 if (HS_SHLO == he) 1183 mc->mc_flags |= MC_HAVE_SHLO; 1184 else 1185 mc->mc_flags &= ~MC_HAVE_SHLO; 1186 1187 MCHIST_APPEND(mc, he == DATA_NOT_ENOUGH ? MCHE_HANDLE_NOT_ENOUGH : 1188 he == HS_SHLO ? MCHE_HANDLE_SHLO : 1189 he == HS_1RTT ? MCHE_HANDLE_1RTT : 1190 he == HS_2RTT ? MCHE_HANDLE_2RTT : 1191 he == HS_ERROR ? MCHE_HANDLE_ERROR : 1192 MCHE_HAHDLE_UNKNOWN); 1193 1194 if ((HS_SHLO == he || HS_1RTT == he) && !mc->mc_rtt_stats.srtt) 1195 { 1196 uint32_t irtt; 1197 if (0 == mc->mc_conn.cn_esf.g->esf_get_peer_setting( 1198 mc->mc_conn.cn_enc_session, QTAG_IRTT, &irtt)) 1199 { 1200 /* Do not allow the client to specify unreasonable values: 1201 * smaller than 10ms or larger than 15s. Per reference 1202 * implementation. 1203 */ 1204 if (irtt > 15 * 1000 * 1000) 1205 irtt = 15 * 1000 * 1000; 1206 else if (irtt < 10 * 1000) 1207 irtt = 10 * 1000; 1208 lsquic_rtt_stats_update(&mc->mc_rtt_stats, irtt, 0); 1209 LSQ_DEBUG("Set initial SRTT to %"PRIu32" usec based on client-" 1210 "supplied IRTT value", irtt); 1211 } 1212 } 1213 1214 switch (he) 1215 { 1216 case DATA_NOT_ENOUGH: 1217 LSQ_DEBUG("lsquic_enc_session_handle_chlo needs more data"); 1218 break; 1219 case HS_SHLO: 1220 mc->mc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE; 1221 mc->mc_flags |= MC_PROMOTE; 1222 LSQ_DEBUG("lsquic_enc_session_handle_chlo returned %d, promote", he); 1223 /* Fall through */ 1224 case HS_1RTT: 1225 assert(out_len > 0); 1226 if (mc->mc_conn.cn_version < LSQVER_046 1227 && !mc->mc_conn.cn_esf.g->esf_get_peer_option( 1228 mc->mc_conn.cn_enc_session, QTAG_NSTP)) 1229 mc->mc_flags |= MC_STOP_WAIT_ON; 1230 if (0 != packetize_response(mc, buf_out, out_len, 1231 nonce_set ? nonce_buf : NULL)) 1232 goto end; 1233 mc->mc_read_off += bufsz; 1234 for (n = 0; n < n_contig; ++n) 1235 hsk_chunks[n].hsk_packet_in->pi_flags &= ~PI_HSK_STREAM; 1236 LSQ_DEBUG("read offset is now %hu", mc->mc_read_off); 1237 break; 1238 default: 1239 LSQ_WARN("unexpected return value from lsquic_enc_session_handle_chlo: %u", he); 1240 /* fallthru */ 1241 case HS_ERROR: 1242#if !LSQUIC_KEEP_ENC_SESS_HISTORY 1243 mc->mc_conn.cn_esf.g->esf_destroy(mc->mc_conn.cn_enc_session); 1244 mc->mc_conn.cn_enc_session = NULL; 1245#endif 1246 mc->mc_flags |= MC_HSK_ERR; 1247 LSQ_INFO("lsquic_enc_session_handle_chlo returned an error (%d)", he); 1248 goto end; 1249 } 1250 1251 rv = 0; 1252 1253 end: 1254 mc->mc_flags &= ~MC_HAVE_SHLO; 1255 if (buf_in_16k) 1256 lsquic_mm_put_16k(&mc->mc_enpub->enp_mm, buf_in_16k); 1257 if (buf_out) 1258 lsquic_mm_put_16k(&mc->mc_enpub->enp_mm, buf_out); 1259 return rv; 1260} 1261 1262 1263struct mini_rechist 1264{ 1265 const struct mini_conn *mc; 1266 mconn_packno_set_t cur_set; 1267 int cur_idx; 1268 struct lsquic_packno_range range; /* We return a pointer to this */ 1269}; 1270 1271 1272static void 1273mini_rechist_init (struct mini_rechist *rechist, const struct mini_conn *mc) 1274{ 1275 rechist->mc = mc; 1276 rechist->cur_set = 0; 1277 rechist->cur_idx = 0; 1278} 1279 1280 1281static lsquic_time_t 1282mini_rechist_largest_recv (void *rechist_ctx) 1283{ 1284 struct mini_rechist *rechist = rechist_ctx; 1285 const struct mini_conn *mc = rechist->mc; 1286 lsquic_time_t delta = mc->mc_largest_recv[0] 1287 + (mc->mc_largest_recv[1] << 8) 1288 + (mc->mc_largest_recv[2] << 16); 1289 LSQ_DEBUG("%s: largest received: %"PRIu64" usec since creation", 1290 __func__, delta); 1291 return mc->mc_created + delta; 1292} 1293 1294 1295static const struct lsquic_packno_range * 1296mini_rechist_next (void *rechist_ctx) 1297{ 1298 struct mini_rechist *rechist = rechist_ctx; 1299 const struct mini_conn *mc = rechist->mc; 1300 mconn_packno_set_t packnos; 1301 int i; 1302 1303 packnos = rechist->cur_set; 1304 if (0 == packnos) 1305 return NULL; 1306 1307 /* There may be a faster way to do this, but for now, we just want 1308 * correctness. 1309 */ 1310 for (i = rechist->cur_idx; i >= 0; --i) 1311 if (packnos & (1ULL << i)) 1312 { 1313 rechist->range.low = i + 1; 1314 rechist->range.high = i + 1; 1315 break; 1316 } 1317 assert(i >= 0); /* We must have hit at least one bit */ 1318 --i; 1319 for ( ; i >= 0 && (packnos & (1ULL << i)); --i) 1320 rechist->range.low = i + 1; 1321 if (i >= 0) 1322 { 1323 rechist->cur_set = packnos & ((1ULL << i) - 1); 1324 rechist->cur_idx = i; 1325 } 1326 else 1327 rechist->cur_set = 0; 1328 LSQ_DEBUG("%s: return [%"PRIu64", %"PRIu64"]", __func__, 1329 rechist->range.low, rechist->range.high); 1330 return &rechist->range; 1331} 1332 1333 1334static const struct lsquic_packno_range * 1335mini_rechist_first (void *rechist_ctx) 1336{ 1337 struct mini_rechist *rechist = rechist_ctx; 1338 rechist->cur_set = rechist->mc->mc_received_packnos; 1339 rechist->cur_idx = highest_bit_set(rechist->cur_set); 1340 return mini_rechist_next(rechist_ctx); 1341} 1342 1343 1344static lsquic_packno_t 1345least_unacked (const struct mini_conn *mc) 1346{ 1347 mconn_packno_set_t unacked; 1348 lsquic_packno_t packno; 1349 unacked = mc->mc_sent_packnos & ~mc->mc_acked_packnos; 1350 if (unacked) 1351 packno = lowest_bit_set(unacked) + 1; 1352 else 1353 packno = highest_bit_set(mc->mc_sent_packnos) + 2; 1354 LSQ_DEBUG("%s: least unacked: %"PRIu64, __func__, packno); 1355 return packno; 1356} 1357 1358 1359static int 1360generate_ack_and_stop_waiting (struct mini_conn *mc, lsquic_time_t now) 1361{ 1362 lsquic_packet_out_t *packet_out; 1363 struct mini_rechist rechist; 1364 int len, not_used_has_missing; 1365 lsquic_packno_t lunack; 1366 1367 /* Chrome's quic_server places ACK and STOP_WAITING frames into a separate 1368 * packet. 1369 */ 1370 packet_out = allocate_packet_out(mc, NULL); 1371 if (!packet_out) 1372 return -1; 1373 1374 /* Generate ACK frame */ 1375 mini_rechist_init(&rechist, mc); 1376 len = mc->mc_conn.cn_pf->pf_gen_ack_frame(packet_out->po_data + packet_out->po_data_sz, 1377 lsquic_packet_out_avail(packet_out), mini_rechist_first, 1378 mini_rechist_next, mini_rechist_largest_recv, &rechist, 1379 now, ¬_used_has_missing, &packet_out->po_ack2ed, NULL); 1380 if (len < 0) 1381 { 1382 LSQ_WARN("could not generate ACK frame"); 1383 return -1; 1384 } 1385 EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, mc->mc_conn.cn_pf, 1386 packet_out->po_data + packet_out->po_data_sz, len); 1387 packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK; 1388 packet_out->po_data_sz += len; 1389 packet_out->po_regen_sz += len; 1390 LSQ_DEBUG("wrote ACK frame of size %d", len); 1391 1392 /* Generate STOP_WAITING frame */ 1393 if ((mc->mc_flags & MC_STOP_WAIT_ON) && mc->mc_sent_packnos) 1394 { 1395 lunack = least_unacked(mc); 1396 len = mc->mc_conn.cn_pf->pf_gen_stop_waiting_frame(packet_out->po_data + 1397 packet_out->po_data_sz, 1398 lsquic_packet_out_avail(packet_out), packet_out->po_packno, 1399 lsquic_packet_out_packno_bits(packet_out), lunack); 1400 if (len < 0) 1401 { 1402 LSQ_WARN("could not generate STOP_WAITING frame"); 1403 return -1; 1404 } 1405 packet_out->po_data_sz += len; 1406 packet_out->po_regen_sz += len; 1407 packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING; 1408 LSQ_DEBUG("wrote STOP_WAITING frame of size %d", len); 1409 EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, lunack); 1410 } 1411 else if (mc->mc_flags & MC_STOP_WAIT_ON) 1412 LSQ_DEBUG("nothing sent: no need to generate STOP_WAITING frame"); 1413 1414 mc->mc_flags |= MC_UNSENT_ACK; 1415 return 0; 1416} 1417 1418 1419static int 1420calc_retx_timeout (const struct mini_conn *mc) 1421{ 1422 lsquic_time_t to; 1423 to = lsquic_rtt_stats_get_srtt(&mc->mc_rtt_stats); 1424 if (to) 1425 { 1426 to += to / 2; 1427 if (to < 10000) 1428 to = 10000; 1429 } 1430 else 1431 to = 300000; 1432 return to << mc->mc_hsk_count; 1433} 1434 1435 1436static void 1437return_enc_data (struct mini_conn *mc, struct lsquic_packet_out *packet_out) 1438{ 1439 mc->mc_enpub->enp_pmi->pmi_return(mc->mc_enpub->enp_pmi_ctx, 1440 mc->mc_path.np_peer_ctx, packet_out->po_enc_data, 1441 lsquic_packet_out_ipv6(packet_out)); 1442 packet_out->po_flags &= ~PO_ENCRYPTED; 1443 packet_out->po_enc_data = NULL; 1444} 1445 1446 1447static int 1448repackage_packet (struct mini_conn *mc, lsquic_packet_out_t *packet_out) 1449{ 1450 const lsquic_packno_t oldno = packet_out->po_packno; 1451 const lsquic_packno_t packno = next_packno(mc); 1452 if (packno > MINICONN_MAX_PACKETS) 1453 return -1; 1454 1455 LSQ_DEBUG("Packet %"PRIu64" repackaged for resending as packet %"PRIu64, 1456 oldno, packno); 1457 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "packet %"PRIu64" repackaged for " 1458 "resending as packet %"PRIu64, oldno, packno); 1459 packet_out->po_packno = packno; 1460 packet_out->po_flags &= ~PO_SENT; 1461 if (packet_out->po_flags & PO_ENCRYPTED) 1462 return_enc_data(mc, packet_out); 1463 TAILQ_INSERT_TAIL(&mc->mc_packets_out, packet_out, po_next); 1464 return 0; 1465} 1466 1467 1468static int 1469handle_losses_and_have_unsent (struct mini_conn *mc, lsquic_time_t now) 1470{ 1471 TAILQ_HEAD(, lsquic_packet_out) lost_packets = 1472 TAILQ_HEAD_INITIALIZER(lost_packets); 1473 lsquic_packet_out_t *packet_out, *next; 1474 lsquic_time_t retx_to = 0; 1475 unsigned n_to_send = 0; 1476 1477 for (packet_out = TAILQ_FIRST(&mc->mc_packets_out); packet_out; 1478 packet_out = next) 1479 { 1480 next = TAILQ_NEXT(packet_out, po_next); 1481 if (packet_out->po_flags & PO_SENT) 1482 { 1483 if (0 == retx_to) 1484 retx_to = calc_retx_timeout(mc); 1485 if (packet_out->po_sent + retx_to < now) 1486 { 1487 LSQ_DEBUG("packet %"PRIu64" has been lost (rto: %"PRIu64")", 1488 packet_out->po_packno, retx_to); 1489 TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next); 1490 TAILQ_INSERT_TAIL(&lost_packets, packet_out, po_next); 1491 mc->mc_lost_packnos |= MCONN_PACKET_MASK(packet_out->po_packno); 1492 MCHIST_APPEND(mc, MCHE_PACKET_LOST); 1493 } 1494 } 1495 else 1496 ++n_to_send; 1497 } 1498 1499 mc->mc_hsk_count += !TAILQ_EMPTY(&lost_packets); 1500 1501 while ((packet_out = TAILQ_FIRST(&lost_packets))) 1502 { 1503 TAILQ_REMOVE(&lost_packets, packet_out, po_next); 1504 if ((packet_out->po_frame_types & GQUIC_FRAME_RETRANSMITTABLE_MASK) 1505 && 0 == repackage_packet(mc, packet_out)) 1506 ++n_to_send; 1507 else 1508 mini_destroy_packet(mc, packet_out); 1509 } 1510 1511 return n_to_send > 0; 1512} 1513 1514 1515static int 1516warning_is_warranted (const struct mini_conn *mc) 1517{ 1518 return (mc->mc_flags & (MC_HSK_ERR|MC_OO_PACKNOS)) 1519 || 0x1C /* QUIC_HANDSHAKE_FAILED */ == mc->mc_error_code 1520 || 0x1D /* QUIC_CRYPTO_TAGS_OUT_OF_ORDER */ == mc->mc_error_code 1521 || 0x1E /* QUIC_CRYPTO_TOO_MANY_ENTRIES */ == mc->mc_error_code 1522 || 0x1F /* QUIC_CRYPTO_INVALID_VALUE_LENGTH */ == mc->mc_error_code 1523 || 0x21 /* QUIC_INVALID_CRYPTO_MESSAGE_TYPE */ == mc->mc_error_code 1524 || 0x22 /* QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER */ == mc->mc_error_code 1525 || 0x23 /* QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND */ == mc->mc_error_code 1526 || 0x24 /* QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP */ == mc->mc_error_code 1527 || 0x29 /* QUIC_CRYPTO_TOO_MANY_REJECTS */ == mc->mc_error_code 1528 || 0x2A /* QUIC_PROOF_INVALID */ == mc->mc_error_code 1529 || 0x2B /* QUIC_CRYPTO_DUPLICATE_TAG */ == mc->mc_error_code 1530 || 0x2C /* QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT */ == mc->mc_error_code 1531 || 0x2D /* QUIC_CRYPTO_SERVER_CONFIG_EXPIRED */ == mc->mc_error_code 1532 || 0x35 /* QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED */ == mc->mc_error_code 1533 ; 1534} 1535 1536 1537#if LSQUIC_KEEP_ENC_SESS_HISTORY 1538static void 1539maybe_log_enc_sess_history (const struct mini_conn *mc) 1540{ 1541 char eshist[ESHIST_STR_SIZE]; 1542 enum lsq_log_level log_level; 1543 const char *ua; 1544 1545 if (warning_is_warranted(mc)) 1546 log_level = LSQ_LOG_WARN; 1547 else 1548 log_level = LSQ_LOG_DEBUG; 1549 1550 if (mc->mc_conn.cn_enc_session) 1551 { 1552 mc->mc_conn.cn_esf.g->esf_get_hist(mc->mc_conn.cn_enc_session, eshist); 1553 ua = mc->mc_conn.cn_esf.g->esf_get_ua(mc->mc_conn.cn_enc_session); 1554 LSQ_LOG1(log_level, "enc hist %s; User-Agent: %s", eshist, 1555 ua ? ua : "<not set>"); 1556 } 1557 else 1558 LSQ_LOG1(log_level, "enc session gone: no history to log"); 1559} 1560 1561 1562#endif 1563 1564 1565 1566 1567static int 1568have_packets_to_send (struct mini_conn *mc, lsquic_time_t now) 1569{ 1570 return handle_losses_and_have_unsent(mc, now); 1571} 1572 1573 1574static enum tick_st 1575mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now) 1576{ 1577 struct mini_conn *mc = (struct mini_conn *) lconn; 1578 enum tick_st tick; 1579 1580 ++mc->mc_n_ticks; 1581 1582 if (mc->mc_created + mc->mc_enpub->enp_settings.es_handshake_to < now) 1583 { 1584 LSQ_DEBUG("connection expired: closing"); 1585 tick = TICK_CLOSE; 1586 goto end; 1587 } 1588 1589 if (mc->mc_flags & MC_ERROR) 1590 { 1591 tick = TICK_CLOSE; 1592 goto end; 1593 } 1594 1595 1596 if ((mc->mc_flags & (MC_UNSENT_ACK|MC_GEN_ACK)) == MC_GEN_ACK) 1597 { 1598 if (0 != generate_ack_and_stop_waiting(mc, now)) 1599 { 1600 mc->mc_flags |= MC_ERROR; 1601 tick = TICK_CLOSE; 1602 goto end; 1603 } 1604 else 1605 mc->mc_flags &= ~MC_GEN_ACK; 1606 } 1607 1608 if (have_packets_to_send(mc, now)) 1609 tick = TICK_SEND; 1610 else 1611 tick = TICK_QUIET; 1612 1613 if (mc->mc_flags & MC_PROMOTE) 1614 tick |= TICK_PROMOTE; 1615 1616 end: 1617#if LSQUIC_KEEP_ENC_SESS_HISTORY 1618 if (tick & (TICK_CLOSE|TICK_PROMOTE)) 1619 maybe_log_enc_sess_history(mc); 1620#endif 1621 1622 return tick; 1623} 1624 1625 1626static void 1627process_packet (struct mini_conn *mc, struct lsquic_packet_in *packet_in) 1628{ 1629 switch (process_regular_packet(mc, packet_in)) 1630 { 1631 case PRP_KEEP: 1632 assert(packet_in->pi_flags & PI_OWN_DATA); 1633 lsquic_packet_in_upref(packet_in); 1634 TAILQ_INSERT_TAIL(&mc->mc_packets_in, packet_in, pi_next); 1635 if (mc->mc_flags & MC_HAVE_NEW_HSK) 1636 { 1637 if (0 != continue_handshake(mc)) 1638 mc->mc_flags |= MC_ERROR; 1639 mc->mc_flags &= ~MC_HAVE_NEW_HSK; 1640 } 1641 break; 1642 case PRP_DEFER: 1643 assert(packet_in->pi_flags & PI_OWN_DATA); 1644 lsquic_packet_in_upref(packet_in); 1645 if (mc->mc_n_deferred < MINI_CONN_MAX_DEFERRED) 1646 { 1647 TAILQ_INSERT_TAIL(&mc->mc_deferred, packet_in, pi_next); 1648 ++mc->mc_n_deferred; 1649 } 1650 else 1651 LSQ_DEBUG("won't defer more than %u packets: drop", 1652 MINI_CONN_MAX_DEFERRED); 1653 break; 1654 case PRP_ERROR: 1655 mc->mc_flags |= MC_ERROR; 1656 break; 1657 case PRP_DROP: 1658 break; 1659 } 1660} 1661 1662 1663/* Keep deferred list ordered by packet number, so that we can process all 1664 * of them in a single pass. 1665 */ 1666static void 1667insert_into_deferred (struct mini_conn *mc, lsquic_packet_in_t *new_packet) 1668{ 1669 lsquic_packet_in_t *packet_in; 1670 1671 lsquic_packet_in_upref(new_packet); 1672 1673 TAILQ_FOREACH(packet_in, &mc->mc_deferred, pi_next) 1674 if (packet_in->pi_packno > new_packet->pi_packno) 1675 break; 1676 1677 if (packet_in) 1678 TAILQ_INSERT_BEFORE(packet_in, new_packet, pi_next); 1679 else 1680 TAILQ_INSERT_TAIL(&mc->mc_deferred, new_packet, pi_next); 1681 ++mc->mc_n_deferred; 1682} 1683 1684 1685static void 1686process_deferred_packets (struct mini_conn *mc) 1687{ 1688 lsquic_packet_in_t *last, *packet_in; 1689 int reached_last; 1690 1691 last = TAILQ_LAST(&mc->mc_deferred, head_packet_in); 1692 do 1693 { 1694 packet_in = TAILQ_FIRST(&mc->mc_deferred); 1695 TAILQ_REMOVE(&mc->mc_deferred, packet_in, pi_next); 1696 --mc->mc_n_deferred; 1697 process_packet(mc, packet_in); 1698 reached_last = packet_in == last; 1699 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1700 } 1701 while (!reached_last); 1702} 1703 1704 1705#if LSQUIC_RECORD_INORD_HIST 1706/* Packet number is encoded as a sequence of 1-bits and stored in mc_inord_hist 1707 * separated by 0 bits. For example, sequence of packet numbers 3, 2, 1 would 1708 * be encoded as (starting with LSB) 1110110100000000... This is not the most 1709 * space-efficient scheme, but it is simple to implement and should suffice for 1710 * our purposes. 1711 */ 1712static void 1713record_inord_packno (struct mini_conn *mc, lsquic_packno_t packno) 1714{ 1715 int n_avail; 1716 lsquic_packno_t mask; 1717 1718 for ( ; mc->mc_inord_idx < sizeof(mc->mc_inord_hist) / 1719 sizeof(mc->mc_inord_hist[0]); ++mc->mc_inord_idx) 1720 { 1721 if (mc->mc_inord_hist[ mc->mc_inord_idx ]) 1722 n_avail = __builtin_clzll(mc->mc_inord_hist[ mc->mc_inord_idx ]) - 1; 1723 else 1724 n_avail = sizeof(mc->mc_inord_hist[ mc->mc_inord_idx ]) * 8; 1725 if (n_avail >= (int) packno) 1726 { 1727 mask = (1ULL << (int) packno) - 1; 1728 mask <<= sizeof(mc->mc_inord_hist[ mc->mc_inord_idx ]) * 8 - n_avail; 1729 mc->mc_inord_hist[ mc->mc_inord_idx ] |= mask; 1730 return; /* Success */ 1731 } 1732 } 1733} 1734 1735 1736static void 1737inord_to_str (const struct mini_conn *mc, char *buf, size_t bufsz) 1738{ 1739 unsigned long long hist; 1740 size_t off; 1741 ssize_t nw; 1742 unsigned n; 1743 int n_trail; 1744 1745 off = 0; 1746 for (n = 0; n < sizeof(mc->mc_inord_hist) / 1747 sizeof(mc->mc_inord_hist[0]); ++n) 1748 { 1749 hist = mc->mc_inord_hist[n]; 1750 while (hist) 1751 { 1752 n_trail = __builtin_ctzll(~hist); 1753 nw = snprintf(buf + off, bufsz - off, 1754 /* No spaces are included on purpose: this makes it a single 1755 * field and thus easy to process log using standard command- 1756 * line tools, such as sork -k, for example. 1757 */ 1758 (off ? ",%d" : "%d"), n_trail); 1759 if ((size_t) nw > bufsz - off || nw < 0) 1760 break; 1761 off += nw; 1762 hist >>= n_trail + 1; 1763 } 1764 } 1765 buf[ bufsz - 1 ] = '\0'; /* CYA */ 1766} 1767 1768 1769#endif 1770 1771 1772static void 1773mini_conn_ci_packet_in (struct lsquic_conn *lconn, 1774 struct lsquic_packet_in *packet_in) 1775{ 1776 struct mini_conn *mc = (struct mini_conn *) lconn; 1777 1778#if LSQUIC_RECORD_INORD_HIST 1779 record_inord_packno(mc, packet_in->pi_packno); 1780#endif 1781#if 0 1782 /* A convenient way to test lsquic_is_valid_hs_packet(): */ 1783 if (!(mc->mc_sent_packnos)) 1784 assert(lsquic_is_valid_hs_packet(NULL, packet_in->pi_data, 1785 packet_in->pi_data_sz)); 1786#endif 1787 1788 if (mc->mc_flags & MC_ERROR) 1789 { 1790 LSQ_DEBUG("error state: ignore packet %"PRIu64, packet_in->pi_packno); 1791 return; 1792 } 1793 1794 if (lsquic_packet_in_is_gquic_prst(packet_in)) 1795 { 1796 LSQ_INFO("received reset packet"); 1797 mc->mc_flags |= MC_ERROR; 1798 MCHIST_APPEND(mc, MCHE_PRST_IN); 1799 return; 1800 } 1801 1802 LSQ_DEBUG("packet in: %"PRIu64, packet_in->pi_packno); 1803 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 1804 1805 1806 /* Check receive history */ 1807 if (0 == packet_in->pi_packno) 1808 { 1809 LSQ_DEBUG("invalid packet number 0"); 1810 mc->mc_flags |= MC_ERROR; 1811 MCHIST_APPEND(mc, MCHE_PACKET0_IN); 1812 return; 1813 } 1814 if (packet_in->pi_packno > MINICONN_MAX_PACKETS) 1815 { 1816 LSQ_DEBUG("packet number %"PRIu64" is too large (max %zd)", 1817 packet_in->pi_packno, MINICONN_MAX_PACKETS); 1818 mc->mc_flags |= MC_ERROR; 1819 MCHIST_APPEND(mc, MCHE_PACKET2LARGE_IN); 1820 return; 1821 } 1822 if (MCONN_PACKET_MASK(packet_in->pi_packno) & mc->mc_received_packnos) 1823 { 1824 LSQ_DEBUG("duplicate packet %"PRIu64", ignoring", packet_in->pi_packno); 1825 MCHIST_APPEND(mc, MCHE_PACKET_DUP_IN); 1826 return; 1827 } 1828 1829 if (TAILQ_EMPTY(&mc->mc_deferred)) 1830 process_packet(mc, packet_in); 1831 else if (mc->mc_n_deferred < MINI_CONN_MAX_DEFERRED) 1832 { 1833 insert_into_deferred(mc, packet_in); 1834 process_deferred_packets(mc); 1835 } 1836 else 1837 LSQ_DEBUG("won't defer more than %u packets: drop", 1838 MINI_CONN_MAX_DEFERRED); 1839} 1840 1841 1842/* Q050 is different is that packet numbers are not known until after the 1843 * packet is decrypted, so we have to follow different logic here. 1844 */ 1845static void 1846mini_conn_ci_Q050_packet_in (struct lsquic_conn *lconn, 1847 struct lsquic_packet_in *packet_in) 1848{ 1849 struct mini_conn *mc = (struct mini_conn *) lconn; 1850 enum proc_rp prp; 1851 1852 if (mc->mc_flags & MC_ERROR) 1853 { 1854 LSQ_DEBUG("error state: ignore packet"); 1855 return; 1856 } 1857 1858 if (!mc->mc_conn.cn_enc_session) 1859 { 1860 mc->mc_conn.cn_enc_session = 1861 mc->mc_conn.cn_esf.g->esf_create_server(&mc->mc_conn, 1862 mc->mc_conn.cn_cid, mc->mc_enpub); 1863 if (!mc->mc_conn.cn_enc_session) 1864 { 1865 LSQ_WARN("cannot create new enc session"); 1866 mc->mc_flags |= MC_ERROR; 1867 return; 1868 } 1869 MCHIST_APPEND(mc, MCHE_NEW_ENC_SESS); 1870 } 1871 1872 assert(!(packet_in->pi_flags & PI_DECRYPTED)); 1873 prp = conn_decrypt_packet_or(mc, packet_in); 1874 switch (prp) 1875 { 1876 case PRP_KEEP: 1877 break; 1878 case PRP_DROP: 1879 return; 1880 case PRP_ERROR: 1881 mc->mc_flags |= MC_ERROR; 1882 return; 1883 default: 1884 if (mc->mc_n_deferred >= MINI_CONN_MAX_DEFERRED) 1885 { 1886 LSQ_DEBUG("won't defer more than %u packets: drop", 1887 MINI_CONN_MAX_DEFERRED); 1888 return; 1889 } 1890 assert(prp == PRP_DEFER); 1891 assert(packet_in->pi_flags & PI_OWN_DATA); 1892 lsquic_packet_in_upref(packet_in); 1893 TAILQ_INSERT_TAIL(&mc->mc_deferred, packet_in, pi_next); 1894 ++mc->mc_n_deferred; 1895 return; 1896 } 1897 1898 assert(prp == PRP_KEEP); 1899 process_packet(mc, packet_in); 1900} 1901 1902 1903static struct lsquic_packet_out * 1904mini_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size) 1905{ 1906 struct mini_conn *mc = (struct mini_conn *) lconn; 1907 lsquic_packet_out_t *packet_out; 1908 1909 assert(0 == size); 1910 TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) 1911 { 1912 if (packet_out->po_flags & PO_SENT) 1913 continue; 1914 packet_out->po_flags |= PO_SENT; 1915 LSQ_DEBUG("packet_to_send: %"PRIu64, packet_out->po_packno); 1916 return packet_out; 1917 } 1918 return NULL; 1919} 1920 1921 1922static void 1923mini_conn_ci_packet_sent (struct lsquic_conn *lconn, 1924 struct lsquic_packet_out *packet_out) 1925{ 1926 struct mini_conn *mc = (struct mini_conn *) lconn; 1927 mc->mc_sent_packnos |= MCONN_PACKET_MASK(packet_out->po_packno); 1928 if (packet_out->po_frame_types & (1 << QUIC_FRAME_ACK)) 1929 { 1930 assert(mc->mc_flags & MC_UNSENT_ACK); 1931 mc->mc_flags &= ~MC_UNSENT_ACK; 1932 } 1933 LSQ_DEBUG("%s: packet %"PRIu64" sent", __func__, packet_out->po_packno); 1934 MCHIST_APPEND(mc, MCHE_PACKET_SENT); 1935} 1936 1937 1938static void 1939mini_conn_ci_packet_not_sent (struct lsquic_conn *lconn, 1940 struct lsquic_packet_out *packet_out) 1941{ 1942 struct mini_conn *mc = (struct mini_conn *) lconn; 1943 packet_out->po_flags &= ~PO_SENT; 1944 LSQ_DEBUG("%s: packet %"PRIu64" not sent", __func__, packet_out->po_packno); 1945 MCHIST_APPEND(mc, MCHE_PACKET_DELAYED); 1946} 1947 1948 1949static void 1950mini_conn_ci_destroy (struct lsquic_conn *lconn) 1951{ 1952 assert(!(lconn->cn_flags & LSCONN_HASHED)); 1953 struct mini_conn *mc = (struct mini_conn *) lconn; 1954 lsquic_packet_in_t *packet_in; 1955 mconn_packno_set_t still_deferred = 0, in_flight; 1956 enum lsq_log_level log_level; 1957#if LSQUIC_RECORD_INORD_HIST 1958 char inord_str[0x100]; 1959#endif 1960 while ((packet_in = TAILQ_FIRST(&mc->mc_packets_in))) 1961 { 1962 TAILQ_REMOVE(&mc->mc_packets_in, packet_in, pi_next); 1963 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1964 } 1965 while ((packet_in = TAILQ_FIRST(&mc->mc_deferred))) 1966 { 1967 TAILQ_REMOVE(&mc->mc_deferred, packet_in, pi_next); 1968 --mc->mc_n_deferred; 1969 still_deferred |= MCONN_PACKET_MASK(packet_in->pi_packno); 1970 lsquic_packet_in_put(&mc->mc_enpub->enp_mm, packet_in); 1971 } 1972 if (TAILQ_EMPTY(&mc->mc_packets_out)) 1973 in_flight = ~0ull; /* Indicates that packets were dropped before */ 1974 else 1975 in_flight = drop_packets_out(mc); 1976 if (mc->mc_conn.cn_enc_session) 1977 mc->mc_conn.cn_esf.g->esf_destroy(mc->mc_conn.cn_enc_session); 1978 log_level = warning_is_warranted(mc) ? LSQ_LOG_WARN : LSQ_LOG_DEBUG; 1979#if LSQUIC_RECORD_INORD_HIST 1980 if (LSQ_LOG_ENABLED(log_level)) 1981 inord_to_str(mc, inord_str, sizeof(inord_str)); 1982#endif 1983#if LSQUIC_KEEP_MINICONN_HISTORY 1984 const unsigned hist_idx = MCHIST_MASK & mc->mc_hist_idx; 1985 if (MCHE_EMPTY == mc->mc_hist_buf[ hist_idx ]) 1986 LSQ_LOG(log_level, "destroyed. Diagnostics: conn flags: 0x%X, " 1987 "mc flags: 0x%X, " 1988#if LSQUIC_RECORD_INORD_HIST 1989 "incoming-history (trunc: %d) %s, " 1990#endif 1991 "received: %"PRIX64", sent: %"PRIX64", lost: %"PRIX64", " 1992 "deferred: %"PRIX64", still-deferred: %"PRIX64", " 1993 "dropped: %"PRIX64", in-flight: %"PRIX64", acked: %"PRIX64", " 1994 "error_code: 0x%X, ticks: %hu, pack size: %hu, " 1995 "lifetime: %"PRIu64" usec, version: %s, " 1996 "mc hist: %.*s", mc->mc_conn.cn_flags, 1997 mc->mc_flags, 1998#if LSQUIC_RECORD_INORD_HIST 1999 mc->mc_inord_idx >= sizeof(mc->mc_inord_hist) / 2000 sizeof(mc->mc_inord_hist[0]), inord_str, 2001#endif 2002 mc->mc_received_packnos, mc->mc_sent_packnos, mc->mc_lost_packnos, 2003 mc->mc_deferred_packnos, still_deferred, 2004 mc->mc_dropped_packnos, in_flight, mc->mc_acked_packnos, 2005 mc->mc_error_code, mc->mc_n_ticks, mc->mc_conn.cn_pack_size, 2006 lsquic_time_now() - mc->mc_created, 2007 lsquic_ver2str[mc->mc_conn.cn_version], 2008 (int) hist_idx, mc->mc_hist_buf); 2009 else 2010 LSQ_LOG(log_level, "destroyed. Diagnostics: conn flags: 0x%X, " 2011 "mc flags: 0x%X, " 2012#if LSQUIC_RECORD_INORD_HIST 2013 "incoming-history (trunc: %d) %s, " 2014#endif 2015 "received: %"PRIX64", sent: %"PRIX64", lost: %"PRIX64", " 2016 "deferred: %"PRIX64", still-deferred: %"PRIX64", " 2017 "dropped: %"PRIX64", in-flight: %"PRIX64", acked: %"PRIX64", " 2018 "error_code: 0x%X, ticks: %hu, pack size: %hu, " 2019 "lifetime: %"PRIu64" usec, version: %s, " 2020 "mc hist: %.*s%.*s", mc->mc_conn.cn_flags, 2021 mc->mc_flags, 2022#if LSQUIC_RECORD_INORD_HIST 2023 mc->mc_inord_idx >= sizeof(mc->mc_inord_hist) / 2024 sizeof(mc->mc_inord_hist[0]), inord_str, 2025#endif 2026 mc->mc_received_packnos, mc->mc_sent_packnos, mc->mc_lost_packnos, 2027 mc->mc_deferred_packnos, still_deferred, 2028 mc->mc_dropped_packnos, in_flight, mc->mc_acked_packnos, 2029 mc->mc_error_code, mc->mc_n_ticks, mc->mc_conn.cn_pack_size, 2030 lsquic_time_now() - mc->mc_created, 2031 lsquic_ver2str[mc->mc_conn.cn_version], 2032 (int) (sizeof(mc->mc_hist_buf) - hist_idx), 2033 mc->mc_hist_buf + hist_idx, (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", 2045 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#endif 2057 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "mini connection destroyed"); 2058 lsquic_malo_put(mc); 2059} 2060 2061 2062#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 2063static void 2064mini_conn_ci_packet_in_disable_handshake (struct lsquic_conn *lconn, 2065 struct lsquic_packet_in *packet_in) 2066{ 2067 struct mini_conn *mc = (struct mini_conn *) lconn; 2068 if (0 == (mc->mc_flags & MC_ERROR)) 2069 { 2070 if (packet_in->pi_packno > MINICONN_MAX_PACKETS) 2071 mc->mc_flags |= MC_ERROR; 2072 else if (!(mc->mc_received_packnos & 2073 MCONN_PACKET_MASK(packet_in->pi_packno))) 2074 { 2075 lsquic_packet_in_upref(packet_in); 2076 TAILQ_INSERT_TAIL(&mc->mc_packets_in, packet_in, pi_next); 2077 mc->mc_received_packnos |= MCONN_PACKET_MASK(packet_in->pi_packno); 2078 } 2079 } 2080} 2081 2082 2083static enum tick_st 2084mini_conn_ci_tick_disable_handshake (struct lsquic_conn *lconn, 2085 lsquic_time_t now) 2086{ 2087 struct mini_conn *mc = (struct mini_conn *) lconn; 2088 LSQ_WARN("handshake disabled, promote me now"); 2089 lconn->cn_flags |= LSCONN_HANDSHAKE_DONE; 2090 mc->mc_conn.cn_enc_session = 2091 mc->mc_conn.cn_esf.g->esf_create_server(lconn->cn_cid, mc->mc_enpub, 0); 2092 mc->mc_conn.cn_esf.g->esf_set_handshake_completed(mc->mc_conn.cn_enc_session); 2093 return TICK_PROMOTE; 2094} 2095 2096 2097#endif 2098 2099 2100static struct lsquic_engine * 2101mini_conn_ci_get_engine (struct lsquic_conn *lconn) 2102{ 2103 struct mini_conn *mc = (struct mini_conn *) lconn; 2104 return mc->mc_enpub->enp_engine; 2105} 2106 2107 2108static void 2109mini_conn_ci_hsk_done (struct lsquic_conn *lconn, enum lsquic_hsk_status status) 2110{ 2111 assert(0); 2112} 2113 2114 2115static int 2116mini_conn_ci_is_tickable (struct lsquic_conn *lconn) 2117{ 2118 /* A mini connection is never tickable: Either there are incoming 2119 * packets, in which case, the connection is going to be ticked, or 2120 * there is an alarm pending, in which case it will be handled via 2121 * the attq. 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 2266#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 2267static const struct conn_iface mini_conn_iface_disable_handshake = { 2268 .ci_abort_error = mini_conn_ci_abort_error, 2269 .ci_client_call_on_new = mini_conn_ci_client_call_on_new, 2270 .ci_destroy = mini_conn_ci_destroy, 2271 .ci_get_engine = mini_conn_ci_get_engine, 2272 .ci_hsk_done = mini_conn_ci_hsk_done, 2273 .ci_internal_error = mini_conn_ci_internal_error, 2274 .ci_is_tickable = mini_conn_ci_is_tickable, 2275 .ci_next_packet_to_send = mini_conn_ci_next_packet_to_send, 2276 .ci_next_tick_time = mini_conn_ci_next_tick_time, 2277 .ci_packet_in = mini_conn_ci_packet_in_disable_handshake, 2278 .ci_packet_not_sent = mini_conn_ci_packet_not_sent, 2279 .ci_packet_sent = mini_conn_ci_packet_sent, 2280 .ci_tick = mini_conn_ci_tick_disable_handshake, 2281 .ci_tls_alert = mini_conn_ci_tls_alert, 2282}; 2283#endif 2284 2285typedef char largest_recv_holds_at_least_16_seconds[ 2286 ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) / 1000000 2287 >= 16) - 1]; 2288 2289typedef char max_lifespan_smaller_than_largest_recv[ 2290 ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) > 2291 MAX_MINI_CONN_LIFESPAN_IN_USEC) - 1]; 2292