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