lsquic_full_conn.c revision 123f1164
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_full_conn.c -- A "full" connection object has full functionality 4 */ 5 6#include <assert.h> 7#include <errno.h> 8#include <inttypes.h> 9#include <stdarg.h> 10#include <stdlib.h> 11#include <string.h> 12#ifndef WIN32 13#include <netinet/in.h> 14#include <sys/socket.h> 15#include <sys/time.h> 16#endif 17#include <sys/queue.h> 18 19#include <openssl/ssl.h> 20 21#include "lsquic_types.h" 22#include "lsquic_sizes.h" 23#include "lsquic.h" 24#include "lsquic_packet_common.h" 25#include "lsquic_alarmset.h" 26#include "lsquic_packet_gquic.h" 27#include "lsquic_parse.h" 28#include "lsquic_packet_in.h" 29#include "lsquic_packet_out.h" 30#include "lsquic_rechist.h" 31#include "lsquic_util.h" 32#include "lsquic_conn_flow.h" 33#include "lsquic_sfcw.h" 34#include "lsquic_varint.h" 35#include "lsquic_hq.h" 36#include "lsquic_hash.h" 37#include "lsquic_stream.h" 38#include "lsquic_senhist.h" 39#include "lsquic_rtt.h" 40#include "lsquic_cubic.h" 41#include "lsquic_pacer.h" 42#include "lsquic_bw_sampler.h" 43#include "lsquic_minmax.h" 44#include "lsquic_bbr.h" 45#include "lsquic_adaptive_cc.h" 46#include "lsquic_set.h" 47#include "lsquic_malo.h" 48#include "lsquic_chsk_stream.h" 49#include "lsquic_shsk_stream.h" 50#include "lshpack.h" 51#include "lsquic_str.h" 52#include "lsquic_qtags.h" 53#include "lsquic_enc_sess.h" 54#include "lsquic_headers_stream.h" 55#include "lsquic_frame_common.h" 56#include "lsquic_frame_reader.h" 57#include "lsquic_frame_writer.h" 58#include "lsquic_http1x_if.h" 59#include "lsquic_mm.h" 60#include "lsquic_engine_public.h" 61#include "lsquic_spi.h" 62#include "lsquic_ev_log.h" 63#include "lsquic_version.h" 64#include "lsquic_headers.h" 65#include "lsquic_handshake.h" 66#include "lsquic_attq.h" 67 68#include "lsquic_conn.h" 69#include "lsquic_send_ctl.h" 70#include "lsquic_conn_public.h" 71#include "lsquic_ver_neg.h" 72#include "lsquic_mini_conn.h" 73#include "lsquic_full_conn.h" 74 75#define LSQUIC_LOGGER_MODULE LSQLM_CONN 76#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&conn->fc_conn) 77#include "lsquic_logger.h" 78 79enum stream_if { STREAM_IF_STD, STREAM_IF_HSK, STREAM_IF_HDR, N_STREAM_IFS }; 80 81#define MAX_RETR_PACKETS_SINCE_LAST_ACK 2 82#define ACK_TIMEOUT 25000 83 84/* Maximum number of ACK ranges that can fit into gQUIC ACK frame */ 85#define MAX_ACK_RANGES 256 86 87/* IMPORTANT: Keep values of FC_SERVER and FC_HTTP same as LSENG_SERVER 88 * and LSENG_HTTP. 89 */ 90enum full_conn_flags { 91 FC_SERVER = LSENG_SERVER, /* Server mode */ 92 FC_HTTP = LSENG_HTTP, /* HTTP mode */ 93 FC_TIMED_OUT = (1 << 2), 94#define FC_BIT_ERROR 3 95 FC_ERROR = (1 << FC_BIT_ERROR), 96 FC_ABORTED = (1 << 4), 97 FC_CLOSING = (1 << 5), /* Closing */ 98 FC_SEND_PING = (1 << 6), /* PING frame scheduled */ 99 FC_NSTP = (1 << 7), /* NSTP mode */ 100 FC_SEND_GOAWAY = (1 << 8), 101 FC_SEND_WUF = (1 << 9), 102 FC_SEND_STOP_WAITING 103 = (1 <<10), 104 FC_ACK_QUEUED = (1 <<11), 105 FC_ACK_HAD_MISS = (1 <<12), /* Last ACK frame had missing packets. */ 106 FC_CREATED_OK = (1 <<13), 107 FC_RECV_CLOSE = (1 <<14), /* Received CONNECTION_CLOSE frame */ 108 FC_GOING_AWAY = (1 <<15), /* Do not accept or create new streams */ 109 FC_GOAWAY_SENT = (1 <<16), /* Only send GOAWAY once */ 110 FC_SUPPORT_PUSH = (1 <<17), 111 FC_GOT_PRST = (1 <<18), /* Received public reset packet */ 112 FC_FIRST_TICK = (1 <<19), 113 FC_TICK_CLOSE = (1 <<20), /* We returned TICK_CLOSE */ 114 FC_HSK_FAILED = (1 <<21), 115 FC_HAVE_SAVED_ACK = (1 <<22), 116 FC_ABORT_COMPLAINED 117 = (1 <<23), 118 FC_GOT_SREJ = (1 <<24), /* Don't schedule ACK alarm */ 119 FC_NOPROG_TIMEOUT = (1 <<25), 120}; 121 122#define FC_IMMEDIATE_CLOSE_FLAGS \ 123 (FC_TIMED_OUT|FC_ERROR|FC_ABORTED|FC_HSK_FAILED) 124 125#if LSQUIC_KEEP_STREAM_HISTORY 126#define KEEP_CLOSED_STREAM_HISTORY 0 127#endif 128 129#if KEEP_CLOSED_STREAM_HISTORY 130struct stream_history 131{ 132 lsquic_stream_id_t shist_stream_id; 133 enum stream_flags shist_stream_flags; 134 unsigned char shist_hist_buf[1 << SM_HIST_BITS]; 135}; 136#define SHIST_BITS 5 137#define SHIST_MASK ((1 << SHIST_BITS) - 1) 138#endif 139 140#ifndef KEEP_PACKET_HISTORY 141#ifdef NDEBUG 142#define KEEP_PACKET_HISTORY 0 143#else 144#define KEEP_PACKET_HISTORY 16 145#endif 146#endif 147 148#if KEEP_PACKET_HISTORY 149struct packet_el 150{ 151 lsquic_time_t time; 152 enum quic_ft_bit frame_types; 153}; 154 155struct recent_packets 156{ 157 struct packet_el els[KEEP_PACKET_HISTORY]; 158 unsigned idx; 159}; 160#endif 161 162struct stream_id_to_reset 163{ 164 STAILQ_ENTRY(stream_id_to_reset) sitr_next; 165 lsquic_stream_id_t sitr_stream_id; 166}; 167 168 169struct full_conn 170{ 171 struct lsquic_conn fc_conn; 172 struct conn_cid_elem fc_cces[2]; 173 struct lsquic_rechist fc_rechist; 174 struct { 175 const struct lsquic_stream_if *stream_if; 176 void *stream_if_ctx; 177 } fc_stream_ifs[N_STREAM_IFS]; 178 struct lsquic_send_ctl fc_send_ctl; 179 struct lsquic_conn_public fc_pub; 180 lsquic_alarmset_t fc_alset; 181 lsquic_set64_t fc_closed_stream_ids[2]; 182 const struct lsquic_engine_settings 183 *fc_settings; 184 struct lsquic_engine_public *fc_enpub; 185 lsquic_packno_t fc_max_ack_packno; 186 lsquic_packno_t fc_max_swf_packno; 187 lsquic_time_t fc_mem_logged_last; 188 struct { 189 unsigned max_streams_in; 190 unsigned max_streams_out; 191 unsigned max_conn_send; 192 unsigned max_stream_send; 193 } fc_cfg; 194 enum full_conn_flags fc_flags; 195 /* Number ackable packets received since last ACK was sent: */ 196 unsigned fc_n_slack_akbl; 197 unsigned fc_n_delayed_streams; 198 unsigned fc_n_cons_unretx; 199 lsquic_stream_id_t fc_last_stream_id; 200 lsquic_stream_id_t fc_max_peer_stream_id; 201 lsquic_stream_id_t fc_goaway_stream_id; 202 struct ver_neg fc_ver_neg; 203 union { 204 struct client_hsk_ctx client; 205 struct server_hsk_ctx server; 206 } fc_hsk_ctx; 207#if LSQUIC_CONN_STATS 208 struct conn_stats fc_stats; 209 struct conn_stats *fc_last_stats; 210#endif 211#if KEEP_CLOSED_STREAM_HISTORY 212 /* Rolling log of histories of closed streams. Older entries are 213 * overwritten. 214 */ 215 struct stream_history fc_stream_histories[1 << SHIST_BITS]; 216 unsigned fc_stream_hist_idx; 217#endif 218 char *fc_errmsg; 219#if KEEP_PACKET_HISTORY 220 struct recent_packets fc_recent_packets[2]; /* 0: in; 1: out */ 221#endif 222 STAILQ_HEAD(, stream_id_to_reset) 223 fc_stream_ids_to_reset; 224 lsquic_time_t fc_saved_ack_received; 225 struct network_path fc_path; 226 unsigned fc_orig_versions; /* Client only */ 227 enum enc_level fc_crypto_enc_level; 228 struct ack_info fc_ack; 229}; 230 231static const struct ver_neg server_ver_neg; 232 233 234#define MAX_ERRMSG 256 235 236#define SET_ERRMSG(conn, ...) do { \ 237 if (!(conn)->fc_errmsg) \ 238 (conn)->fc_errmsg = malloc(MAX_ERRMSG); \ 239 if ((conn)->fc_errmsg) \ 240 snprintf((conn)->fc_errmsg, MAX_ERRMSG, __VA_ARGS__); \ 241} while (0) 242 243#define ABORT_WITH_FLAG(conn, log_level, flag, ...) do { \ 244 SET_ERRMSG(conn, __VA_ARGS__); \ 245 if (!((conn)->fc_flags & FC_ABORT_COMPLAINED)) \ 246 LSQ_LOG(log_level, "Abort connection: " __VA_ARGS__); \ 247 (conn)->fc_flags |= flag|FC_ABORT_COMPLAINED; \ 248} while (0) 249 250#define ABORT_ERROR(...) \ 251 ABORT_WITH_FLAG(conn, LSQ_LOG_ERROR, FC_ERROR, __VA_ARGS__) 252#define ABORT_WARN(...) \ 253 ABORT_WITH_FLAG(conn, LSQ_LOG_WARN, FC_ERROR, __VA_ARGS__) 254 255static void 256idle_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now); 257 258static void 259ping_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now); 260 261static void 262handshake_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now); 263 264static void 265ack_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now); 266 267static lsquic_stream_t * 268new_stream (struct full_conn *conn, lsquic_stream_id_t stream_id, 269 enum stream_ctor_flags); 270 271static struct lsquic_stream * 272new_stream_ext (struct full_conn *, lsquic_stream_id_t, enum stream_if, 273 enum stream_ctor_flags); 274 275static void 276reset_ack_state (struct full_conn *conn); 277 278static int 279write_is_possible (struct full_conn *); 280 281static const struct headers_stream_callbacks *headers_callbacks_ptr; 282 283#if KEEP_CLOSED_STREAM_HISTORY 284 285static void 286save_stream_history (struct full_conn *conn, const lsquic_stream_t *stream) 287{ 288 sm_hist_idx_t idx; 289 struct stream_history *const shist = 290 &conn->fc_stream_histories[ conn->fc_stream_hist_idx++ & SHIST_MASK ]; 291 292 shist->shist_stream_id = stream->id; 293 shist->shist_stream_flags = stream->stream_flags; 294 295 idx = stream->sm_hist_idx & SM_HIST_IDX_MASK; 296 if ('\0' == stream->sm_hist_buf[ idx ]) 297 memcpy(shist->shist_hist_buf, stream->sm_hist_buf, idx + 1); 298 else 299 { 300 memcpy(shist->shist_hist_buf, 301 stream->sm_hist_buf + idx, sizeof(stream->sm_hist_buf) - idx); 302 memcpy(shist->shist_hist_buf + sizeof(shist->shist_hist_buf) - idx, 303 stream->sm_hist_buf, idx); 304 } 305} 306 307 308static const struct stream_history * 309find_stream_history (const struct full_conn *conn, lsquic_stream_id_t stream_id) 310{ 311 const struct stream_history *shist; 312 const struct stream_history *const shist_end = 313 conn->fc_stream_histories + (1 << SHIST_BITS); 314 for (shist = conn->fc_stream_histories; shist < shist_end; ++shist) 315 if (shist->shist_stream_id == stream_id) 316 return shist; 317 return NULL; 318} 319 320 321# define SAVE_STREAM_HISTORY(conn, stream) save_stream_history(conn, stream) 322#else 323# define SAVE_STREAM_HISTORY(conn, stream) 324#endif 325 326#if KEEP_PACKET_HISTORY 327static void 328recent_packet_hist_new (struct full_conn *conn, unsigned out, 329 lsquic_time_t time) 330{ 331 unsigned idx; 332 idx = conn->fc_recent_packets[out].idx++ % KEEP_PACKET_HISTORY; 333 conn->fc_recent_packets[out].els[idx].time = time; 334} 335 336static void 337recent_packet_hist_frames (struct full_conn *conn, unsigned out, 338 enum quic_ft_bit frame_types) 339{ 340 unsigned idx; 341 idx = (conn->fc_recent_packets[out].idx - 1) % KEEP_PACKET_HISTORY; 342 conn->fc_recent_packets[out].els[idx].frame_types |= frame_types; 343} 344#else 345#define recent_packet_hist_new(conn, out, time) 346#define recent_packet_hist_frames(conn, out, frames) 347#endif 348 349static unsigned 350highest_bit_set (unsigned sz) 351{ 352#if __GNUC__ 353 unsigned clz = __builtin_clz(sz); 354 return 31 - clz; 355#else 356 unsigned n, y; 357 n = 32; 358 y = sz >> 16; if (y) { n -= 16; sz = y; } 359 y = sz >> 8; if (y) { n -= 8; sz = y; } 360 y = sz >> 4; if (y) { n -= 4; sz = y; } 361 y = sz >> 2; if (y) { n -= 2; sz = y; } 362 y = sz >> 1; if (y) return 31 - n + 2; 363 return 31 - n + sz; 364#endif 365} 366 367 368static size_t 369calc_mem_used (const struct full_conn *conn) 370{ 371 const lsquic_stream_t *stream; 372 const struct lsquic_hash_elem *el; 373 size_t size; 374 375 size = sizeof(*conn); 376 size -= sizeof(conn->fc_send_ctl); 377 size += lsquic_send_ctl_mem_used(&conn->fc_send_ctl); 378 size += lsquic_hash_mem_used(conn->fc_pub.all_streams); 379 size += lsquic_malo_mem_used(conn->fc_pub.packet_out_malo); 380 if (conn->fc_pub.u.gquic.hs) 381 size += lsquic_headers_stream_mem_used(conn->fc_pub.u.gquic.hs); 382 383 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 384 el = lsquic_hash_next(conn->fc_pub.all_streams)) 385 { 386 stream = lsquic_hashelem_getdata(el); 387 size += lsquic_stream_mem_used(stream); 388 } 389 size += conn->fc_conn.cn_esf.g->esf_mem_used(conn->fc_conn.cn_enc_session); 390 391 return size; 392} 393 394 395static void 396set_versions (struct full_conn *conn, unsigned versions, 397 enum lsquic_version *ver) 398{ 399 conn->fc_ver_neg.vn_supp = versions; 400 conn->fc_ver_neg.vn_ver = (ver) ? *ver : highest_bit_set(versions); 401 conn->fc_ver_neg.vn_buf = lsquic_ver2tag(conn->fc_ver_neg.vn_ver); 402 conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver; 403 conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver); 404 LSQ_DEBUG("negotiating version %s", 405 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 406} 407 408 409static void 410init_ver_neg (struct full_conn *conn, unsigned versions, 411 enum lsquic_version *ver) 412{ 413 set_versions(conn, versions, ver); 414 conn->fc_ver_neg.vn_tag = &conn->fc_ver_neg.vn_buf; 415 conn->fc_ver_neg.vn_state = VN_START; 416} 417 418 419/* If peer supplies odd values, we abort the connection immediately rather 420 * that wait for it to finish "naturally" due to inability to send things. 421 */ 422#ifdef NDEBUG 423static 424#endif 425void 426lsquic_full_conn_on_peer_config (struct full_conn *conn, unsigned peer_cfcw, 427 unsigned peer_sfcw, unsigned max_streams_out) 428{ 429 lsquic_stream_t *stream; 430 struct lsquic_hash_elem *el; 431 432 LSQ_INFO("Applying peer config: cfcw: %u; sfcw: %u; # streams: %u", 433 peer_cfcw, peer_sfcw, max_streams_out); 434 435 if (peer_cfcw < conn->fc_pub.conn_cap.cc_sent) 436 { 437 ABORT_ERROR("peer specified CFCW=%u bytes, which is smaller than " 438 "the amount of data already sent on this connection (%"PRIu64 439 " bytes)", peer_cfcw, conn->fc_pub.conn_cap.cc_sent); 440 return; 441 } 442 443 conn->fc_cfg.max_streams_out = max_streams_out; 444 conn->fc_pub.conn_cap.cc_max = peer_cfcw; 445 446 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 447 el = lsquic_hash_next(conn->fc_pub.all_streams)) 448 { 449 stream = lsquic_hashelem_getdata(el); 450 if (0 != lsquic_stream_set_max_send_off(stream, peer_sfcw)) 451 { 452 ABORT_ERROR("cannot set peer-supplied SFCW=%u on stream %"PRIu64, 453 peer_sfcw, stream->id); 454 return; 455 } 456 } 457 458 conn->fc_cfg.max_stream_send = peer_sfcw; 459} 460 461 462static int 463send_smhl (const struct full_conn *conn) 464{ 465 uint32_t smhl; 466 return conn->fc_conn.cn_enc_session 467 && 0 == conn->fc_conn.cn_esf.g->esf_get_peer_setting( 468 conn->fc_conn.cn_enc_session, QTAG_SMHL, &smhl) 469 && 1 == smhl; 470} 471 472 473/* Once handshake has been completed, send settings to peer if appropriate. 474 */ 475static void 476maybe_send_settings (struct full_conn *conn) 477{ 478 struct lsquic_http2_setting settings[2]; 479 unsigned n_settings = 0; 480 481 if (conn->fc_settings->es_max_header_list_size && send_smhl(conn)) 482 { 483 settings[n_settings].id = SETTINGS_MAX_HEADER_LIST_SIZE; 484 settings[n_settings].value = conn->fc_settings->es_max_header_list_size; 485 LSQ_DEBUG("sending settings SETTINGS_MAX_HEADER_LIST_SIZE=%u", 486 settings[n_settings].value); 487 ++n_settings; 488 } 489 if (!(conn->fc_flags & FC_SERVER) && !conn->fc_settings->es_support_push) 490 { 491 settings[n_settings].id = SETTINGS_ENABLE_PUSH; 492 settings[n_settings].value = 0; 493 LSQ_DEBUG("sending settings SETTINGS_ENABLE_PUSH=%u", 494 settings[n_settings].value); 495 ++n_settings; 496 } 497 498 if (n_settings) 499 { 500 if (0 != lsquic_headers_stream_send_settings(conn->fc_pub.u.gquic.hs, 501 settings, n_settings)) 502 ABORT_ERROR("could not send settings"); 503 } 504 else 505 LSQ_DEBUG("not sending any settings"); 506} 507 508 509static int 510apply_peer_settings (struct full_conn *conn) 511{ 512 uint32_t cfcw, sfcw, mids; 513 unsigned n; 514 const struct { 515 uint32_t tag; 516 uint32_t *val; 517 const char *tag_str; 518 } tags[] = { 519 { QTAG_CFCW, &cfcw, "CFCW", }, 520 { QTAG_SFCW, &sfcw, "SFCW", }, 521 { QTAG_MIDS, &mids, "MIDS", }, 522 }; 523 524#ifndef NDEBUG 525 if (getenv("LSQUIC_TEST_ENGINE_DTOR")) 526 return 0; 527#endif 528 529 for (n = 0; n < sizeof(tags) / sizeof(tags[0]); ++n) 530 if (0 != conn->fc_conn.cn_esf.g->esf_get_peer_setting( 531 conn->fc_conn.cn_enc_session, tags[n].tag, tags[n].val)) 532 { 533 LSQ_INFO("peer did not supply value for %s", tags[n].tag_str); 534 return -1; 535 } 536 537 LSQ_DEBUG("peer settings: CFCW: %u; SFCW: %u; MIDS: %u", 538 cfcw, sfcw, mids); 539 lsquic_full_conn_on_peer_config(conn, cfcw, sfcw, mids); 540 return 0; 541} 542 543static const struct conn_iface *full_conn_iface_ptr; 544 545 546/* gQUIC up to version Q046 has handshake stream 1 and headers stream 3. 547 * Q050 and later have "crypto streams" -- meaning CRYPTO frames, not 548 * STREAM frames and no stream IDs -- and headers stream 1. 549 */ 550static lsquic_stream_id_t 551headers_stream_id_by_ver (enum lsquic_version version) 552{ 553 if (version < LSQVER_050) 554 return 3; 555 else 556 return 1; 557} 558 559 560static lsquic_stream_id_t 561headers_stream_id_by_conn (const struct full_conn *conn) 562{ 563 return headers_stream_id_by_ver(conn->fc_conn.cn_version); 564} 565 566 567static lsquic_stream_id_t 568hsk_stream_id (const struct full_conn *conn) 569{ 570 if (conn->fc_conn.cn_version < LSQVER_050) 571 return 1; 572 else 573 /* Use this otherwise invalid stream ID as ID for the gQUIC crypto 574 * stream. 575 */ 576 return (uint64_t) -1; 577} 578 579 580static int 581has_handshake_stream (const struct full_conn *conn) 582{ 583 return conn->fc_conn.cn_version < LSQVER_050; 584} 585 586 587static int 588is_handshake_stream_id (const struct full_conn *conn, 589 lsquic_stream_id_t stream_id) 590{ 591 return conn->fc_conn.cn_version < LSQVER_050 && stream_id == 1; 592} 593 594 595static struct full_conn * 596new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub, 597 unsigned flags, enum lsquic_version version) 598{ 599 struct full_conn *conn; 600 lsquic_stream_t *headers_stream; 601 int saved_errno; 602 603 assert(0 == (flags & ~(FC_SERVER|FC_HTTP))); 604 605 conn = calloc(1, sizeof(*conn)); 606 if (!conn) 607 return NULL; 608 headers_stream = NULL; 609 conn->fc_conn.cn_if = full_conn_iface_ptr; 610 conn->fc_conn.cn_cces = conn->fc_cces; 611 conn->fc_conn.cn_cces_mask = 1; 612 conn->fc_conn.cn_cid = cid; 613 conn->fc_flags = flags; 614 conn->fc_enpub = enpub; 615 conn->fc_pub.enpub = enpub; 616 conn->fc_pub.mm = &enpub->enp_mm; 617 conn->fc_pub.lconn = &conn->fc_conn; 618 conn->fc_pub.send_ctl = &conn->fc_send_ctl; 619#if LSQUIC_CONN_STATS 620 conn->fc_pub.conn_stats = &conn->fc_stats; 621#endif 622 conn->fc_pub.packet_out_malo = 623 lsquic_malo_create(sizeof(struct lsquic_packet_out)); 624 conn->fc_pub.path = &conn->fc_path; 625 conn->fc_pub.max_peer_ack_usec = ACK_TIMEOUT; 626 conn->fc_stream_ifs[STREAM_IF_STD].stream_if = enpub->enp_stream_if; 627 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = enpub->enp_stream_if_ctx; 628 conn->fc_settings = &enpub->enp_settings; 629 /* Calculate maximum number of incoming streams using the same mechanism 630 * and parameters as found in Chrome: 631 */ 632 conn->fc_cfg.max_streams_in = 633 (unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f); 634 if (conn->fc_cfg.max_streams_in < 635 enpub->enp_settings.es_max_streams_in + 10) 636 conn->fc_cfg.max_streams_in = 637 enpub->enp_settings.es_max_streams_in + 10; 638 /* `max_streams_out' gets reset when handshake is complete and we 639 * learn of peer settings. 100 seems like a sane default value 640 * because it is what other implementations use. In server mode, 641 * we do not open any streams until the handshake is complete; in 642 * client mode, we are limited to 98 outgoing requests alongside 643 * handshake and headers streams. 644 */ 645 conn->fc_cfg.max_streams_out = 100; 646 TAILQ_INIT(&conn->fc_pub.sending_streams); 647 TAILQ_INIT(&conn->fc_pub.read_streams); 648 TAILQ_INIT(&conn->fc_pub.write_streams); 649 TAILQ_INIT(&conn->fc_pub.service_streams); 650 STAILQ_INIT(&conn->fc_stream_ids_to_reset); 651 lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW); 652 lsquic_alarmset_init(&conn->fc_alset, &conn->fc_conn); 653 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn); 654 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK_APP, ack_alarm_expired, conn); 655 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn); 656 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn); 657 lsquic_set64_init(&conn->fc_closed_stream_ids[0]); 658 lsquic_set64_init(&conn->fc_closed_stream_ids[1]); 659 lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw); 660 lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub, 661 flags & FC_SERVER ? &server_ver_neg : &conn->fc_ver_neg, 662 &conn->fc_pub, 0); 663 664 conn->fc_pub.all_streams = lsquic_hash_create(); 665 if (!conn->fc_pub.all_streams) 666 goto cleanup_on_error; 667 lsquic_rechist_init(&conn->fc_rechist, 0, MAX_ACK_RANGES); 668 if (conn->fc_flags & FC_HTTP) 669 { 670 conn->fc_pub.u.gquic.hs = lsquic_headers_stream_new( 671 !!(conn->fc_flags & FC_SERVER), conn->fc_enpub, 672 headers_callbacks_ptr, 673#if LSQUIC_CONN_STATS 674 &conn->fc_stats, 675#endif 676 conn); 677 if (!conn->fc_pub.u.gquic.hs) 678 goto cleanup_on_error; 679 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = lsquic_headers_stream_if; 680 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.u.gquic.hs; 681 headers_stream = new_stream_ext(conn, headers_stream_id_by_ver(version), 682 STREAM_IF_HDR, 683 SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_HEADERS); 684 if (!headers_stream) 685 goto cleanup_on_error; 686 } 687 else 688 { 689 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = enpub->enp_stream_if; 690 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = enpub->enp_stream_if_ctx; 691 } 692 if (conn->fc_settings->es_support_push) 693 conn->fc_flags |= FC_SUPPORT_PUSH; 694 conn->fc_conn.cn_n_cces = sizeof(conn->fc_cces) / sizeof(conn->fc_cces[0]); 695 if (conn->fc_settings->es_noprogress_timeout) 696 conn->fc_flags |= FC_NOPROG_TIMEOUT; 697 return conn; 698 699 cleanup_on_error: 700 saved_errno = errno; 701 702 if (conn->fc_pub.all_streams) 703 lsquic_hash_destroy(conn->fc_pub.all_streams); 704 lsquic_rechist_cleanup(&conn->fc_rechist); 705 if (conn->fc_flags & FC_HTTP) 706 { 707 if (conn->fc_pub.u.gquic.hs) 708 lsquic_headers_stream_destroy(conn->fc_pub.u.gquic.hs); 709 if (headers_stream) 710 lsquic_stream_destroy(headers_stream); 711 } 712 memset(conn, 0, sizeof(*conn)); 713 free(conn); 714 715 errno = saved_errno; 716 return NULL; 717} 718 719 720struct lsquic_conn * 721lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub, 722 unsigned versions, unsigned flags, 723 const char *hostname, unsigned short max_packet_size, 724 int is_ipv4, 725 const unsigned char *sess_resume, size_t sess_resume_len) 726{ 727 struct full_conn *conn; 728 enum lsquic_version version, sess_resume_version; 729 lsquic_cid_t cid; 730 const struct enc_session_funcs_gquic *esf_g; 731 732 versions &= (~LSQUIC_IETF_VERSIONS & LSQUIC_SUPPORTED_VERSIONS); 733 assert(versions); 734 version = highest_bit_set(versions); 735 if (sess_resume) 736 { 737 sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_len); 738 if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions)) 739 version = sess_resume_version; 740 } 741 esf_g = select_esf_gquic_by_ver(version); 742 lsquic_generate_cid_gquic(&cid); 743 if (!max_packet_size) 744 { 745 if (enpub->enp_settings.es_base_plpmtu) 746 max_packet_size = enpub->enp_settings.es_base_plpmtu; 747 else if (is_ipv4) 748 max_packet_size = GQUIC_MAX_IPv4_PACKET_SZ; 749 else 750 max_packet_size = GQUIC_MAX_IPv6_PACKET_SZ; 751 } 752 conn = new_conn_common(cid, enpub, flags, version); 753 if (!conn) 754 return NULL; 755 init_ver_neg(conn, versions, &version); 756 conn->fc_path.np_pack_size = max_packet_size; 757 conn->fc_conn.cn_esf_c = select_esf_common_by_ver(version); 758 conn->fc_conn.cn_esf.g = esf_g; 759 conn->fc_conn.cn_enc_session = 760 conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname, 761 cid, conn->fc_enpub, sess_resume, sess_resume_len); 762 if (!conn->fc_conn.cn_enc_session) 763 { 764 LSQ_WARN("could not create enc session: %s", strerror(errno)); 765 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 766 return NULL; 767 } 768 769 if (conn->fc_flags & FC_HTTP) 770 conn->fc_last_stream_id = headers_stream_id_by_conn(conn); /* Client goes (3?), 5, 7, 9.... */ 771 else if (has_handshake_stream(conn)) 772 conn->fc_last_stream_id = 1; 773 else 774 conn->fc_last_stream_id = (uint64_t) -1; /* +2 will get us to 1 */ 775 conn->fc_hsk_ctx.client.lconn = &conn->fc_conn; 776 conn->fc_hsk_ctx.client.mm = &enpub->enp_mm; 777 conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg; 778 conn->fc_stream_ifs[STREAM_IF_HSK] 779 .stream_if = &lsquic_client_hsk_stream_if; 780 conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client; 781 conn->fc_orig_versions = versions; 782 if (conn->fc_settings->es_handshake_to) 783 lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE, 784 lsquic_time_now() + conn->fc_settings->es_handshake_to); 785 if (!new_stream_ext(conn, hsk_stream_id(conn), STREAM_IF_HSK, 786 SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_CRYPTO 787 |(conn->fc_conn.cn_version >= LSQVER_050 ? SCF_CRYPTO_FRAMES : 0))) 788 { 789 LSQ_WARN("could not create handshake stream: %s", strerror(errno)); 790 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 791 return NULL; 792 } 793 conn->fc_flags |= FC_CREATED_OK; 794 LSQ_INFO("Created new client connection"); 795 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "created full connection"); 796 return &conn->fc_conn; 797} 798 799 800static void 801full_conn_ci_client_call_on_new (struct lsquic_conn *lconn) 802{ 803 struct full_conn *const conn = (struct full_conn *) lconn; 804 assert(conn->fc_flags & FC_CREATED_OK); 805 lconn->cn_conn_ctx = conn->fc_stream_ifs[STREAM_IF_STD].stream_if 806 ->on_new_conn(conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, lconn); 807} 808 809 810/* This function is special in that it peeks into fc_send_ctl. Other functions 811 * should not do that. 812 */ 813struct lsquic_conn * 814lsquic_gquic_full_conn_server_new (struct lsquic_engine_public *enpub, 815 unsigned flags, lsquic_conn_t *lconn_mini) 816{ 817 struct full_conn *conn; 818 struct mini_conn *mc; 819 lsquic_conn_t *lconn_full; 820 lsquic_packet_in_t *packet_in; 821 lsquic_packet_out_t *packet_out; 822 lsquic_stream_t *hsk_stream; 823 lsquic_packno_t next_packno; 824 mconn_packno_set_t received; 825 unsigned n; 826 uint32_t tcid0_val; 827 int have_errors = 0, tcid0; 828 int have_outgoing_ack = 0; 829 830 mc = (struct mini_conn *) lconn_mini; 831 conn = new_conn_common(lconn_mini->cn_cid, enpub, flags, 832 lconn_mini->cn_version); 833 if (!conn) 834 return NULL; 835 lconn_full = &conn->fc_conn; 836 conn->fc_last_stream_id = 0; /* Server goes 2, 4, 6.... */ 837 if (conn->fc_flags & FC_HTTP) 838 conn->fc_max_peer_stream_id = headers_stream_id_by_conn(conn); 839 else if (has_handshake_stream(conn)) 840 conn->fc_max_peer_stream_id = 1; 841 else 842 conn->fc_max_peer_stream_id = (uint64_t) -1; 843 conn->fc_stream_ifs[STREAM_IF_HSK] 844 .stream_if = &lsquic_server_hsk_stream_if; 845 conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.server; 846 conn->fc_ver_neg.vn_ver = lconn_mini->cn_version; 847 conn->fc_conn.cn_version = lconn_mini->cn_version; 848 conn->fc_conn.cn_pf = lconn_mini->cn_pf; 849 conn->fc_conn.cn_esf_c = lconn_mini->cn_esf_c; 850 conn->fc_conn.cn_esf.g = lconn_mini->cn_esf.g; 851 conn->fc_conn.cn_flags |= LSCONN_VER_SET | LSCONN_SERVER; 852 conn->fc_pub.rtt_stats = mc->mc_rtt_stats; 853 854 conn->fc_hsk_ctx.server.lconn = lconn_full; 855 conn->fc_hsk_ctx.server.enpub = enpub; 856 857 /* TODO Optimize: we don't need an actual crypto stream and handler 858 * on the server side, as we don't do anything with it. We can 859 * throw out appropriate frames earlier. 860 */ 861 862 /* Adjust offsets in the HANDSHAKE stream: */ 863 hsk_stream = new_stream_ext(conn, hsk_stream_id(conn), STREAM_IF_HSK, 864 SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_CRYPTO 865 |(conn->fc_conn.cn_version >= LSQVER_050 ? SCF_CRYPTO_FRAMES : 0)); 866 if (!hsk_stream) 867 { 868 LSQ_DEBUG("could not create handshake stream: %s", strerror(errno)); 869 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 870 return NULL; 871 } 872 hsk_stream->tosend_off = mc->mc_write_off; 873 hsk_stream->read_offset = mc->mc_read_off; 874 if (0 != lsquic_stream_update_sfcw(hsk_stream, mc->mc_write_off)) 875 { 876 LSQ_WARN("Invalid write offset %u", mc->mc_write_off); 877 ++have_errors; 878 } 879 880 assert(lconn_full->cn_enc_session == NULL); 881 lconn_full->cn_enc_session = lconn_mini->cn_enc_session; 882 lconn_mini->cn_enc_session = NULL; 883 lconn_full->cn_esf_c->esf_set_conn(lconn_full->cn_enc_session, 884 &conn->fc_conn); 885 886 lsquic_send_ctl_verneg_done(&conn->fc_send_ctl); 887 conn->fc_send_ctl.sc_cur_packno = mc->mc_cur_packno; 888 lsquic_send_ctl_begin_optack_detection(&conn->fc_send_ctl); 889 890 /* Remove those that still exist from the set: they will be marked as 891 * received during regular processing in ci_packet_in() later on. 892 */ 893 received = mc->mc_received_packnos; 894 TAILQ_FOREACH(packet_in, &mc->mc_packets_in, pi_next) 895 received &= ~MCONN_PACKET_MASK(packet_in->pi_packno); 896 897 for (n = 0; received; ++n) 898 { 899 if (received & (1U << n)) 900 /* Setting `now' to zero is OK here, as we should have had at 901 * least one other packet above. 902 */ 903 lsquic_rechist_received(&conn->fc_rechist, n + 1, 0); 904 received &= ~(1U << n); 905 } 906 907 /* Mini connection sends out packets 1, 2, 3... and so on. It deletes 908 * packets that have been successfully sent and acked or those that have 909 * been lost. We take ownership of all packets in mc_packets_out; those 910 * that are not on the list are recorded in fc_send_ctl.sc_senhist. 911 */ 912 next_packno = 0; 913 while ((packet_out = TAILQ_FIRST(&mc->mc_packets_out))) 914 { 915 TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next); 916 917 /* Holes in the sequence signify ACKed or lost packets */ 918 ++next_packno; 919 for ( ; next_packno < packet_out->po_packno; ++next_packno) 920 lsquic_senhist_add(&conn->fc_send_ctl.sc_senhist, next_packno); 921 922 packet_out->po_path = &conn->fc_path; 923 if (mc->mc_sent_packnos & MCONN_PACKET_MASK(packet_out->po_packno)) 924 { 925 LSQ_DEBUG("got sent packet_out %"PRIu64" from mini", 926 packet_out->po_packno); 927 if (0 != lsquic_send_ctl_sent_packet(&conn->fc_send_ctl, 928 packet_out) 929 && !have_errors /* Warn once */) 930 { 931 ++have_errors; 932 LSQ_WARN("could not add packet %"PRIu64" to sent set: %s", 933 packet_out->po_packno, strerror(errno)); 934 } 935 } 936 else 937 { 938 LSQ_DEBUG("got unsent packet_out %"PRIu64" from mini (will send)", 939 packet_out->po_packno); 940 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 941 have_outgoing_ack |= packet_out->po_frame_types & 942 (1 << QUIC_FRAME_ACK); 943 } 944 } 945 946 assert(lconn_mini->cn_flags & LSCONN_HANDSHAKE_DONE); 947 lconn_full->cn_flags |= LSCONN_HANDSHAKE_DONE; 948 949 lconn_full->cn_flags |= lconn_mini->cn_flags & 950 LSCONN_PEER_GOING_AWAY /* We are OK with fc_goaway_stream_id = 0 */; 951 conn->fc_path = mc->mc_path; 952 953 if (0 == apply_peer_settings(conn)) 954 { 955 if (conn->fc_flags & FC_HTTP) 956 maybe_send_settings(conn); 957 } 958 else 959 ++have_errors; 960 961 if (0 == have_errors) 962 { 963 tcid0 = conn->fc_settings->es_support_tcid0 964 && 0 == conn->fc_conn.cn_esf.g->esf_get_peer_setting( 965 conn->fc_conn.cn_enc_session, QTAG_TCID, &tcid0_val) 966 && 0 == tcid0_val; 967 lsquic_send_ctl_set_tcid0(&conn->fc_send_ctl, tcid0); 968 if (tcid0) 969 conn->fc_conn.cn_flags |= LSCONN_TCID0; 970 conn->fc_flags |= FC_CREATED_OK|FC_FIRST_TICK; 971 if (conn->fc_conn.cn_version >= LSQVER_046 972 || conn->fc_conn.cn_esf.g->esf_get_peer_option( 973 conn->fc_conn.cn_enc_session, QTAG_NSTP)) 974 { 975 conn->fc_flags |= FC_NSTP; 976 lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl); 977 } 978 LSQ_DEBUG("Calling on_new_conn callback"); 979 lconn_full->cn_conn_ctx = enpub->enp_stream_if->on_new_conn( 980 enpub->enp_stream_if_ctx, &conn->fc_conn); 981 /* Now that user code knows about this connection, process incoming 982 * packets, if any. 983 */ 984 while ((packet_in = TAILQ_FIRST(&mc->mc_packets_in))) 985 { 986 TAILQ_REMOVE(&mc->mc_packets_in, packet_in, pi_next); 987 packet_in->pi_flags |= PI_FROM_MINI; 988 conn->fc_conn.cn_if->ci_packet_in(&conn->fc_conn, packet_in); 989 lsquic_packet_in_put(conn->fc_pub.mm, packet_in); 990 } 991 /* At this point we may have errors, but we promote it anyway: this is 992 * so that CONNECTION_CLOSE frame can be generated and sent out. 993 */ 994 if (have_outgoing_ack) 995 reset_ack_state(conn); 996 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, 997 lsquic_time_now() + conn->fc_settings->es_idle_conn_to); 998 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "created full connection"); 999 LSQ_INFO("Created new server connection"); 1000 return &conn->fc_conn; 1001 } 1002 else 1003 { 1004 LSQ_DEBUG("hit errors creating connection, return NULL"); 1005 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 1006 return NULL; 1007 } 1008} 1009 1010 1011static int 1012is_our_stream (const struct full_conn *conn, const lsquic_stream_t *stream) 1013{ 1014 int is_server = !!(conn->fc_flags & FC_SERVER); 1015 return (1 & stream->id) ^ is_server; 1016} 1017 1018 1019static unsigned 1020count_streams (const struct full_conn *conn, int peer) 1021{ 1022 const lsquic_stream_t *stream; 1023 unsigned count; 1024 int ours; 1025 int is_server; 1026 struct lsquic_hash_elem *el; 1027 1028 peer = !!peer; 1029 is_server = !!(conn->fc_flags & FC_SERVER); 1030 count = 0; 1031 1032 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 1033 el = lsquic_hash_next(conn->fc_pub.all_streams)) 1034 { 1035 stream = lsquic_hashelem_getdata(el); 1036 ours = (1 & stream->id) ^ is_server; 1037 if (ours ^ peer) 1038 count += !(lsquic_stream_is_closed(stream) 1039 /* When counting peer-initiated streams, do not 1040 * include those that have been reset: 1041 */ 1042 || (peer && lsquic_stream_is_reset(stream))); 1043 } 1044 1045 return count; 1046} 1047 1048 1049enum stream_count { SCNT_ALL, SCNT_PEER, SCNT_CLOSED, SCNT_RESET, 1050 SCNT_RES_UNCLO /* reset and not closed */, N_SCNTS }; 1051 1052static void 1053collect_stream_counts (const struct full_conn *conn, int peer, 1054 unsigned counts[N_SCNTS]) 1055{ 1056 const lsquic_stream_t *stream; 1057 int ours; 1058 int is_server; 1059 struct lsquic_hash_elem *el; 1060 1061 peer = !!peer; 1062 is_server = !!(conn->fc_flags & FC_SERVER); 1063 memset(counts, 0, N_SCNTS * sizeof(counts[0])); 1064 1065 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 1066 el = lsquic_hash_next(conn->fc_pub.all_streams)) 1067 { 1068 ++counts[SCNT_ALL]; 1069 stream = lsquic_hashelem_getdata(el); 1070 ours = (1 & stream->id) ^ is_server; 1071 if (ours ^ peer) 1072 { 1073 ++counts[SCNT_PEER]; 1074 counts[SCNT_CLOSED] += lsquic_stream_is_closed(stream); 1075 counts[SCNT_RESET] += !!lsquic_stream_is_reset(stream); 1076 counts[SCNT_RES_UNCLO] += lsquic_stream_is_reset(stream) 1077 && !lsquic_stream_is_closed(stream); 1078 } 1079 } 1080} 1081 1082 1083static void 1084full_conn_ci_destroy (lsquic_conn_t *lconn) 1085{ 1086 struct full_conn *conn = (struct full_conn *) lconn; 1087 struct lsquic_hash_elem *el; 1088 struct lsquic_stream *stream; 1089 struct stream_id_to_reset *sitr; 1090 1091 LSQ_DEBUG("destroy connection"); 1092 conn->fc_flags |= FC_CLOSING; 1093 lsquic_set64_cleanup(&conn->fc_closed_stream_ids[0]); 1094 lsquic_set64_cleanup(&conn->fc_closed_stream_ids[1]); 1095 while ((el = lsquic_hash_first(conn->fc_pub.all_streams))) 1096 { 1097 stream = lsquic_hashelem_getdata(el); 1098 lsquic_hash_erase(conn->fc_pub.all_streams, el); 1099 lsquic_stream_destroy(stream); 1100 } 1101 lsquic_hash_destroy(conn->fc_pub.all_streams); 1102 if (conn->fc_flags & FC_CREATED_OK) 1103 conn->fc_stream_ifs[STREAM_IF_STD].stream_if 1104 ->on_conn_closed(&conn->fc_conn); 1105 if (conn->fc_pub.u.gquic.hs) 1106 lsquic_headers_stream_destroy(conn->fc_pub.u.gquic.hs); 1107 1108 lsquic_send_ctl_cleanup(&conn->fc_send_ctl); 1109 lsquic_rechist_cleanup(&conn->fc_rechist); 1110 if (conn->fc_conn.cn_enc_session) 1111 conn->fc_conn.cn_esf.g->esf_destroy(conn->fc_conn.cn_enc_session); 1112 lsquic_malo_destroy(conn->fc_pub.packet_out_malo); 1113#if LSQUIC_CONN_STATS 1114 LSQ_NOTICE("# ticks: %lu", conn->fc_stats.n_ticks); 1115 LSQ_NOTICE("received %lu packets, of which %lu were not decryptable, %lu were " 1116 "dups and %lu were errors; sent %lu packets, avg stream data per outgoing" 1117 " packet is %lu bytes", 1118 conn->fc_stats.in.packets, conn->fc_stats.in.undec_packets, 1119 conn->fc_stats.in.dup_packets, conn->fc_stats.in.err_packets, 1120 conn->fc_stats.out.packets, 1121 conn->fc_stats.out.stream_data_sz / 1122 (conn->fc_stats.out.packets ? conn->fc_stats.out.packets : 1)); 1123 LSQ_NOTICE("ACKs: in: %lu; processed: %lu; merged: %lu", 1124 conn->fc_stats.in.n_acks, conn->fc_stats.in.n_acks_proc, 1125 conn->fc_stats.in.n_acks_merged); 1126 free(conn->fc_last_stats); 1127#endif 1128 while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset))) 1129 { 1130 STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next); 1131 free(sitr); 1132 } 1133 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "full connection destroyed"); 1134 free(conn->fc_errmsg); 1135 free(conn); 1136} 1137 1138 1139static void 1140conn_mark_stream_closed (struct full_conn *conn, lsquic_stream_id_t stream_id) 1141{ /* Because stream IDs are distributed unevenly -- there is a set of odd 1142 * stream IDs and a set of even stream IDs -- it is more efficient to 1143 * maintain two sets of closed stream IDs. 1144 */ 1145 int idx = stream_id & 1; 1146 stream_id >>= 1; 1147 if (0 != lsquic_set64_add(&conn->fc_closed_stream_ids[idx], stream_id)) 1148 ABORT_ERROR("could not add element to set: %s", strerror(errno)); 1149} 1150 1151 1152static int 1153conn_is_stream_closed (struct full_conn *conn, lsquic_stream_id_t stream_id) 1154{ 1155 int idx = stream_id & 1; 1156 stream_id >>= 1; 1157 return lsquic_set64_has(&conn->fc_closed_stream_ids[idx], stream_id); 1158} 1159 1160 1161static void 1162set_ack_timer (struct full_conn *conn, lsquic_time_t now) 1163{ 1164 lsquic_alarmset_set(&conn->fc_alset, AL_ACK_APP, now + ACK_TIMEOUT); 1165 LSQ_DEBUG("ACK alarm set to %"PRIu64, now + ACK_TIMEOUT); 1166} 1167 1168 1169static void 1170ack_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry, 1171 lsquic_time_t now) 1172{ 1173 struct full_conn *conn = ctx; 1174 LSQ_DEBUG("ACK timer expired (%"PRIu64" < %"PRIu64"): ACK queued", 1175 expiry, now); 1176 conn->fc_flags |= FC_ACK_QUEUED; 1177} 1178 1179 1180static void 1181try_queueing_ack (struct full_conn *conn, int was_missing, lsquic_time_t now) 1182{ 1183 if (conn->fc_n_slack_akbl >= MAX_RETR_PACKETS_SINCE_LAST_ACK || 1184 ((conn->fc_flags & FC_ACK_HAD_MISS) && was_missing) || 1185 lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl) > 1) 1186 { 1187 lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP); 1188 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 1189 conn->fc_flags |= FC_ACK_QUEUED; 1190 LSQ_DEBUG("ACK queued: ackable: %u; had_miss: %d; " 1191 "was_missing: %d; n_stop_waiting: %u", 1192 conn->fc_n_slack_akbl, 1193 !!(conn->fc_flags & FC_ACK_HAD_MISS), was_missing, 1194 lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl)); 1195 } 1196 else if (conn->fc_n_slack_akbl > 0) 1197 set_ack_timer(conn, now); 1198} 1199 1200 1201static void 1202reset_ack_state (struct full_conn *conn) 1203{ 1204 conn->fc_n_slack_akbl = 0; 1205 lsquic_send_ctl_n_stop_waiting_reset(&conn->fc_send_ctl); 1206 conn->fc_flags &= ~FC_ACK_QUEUED; 1207 lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP); 1208 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 1209 LSQ_DEBUG("ACK state reset"); 1210} 1211 1212 1213#if 1 1214# define verify_ack_frame(a, b, c) 1215#else 1216static void 1217verify_ack_frame (struct full_conn *conn, const unsigned char *buf, int bufsz) 1218{ 1219 unsigned i; 1220 int parsed_len; 1221 struct ack_info *ack_info; 1222 const struct lsquic_packno_range *range; 1223 char ack_buf[512]; 1224 unsigned buf_off = 0; 1225 int nw; 1226 1227 ack_info = conn->fc_pub.mm->acki; 1228 parsed_len = parse_ack_frame(buf, bufsz, ack_info); 1229 assert(parsed_len == bufsz); 1230 1231 for (range = lsquic_rechist_first(&conn->fc_rechist), i = 0; range; 1232 range = lsquic_rechist_next(&conn->fc_rechist), ++i) 1233 { 1234 assert(i < ack_info->n_ranges); 1235 assert(range->high == ack_info->ranges[i].high); 1236 assert(range->low == ack_info->ranges[i].low); 1237 if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)) 1238 { 1239 nw = snprintf(ack_buf + buf_off, sizeof(ack_buf) - buf_off, 1240 "[%"PRIu64"-%"PRIu64"]", range->high, range->low); 1241 assert(nw >= 0); 1242 buf_off += nw; 1243 } 1244 } 1245 assert(i == ack_info->n_ranges); 1246 LSQ_DEBUG("Sent ACK frame %s", ack_buf); 1247} 1248#endif 1249 1250 1251static void 1252full_conn_ci_write_ack (struct lsquic_conn *lconn, 1253 struct lsquic_packet_out *packet_out) 1254{ 1255 struct full_conn *conn = (struct full_conn *) lconn; 1256 lsquic_time_t now; 1257 int has_missing, w; 1258 1259 now = lsquic_time_now(); 1260 w = conn->fc_conn.cn_pf->pf_gen_ack_frame( 1261 packet_out->po_data + packet_out->po_data_sz, 1262 lsquic_packet_out_avail(packet_out), 1263 (gaf_rechist_first_f) lsquic_rechist_first, 1264 (gaf_rechist_next_f) lsquic_rechist_next, 1265 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 1266 &conn->fc_rechist, now, &has_missing, &packet_out->po_ack2ed, 1267 NULL); 1268 if (w < 0) { 1269 ABORT_ERROR("generating ACK frame failed: %d", errno); 1270 return; 1271 } 1272#if LSQUIC_CONN_STATS 1273 ++conn->fc_stats.out.acks; 1274#endif 1275 EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, conn->fc_conn.cn_pf, 1276 packet_out->po_data + packet_out->po_data_sz, w); 1277 verify_ack_frame(conn, packet_out->po_data + packet_out->po_data_sz, w); 1278 lsquic_send_ctl_scheduled_ack(&conn->fc_send_ctl, PNS_APP, 1279 packet_out->po_ack2ed); 1280 packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK; 1281 if (0 != lsquic_packet_out_add_frame(packet_out, conn->fc_pub.mm, 0, 1282 QUIC_FRAME_ACK, packet_out->po_data_sz, w)) 1283 { 1284 ABORT_ERROR("adding frame to packet failed: %d", errno); 1285 return; 1286 } 1287 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, w); 1288 packet_out->po_regen_sz += w; 1289 if (has_missing) 1290 conn->fc_flags |= FC_ACK_HAD_MISS; 1291 else 1292 conn->fc_flags &= ~FC_ACK_HAD_MISS; 1293 LSQ_DEBUG("Put %d bytes of ACK frame into packet on outgoing queue", w); 1294 if (conn->fc_n_cons_unretx >= 20 && 1295 !lsquic_send_ctl_have_outgoing_retx_frames(&conn->fc_send_ctl)) 1296 { 1297 LSQ_DEBUG("schedule WINDOW_UPDATE frame after %u non-retx " 1298 "packets sent", conn->fc_n_cons_unretx); 1299 conn->fc_flags |= FC_SEND_WUF; 1300 } 1301 reset_ack_state(conn); 1302} 1303 1304 1305static lsquic_stream_t * 1306new_stream_ext (struct full_conn *conn, lsquic_stream_id_t stream_id, 1307 enum stream_if if_idx, enum stream_ctor_flags stream_ctor_flags) 1308{ 1309 struct lsquic_stream *stream; 1310 1311 stream = lsquic_stream_new(stream_id, &conn->fc_pub, 1312 conn->fc_stream_ifs[if_idx].stream_if, 1313 conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw, 1314 stream_ctor_flags & SCF_CRYPTO 1315 ? 16 * 1024 : conn->fc_cfg.max_stream_send, 1316 stream_ctor_flags); 1317 if (stream) 1318 lsquic_hash_insert(conn->fc_pub.all_streams, &stream->id, 1319 sizeof(stream->id), stream, &stream->sm_hash_el); 1320 return stream; 1321} 1322 1323 1324static lsquic_stream_t * 1325new_stream (struct full_conn *conn, lsquic_stream_id_t stream_id, 1326 enum stream_ctor_flags flags) 1327{ 1328 flags |= SCF_DI_AUTOSWITCH; 1329 if (conn->fc_pub.u.gquic.hs) 1330 flags |= SCF_HTTP; 1331 if (conn->fc_enpub->enp_settings.es_rw_once) 1332 flags |= SCF_DISP_RW_ONCE; 1333 if (conn->fc_enpub->enp_settings.es_delay_onclose) 1334 flags |= SCF_DELAY_ONCLOSE; 1335 1336 return new_stream_ext(conn, stream_id, STREAM_IF_STD, flags); 1337} 1338 1339 1340static lsquic_stream_id_t 1341generate_stream_id (struct full_conn *conn) 1342{ 1343 conn->fc_last_stream_id += 2; 1344 return conn->fc_last_stream_id; 1345} 1346 1347 1348static unsigned 1349full_conn_ci_n_pending_streams (const struct lsquic_conn *lconn) 1350{ 1351 const struct full_conn *conn = (const struct full_conn *) lconn; 1352 return conn->fc_n_delayed_streams; 1353} 1354 1355 1356static unsigned 1357full_conn_ci_cancel_pending_streams (struct lsquic_conn *lconn, unsigned n) 1358{ 1359 struct full_conn *conn = (struct full_conn *) lconn; 1360 if (n > conn->fc_n_delayed_streams) 1361 conn->fc_n_delayed_streams = 0; 1362 else 1363 conn->fc_n_delayed_streams -= n; 1364 return conn->fc_n_delayed_streams; 1365} 1366 1367 1368static int 1369either_side_going_away (const struct full_conn *conn) 1370{ 1371 return (conn->fc_flags & FC_GOING_AWAY) 1372 || (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY); 1373} 1374 1375 1376static unsigned 1377full_conn_ci_n_avail_streams (const lsquic_conn_t *lconn) 1378{ 1379 struct full_conn *conn = (struct full_conn *) lconn; 1380 unsigned stream_count = count_streams(conn, 0); 1381 if (conn->fc_cfg.max_streams_out < stream_count) 1382 return 0; 1383 return conn->fc_cfg.max_streams_out - stream_count; 1384} 1385 1386 1387static int 1388handshake_done_or_doing_sess_resume (const struct full_conn *conn) 1389{ 1390 return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) 1391 || conn->fc_conn.cn_esf_c->esf_is_sess_resume_enabled( 1392 conn->fc_conn.cn_enc_session); 1393} 1394 1395 1396static void 1397full_conn_ci_make_stream (struct lsquic_conn *lconn) 1398{ 1399 struct full_conn *conn = (struct full_conn *) lconn; 1400 if (handshake_done_or_doing_sess_resume(conn) 1401 && full_conn_ci_n_avail_streams(lconn) > 0) 1402 { 1403 if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW)) 1404 ABORT_ERROR("could not create new stream: %s", strerror(errno)); 1405 } 1406 else if (either_side_going_away(conn)) 1407 (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream( 1408 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL); 1409 else 1410 { 1411 ++conn->fc_n_delayed_streams; 1412 LSQ_DEBUG("delayed stream creation. Backlog size: %u", 1413 conn->fc_n_delayed_streams); 1414 } 1415} 1416 1417 1418static lsquic_stream_t * 1419find_stream_by_id (struct full_conn *conn, lsquic_stream_id_t stream_id) 1420{ 1421 struct lsquic_hash_elem *el; 1422 el = lsquic_hash_find(conn->fc_pub.all_streams, &stream_id, sizeof(stream_id)); 1423 if (el) 1424 return lsquic_hashelem_getdata(el); 1425 else 1426 return NULL; 1427} 1428 1429 1430static struct lsquic_stream * 1431full_conn_ci_get_stream_by_id (struct lsquic_conn *lconn, 1432 lsquic_stream_id_t stream_id) 1433{ 1434 struct full_conn *conn = (struct full_conn *) lconn; 1435 struct lsquic_stream *stream; 1436 1437 stream = find_stream_by_id(conn, stream_id); 1438 if (stream && !lsquic_stream_is_closed(stream)) 1439 return stream; 1440 else 1441 return NULL; 1442} 1443 1444 1445static struct lsquic_engine * 1446full_conn_ci_get_engine (struct lsquic_conn *lconn) 1447{ 1448 struct full_conn *conn = (struct full_conn *) lconn; 1449 return conn->fc_enpub->enp_engine; 1450} 1451 1452 1453static struct network_path * 1454full_conn_ci_get_path (struct lsquic_conn *lconn, const struct sockaddr *sa) 1455{ 1456 struct full_conn *conn = (struct full_conn *) lconn; 1457 1458 return &conn->fc_path; 1459} 1460 1461 1462static unsigned char 1463full_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, 1464 const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 1465{ 1466 struct full_conn *conn = (struct full_conn *) lconn; 1467 1468 if (NP_IS_IPv6(&conn->fc_path) != (AF_INET6 == peer_sa->sa_family)) 1469 lsquic_send_ctl_return_enc_data(&conn->fc_send_ctl); 1470 1471 size_t len = peer_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) 1472 : sizeof(struct sockaddr_in6); 1473 1474 memcpy(conn->fc_path.np_peer_addr, peer_sa, len); 1475 1476 len = local_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) 1477 : sizeof(struct sockaddr_in6); 1478 memcpy(conn->fc_path.np_local_addr, local_sa, len); 1479 conn->fc_path.np_peer_ctx = peer_ctx; 1480 return 0; 1481} 1482 1483 1484static ptrdiff_t 1485count_zero_bytes (const unsigned char *p, size_t len) 1486{ 1487 const unsigned char *const end = p + len; 1488 while (p < end && 0 == *p) 1489 ++p; 1490 return len - (end - p); 1491} 1492 1493 1494static unsigned 1495process_padding_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1496 const unsigned char *p, size_t len) 1497{ 1498 len = (size_t) count_zero_bytes(p, len); 1499 EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len); 1500 return len; 1501} 1502 1503 1504static void 1505log_conn_flow_control (struct full_conn *conn) 1506{ 1507 LSQ_DEBUG("connection flow cap: wrote: %"PRIu64 1508 "; max: %"PRIu64, conn->fc_pub.conn_cap.cc_sent, 1509 conn->fc_pub.conn_cap.cc_max); 1510 LSQ_DEBUG("connection flow control window: read: %"PRIu64 1511 "; max: %"PRIu64, conn->fc_pub.cfcw.cf_max_recv_off, 1512 conn->fc_pub.cfcw.cf_recv_off); 1513} 1514 1515 1516static unsigned 1517process_ping_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1518 const unsigned char *p, size_t len) 1519{ /* This frame causes ACK frame to be queued, but nothing to do here; 1520 * return the length of this frame. 1521 */ 1522 EV_LOG_PING_FRAME_IN(LSQUIC_LOG_CONN_ID); 1523 LSQ_DEBUG("received PING"); 1524 if (conn->fc_flags & FC_SERVER) 1525 log_conn_flow_control(conn); 1526 return 1; 1527} 1528 1529 1530static int 1531is_peer_initiated (const struct full_conn *conn, lsquic_stream_id_t stream_id) 1532{ 1533 unsigned is_server = !!(conn->fc_flags & FC_SERVER); 1534 int peer_initiated = (stream_id & 1) == is_server; 1535 return peer_initiated; 1536} 1537 1538 1539static void 1540maybe_schedule_reset_for_stream (struct full_conn *conn, lsquic_stream_id_t stream_id) 1541{ 1542 struct stream_id_to_reset *sitr; 1543 1544 if (conn_is_stream_closed(conn, stream_id)) 1545 return; 1546 1547 sitr = malloc(sizeof(*sitr)); 1548 if (!sitr) 1549 return; 1550 1551 sitr->sitr_stream_id = stream_id; 1552 STAILQ_INSERT_TAIL(&conn->fc_stream_ids_to_reset, sitr, sitr_next); 1553 conn_mark_stream_closed(conn, stream_id); 1554} 1555 1556 1557static unsigned 1558process_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1559 const unsigned char *p, size_t len) 1560{ 1561 stream_frame_t *stream_frame; 1562 lsquic_stream_t *stream; 1563 enum enc_level enc_level; 1564 int parsed_len; 1565 1566#ifndef LSQUIC_REDO_FAILED_INSERTION 1567#define LSQUIC_REDO_FAILED_INSERTION 0 1568#endif 1569#if LSQUIC_REDO_FAILED_INSERTION 1570 enum lsq_log_level saved_levels[3]; 1571#if defined(__GNUC__) && !defined(__clang__) 1572 /* gcc complains about this -- incorrectly -- in optimized mode */ 1573 saved_levels[0] = 0; 1574 saved_levels[1] = 0; 1575 saved_levels[2] = 0; 1576#endif 1577 int again = 0; 1578 redo: 1579#endif 1580 stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame); 1581 if (!stream_frame) 1582 { 1583 LSQ_WARN("could not allocate stream frame: %s", strerror(errno)); 1584 return 0; 1585 } 1586 1587 parsed_len = conn->fc_conn.cn_pf->pf_parse_stream_frame(p, len, 1588 stream_frame); 1589 if (parsed_len < 0) { 1590 lsquic_malo_put(stream_frame); 1591 return 0; 1592 } 1593 EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame); 1594 LSQ_DEBUG("Got stream frame for stream #%"PRIu64, stream_frame->stream_id); 1595#if LSQUIC_CONN_STATS 1596 ++conn->fc_stats.in.stream_frames; 1597 conn->fc_stats.in.stream_data_sz += stream_frame->data_frame.df_size; 1598#endif 1599 1600 enc_level = lsquic_packet_in_enc_level(packet_in); 1601 if (!is_handshake_stream_id(conn, stream_frame->stream_id) 1602 && enc_level == ENC_LEV_CLEAR) 1603 { 1604 lsquic_malo_put(stream_frame); 1605 ABORT_ERROR("received unencrypted data for stream %"PRIu64, 1606 stream_frame->stream_id); 1607 return 0; 1608 } 1609 1610 if (conn->fc_flags & FC_CLOSING) 1611 { 1612 LSQ_DEBUG("Connection closing: ignore frame"); 1613 lsquic_malo_put(stream_frame); 1614 return parsed_len; 1615 } 1616 1617 stream = find_stream_by_id(conn, stream_frame->stream_id); 1618 if (stream) 1619 { 1620 if (lsquic_stream_is_reset(stream)) 1621 { 1622 LSQ_DEBUG("stream %"PRIu64" is reset, ignore frame", stream->id); 1623 lsquic_malo_put(stream_frame); 1624 return parsed_len; 1625 } 1626 } 1627 else 1628 { 1629 if (conn_is_stream_closed(conn, stream_frame->stream_id)) 1630 { 1631 LSQ_DEBUG("drop frame for closed stream %"PRIu64, 1632 stream_frame->stream_id); 1633 lsquic_malo_put(stream_frame); 1634 return parsed_len; 1635 } 1636 if (is_peer_initiated(conn, stream_frame->stream_id)) 1637 { 1638 unsigned in_count = count_streams(conn, 1); 1639 LSQ_DEBUG("number of peer-initiated streams: %u", in_count); 1640 if (in_count >= conn->fc_cfg.max_streams_in) 1641 { 1642 if (!(conn->fc_flags & FC_ABORT_COMPLAINED)) 1643 { 1644 unsigned counts[N_SCNTS]; 1645 collect_stream_counts(conn, 1, counts); 1646 ABORT_WARN("incoming stream would exceed limit: %u. " 1647 "all: %u; peer: %u; closed: %u; reset: %u; reset " 1648 "and not closed: %u", conn->fc_cfg.max_streams_in, 1649 counts[SCNT_ALL], counts[SCNT_PEER], 1650 counts[SCNT_CLOSED], counts[SCNT_RESET], 1651 counts[SCNT_RES_UNCLO]); 1652 } 1653 lsquic_malo_put(stream_frame); 1654 return 0; 1655 } 1656 if ((conn->fc_flags & FC_GOING_AWAY) && 1657 stream_frame->stream_id > conn->fc_max_peer_stream_id) 1658 { 1659 LSQ_DEBUG("going away: reset new incoming stream %"PRIu64, 1660 stream_frame->stream_id); 1661 maybe_schedule_reset_for_stream(conn, stream_frame->stream_id); 1662 lsquic_malo_put(stream_frame); 1663 return parsed_len; 1664 } 1665 } 1666 else 1667 { 1668 ABORT_ERROR("frame for never-initiated stream"); 1669 lsquic_malo_put(stream_frame); 1670 return 0; 1671 } 1672 stream = new_stream(conn, stream_frame->stream_id, SCF_CALL_ON_NEW); 1673 if (!stream) 1674 { 1675 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 1676 lsquic_malo_put(stream_frame); 1677 return 0; 1678 } 1679 if (stream_frame->stream_id > conn->fc_max_peer_stream_id) 1680 conn->fc_max_peer_stream_id = stream_frame->stream_id; 1681 } 1682 1683 stream_frame->packet_in = lsquic_packet_in_get(packet_in); 1684 if (0 != lsquic_stream_frame_in(stream, stream_frame)) 1685 { 1686 ABORT_ERROR("cannot insert stream frame"); 1687#if LSQUIC_REDO_FAILED_INSERTION 1688 if (again++) 1689 { 1690 lsq_log_levels[LSQLM_STREAM] = saved_levels[0]; 1691 lsq_log_levels[LSQLM_DI] = saved_levels[1]; 1692 lsq_log_levels[LSQLM_CONN] = saved_levels[2]; 1693 } 1694 else if (!(LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_STREAM) 1695 && LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_DI) 1696 && LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_CONN))) 1697 { 1698 saved_levels[0] = lsq_log_levels[LSQLM_STREAM]; 1699 saved_levels[1] = lsq_log_levels[LSQLM_DI]; 1700 saved_levels[2] = lsq_log_levels[LSQLM_CONN]; 1701 lsq_log_levels[LSQLM_STREAM] = LSQ_LOG_DEBUG; 1702 lsq_log_levels[LSQLM_DI] = LSQ_LOG_DEBUG; 1703 lsq_log_levels[LSQLM_CONN] = LSQ_LOG_DEBUG; 1704 lsquic_stream_dump_state(stream); 1705 LSQ_DEBUG("inserting frame again, this time with debug logging"); 1706 goto redo; 1707 } 1708#endif 1709 return 0; 1710 } 1711 1712 if (lsquic_stream_is_crypto(stream) 1713 && (stream->sm_qflags & SMQF_WANT_READ) 1714 && !(conn->fc_flags & FC_SERVER) 1715 && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)) 1716 { /* To enable decryption, process handshake stream as soon as its 1717 * data frames are received. 1718 * 1719 * TODO: this does not work when packets are reordered. A more 1720 * flexible solution would defer packet decryption if handshake 1721 * has not been completed yet. Nevertheless, this is good enough 1722 * for now. 1723 */ 1724 lsquic_stream_dispatch_read_events(stream); 1725 } 1726 1727 return parsed_len; 1728} 1729 1730 1731static unsigned 1732process_crypto_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1733 const unsigned char *p, size_t len) 1734{ 1735 struct lsquic_stream *stream; 1736 stream_frame_t *stream_frame; 1737 enum enc_level enc_level; 1738 int parsed_len; 1739 1740 stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame); 1741 if (!stream_frame) 1742 { 1743 LSQ_WARN("could not allocate stream frame: %s", strerror(errno)); 1744 return 0; 1745 } 1746 1747 parsed_len = conn->fc_conn.cn_pf->pf_parse_crypto_frame(p, len, 1748 stream_frame); 1749 if (parsed_len < 0) 1750 { 1751 lsquic_malo_put(stream_frame); 1752 return 0; 1753 } 1754 enc_level = lsquic_packet_in_enc_level(packet_in); 1755 EV_LOG_CRYPTO_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame, enc_level); 1756 LSQ_DEBUG("Got CRYPTO frame on enc level %s", lsquic_enclev2str[enc_level]); 1757 1758 if (enc_level < conn->fc_crypto_enc_level) 1759 { 1760 LSQ_DEBUG("Old enc level: ignore frame"); 1761 lsquic_malo_put(stream_frame); 1762 return parsed_len; 1763 } 1764 1765 if (conn->fc_flags & FC_CLOSING) 1766 { 1767 LSQ_DEBUG("Connection closing: ignore frame"); 1768 lsquic_malo_put(stream_frame); 1769 return parsed_len; 1770 } 1771 1772 stream = find_stream_by_id(conn, hsk_stream_id(conn)); 1773 if (!stream) 1774 { 1775 LSQ_WARN("cannot find handshake stream for CRYPTO frame"); 1776 lsquic_malo_put(stream_frame); 1777 return 0; 1778 } 1779 1780 if (enc_level > conn->fc_crypto_enc_level) 1781 { 1782 stream->read_offset = 0; 1783 stream->tosend_off = 0; 1784 conn->fc_crypto_enc_level = enc_level; 1785 LSQ_DEBUG("reset handshake stream offsets, new enc level %u", 1786 (unsigned) enc_level); 1787 } 1788 1789 stream_frame->packet_in = lsquic_packet_in_get(packet_in); 1790 if (0 != lsquic_stream_frame_in(stream, stream_frame)) 1791 { 1792 ABORT_ERROR("cannot insert stream frame"); 1793 return 0; 1794 } 1795 1796 if ((stream->sm_qflags & SMQF_WANT_READ) 1797 && !(conn->fc_flags & FC_SERVER) 1798 && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)) 1799 { 1800 /* XXX what happens for server? */ 1801 lsquic_stream_dispatch_read_events(stream); 1802 } 1803 1804 return parsed_len; 1805} 1806 1807 1808static unsigned 1809process_invalid_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1810 const unsigned char *p, size_t len) 1811{ 1812 ABORT_ERROR("invalid frame"); 1813 return 0; 1814} 1815 1816 1817/* Reset locally-initiated streams whose IDs is larger than the stream ID 1818 * specified in received GOAWAY frame. 1819 */ 1820static void 1821reset_local_streams_over_goaway (struct full_conn *conn) 1822{ 1823 const unsigned is_server = !!(conn->fc_flags & FC_SERVER); 1824 lsquic_stream_t *stream; 1825 struct lsquic_hash_elem *el; 1826 1827 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 1828 el = lsquic_hash_next(conn->fc_pub.all_streams)) 1829 { 1830 stream = lsquic_hashelem_getdata(el); 1831 if (stream->id > conn->fc_goaway_stream_id && 1832 ((stream->id & 1) ^ is_server /* Locally initiated? */)) 1833 { 1834 lsquic_stream_received_goaway(stream); 1835 } 1836 } 1837} 1838 1839 1840static unsigned 1841process_goaway_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1842 const unsigned char *p, size_t len) 1843{ 1844 lsquic_stream_id_t stream_id; 1845 uint32_t error_code; 1846 uint16_t reason_length; 1847 const char *reason; 1848 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_goaway_frame(p, len, 1849 &error_code, &stream_id, &reason_length, &reason); 1850 if (parsed_len < 0) 1851 return 0; 1852 EV_LOG_GOAWAY_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, stream_id, 1853 reason_length, reason); 1854 LSQ_DEBUG("received GOAWAY frame, last good stream ID: %"PRIu64 1855 ", error code: 0x%X, reason: `%.*s'", stream_id, error_code, 1856 reason_length, reason); 1857 if (0 == (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY)) 1858 { 1859 conn->fc_conn.cn_flags |= LSCONN_PEER_GOING_AWAY; 1860 conn->fc_goaway_stream_id = stream_id; 1861 if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received) 1862 { 1863 LSQ_DEBUG("calling on_goaway_received"); 1864 conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received( 1865 &conn->fc_conn); 1866 } 1867 else 1868 LSQ_DEBUG("on_goaway_received not registered"); 1869 reset_local_streams_over_goaway(conn); 1870 } 1871 else 1872 LSQ_DEBUG("ignore duplicate GOAWAY frame"); 1873 return parsed_len; 1874} 1875 1876 1877static void 1878log_invalid_ack_frame (struct full_conn *conn, const unsigned char *p, 1879 int parsed_len, const struct ack_info *acki) 1880{ 1881 char *buf; 1882 1883 buf = malloc(0x1000); 1884 if (!buf) 1885 { 1886 LSQ_WARN("malloc failed"); 1887 return; 1888 } 1889 1890 lsquic_senhist_tostr(&conn->fc_send_ctl.sc_senhist, buf, 0x1000); 1891 LSQ_WARN("send history: %s", buf); 1892 lsquic_hexdump(p, parsed_len, buf, 0x1000); 1893 LSQ_WARN("raw ACK frame:\n%s", buf); 1894 lsquic_acki2str(acki, buf, 0x1000); 1895 LSQ_WARN("parsed ACK frame: %s", buf); 1896 free(buf); 1897} 1898 1899 1900static int 1901process_ack (struct full_conn *conn, struct ack_info *acki, 1902 lsquic_time_t received, lsquic_time_t now) 1903{ 1904#if LSQUIC_CONN_STATS 1905 ++conn->fc_stats.in.n_acks_proc; 1906#endif 1907 LSQ_DEBUG("Processing ACK"); 1908 if (0 == lsquic_send_ctl_got_ack(&conn->fc_send_ctl, acki, received, now)) 1909 { 1910 if (lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl, PNS_APP)) 1911 lsquic_rechist_stop_wait(&conn->fc_rechist, 1912 lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl, PNS_APP) 1913 + 1); 1914 return 0; 1915 } 1916 else 1917 { 1918 ABORT_ERROR("Received invalid ACK"); 1919 return -1; 1920 } 1921} 1922 1923 1924static unsigned 1925process_ack_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1926 const unsigned char *p, size_t len) 1927{ 1928 struct ack_info *new_acki; 1929 int parsed_len; 1930 lsquic_time_t warn_time; 1931 1932#if LSQUIC_CONN_STATS 1933 ++conn->fc_stats.in.n_acks; 1934#endif 1935 1936 if (conn->fc_flags & FC_HAVE_SAVED_ACK) 1937 new_acki = conn->fc_pub.mm->acki; 1938 else 1939 new_acki = &conn->fc_ack; 1940 1941 parsed_len = conn->fc_conn.cn_pf->pf_parse_ack_frame(p, len, new_acki, 0); 1942 if (parsed_len < 0) 1943 goto err; 1944 1945 if (empty_ack_frame(new_acki)) 1946 { 1947 LSQ_DEBUG("Ignore empty ACK frame"); 1948 return parsed_len; 1949 } 1950 if (packet_in->pi_packno <= conn->fc_max_ack_packno) 1951 { 1952 LSQ_DEBUG("Ignore old ack (max %"PRIu64")", conn->fc_max_ack_packno); 1953 return parsed_len; 1954 } 1955 1956 new_acki->pns = PNS_APP; 1957 EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, new_acki); 1958 conn->fc_max_ack_packno = packet_in->pi_packno; 1959 1960 if (new_acki == &conn->fc_ack) 1961 { 1962 LSQ_DEBUG("Saved ACK"); 1963 conn->fc_flags |= FC_HAVE_SAVED_ACK; 1964 conn->fc_saved_ack_received = packet_in->pi_received; 1965 } 1966 else 1967 { 1968 if (0 == lsquic_merge_acks(&conn->fc_ack, new_acki)) 1969 { 1970#if LSQUIC_CONN_STATS 1971 ++conn->fc_stats.in.n_acks_merged; 1972#endif 1973 LSQ_DEBUG("merged into saved ACK, getting %s", 1974 (lsquic_acki2str(&conn->fc_ack, conn->fc_pub.mm->ack_str, 1975 MAX_ACKI_STR_SZ), conn->fc_pub.mm->ack_str)); 1976 } 1977 else 1978 { 1979 LSQ_DEBUG("could not merge new ACK into saved ACK"); 1980 if (0 != process_ack(conn, &conn->fc_ack, packet_in->pi_received, 1981 packet_in->pi_received)) 1982 goto err; 1983 conn->fc_ack = *new_acki; 1984 } 1985 conn->fc_saved_ack_received = packet_in->pi_received; 1986 } 1987 1988 return parsed_len; 1989 1990 err: 1991 warn_time = lsquic_time_now(); 1992 if (0 == conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL] 1993 || conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL] 1994 + WARNING_INTERVAL < warn_time) 1995 { 1996 conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL] = warn_time; 1997 log_invalid_ack_frame(conn, p, parsed_len, new_acki); 1998 } 1999 return 0; 2000} 2001 2002 2003static unsigned 2004process_stop_waiting_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2005 const unsigned char *p, size_t len) 2006{ 2007 lsquic_packno_t least, cutoff; 2008 enum packno_bits bits; 2009 int parsed_len; 2010 2011 bits = lsquic_packet_in_packno_bits(packet_in); 2012 2013 if (conn->fc_flags & FC_NSTP) 2014 { 2015 LSQ_DEBUG("NSTP on: ignore STOP_WAITING frame"); 2016 parsed_len = conn->fc_conn.cn_pf->pf_skip_stop_waiting_frame(len, bits); 2017 if (parsed_len > 0) 2018 return (unsigned) parsed_len; 2019 else 2020 return 0; 2021 } 2022 2023 parsed_len = conn->fc_conn.cn_pf->pf_parse_stop_waiting_frame(p, len, 2024 packet_in->pi_packno, bits, &least); 2025 if (parsed_len < 0) 2026 return 0; 2027 2028 if (packet_in->pi_packno <= conn->fc_max_swf_packno) 2029 { 2030 LSQ_DEBUG("ignore old STOP_WAITING frame"); 2031 return parsed_len; 2032 } 2033 2034 LSQ_DEBUG("Got STOP_WAITING frame, least unacked: %"PRIu64, least); 2035 EV_LOG_STOP_WAITING_FRAME_IN(LSQUIC_LOG_CONN_ID, least); 2036 2037 if (least > packet_in->pi_packno) 2038 { 2039 ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is larger " 2040 "than the packet number%"PRIu64, least, packet_in->pi_packno); 2041 return 0; 2042 } 2043 2044 cutoff = lsquic_rechist_cutoff(&conn->fc_rechist); 2045 if (cutoff && least < cutoff) 2046 { 2047 ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is smaller " 2048 "than the cutoff %"PRIu64, least, cutoff); 2049 return 0; 2050 } 2051 2052 conn->fc_max_swf_packno = packet_in->pi_packno; 2053 lsquic_rechist_stop_wait(&conn->fc_rechist, least); 2054 return parsed_len; 2055} 2056 2057 2058static unsigned 2059process_blocked_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2060 const unsigned char *p, size_t len) 2061{ 2062 lsquic_stream_id_t stream_id; 2063 struct lsquic_stream *stream; 2064 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_blocked_frame(p, len, 2065 &stream_id); 2066 if (parsed_len < 0) 2067 return 0; 2068 EV_LOG_BLOCKED_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id); 2069 LSQ_DEBUG("Peer reports stream %"PRIu64" as blocked", stream_id); 2070 if (stream_id) 2071 { 2072 stream = find_stream_by_id(conn, stream_id); 2073 if (stream) 2074 lsquic_stream_peer_blocked_gquic(stream); 2075 } 2076 else 2077 conn->fc_flags |= FC_SEND_WUF; 2078 return parsed_len; 2079} 2080 2081 2082static unsigned 2083process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2084 const unsigned char *p, size_t len) 2085{ 2086 lsquic_stream_t *stream; 2087 struct lsquic_hash_elem *el; 2088 uint64_t error_code; 2089 uint16_t reason_len; 2090 uint8_t reason_off; 2091 int parsed_len; 2092 2093 parsed_len = conn->fc_conn.cn_pf->pf_parse_connect_close_frame(p, len, 2094 NULL, &error_code, &reason_len, &reason_off); 2095 if (parsed_len < 0) 2096 return 0; 2097 EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, 2098 (int) reason_len, (const char *) p + reason_off); 2099 LSQ_INFO("Received CONNECTION_CLOSE frame (code: %"PRIu64"; reason: %.*s)", 2100 error_code, (int) reason_len, (const char *) p + reason_off); 2101 if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received) 2102 conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received( 2103 &conn->fc_conn, -1, error_code, (const char *) p + reason_off, reason_len); 2104 conn->fc_flags |= FC_RECV_CLOSE; 2105 if (!(conn->fc_flags & FC_CLOSING)) 2106 { 2107 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 2108 el = lsquic_hash_next(conn->fc_pub.all_streams)) 2109 { 2110 stream = lsquic_hashelem_getdata(el); 2111 lsquic_stream_shutdown_internal(stream); 2112 } 2113 conn->fc_flags |= FC_CLOSING; 2114 } 2115 return parsed_len; 2116} 2117 2118 2119static unsigned 2120process_rst_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2121 const unsigned char *p, size_t len) 2122{ 2123 lsquic_stream_id_t stream_id; 2124 uint64_t offset, error_code; 2125 lsquic_stream_t *stream; 2126 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_rst_frame(p, len, 2127 &stream_id, &offset, &error_code); 2128 if (parsed_len < 0) 2129 return 0; 2130 2131 EV_LOG_RST_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset, 2132 error_code); 2133 LSQ_DEBUG("Got RST_STREAM; stream: %"PRIu64"; offset: 0x%"PRIX64, stream_id, 2134 offset); 2135 if (0 == stream_id) 2136 { /* Follow reference implementation and ignore this apparently 2137 * invalid frame. 2138 */ 2139 return parsed_len; 2140 } 2141 2142 stream = find_stream_by_id(conn, stream_id); 2143 if (stream && lsquic_stream_is_critical(stream)) 2144 { 2145 ABORT_ERROR("received reset on static stream %"PRIu64, stream_id); 2146 return 0; 2147 } 2148 if (!stream) 2149 { 2150 if (conn_is_stream_closed(conn, stream_id)) 2151 { 2152 LSQ_DEBUG("got reset frame for closed stream %"PRIu64, stream_id); 2153 return parsed_len; 2154 } 2155 if (!is_peer_initiated(conn, stream_id)) 2156 { 2157 ABORT_ERROR("received reset for never-initiated stream %"PRIu64, 2158 stream_id); 2159 return 0; 2160 } 2161 stream = new_stream(conn, stream_id, SCF_CALL_ON_NEW); 2162 if (!stream) 2163 { 2164 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 2165 return 0; 2166 } 2167 if (stream_id > conn->fc_max_peer_stream_id) 2168 conn->fc_max_peer_stream_id = stream_id; 2169 } 2170 2171 if (0 != lsquic_stream_rst_in(stream, offset, error_code)) 2172 { 2173 ABORT_ERROR("received invalid RST_STREAM"); 2174 return 0; 2175 } 2176 return parsed_len; 2177} 2178 2179 2180static unsigned 2181process_window_update_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2182 const unsigned char *p, size_t len) 2183{ 2184 lsquic_stream_id_t stream_id; 2185 uint64_t offset; 2186 const int parsed_len = 2187 conn->fc_conn.cn_pf->pf_parse_window_update_frame(p, len, 2188 &stream_id, &offset); 2189 if (parsed_len < 0) 2190 return 0; 2191 EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset); 2192 if (stream_id) 2193 { 2194 lsquic_stream_t *stream = find_stream_by_id(conn, stream_id); 2195 if (stream) 2196 { 2197 LSQ_DEBUG("Got window update frame, stream: %"PRIu64 2198 "; offset: 0x%"PRIX64, stream_id, offset); 2199 lsquic_stream_window_update(stream, offset); 2200 } 2201 else /* Perhaps a result of lost packets? */ 2202 LSQ_DEBUG("Got window update frame for non-existing stream %"PRIu64 2203 " (offset: 0x%"PRIX64")", stream_id, offset); 2204 } 2205 else if (offset > conn->fc_pub.conn_cap.cc_max) 2206 { 2207 conn->fc_pub.conn_cap.cc_max = offset; 2208 assert(conn->fc_pub.conn_cap.cc_max >= conn->fc_pub.conn_cap.cc_sent); 2209 LSQ_DEBUG("Connection WUF, new offset 0x%"PRIX64, offset); 2210 } 2211 else 2212 LSQ_DEBUG("Throw ouw duplicate connection WUF"); 2213 return parsed_len; 2214} 2215 2216 2217typedef unsigned (*process_frame_f)( 2218 struct full_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t); 2219 2220static process_frame_f const process_frames[N_QUIC_FRAMES] = 2221{ 2222 [QUIC_FRAME_ACK] = process_ack_frame, 2223 [QUIC_FRAME_BLOCKED] = process_blocked_frame, 2224 [QUIC_FRAME_CONNECTION_CLOSE] = process_connection_close_frame, 2225 [QUIC_FRAME_CRYPTO] = process_crypto_frame, 2226 [QUIC_FRAME_GOAWAY] = process_goaway_frame, 2227 [QUIC_FRAME_INVALID] = process_invalid_frame, 2228 [QUIC_FRAME_PADDING] = process_padding_frame, 2229 [QUIC_FRAME_PING] = process_ping_frame, 2230 [QUIC_FRAME_RST_STREAM] = process_rst_stream_frame, 2231 [QUIC_FRAME_STOP_WAITING] = process_stop_waiting_frame, 2232 [QUIC_FRAME_STREAM] = process_stream_frame, 2233 [QUIC_FRAME_WINDOW_UPDATE] = process_window_update_frame, 2234}; 2235 2236static unsigned 2237process_packet_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 2238 const unsigned char *p, size_t len) 2239{ 2240 enum quic_frame_type type; 2241 2242 type = conn->fc_conn.cn_pf->pf_parse_frame_type(p, len); 2243 packet_in->pi_frame_types |= 1 << type; 2244 recent_packet_hist_frames(conn, 0, 1 << type); 2245 return process_frames[type](conn, packet_in, p, len); 2246} 2247 2248 2249static void 2250process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2251{ 2252 int s; 2253 struct ver_iter vi; 2254 lsquic_ver_tag_t ver_tag; 2255 enum lsquic_version version; 2256 unsigned versions = 0; 2257 2258 LSQ_DEBUG("Processing version-negotiation packet"); 2259 2260 if (conn->fc_ver_neg.vn_state != VN_START) 2261 { 2262 LSQ_DEBUG("ignore a likely duplicate version negotiation packet"); 2263 return; 2264 } 2265 2266 for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s; 2267 s = lsquic_packet_in_ver_next(&vi, &ver_tag)) 2268 { 2269 version = lsquic_tag2ver(ver_tag); 2270 if (version < N_LSQVER) 2271 { 2272 versions |= 1 << version; 2273 LSQ_DEBUG("server supports version %s", lsquic_ver2str[version]); 2274 EV_LOG_VER_NEG(LSQUIC_LOG_CONN_ID, 2275 "supports", lsquic_ver2str[version]); 2276 } 2277 } 2278 2279 if (versions & (1 << conn->fc_ver_neg.vn_ver)) 2280 { 2281 ABORT_ERROR("server replied with version we support: %s", 2282 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 2283 return; 2284 } 2285 2286 versions &= conn->fc_ver_neg.vn_supp; 2287 if (0 == versions) 2288 { 2289 ABORT_ERROR("client does not support any of the server-specified " 2290 "versions"); 2291 return; 2292 } 2293 2294 set_versions(conn, versions, NULL); 2295 conn->fc_ver_neg.vn_state = VN_IN_PROGRESS; 2296 lsquic_send_ctl_expire_all(&conn->fc_send_ctl); 2297} 2298 2299 2300static void 2301reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2302{ 2303 lsquic_packno_t cur_packno, max_packno; 2304 enum packno_bits bits; 2305 unsigned packet_len; 2306 2307 cur_packno = packet_in->pi_packno; 2308 max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist); 2309 bits = lsquic_packet_in_packno_bits(packet_in); 2310 packet_len = conn->fc_conn.cn_pf->pf_packno_bits2len(bits); 2311 packet_in->pi_packno = lsquic_restore_packno(cur_packno, packet_len, 2312 max_packno); 2313 LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") " 2314 "to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno); 2315} 2316 2317 2318static enum dec_packin 2319conn_decrypt_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2320{ 2321 return conn->fc_conn.cn_esf_c->esf_decrypt_packet( 2322 conn->fc_conn.cn_enc_session, conn->fc_enpub, 2323 &conn->fc_conn, packet_in); 2324} 2325 2326 2327static void 2328parse_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2329{ 2330 const unsigned char *p, *pend; 2331 unsigned len; 2332 2333 p = packet_in->pi_data + packet_in->pi_header_sz; 2334 pend = packet_in->pi_data + packet_in->pi_data_sz; 2335 2336 while (p < pend) 2337 { 2338 len = process_packet_frame(conn, packet_in, p, pend - p); 2339 if (len > 0) 2340 p += len; 2341 else 2342 { 2343 ABORT_ERROR("Error parsing frame"); 2344 break; 2345 } 2346 } 2347} 2348 2349 2350static int 2351conn_is_stateless_reset (const struct full_conn *conn, 2352 const struct lsquic_packet_in *packet_in) 2353{ 2354 return packet_in->pi_data_sz > SRST_LENGTH 2355 && 0 == conn->fc_conn.cn_esf_c->esf_verify_reset_token( 2356 conn->fc_conn.cn_enc_session, 2357 packet_in->pi_data + packet_in->pi_data_sz - SRST_LENGTH, 2358 SRST_LENGTH); 2359} 2360 2361 2362static int 2363process_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2364{ 2365 enum received_st st; 2366 enum quic_ft_bit frame_types; 2367 int was_missing; 2368 2369 if (conn->fc_conn.cn_version < LSQVER_050) 2370 { 2371 reconstruct_packet_number(conn, packet_in); 2372 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 2373 } 2374 2375#if LSQUIC_CONN_STATS 2376 ++conn->fc_stats.in.packets; 2377#endif 2378 2379 /* The packet is decrypted before receive history is updated. This is 2380 * done to make sure that a bad packet won't occupy a slot in receive 2381 * history and subsequent good packet won't be marked as a duplicate. 2382 */ 2383 if (0 == (packet_in->pi_flags & PI_DECRYPTED) && 2384 DECPI_OK != conn_decrypt_packet(conn, packet_in)) 2385 { 2386 if (conn_is_stateless_reset(conn, packet_in)) 2387 { 2388 LSQ_INFO("received public reset packet: aborting connection"); 2389 conn->fc_flags |= FC_GOT_PRST; 2390 return -1; 2391 } 2392 else 2393 { 2394 LSQ_INFO("could not decrypt packet"); 2395#if LSQUIC_CONN_STATS 2396 ++conn->fc_stats.in.undec_packets; 2397#endif 2398 return 0; 2399 } 2400 } 2401 2402 if (conn->fc_conn.cn_version >= LSQVER_050) 2403 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 2404 2405 st = lsquic_rechist_received(&conn->fc_rechist, packet_in->pi_packno, 2406 packet_in->pi_received); 2407 switch (st) { 2408 case REC_ST_OK: 2409 parse_regular_packet(conn, packet_in); 2410 if (0 == (conn->fc_flags & (FC_ACK_QUEUED|FC_GOT_SREJ))) 2411 { 2412 frame_types = packet_in->pi_frame_types; 2413 if ((conn->fc_flags & FC_GOING_AWAY) 2414 && lsquic_hash_count(conn->fc_pub.all_streams) < 3) 2415 { 2416 /* Ignore PING frames if we are going away and there are no 2417 * active streams. (HANDSHAKE and HEADERS streams are the 2418 * two streams that are always in the all_streams hash). 2419 */ 2420 frame_types &= ~(1 << QUIC_FRAME_PING); 2421 } 2422 was_missing = packet_in->pi_packno != 2423 lsquic_rechist_largest_packno(&conn->fc_rechist); 2424 conn->fc_n_slack_akbl += !!(frame_types & GQUIC_FRAME_ACKABLE_MASK); 2425 try_queueing_ack(conn, was_missing, packet_in->pi_received); 2426 } 2427 else if (conn->fc_flags & FC_GOT_SREJ) 2428 conn->fc_flags &= ~FC_GOT_SREJ; 2429 return 0; 2430 case REC_ST_DUP: 2431#if LSQUIC_CONN_STATS 2432 ++conn->fc_stats.in.dup_packets; 2433#endif 2434 LSQ_INFO("packet %"PRIu64" is a duplicate", packet_in->pi_packno); 2435 return 0; 2436 default: 2437 assert(0); 2438 /* Fall through */ 2439 case REC_ST_ERR: 2440#if LSQUIC_CONN_STATS 2441 ++conn->fc_stats.in.err_packets; 2442#endif 2443 LSQ_INFO("error processing packet %"PRIu64, packet_in->pi_packno); 2444 return -1; 2445 } 2446} 2447 2448 2449/* TODO: Possible optimization: in server mode, we do not perform version 2450 * negotiation. We can use different functions in client mode (this 2451 * function) and server mode (a different, faster function that ignores 2452 * version flags). 2453 */ 2454static int 2455process_incoming_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 2456{ 2457 int is_prst, is_verneg; 2458 2459 recent_packet_hist_new(conn, 0, packet_in->pi_received); 2460 LSQ_DEBUG("Processing packet %"PRIu64, packet_in->pi_packno); 2461 2462 is_prst = lsquic_packet_in_is_gquic_prst(packet_in); 2463 is_verneg = lsquic_packet_in_is_verneg(packet_in); 2464 2465 /* See flowchart in Section 4.1 of [draft-ietf-quic-transport-00]. We test 2466 * for the common case first. 2467 */ 2468 if (0 == is_prst && 0 == is_verneg) 2469 { 2470 if (conn->fc_ver_neg.vn_tag) 2471 { 2472 assert(conn->fc_ver_neg.vn_state != VN_END); 2473 conn->fc_ver_neg.vn_state = VN_END; 2474 conn->fc_ver_neg.vn_tag = NULL; 2475 conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver; 2476 conn->fc_conn.cn_flags |= LSCONN_VER_SET; 2477 assert(!(conn->fc_flags & FC_NSTP)); /* This bit off at start */ 2478 if (conn->fc_conn.cn_version >= LSQVER_046 2479 || conn->fc_settings->es_support_nstp) 2480 { 2481 conn->fc_flags |= FC_NSTP; 2482 lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl); 2483 } 2484 LSQ_DEBUG("end of version negotiation: agreed upon %s", 2485 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 2486 lsquic_send_ctl_verneg_done(&conn->fc_send_ctl); 2487 EV_LOG_VER_NEG(LSQUIC_LOG_CONN_ID, 2488 "agreed", lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 2489 } 2490 return process_regular_packet(conn, packet_in); 2491 } 2492 else if (is_prst) 2493 { 2494 LSQ_INFO("received public reset packet: aborting connection"); 2495 conn->fc_flags |= FC_GOT_PRST; 2496 return -1; 2497 } 2498 else 2499 { 2500 if (conn->fc_flags & FC_SERVER) 2501 return process_regular_packet(conn, packet_in); 2502 else if (conn->fc_ver_neg.vn_tag) 2503 { 2504 process_ver_neg_packet(conn, packet_in); 2505 return 0; 2506 } 2507 else 2508 { 2509 LSQ_DEBUG("unexpected version negotiation packet: ignore it"); 2510 return 0; 2511 } 2512 } 2513} 2514 2515 2516static void 2517idle_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry, 2518 lsquic_time_t now) 2519{ 2520 struct full_conn *conn = ctx; 2521 2522 if ((conn->fc_flags & FC_NOPROG_TIMEOUT) 2523 && conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout < now) 2524 { 2525 LSQ_DEBUG("connection timed out due to lack of progress"); 2526 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "connection timed out due to " 2527 "lack of progress"); 2528 /* Different flag so that CONNECTION_CLOSE frame is sent */ 2529 conn->fc_flags |= FC_ABORTED; 2530 } 2531 else 2532 { 2533 LSQ_DEBUG("connection timed out"); 2534 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "connection timed out"); 2535 conn->fc_flags |= FC_TIMED_OUT; 2536 } 2537} 2538 2539 2540static void 2541handshake_alarm_expired (enum alarm_id al_id, void *ctx, 2542 lsquic_time_t expiry, lsquic_time_t now) 2543{ 2544 struct full_conn *conn = ctx; 2545 LSQ_DEBUG("connection timed out: handshake timed out"); 2546 conn->fc_flags |= FC_TIMED_OUT; 2547} 2548 2549 2550static void 2551ping_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry, 2552 lsquic_time_t now) 2553{ 2554 struct full_conn *conn = ctx; 2555 LSQ_DEBUG("Ping alarm rang: schedule PING frame to be generated"); 2556 conn->fc_flags |= FC_SEND_PING; 2557} 2558 2559 2560static lsquic_packet_out_t * 2561get_writeable_packet (struct full_conn *conn, unsigned need_at_least) 2562{ 2563 lsquic_packet_out_t *packet_out; 2564 int is_err; 2565 2566 packet_out = lsquic_send_ctl_get_writeable_packet(&conn->fc_send_ctl, 2567 PNS_APP, need_at_least, &conn->fc_path, 0, &is_err); 2568 if (!packet_out && is_err) 2569 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 2570 return packet_out; 2571} 2572 2573 2574static int 2575generate_wuf_stream (struct full_conn *conn, lsquic_stream_t *stream) 2576{ 2577 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, GQUIC_WUF_SZ); 2578 if (!packet_out) 2579 return 0; 2580 const uint64_t recv_off = lsquic_stream_fc_recv_off(stream); 2581 int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame( 2582 packet_out->po_data + packet_out->po_data_sz, 2583 lsquic_packet_out_avail(packet_out), stream->id, recv_off); 2584 if (sz < 0) { 2585 ABORT_ERROR("gen_window_update_frame failed"); 2586 return 0; 2587 } 2588 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2589 packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE; 2590 LSQ_DEBUG("wrote WUF: stream %"PRIu64"; offset 0x%"PRIX64, stream->id, 2591 recv_off); 2592 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, 2593 "wrote WUF: stream %"PRIu64"; offset 0x%"PRIX64, stream->id, recv_off); 2594 return 1; 2595} 2596 2597 2598static void 2599generate_wuf_conn (struct full_conn *conn) 2600{ 2601 assert(conn->fc_flags & FC_SEND_WUF); 2602 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, GQUIC_WUF_SZ); 2603 if (!packet_out) 2604 return; 2605 const uint64_t recv_off = lsquic_cfcw_get_fc_recv_off(&conn->fc_pub.cfcw); 2606 int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame( 2607 packet_out->po_data + packet_out->po_data_sz, 2608 lsquic_packet_out_avail(packet_out), 0, recv_off); 2609 if (sz < 0) { 2610 ABORT_ERROR("gen_window_update_frame failed"); 2611 return; 2612 } 2613 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2614 packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE; 2615 conn->fc_flags &= ~FC_SEND_WUF; 2616 LSQ_DEBUG("wrote connection WUF: offset 0x%"PRIX64, recv_off); 2617} 2618 2619 2620static void 2621maybe_close_conn (struct full_conn *conn) 2622{ 2623#ifndef NDEBUG 2624 struct lsquic_stream *stream; 2625 struct lsquic_hash_elem *el; 2626#endif 2627 2628 if ((conn->fc_flags & (FC_CLOSING|FC_GOAWAY_SENT|FC_SERVER)) 2629 == (FC_GOAWAY_SENT|FC_SERVER) 2630 && lsquic_hash_count(conn->fc_pub.all_streams) == 2) 2631 { 2632#ifndef NDEBUG 2633 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 2634 el = lsquic_hash_next(conn->fc_pub.all_streams)) 2635 { 2636 stream = lsquic_hashelem_getdata(el); 2637 assert(stream->sm_bflags & (SMBF_CRYPTO|SMBF_HEADERS)); 2638 } 2639#endif 2640 conn->fc_flags |= FC_RECV_CLOSE; /* Fake -- trigger "ok to close" */ 2641 conn->fc_flags |= FC_CLOSING; 2642 LSQ_DEBUG("closing connection: GOAWAY sent and no responses remain"); 2643 } 2644} 2645 2646 2647static void 2648generate_goaway_frame (struct full_conn *conn) 2649{ 2650 int reason_len = 0; 2651 lsquic_packet_out_t *packet_out = 2652 get_writeable_packet(conn, GQUIC_GOAWAY_FRAME_SZ + reason_len); 2653 if (!packet_out) 2654 return; 2655 int sz = conn->fc_conn.cn_pf->pf_gen_goaway_frame( 2656 packet_out->po_data + packet_out->po_data_sz, 2657 lsquic_packet_out_avail(packet_out), 0, conn->fc_max_peer_stream_id, 2658 NULL, reason_len); 2659 if (sz < 0) { 2660 ABORT_ERROR("gen_goaway_frame failed"); 2661 return; 2662 } 2663 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2664 packet_out->po_frame_types |= 1 << QUIC_FRAME_GOAWAY; 2665 conn->fc_flags &= ~FC_SEND_GOAWAY; 2666 conn->fc_flags |= FC_GOAWAY_SENT; 2667 LSQ_DEBUG("wrote GOAWAY frame: stream id: %"PRIu64, 2668 conn->fc_max_peer_stream_id); 2669 maybe_close_conn(conn); 2670} 2671 2672 2673static void 2674generate_connection_close_packet (struct full_conn *conn) 2675{ 2676 lsquic_packet_out_t *packet_out; 2677 2678 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP, 2679 &conn->fc_path); 2680 if (!packet_out) 2681 { 2682 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 2683 return; 2684 } 2685 2686 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 2687 int sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(packet_out->po_data + packet_out->po_data_sz, 2688 lsquic_packet_out_avail(packet_out), 0, 16 /* PEER_GOING_AWAY */, 2689 NULL, 0); 2690 if (sz < 0) { 2691 ABORT_ERROR("generate_connection_close_packet failed"); 2692 return; 2693 } 2694 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2695 packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE; 2696 LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet"); 2697} 2698 2699 2700static int 2701generate_blocked_frame (struct full_conn *conn, lsquic_stream_id_t stream_id) 2702{ 2703 lsquic_packet_out_t *packet_out = 2704 get_writeable_packet(conn, GQUIC_BLOCKED_FRAME_SZ); 2705 if (!packet_out) 2706 return 0; 2707 int sz = conn->fc_conn.cn_pf->pf_gen_blocked_frame( 2708 packet_out->po_data + packet_out->po_data_sz, 2709 lsquic_packet_out_avail(packet_out), stream_id); 2710 if (sz < 0) { 2711 ABORT_ERROR("gen_blocked_frame failed"); 2712 return 0; 2713 } 2714 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2715 packet_out->po_frame_types |= 1 << QUIC_FRAME_BLOCKED; 2716 LSQ_DEBUG("wrote blocked frame: stream %"PRIu64, stream_id); 2717 return 1; 2718} 2719 2720 2721static int 2722generate_stream_blocked_frame (struct full_conn *conn, lsquic_stream_t *stream) 2723{ 2724 if (generate_blocked_frame(conn, stream->id)) 2725 { 2726 lsquic_stream_blocked_frame_sent(stream); 2727 return 1; 2728 } 2729 else 2730 return 0; 2731} 2732 2733 2734static int 2735generate_rst_stream_frame (struct full_conn *conn, lsquic_stream_t *stream) 2736{ 2737 lsquic_packet_out_t *packet_out; 2738 int sz, s; 2739 2740 packet_out = get_writeable_packet(conn, GQUIC_RST_STREAM_SZ); 2741 if (!packet_out) 2742 return 0; 2743 /* TODO Possible optimization: instead of using stream->tosend_off as the 2744 * offset, keep track of the offset that was actually sent: include it 2745 * into frame_rec and update a new per-stream "maximum offset actually 2746 * sent" field. Then, if a stream is reset, the connection cap can be 2747 * increased. 2748 */ 2749 sz = conn->fc_conn.cn_pf->pf_gen_rst_frame( 2750 packet_out->po_data + packet_out->po_data_sz, 2751 lsquic_packet_out_avail(packet_out), stream->id, 2752 stream->tosend_off, stream->error_code); 2753 if (sz < 0) { 2754 ABORT_ERROR("gen_rst_frame failed"); 2755 return 0; 2756 } 2757 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2758 packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM; 2759 s = lsquic_packet_out_add_stream(packet_out, conn->fc_pub.mm, stream, 2760 QUIC_FRAME_RST_STREAM, packet_out->po_data_sz, sz); 2761 if (s != 0) 2762 { 2763 ABORT_ERROR("adding stream to packet failed: %s", strerror(errno)); 2764 return 0; 2765 } 2766 lsquic_stream_rst_frame_sent(stream); 2767 LSQ_DEBUG("wrote RST: stream %"PRIu64"; offset 0x%"PRIX64"; error code " 2768 "%"PRIu64, stream->id, stream->tosend_off, stream->error_code); 2769 return 1; 2770} 2771 2772 2773static void 2774generate_ping_frame (struct full_conn *conn) 2775{ 2776 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, 1); 2777 if (!packet_out) 2778 { 2779 LSQ_DEBUG("cannot get writeable packet for PING frame"); 2780 return; 2781 } 2782 int sz = conn->fc_conn.cn_pf->pf_gen_ping_frame( 2783 packet_out->po_data + packet_out->po_data_sz, 2784 lsquic_packet_out_avail(packet_out)); 2785 if (sz < 0) { 2786 ABORT_ERROR("gen_blocked_frame failed"); 2787 return; 2788 } 2789 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2790 packet_out->po_frame_types |= 1 << QUIC_FRAME_PING; 2791 LSQ_DEBUG("wrote PING frame"); 2792 if (!(conn->fc_flags & FC_SERVER)) 2793 log_conn_flow_control(conn); 2794} 2795 2796 2797static void 2798generate_stop_waiting_frame (struct full_conn *conn) 2799{ 2800 assert(conn->fc_flags & FC_SEND_STOP_WAITING); 2801 2802 int sz; 2803 unsigned packnum_len; 2804 lsquic_packno_t least_unacked; 2805 lsquic_packet_out_t *packet_out; 2806 2807 /* Get packet that has room for the minimum size STOP_WAITING frame: */ 2808 packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len(GQUIC_PACKNO_LEN_1); 2809 packet_out = get_writeable_packet(conn, 1 + packnum_len); 2810 if (!packet_out) 2811 return; 2812 2813 /* Now calculate number of bytes we really need. If there is not enough 2814 * room in the current packet, get a new one. 2815 */ 2816 packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len( 2817 lsquic_packet_out_packno_bits(packet_out)); 2818 if ((unsigned) lsquic_packet_out_avail(packet_out) < 1 + packnum_len) 2819 { 2820 packet_out = get_writeable_packet(conn, 1 + packnum_len); 2821 if (!packet_out) 2822 return; 2823 /* Here, a new packet has been allocated, The number of bytes needed 2824 * to represent packet number in the STOP_WAITING frame may have 2825 * increased. However, this does not matter, because the newly 2826 * allocated packet must have room for a STOP_WAITING frame of any 2827 * size. 2828 */ 2829 } 2830 2831 least_unacked = lsquic_send_ctl_smallest_unacked(&conn->fc_send_ctl); 2832 sz = conn->fc_conn.cn_pf->pf_gen_stop_waiting_frame( 2833 packet_out->po_data + packet_out->po_data_sz, 2834 lsquic_packet_out_avail(packet_out), packet_out->po_packno, 2835 lsquic_packet_out_packno_bits(packet_out), least_unacked); 2836 if (sz < 0) { 2837 ABORT_ERROR("gen_stop_waiting_frame failed"); 2838 return; 2839 } 2840 if (0 != lsquic_packet_out_add_frame(packet_out, conn->fc_pub.mm, 0, 2841 QUIC_FRAME_STOP_WAITING, packet_out->po_data_sz, sz)) 2842 { 2843 ABORT_ERROR("adding frame to packet failed: %d", errno); 2844 return; 2845 } 2846 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2847 packet_out->po_regen_sz += sz; 2848 packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING; 2849 conn->fc_flags &= ~FC_SEND_STOP_WAITING; 2850 LSQ_DEBUG("wrote STOP_WAITING frame: least unacked: %"PRIu64, 2851 least_unacked); 2852 EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, least_unacked); 2853} 2854 2855 2856static int 2857process_stream_ready_to_send (struct full_conn *conn, lsquic_stream_t *stream) 2858{ 2859 int r = 1; 2860 if (stream->sm_qflags & SMQF_SEND_WUF) 2861 r &= generate_wuf_stream(conn, stream); 2862 if (stream->sm_qflags & SMQF_SEND_BLOCKED) 2863 r &= generate_stream_blocked_frame(conn, stream); 2864 if (stream->sm_qflags & SMQF_SEND_RST) 2865 r &= generate_rst_stream_frame(conn, stream); 2866 return r; 2867} 2868 2869 2870static void 2871process_streams_ready_to_send (struct full_conn *conn) 2872{ 2873 lsquic_stream_t *stream; 2874 struct stream_prio_iter spi; 2875 2876 assert(!TAILQ_EMPTY(&conn->fc_pub.sending_streams)); 2877 2878 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.sending_streams), 2879 TAILQ_LAST(&conn->fc_pub.sending_streams, lsquic_streams_tailq), 2880 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_send_stream), 2881 &conn->fc_pub, "send", NULL, NULL); 2882 2883 for (stream = lsquic_spi_first(&spi); stream; 2884 stream = lsquic_spi_next(&spi)) 2885 if (!process_stream_ready_to_send(conn, stream)) 2886 break; 2887} 2888 2889 2890/* Return true if packetized, false otherwise */ 2891static int 2892packetize_standalone_stream_reset (struct full_conn *conn, lsquic_stream_id_t stream_id) 2893{ 2894 lsquic_packet_out_t *packet_out; 2895 int sz; 2896 2897 packet_out = get_writeable_packet(conn, GQUIC_RST_STREAM_SZ); 2898 if (!packet_out) 2899 return 0; 2900 2901 sz = conn->fc_conn.cn_pf->pf_gen_rst_frame( 2902 packet_out->po_data + packet_out->po_data_sz, 2903 lsquic_packet_out_avail(packet_out), stream_id, 2904 0, 0x10 /* QUIC_PEER_GOING_AWAY */); 2905 if (sz < 0) { 2906 ABORT_ERROR("gen_rst_frame failed"); 2907 return 0; 2908 } 2909 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2910 packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM; 2911 LSQ_DEBUG("generated standalone RST_STREAM frame for stream %"PRIu64, 2912 stream_id); 2913 return 1; 2914} 2915 2916 2917static void 2918packetize_standalone_stream_resets (struct full_conn *conn) 2919{ 2920 struct stream_id_to_reset *sitr; 2921 2922 while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset))) 2923 if (packetize_standalone_stream_reset(conn, sitr->sitr_stream_id)) 2924 { 2925 STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next); 2926 free(sitr); 2927 } 2928 else 2929 break; 2930} 2931 2932 2933static void 2934create_delayed_streams (struct full_conn *conn) 2935{ 2936 unsigned stream_count, avail, i; 2937 struct lsquic_stream **new_streams; 2938 2939 stream_count = count_streams(conn, 0); 2940 2941 if (stream_count >= conn->fc_cfg.max_streams_out) 2942 return; 2943 2944 avail = conn->fc_cfg.max_streams_out - stream_count; 2945 if (conn->fc_n_delayed_streams < avail) 2946 avail = conn->fc_n_delayed_streams; 2947 if (avail == 0) 2948 return; 2949 2950 new_streams = malloc(sizeof(new_streams[0]) * avail); 2951 if (!new_streams) 2952 { 2953 ABORT_WARN("%s: malloc failed", __func__); 2954 return; 2955 } 2956 2957 LSQ_DEBUG("creating delayed streams"); 2958 for (i = 0; i < avail; ++i) 2959 { 2960 /* Delay calling on_new in order not to let the user screw up 2961 * the counts by making more streams. 2962 */ 2963 new_streams[i] = new_stream(conn, generate_stream_id(conn), 0); 2964 if (!new_streams[i]) 2965 { 2966 ABORT_ERROR("%s: cannot create new stream: %s", __func__, 2967 strerror(errno)); 2968 goto cleanup; 2969 } 2970 } 2971 LSQ_DEBUG("created %u delayed stream%.*s", avail, avail != 1, "s"); 2972 2973 assert(count_streams(conn, 0) <= conn->fc_cfg.max_streams_out); 2974 conn->fc_n_delayed_streams -= avail; 2975 2976 for (i = 0; i < avail; ++i) 2977 lsquic_stream_call_on_new(new_streams[i]); 2978 cleanup: 2979 free(new_streams); 2980} 2981 2982 2983static void 2984service_streams (struct full_conn *conn) 2985{ 2986 struct lsquic_hash_elem *el; 2987 lsquic_stream_t *stream, *next; 2988 int closed_some = 0; 2989 2990 for (stream = TAILQ_FIRST(&conn->fc_pub.service_streams); stream; stream = next) 2991 { 2992 next = TAILQ_NEXT(stream, next_service_stream); 2993 if (stream->sm_qflags & SMQF_ABORT_CONN) 2994 /* No need to unset this flag or remove this stream: the connection 2995 * is about to be aborted. 2996 */ 2997 ABORT_ERROR("aborted due to error in stream %"PRIu64, stream->id); 2998 if (stream->sm_qflags & SMQF_CALL_ONCLOSE) 2999 { 3000 lsquic_stream_call_on_close(stream); 3001 closed_some |= is_our_stream(conn, stream); 3002 conn_mark_stream_closed(conn, stream->id); 3003 } 3004 if (stream->sm_qflags & SMQF_FREE_STREAM) 3005 { 3006 TAILQ_REMOVE(&conn->fc_pub.service_streams, stream, next_service_stream); 3007 el = lsquic_hash_find(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id)); 3008 if (el) 3009 lsquic_hash_erase(conn->fc_pub.all_streams, el); 3010 SAVE_STREAM_HISTORY(conn, stream); 3011 lsquic_stream_destroy(stream); 3012 } 3013 } 3014 3015 if (either_side_going_away(conn)) 3016 { 3017 while (conn->fc_n_delayed_streams) 3018 { 3019 --conn->fc_n_delayed_streams; 3020 LSQ_DEBUG("goaway mode: delayed stream results in null ctor"); 3021 (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream( 3022 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL); 3023 } 3024 maybe_close_conn(conn); 3025 } 3026 else 3027 if (closed_some && conn->fc_n_delayed_streams) 3028 create_delayed_streams(conn); 3029} 3030 3031 3032struct filter_stream_ctx 3033{ 3034 struct full_conn *conn; 3035 uint32_t last_stream_id, 3036 max_peer_stream_id; 3037}; 3038 3039 3040static int 3041filter_out_old_streams (void *ctx, lsquic_stream_t *stream) 3042{ 3043 struct filter_stream_ctx *const fctx = ctx; 3044 return ((!((stream->id ^ fctx->last_stream_id) & 1) && 3045 stream->id > fctx->last_stream_id) 3046 || 3047 (!((stream->id ^ fctx->max_peer_stream_id) & 1) && 3048 stream->id > fctx->max_peer_stream_id)); 3049} 3050 3051 3052static void 3053process_streams_read_events (struct full_conn *conn) 3054{ 3055 lsquic_stream_t *stream; 3056 struct filter_stream_ctx fctx; 3057 enum stream_q_flags q_flags; 3058 int needs_service; 3059 struct stream_prio_iter spi; 3060 3061 if (TAILQ_EMPTY(&conn->fc_pub.read_streams)) 3062 return; 3063 3064 fctx.last_stream_id = conn->fc_last_stream_id; 3065 fctx.max_peer_stream_id = conn->fc_max_peer_stream_id; 3066 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams), 3067 TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq), 3068 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream), 3069 &conn->fc_pub, "read", NULL, NULL); 3070 3071 needs_service = 0; 3072 for (stream = lsquic_spi_first(&spi); stream; 3073 stream = lsquic_spi_next(&spi)) 3074 { 3075 q_flags = stream->sm_qflags & SMQF_SERVICE_FLAGS; 3076 lsquic_stream_dispatch_read_events(stream); 3077 needs_service |= q_flags ^ (stream->sm_qflags & SMQF_SERVICE_FLAGS); 3078 } 3079 3080 if (needs_service) 3081 service_streams(conn); 3082 3083 /* If new streams were created as result of the read dispatching above, 3084 * process these new streams. This logic is only applicable to in the 3085 * server mode, as a client that creates a stream from an on_read() event 3086 * is not likely to want to *read* from it immediately. 3087 */ 3088 if ((conn->fc_flags & FC_SERVER) && 3089 (fctx.last_stream_id < conn->fc_last_stream_id || 3090 fctx.max_peer_stream_id < conn->fc_max_peer_stream_id)) 3091 { 3092 fctx.conn = conn; 3093 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams), 3094 TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq), 3095 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream), 3096 &conn->fc_pub, "read-new", 3097 filter_out_old_streams, &fctx); 3098 for (stream = lsquic_spi_first(&spi); stream; 3099 stream = lsquic_spi_next(&spi)) 3100 lsquic_stream_dispatch_read_events(stream); 3101 } 3102} 3103 3104 3105static void 3106maybe_conn_flush_headers_stream (struct full_conn *conn) 3107{ 3108 lsquic_stream_t *stream; 3109 3110 if (conn->fc_flags & FC_HTTP) 3111 { 3112 stream = lsquic_headers_stream_get_stream(conn->fc_pub.u.gquic.hs); 3113 if (lsquic_stream_has_data_to_flush(stream)) 3114 (void) lsquic_stream_flush(stream); 3115 } 3116} 3117 3118 3119static void 3120process_streams_write_events (struct full_conn *conn, int high_prio) 3121{ 3122 lsquic_stream_t *stream; 3123 struct stream_prio_iter spi; 3124 3125 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.write_streams), 3126 TAILQ_LAST(&conn->fc_pub.write_streams, lsquic_streams_tailq), 3127 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_write_stream), 3128 &conn->fc_pub, 3129 high_prio ? "write-high" : "write-low", NULL, NULL); 3130 3131 if (high_prio) 3132 lsquic_spi_drop_non_high(&spi); 3133 else 3134 lsquic_spi_drop_high(&spi); 3135 3136 for (stream = lsquic_spi_first(&spi); stream && write_is_possible(conn); 3137 stream = lsquic_spi_next(&spi)) 3138 if (stream->sm_qflags & SMQF_WRITE_Q_FLAGS) 3139 lsquic_stream_dispatch_write_events(stream); 3140 3141 maybe_conn_flush_headers_stream(conn); 3142} 3143 3144 3145static void 3146process_hsk_stream_read_events (struct full_conn *conn) 3147{ 3148 lsquic_stream_t *stream; 3149 TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream) 3150 if (lsquic_stream_is_crypto(stream)) 3151 { 3152 lsquic_stream_dispatch_read_events(stream); 3153 break; 3154 } 3155} 3156 3157 3158static void 3159process_hsk_stream_write_events (struct full_conn *conn) 3160{ 3161 lsquic_stream_t *stream; 3162 TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, next_write_stream) 3163 if (lsquic_stream_is_crypto(stream)) 3164 { 3165 lsquic_stream_dispatch_write_events(stream); 3166 break; 3167 } 3168} 3169 3170 3171static void 3172generate_ack_frame (struct full_conn *conn) 3173{ 3174 lsquic_packet_out_t *packet_out; 3175 3176 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP, 3177 &conn->fc_path); 3178 if (packet_out) 3179 { 3180 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 3181 full_conn_ci_write_ack(&conn->fc_conn, packet_out); 3182 } 3183 else 3184 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 3185} 3186 3187 3188static int 3189conn_ok_to_close (const struct full_conn *conn) 3190{ 3191 assert(conn->fc_flags & FC_CLOSING); 3192 return !(conn->fc_flags & FC_SERVER) 3193 || (conn->fc_flags & FC_RECV_CLOSE) 3194 || ( 3195 !lsquic_send_ctl_have_outgoing_stream_frames(&conn->fc_send_ctl) 3196 && lsquic_hash_count(conn->fc_pub.all_streams) == 0 3197 && lsquic_send_ctl_have_unacked_stream_frames(&conn->fc_send_ctl) == 0); 3198} 3199 3200 3201static enum tick_st 3202immediate_close (struct full_conn *conn) 3203{ 3204 lsquic_packet_out_t *packet_out; 3205 const char *error_reason; 3206 unsigned error_code; 3207 int sz; 3208 3209 if (conn->fc_flags & (FC_TICK_CLOSE|FC_GOT_PRST)) 3210 return TICK_CLOSE; 3211 3212 conn->fc_flags |= FC_TICK_CLOSE; 3213 3214 /* No reason to send anything that's been scheduled if connection is 3215 * being closed immedately. This also ensures that packet numbers 3216 * sequence is always increasing. 3217 */ 3218 lsquic_send_ctl_drop_scheduled(&conn->fc_send_ctl); 3219 3220 if ((conn->fc_flags & FC_TIMED_OUT) && conn->fc_settings->es_silent_close) 3221 return TICK_CLOSE; 3222 3223 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP, 3224 &conn->fc_path); 3225 if (!packet_out) 3226 { 3227 LSQ_WARN("cannot allocate packet: %s", strerror(errno)); 3228 return TICK_CLOSE; 3229 } 3230 3231 assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT|FC_HSK_FAILED)); 3232 if (conn->fc_flags & FC_ERROR) 3233 { 3234 error_code = 0x01; /* QUIC_INTERNAL_ERROR */ 3235 error_reason = "connection error"; 3236 } 3237 else if (conn->fc_flags & FC_ABORTED) 3238 { 3239 error_code = 0x10; /* QUIC_PEER_GOING_AWAY */ 3240 error_reason = "user aborted connection"; 3241 } 3242 else if (conn->fc_flags & FC_TIMED_OUT) 3243 { 3244 error_code = 0x19; /* QUIC_NETWORK_IDLE_TIMEOUT */ 3245 error_reason = "connection timed out"; 3246 } 3247 else if (conn->fc_flags & FC_HSK_FAILED) 3248 { 3249 error_code = 0x2A; /* QUIC_PROOF_INVALID */ 3250 error_reason = "handshake failed"; 3251 } 3252 else 3253 { 3254 error_code = 0x10; /* QUIC_PEER_GOING_AWAY */ 3255 error_reason = NULL; 3256 } 3257 3258 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 3259 sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame( 3260 packet_out->po_data + packet_out->po_data_sz, 3261 lsquic_packet_out_avail(packet_out), 0, error_code, 3262 error_reason, error_reason ? strlen(error_reason) : 0); 3263 if (sz < 0) { 3264 LSQ_WARN("%s failed", __func__); 3265 return TICK_CLOSE; 3266 } 3267 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 3268 packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE; 3269 LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet"); 3270 return TICK_SEND|TICK_CLOSE; 3271} 3272 3273 3274static int 3275write_is_possible (struct full_conn *conn) 3276{ 3277 const lsquic_packet_out_t *packet_out; 3278 3279 packet_out = lsquic_send_ctl_last_scheduled(&conn->fc_send_ctl, PNS_APP, 3280 &conn->fc_path, 0); 3281 return (packet_out && lsquic_packet_out_avail(packet_out) > 10) 3282 || lsquic_send_ctl_can_send(&conn->fc_send_ctl); 3283} 3284 3285 3286static int 3287should_generate_ack (const struct full_conn *conn) 3288{ 3289 return (conn->fc_flags & FC_ACK_QUEUED) 3290 || lsquic_send_ctl_lost_ack(&conn->fc_send_ctl); 3291} 3292 3293 3294static int 3295full_conn_ci_can_write_ack (struct lsquic_conn *lconn) 3296{ 3297 struct full_conn *conn = (struct full_conn *) lconn; 3298 return should_generate_ack(conn); 3299} 3300 3301 3302struct full_ack_state 3303{ 3304 enum full_conn_flags conn_flags; 3305 enum alarm_id_bit armed_set; 3306 unsigned n_slack_akbl; 3307 unsigned n_stop_waiting; 3308}; 3309 3310 3311typedef char ack_state_size[sizeof(struct full_ack_state) 3312 <= sizeof(struct ack_state) ? 1 : - 1]; 3313 3314static void 3315full_conn_ci_ack_snapshot (struct lsquic_conn *lconn, struct ack_state *opaque) 3316{ 3317 struct full_conn *conn = (struct full_conn *) lconn; 3318 struct full_ack_state *const ack_state = (struct full_ack_state *) opaque; 3319 3320 ack_state->conn_flags = conn->fc_flags; 3321 ack_state->armed_set = conn->fc_alset.as_armed_set; 3322 ack_state->n_slack_akbl = conn->fc_n_slack_akbl; 3323 ack_state->n_stop_waiting 3324 = lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl); 3325 LSQ_DEBUG("take ACK snapshot"); 3326} 3327 3328 3329static void 3330full_conn_ci_ack_rollback (struct lsquic_conn *lconn, struct ack_state *opaque) 3331{ 3332 struct full_ack_state *const ack_state = (struct full_ack_state *) opaque; 3333 struct full_conn *conn = (struct full_conn *) lconn; 3334 3335 conn->fc_flags &= ~(FC_ACK_HAD_MISS|FC_ACK_QUEUED); 3336 conn->fc_flags |= (FC_ACK_HAD_MISS|FC_ACK_QUEUED) 3337 & ack_state->conn_flags; 3338 3339 conn->fc_alset.as_armed_set &= ~ALBIT_ACK_APP; 3340 conn->fc_alset.as_armed_set |= ALBIT_ACK_APP & ack_state->armed_set; 3341 3342 conn->fc_n_slack_akbl = ack_state->n_slack_akbl; 3343 conn->fc_send_ctl.sc_n_stop_waiting = ack_state->n_stop_waiting; 3344 3345 LSQ_DEBUG("roll back ACK state"); 3346} 3347 3348 3349/* This should be called before lsquic_alarmset_ring_expired() */ 3350static void 3351maybe_set_noprogress_alarm (struct full_conn *conn, lsquic_time_t now) 3352{ 3353 lsquic_time_t exp; 3354 3355 if (conn->fc_flags & FC_NOPROG_TIMEOUT) 3356 { 3357 if (conn->fc_pub.last_tick) 3358 { 3359 exp = conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout; 3360 if (!lsquic_alarmset_is_set(&conn->fc_alset, AL_IDLE) 3361 || exp < conn->fc_alset.as_expiry[AL_IDLE]) 3362 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, exp); 3363 conn->fc_pub.last_tick = now; 3364 } 3365 else 3366 { 3367 conn->fc_pub.last_tick = now; 3368 conn->fc_pub.last_prog = now; 3369 } 3370 } 3371} 3372 3373 3374static enum tick_st 3375full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now) 3376{ 3377 struct full_conn *conn = (struct full_conn *) lconn; 3378 int have_delayed_packets; 3379 unsigned n; 3380 int s; 3381 enum tick_st tick = 0; 3382 3383#define CLOSE_IF_NECESSARY() do { \ 3384 if (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS) \ 3385 { \ 3386 tick |= immediate_close(conn); \ 3387 goto close_end; \ 3388 } \ 3389} while (0) 3390 3391#define RETURN_IF_OUT_OF_PACKETS() do { \ 3392 if (!lsquic_send_ctl_can_send(&conn->fc_send_ctl)) \ 3393 { \ 3394 if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl)) \ 3395 { \ 3396 LSQ_DEBUG("used up packet allowance, quiet now (line %d)", \ 3397 __LINE__); \ 3398 tick |= TICK_QUIET; \ 3399 } \ 3400 else \ 3401 { \ 3402 LSQ_DEBUG("used up packet allowance, sending now (line %d)",\ 3403 __LINE__); \ 3404 tick |= TICK_SEND; \ 3405 } \ 3406 goto end; \ 3407 } \ 3408} while (0) 3409 3410#if LSQUIC_CONN_STATS 3411 ++conn->fc_stats.n_ticks; 3412#endif 3413 3414 if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG) 3415 && conn->fc_mem_logged_last + 1000000 <= now) 3416 { 3417 conn->fc_mem_logged_last = now; 3418 LSQ_DEBUG("memory used: %zd bytes", calc_mem_used(conn)); 3419 } 3420 3421 if (conn->fc_flags & FC_HAVE_SAVED_ACK) 3422 { 3423 (void) /* If there is an error, we'll fail shortly */ 3424 process_ack(conn, &conn->fc_ack, conn->fc_saved_ack_received, now); 3425 conn->fc_flags &= ~FC_HAVE_SAVED_ACK; 3426 } 3427 3428 maybe_set_noprogress_alarm(conn, now); 3429 3430 lsquic_send_ctl_tick_in(&conn->fc_send_ctl, now); 3431 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1); 3432 CLOSE_IF_NECESSARY(); 3433 3434 lsquic_alarmset_ring_expired(&conn->fc_alset, now); 3435 CLOSE_IF_NECESSARY(); 3436 3437 /* To make things simple, only stream 1 is active until the handshake 3438 * has been completed. This will be adjusted in the future: the client 3439 * does not want to wait if it has the server information. 3440 */ 3441 if (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) 3442 process_streams_read_events(conn); 3443 else 3444 process_hsk_stream_read_events(conn); 3445 CLOSE_IF_NECESSARY(); 3446 3447 if (lsquic_send_ctl_pacer_blocked(&conn->fc_send_ctl)) 3448 goto skip_write; 3449 3450 if (conn->fc_flags & FC_FIRST_TICK) 3451 { 3452 conn->fc_flags &= ~FC_FIRST_TICK; 3453 have_delayed_packets = 0; 3454 } 3455 else 3456 /* If there are any scheduled packets at this point, it means that 3457 * they were not sent during previous tick; in other words, they 3458 * are delayed. When there are delayed packets, the only packet 3459 * we sometimes add is a packet with an ACK frame, and we add it 3460 * to the *front* of the queue. 3461 */ 3462 have_delayed_packets = lsquic_send_ctl_maybe_squeeze_sched( 3463 &conn->fc_send_ctl); 3464 3465 if (should_generate_ack(conn)) 3466 { 3467 if (have_delayed_packets) 3468 lsquic_send_ctl_reset_packnos(&conn->fc_send_ctl); 3469 3470 generate_ack_frame(conn); 3471 CLOSE_IF_NECESSARY(); 3472 3473 /* Try to send STOP_WAITING frame at the same time we send an ACK 3474 * This follows reference implementation. 3475 */ 3476 if (!(conn->fc_flags & FC_NSTP)) 3477 conn->fc_flags |= FC_SEND_STOP_WAITING; 3478 3479 if (have_delayed_packets) 3480 { 3481 if (conn->fc_flags & FC_SEND_STOP_WAITING) 3482 { 3483 /* TODO: ensure that STOP_WAITING frame is in the same packet 3484 * as the ACK frame in delayed packet mode. 3485 */ 3486 generate_stop_waiting_frame(conn); 3487 CLOSE_IF_NECESSARY(); 3488 } 3489 lsquic_send_ctl_ack_to_front(&conn->fc_send_ctl, 1); 3490 } 3491 } 3492 3493 if (have_delayed_packets) 3494 { 3495 /* The reason for not adding STOP_WAITING and other frames below 3496 * to the packet carrying ACK frame generated when there are delayed 3497 * packets is so that if the ACK packet itself is delayed, it can be 3498 * dropped and replaced by new ACK packet. This way, we are never 3499 * more than 1 packet over CWND. 3500 */ 3501 tick |= TICK_SEND; 3502 goto end; 3503 } 3504 3505 /* Try to fit any of the following three frames -- STOP_WAITING, 3506 * WINDOW_UPDATE, and GOAWAY -- before checking if we have run 3507 * out of packets. If either of them does not fit, it will be 3508 * tried next time around. 3509 */ 3510 if (conn->fc_flags & FC_SEND_STOP_WAITING) 3511 { 3512 generate_stop_waiting_frame(conn); 3513 CLOSE_IF_NECESSARY(); 3514 } 3515 3516 if (lsquic_cfcw_fc_offsets_changed(&conn->fc_pub.cfcw) || 3517 (conn->fc_flags & FC_SEND_WUF)) 3518 { 3519 conn->fc_flags |= FC_SEND_WUF; 3520 generate_wuf_conn(conn); 3521 CLOSE_IF_NECESSARY(); 3522 } 3523 3524 if (conn->fc_flags & FC_SEND_GOAWAY) 3525 { 3526 generate_goaway_frame(conn); 3527 CLOSE_IF_NECESSARY(); 3528 } 3529 3530 n = lsquic_send_ctl_reschedule_packets(&conn->fc_send_ctl); 3531 if (n > 0) 3532 CLOSE_IF_NECESSARY(); 3533 3534 if (conn->fc_conn.cn_flags & LSCONN_SEND_BLOCKED) 3535 { 3536 RETURN_IF_OUT_OF_PACKETS(); 3537 if (generate_blocked_frame(conn, 0)) 3538 conn->fc_conn.cn_flags &= ~LSCONN_SEND_BLOCKED; 3539 } 3540 3541 if (!STAILQ_EMPTY(&conn->fc_stream_ids_to_reset)) 3542 { 3543 packetize_standalone_stream_resets(conn); 3544 CLOSE_IF_NECESSARY(); 3545 } 3546 3547 if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams)) 3548 { 3549 process_streams_ready_to_send(conn); 3550 CLOSE_IF_NECESSARY(); 3551 } 3552 3553 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0); 3554 if (!handshake_done_or_doing_sess_resume(conn)) 3555 { 3556 process_hsk_stream_write_events(conn); 3557 lsquic_send_ctl_maybe_app_limited(&conn->fc_send_ctl, &conn->fc_path); 3558 goto end_write; 3559 } 3560 3561 maybe_conn_flush_headers_stream(conn); 3562 3563 s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_HIGHEST_PRIO); 3564 conn->fc_flags |= (s < 0) << FC_BIT_ERROR; 3565 if (!write_is_possible(conn)) 3566 goto end_write; 3567 3568 if (!TAILQ_EMPTY(&conn->fc_pub.write_streams)) 3569 { 3570 process_streams_write_events(conn, 1); 3571 if (!write_is_possible(conn)) 3572 goto end_write; 3573 } 3574 3575 s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_OTHER_PRIO); 3576 conn->fc_flags |= (s < 0) << FC_BIT_ERROR; 3577 if (!write_is_possible(conn)) 3578 goto end_write; 3579 3580 if (!TAILQ_EMPTY(&conn->fc_pub.write_streams)) 3581 process_streams_write_events(conn, 0); 3582 3583 lsquic_send_ctl_maybe_app_limited(&conn->fc_send_ctl, &conn->fc_path); 3584 3585 end_write: 3586 3587 skip_write: 3588 if ((conn->fc_flags & FC_CLOSING) && conn_ok_to_close(conn)) 3589 { 3590 RETURN_IF_OUT_OF_PACKETS(); 3591 LSQ_DEBUG("connection is OK to close"); 3592 /* This is normal termination sequence. 3593 * 3594 * Generate CONNECTION_CLOSE frame if we are responding to one, have 3595 * packets scheduled to send, or silent close flag is not set. 3596 */ 3597 conn->fc_flags |= FC_TICK_CLOSE; 3598 if ((conn->fc_flags & FC_RECV_CLOSE) || 3599 0 != lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) || 3600 !conn->fc_settings->es_silent_close) 3601 { 3602 generate_connection_close_packet(conn); 3603 tick |= TICK_SEND|TICK_CLOSE; 3604 } 3605 else 3606 tick |= TICK_CLOSE; 3607 goto end; 3608 } 3609 3610 if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl)) 3611 { 3612 if (conn->fc_flags & FC_SEND_PING) 3613 { 3614 RETURN_IF_OUT_OF_PACKETS(); 3615 conn->fc_flags &= ~FC_SEND_PING; 3616 generate_ping_frame(conn); 3617 CLOSE_IF_NECESSARY(); 3618 assert(lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) != 0); 3619 } 3620 else 3621 { 3622 tick |= TICK_QUIET; 3623 goto end; 3624 } 3625 } 3626 else if (conn->fc_settings->es_ping_period) 3627 { 3628 lsquic_alarmset_unset(&conn->fc_alset, AL_PING); 3629 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 3630 conn->fc_flags &= ~FC_SEND_PING; /* It may have rung */ 3631 } 3632 3633 /* From the spec: 3634 * " The PING frame should be used to keep a connection alive when 3635 * " a stream is open. 3636 */ 3637 if (conn->fc_settings->es_ping_period 3638 && lsquic_hash_count(conn->fc_pub.all_streams) > 0) 3639 lsquic_alarmset_set(&conn->fc_alset, AL_PING, 3640 now + conn->fc_settings->es_ping_period * 1000 * 1000); 3641 3642 tick |= TICK_SEND; 3643 3644 end: 3645 service_streams(conn); 3646 CLOSE_IF_NECESSARY(); 3647 3648 close_end: 3649 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1); 3650 lsquic_send_ctl_tick_out(&conn->fc_send_ctl); 3651 return tick; 3652} 3653 3654 3655static void 3656set_earliest_idle_alarm (struct full_conn *conn, lsquic_time_t idle_conn_to) 3657{ 3658 lsquic_time_t exp; 3659 3660 if (conn->fc_pub.last_prog 3661 && (assert(conn->fc_flags & FC_NOPROG_TIMEOUT), 3662 exp = conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout, 3663 exp < idle_conn_to)) 3664 idle_conn_to = exp; 3665 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, idle_conn_to); 3666} 3667 3668 3669static void 3670full_conn_ci_packet_in (lsquic_conn_t *lconn, lsquic_packet_in_t *packet_in) 3671{ 3672 struct full_conn *conn = (struct full_conn *) lconn; 3673 3674#if LSQUIC_CONN_STATS 3675 conn->fc_stats.in.bytes += packet_in->pi_data_sz; 3676#endif 3677 set_earliest_idle_alarm(conn, 3678 packet_in->pi_received + conn->fc_settings->es_idle_conn_to); 3679 if (0 == (conn->fc_flags & FC_ERROR)) 3680 if (0 != process_incoming_packet(conn, packet_in)) 3681 conn->fc_flags |= FC_ERROR; 3682} 3683 3684 3685static lsquic_packet_out_t * 3686full_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, 3687 const struct to_coal *unused) 3688{ 3689 struct full_conn *conn = (struct full_conn *) lconn; 3690 return lsquic_send_ctl_next_packet_to_send(&conn->fc_send_ctl, NULL); 3691} 3692 3693 3694static void 3695full_conn_ci_packet_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out) 3696{ 3697 struct full_conn *conn = (struct full_conn *) lconn; 3698 int s; 3699 3700 recent_packet_hist_new(conn, 1, packet_out->po_sent); 3701 recent_packet_hist_frames(conn, 1, packet_out->po_frame_types); 3702 3703 if (packet_out->po_frame_types & GQUIC_FRAME_RETRANSMITTABLE_MASK) 3704 conn->fc_n_cons_unretx = 0; 3705 else 3706 ++conn->fc_n_cons_unretx; 3707 s = lsquic_send_ctl_sent_packet(&conn->fc_send_ctl, packet_out); 3708 if (s != 0) 3709 ABORT_ERROR("sent packet failed: %s", strerror(errno)); 3710#if LSQUIC_CONN_STATS 3711 ++conn->fc_stats.out.packets; 3712 conn->fc_stats.out.bytes += lsquic_packet_out_sent_sz(lconn, packet_out); 3713#endif 3714} 3715 3716 3717static void 3718full_conn_ci_packet_not_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out) 3719{ 3720 struct full_conn *conn = (struct full_conn *) lconn; 3721 lsquic_send_ctl_delayed_one(&conn->fc_send_ctl, packet_out); 3722} 3723 3724 3725static void 3726full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status) 3727{ 3728 struct full_conn *conn = (struct full_conn *) lconn; 3729 lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE); 3730 switch (status) 3731 { 3732 case LSQ_HSK_RESUMED_FAIL: 3733 case LSQ_HSK_FAIL: 3734 conn->fc_flags |= FC_HSK_FAILED; 3735 break; 3736 case LSQ_HSK_OK: 3737 case LSQ_HSK_RESUMED_OK: 3738 if (0 == apply_peer_settings(conn)) 3739 { 3740 if (conn->fc_flags & FC_HTTP) 3741 maybe_send_settings(conn); 3742 lconn->cn_flags |= LSCONN_HANDSHAKE_DONE; 3743 } 3744 else 3745 conn->fc_flags |= FC_ERROR; 3746 break; 3747 } 3748 if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done) 3749 conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn, 3750 status); 3751 if (status == LSQ_HSK_OK || status == LSQ_HSK_RESUMED_OK) 3752 { 3753 if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info) 3754 conn->fc_conn.cn_esf.g->esf_maybe_dispatch_sess_resume( 3755 conn->fc_conn.cn_enc_session, 3756 conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info); 3757 if (conn->fc_n_delayed_streams) 3758 create_delayed_streams(conn); 3759 if (!(conn->fc_flags & FC_SERVER)) 3760 lsquic_send_ctl_begin_optack_detection(&conn->fc_send_ctl); 3761 } 3762} 3763 3764 3765static void 3766full_conn_ci_abort (struct lsquic_conn *lconn) 3767{ 3768 struct full_conn *conn = (struct full_conn *) lconn; 3769 LSQ_INFO("User aborted connection"); 3770 conn->fc_flags |= FC_ABORTED; 3771} 3772 3773 3774static void 3775full_conn_ci_internal_error (struct lsquic_conn *lconn, 3776 const char *format, ...) 3777{ 3778 struct full_conn *const conn = (struct full_conn *) lconn; 3779 LSQ_INFO("Internal error reported"); 3780 conn->fc_flags |= FC_ERROR; 3781} 3782 3783 3784/* This function should not be called, as this is specific to IETF QUIC */ 3785static void 3786full_conn_ci_abort_error (struct lsquic_conn *lconn, int is_app, 3787 unsigned error_code, const char *fmt, ...) 3788{ 3789 struct full_conn *const conn = (struct full_conn *) lconn; 3790 assert(0); 3791 LSQ_WARN("(GQUIC) abort error is called unexpectedly"); 3792 conn->fc_flags |= FC_ERROR; 3793} 3794 3795 3796static void 3797full_conn_ci_close (struct lsquic_conn *lconn) 3798{ 3799 struct full_conn *conn = (struct full_conn *) lconn; 3800 lsquic_stream_t *stream; 3801 struct lsquic_hash_elem *el; 3802 3803 if (!(conn->fc_flags & FC_CLOSING)) 3804 { 3805 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 3806 el = lsquic_hash_next(conn->fc_pub.all_streams)) 3807 { 3808 stream = lsquic_hashelem_getdata(el); 3809 lsquic_stream_shutdown_internal(stream); 3810 } 3811 conn->fc_flags |= FC_CLOSING; 3812 if (!(conn->fc_flags & FC_GOAWAY_SENT)) 3813 conn->fc_flags |= FC_SEND_GOAWAY; 3814 lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn); 3815 } 3816} 3817 3818 3819static void 3820full_conn_ci_going_away (struct lsquic_conn *lconn) 3821{ 3822 struct full_conn *conn = (struct full_conn *) lconn; 3823 if (!(conn->fc_flags & (FC_CLOSING|FC_GOING_AWAY))) 3824 { 3825 LSQ_INFO("connection marked as going away"); 3826 assert(!(conn->fc_flags & FC_SEND_GOAWAY)); 3827 conn->fc_flags |= FC_GOING_AWAY; 3828 if (!(conn->fc_flags & FC_GOAWAY_SENT)) 3829 { 3830 conn->fc_flags |= FC_SEND_GOAWAY; 3831 lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn); 3832 } 3833 } 3834} 3835 3836 3837/* Find stream when stream ID is read from something other than a STREAM 3838 * frame. If the stream cannot be found or created, the connection is 3839 * aborted. 3840 */ 3841#if __GNUC__ 3842__attribute__((nonnull(4))) 3843#endif 3844static lsquic_stream_t * 3845find_stream_on_non_stream_frame (struct full_conn *conn, 3846 lsquic_stream_id_t stream_id, enum stream_ctor_flags stream_ctor_flags, 3847 const char *what) 3848{ 3849 lsquic_stream_t *stream; 3850 unsigned in_count; 3851 3852 stream = find_stream_by_id(conn, stream_id); 3853 if (stream) 3854 return stream; 3855 3856 if (conn_is_stream_closed(conn, stream_id)) 3857 { 3858 LSQ_DEBUG("drop incoming %s for closed stream %"PRIu64, what, stream_id); 3859 return NULL; 3860 } 3861 3862 /* XXX It seems that if we receive a priority frame for a stream, the 3863 * stream should exist or have existed at some point. Thus, if 3864 * it does not exist, we should return an error here. 3865 */ 3866 3867 if (!is_peer_initiated(conn, stream_id)) 3868 { 3869 ABORT_ERROR("frame for never-initiated stream (push promise?)"); 3870 return NULL; 3871 } 3872 3873 in_count = count_streams(conn, 1); 3874 LSQ_DEBUG("number of peer-initiated streams: %u", in_count); 3875 if (in_count >= conn->fc_cfg.max_streams_in) 3876 { 3877 if (!(conn->fc_flags & FC_ABORT_COMPLAINED)) 3878 { 3879 unsigned counts[N_SCNTS]; 3880 collect_stream_counts(conn, 1, counts); 3881 ABORT_WARN("incoming %s for stream %"PRIu64" would exceed " 3882 "limit: %u. all: %u; peer: %u; closed: %u; reset: %u; reset " 3883 "and not closed: %u", 3884 what, stream_id, conn->fc_cfg.max_streams_in, counts[SCNT_ALL], 3885 counts[SCNT_PEER], counts[SCNT_CLOSED], counts[SCNT_RESET], 3886 counts[SCNT_RES_UNCLO]); 3887 } 3888 return NULL; 3889 } 3890 if ((conn->fc_flags & FC_GOING_AWAY) && 3891 stream_id > conn->fc_max_peer_stream_id) 3892 { 3893 maybe_schedule_reset_for_stream(conn, stream_id); 3894 LSQ_DEBUG("going away: reset new incoming stream %"PRIu64, stream_id); 3895 return NULL; 3896 } 3897 3898 stream = new_stream(conn, stream_id, stream_ctor_flags); 3899 if (!stream) 3900 { 3901 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 3902 return NULL; 3903 } 3904 if (stream_id > conn->fc_max_peer_stream_id) 3905 conn->fc_max_peer_stream_id = stream_id; 3906 3907 return stream; 3908} 3909 3910 3911static void 3912headers_stream_on_conn_error (void *ctx) 3913{ 3914 struct full_conn *conn = ctx; 3915 ABORT_ERROR("connection error reported by HEADERS stream"); 3916} 3917 3918 3919static void 3920headers_stream_on_stream_error (void *ctx, lsquic_stream_id_t stream_id) 3921{ 3922 struct full_conn *conn = ctx; 3923 lsquic_stream_t *stream; 3924 3925 stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW, 3926 "error"); 3927 if (stream) 3928 { 3929 LSQ_DEBUG("resetting stream %"PRIu64" due to error", stream_id); 3930 /* We use code 1, which is QUIC_INTERNAL_ERROR (see 3931 * [draft-hamilton-quic-transport-protocol-01], Section 10), for all 3932 * errors. There does not seem to be a good reason to figure out 3933 * and send more specific error codes. 3934 */ 3935 lsquic_stream_reset_ext(stream, 1, 0); 3936 } 3937} 3938 3939 3940static void 3941headers_stream_on_enable_push (void *ctx, int enable_push) 3942{ 3943 struct full_conn *conn = ctx; 3944 if (0 == enable_push) 3945 { 3946 LSQ_DEBUG("server push %d -> 0", !!(conn->fc_flags & FC_SUPPORT_PUSH)); 3947 conn->fc_flags &= ~FC_SUPPORT_PUSH; 3948 } 3949 else if (conn->fc_settings->es_support_push) 3950 { 3951 LSQ_DEBUG("server push %d -> 1", !!(conn->fc_flags & FC_SUPPORT_PUSH)); 3952 conn->fc_flags |= FC_SUPPORT_PUSH; 3953 } 3954 else 3955 LSQ_INFO("not enabling server push that's disabled in engine settings"); 3956} 3957 3958 3959static void 3960headers_stream_on_incoming_headers (void *ctx, struct uncompressed_headers *uh) 3961{ 3962 struct full_conn *conn = ctx; 3963 lsquic_stream_t *stream; 3964 3965 LSQ_DEBUG("incoming headers for stream %"PRIu64, uh->uh_stream_id); 3966 3967 stream = find_stream_on_non_stream_frame(conn, uh->uh_stream_id, 0, 3968 "headers"); 3969 if (!stream) 3970 goto free_uh; 3971 3972 if (lsquic_stream_is_reset(stream)) 3973 { 3974 LSQ_DEBUG("stream is reset: ignore headers"); 3975 goto free_uh; 3976 } 3977 3978 if (0 != lsquic_stream_uh_in(stream, uh)) 3979 { 3980 ABORT_ERROR("stream %"PRIu64" refused incoming headers", 3981 uh->uh_stream_id); 3982 goto free_uh; 3983 } 3984 3985 if (!(stream->stream_flags & STREAM_ONNEW_DONE)) 3986 lsquic_stream_call_on_new(stream); 3987 3988 return; 3989 3990 free_uh: 3991 if (uh->uh_hset) 3992 conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset); 3993 free(uh); 3994} 3995 3996 3997static void 3998headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) 3999{ 4000 struct full_conn *conn = ctx; 4001 lsquic_stream_t *stream; 4002 4003 assert(!(conn->fc_flags & FC_SERVER)); 4004 4005 LSQ_DEBUG("push promise for stream %"PRIu64" in response to %"PRIu64, 4006 uh->uh_oth_stream_id, uh->uh_stream_id); 4007 4008 if (0 == (uh->uh_stream_id & 1) || 4009 0 != (uh->uh_oth_stream_id & 1)) 4010 { 4011 ABORT_ERROR("invalid push promise stream IDs: %"PRIu64", %"PRIu64, 4012 uh->uh_oth_stream_id, uh->uh_stream_id); 4013 goto free_uh; 4014 } 4015 4016 if (!(conn_is_stream_closed(conn, uh->uh_stream_id) || 4017 find_stream_by_id(conn, uh->uh_stream_id))) 4018 { 4019 ABORT_ERROR("invalid push promise original stream ID %"PRIu64" never " 4020 "initiated", uh->uh_stream_id); 4021 goto free_uh; 4022 } 4023 4024 if (conn_is_stream_closed(conn, uh->uh_oth_stream_id) || 4025 find_stream_by_id(conn, uh->uh_oth_stream_id)) 4026 { 4027 ABORT_ERROR("invalid promised stream ID %"PRIu64" already used", 4028 uh->uh_oth_stream_id); 4029 goto free_uh; 4030 } 4031 4032 stream = new_stream_ext(conn, uh->uh_oth_stream_id, STREAM_IF_STD, 4033 (conn->fc_enpub->enp_settings.es_delay_onclose?SCF_DELAY_ONCLOSE:0)| 4034 SCF_DI_AUTOSWITCH|(conn->fc_enpub->enp_settings.es_rw_once ? 4035 SCF_DISP_RW_ONCE : 0)); 4036 if (!stream) 4037 { 4038 ABORT_ERROR("cannot create stream: %s", strerror(errno)); 4039 goto free_uh; 4040 } 4041 lsquic_stream_push_req(stream, uh); 4042 lsquic_stream_call_on_new(stream); 4043 return; 4044 4045 free_uh: 4046 if (uh->uh_hset) 4047 conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset); 4048 free(uh); 4049} 4050 4051 4052static void 4053headers_stream_on_priority (void *ctx, lsquic_stream_id_t stream_id, 4054 int exclusive, lsquic_stream_id_t dep_stream_id, unsigned weight) 4055{ 4056 struct full_conn *conn = ctx; 4057 lsquic_stream_t *stream; 4058 LSQ_DEBUG("got priority frame for stream %"PRIu64": (ex: %d; dep stream: " 4059 "%"PRIu64"; weight: %u)", stream_id, exclusive, dep_stream_id, weight); 4060 stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW, 4061 "priority"); 4062 if (stream) 4063 lsquic_stream_set_priority_internal(stream, weight); 4064} 4065 4066 4067 4068#define STRLEN(s) (sizeof(s) - 1) 4069 4070static struct uncompressed_headers * 4071synthesize_push_request (struct full_conn *conn, void *hset, 4072 lsquic_stream_id_t pushed_stream_id, const lsquic_stream_t *dep_stream) 4073{ 4074 struct uncompressed_headers *uh; 4075 4076 assert(hset); 4077 4078 uh = malloc(sizeof(*uh)); 4079 if (!uh) 4080 return NULL; 4081 4082 uh->uh_stream_id = pushed_stream_id; 4083 uh->uh_oth_stream_id = 0; /* We don't do dependencies */ 4084 uh->uh_weight = lsquic_stream_priority(dep_stream) / 2 + 1; 4085 uh->uh_exclusive = 0; 4086 uh->uh_flags = UH_FIN; 4087 if (lsquic_http1x_if == conn->fc_enpub->enp_hsi_if) 4088 uh->uh_flags |= UH_H1H; 4089 uh->uh_hset = hset; 4090 4091 return uh; 4092} 4093 4094 4095static int 4096full_conn_ci_is_push_enabled (struct lsquic_conn *lconn) 4097{ 4098 struct full_conn *const conn = (struct full_conn *) lconn; 4099 return conn->fc_flags & FC_SUPPORT_PUSH; 4100} 4101 4102 4103static int 4104full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset, 4105 struct lsquic_stream *dep_stream, const struct lsquic_http_headers *headers) 4106{ 4107 struct full_conn *const conn = (struct full_conn *) lconn; 4108 lsquic_stream_t *pushed_stream; 4109 struct uncompressed_headers *uh; /* We synthesize the request */ 4110 lsquic_stream_id_t stream_id; 4111 int hit_limit; 4112 4113 if ((conn->fc_flags & (FC_SERVER|FC_HTTP)) != (FC_SERVER|FC_HTTP)) 4114 { 4115 LSQ_ERROR("must be server in HTTP mode to push streams"); 4116 return -1; 4117 } 4118 4119 if (lsquic_stream_is_pushed(dep_stream)) 4120 { 4121 LSQ_WARN("cannot push stream dependent on another pushed stream " 4122 "(%"PRIu64")", dep_stream->id); 4123 return -1; 4124 } 4125 4126 if (!(conn->fc_flags & FC_SUPPORT_PUSH)) 4127 { 4128 LSQ_INFO("server push support is disabled"); 4129 return 1; 4130 } 4131 4132 if (!hset) 4133 { 4134 LSQ_ERROR("header set must be specified when pushing"); 4135 return -1; 4136 } 4137 4138 hit_limit = 0; 4139 if (either_side_going_away(conn) || 4140 (hit_limit = 1, count_streams(conn, 0) >= conn->fc_cfg.max_streams_out)) 4141 { 4142 LSQ_DEBUG("cannot create pushed stream: %s", hit_limit ? 4143 "hit connection limit" : "connection is going away"); 4144 return 1; 4145 } 4146 4147 stream_id = generate_stream_id(conn); 4148 uh = synthesize_push_request(conn, hset, stream_id, dep_stream); 4149 if (!uh) 4150 { 4151 ABORT_ERROR("memory allocation failure"); 4152 return -1; 4153 } 4154 4155 pushed_stream = new_stream(conn, stream_id, 0); 4156 if (!pushed_stream) 4157 { 4158 LSQ_WARN("cannot create stream: %s", strerror(errno)); 4159 free(uh); 4160 return -1; 4161 } 4162 4163 if (0 != lsquic_stream_uh_in(pushed_stream, uh)) 4164 { 4165 LSQ_WARN("stream barfed when fed synthetic request"); 4166 free(uh); 4167 return -1; 4168 } 4169 4170 if (0 != lsquic_headers_stream_push_promise(conn->fc_pub.u.gquic.hs, dep_stream->id, 4171 pushed_stream->id, headers)) 4172 { 4173 /* If forget we ever had the hset pointer: */ 4174 lsquic_stream_drop_hset_ref(pushed_stream); 4175 /* Now roll back stream creation and return stream ID: */ 4176 if (pushed_stream->sm_hash_el.qhe_flags & QHE_HASHED) 4177 lsquic_hash_erase(conn->fc_pub.all_streams, 4178 &pushed_stream->sm_hash_el); 4179 lsquic_stream_destroy(pushed_stream); 4180 conn->fc_last_stream_id -= 2; 4181 LSQ_INFO("could not send push promise"); 4182 return -1; 4183 } 4184 4185 lsquic_stream_call_on_new(pushed_stream); 4186 return 0; 4187} 4188 4189 4190static void 4191full_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert) 4192{ 4193 assert(0); 4194} 4195 4196 4197static enum LSQUIC_CONN_STATUS 4198full_conn_ci_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz) 4199{ 4200 struct full_conn *const conn = (struct full_conn *) lconn; 4201 size_t n; 4202 4203 /* Test the common case first: */ 4204 if (!(conn->fc_flags & (FC_ERROR 4205 |FC_TIMED_OUT 4206 |FC_ABORTED 4207 |FC_GOT_PRST 4208 |FC_HSK_FAILED 4209 |FC_CLOSING 4210 |FC_GOING_AWAY))) 4211 { 4212 if (lconn->cn_flags & LSCONN_PEER_GOING_AWAY) 4213 return LSCONN_ST_PEER_GOING_AWAY; 4214 else if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE) 4215 return LSCONN_ST_CONNECTED; 4216 else 4217 return LSCONN_ST_HSK_IN_PROGRESS; 4218 } 4219 4220 if (errbuf && bufsz) 4221 { 4222 if (conn->fc_errmsg) 4223 { 4224 n = bufsz < MAX_ERRMSG ? bufsz : MAX_ERRMSG; 4225 strncpy(errbuf, conn->fc_errmsg, n); 4226 errbuf[n - 1] = '\0'; 4227 } 4228 else 4229 errbuf[0] = '\0'; 4230 } 4231 4232 if (conn->fc_flags & FC_ERROR) 4233 return LSCONN_ST_ERROR; 4234 if (conn->fc_flags & FC_TIMED_OUT) 4235 return LSCONN_ST_TIMED_OUT; 4236 if (conn->fc_flags & FC_ABORTED) 4237 return LSCONN_ST_USER_ABORTED; 4238 if (conn->fc_flags & FC_GOT_PRST) 4239 return LSCONN_ST_RESET; 4240 if (conn->fc_flags & FC_HSK_FAILED) 4241 return LSCONN_ST_HSK_FAILURE; 4242 if (conn->fc_flags & FC_CLOSING) 4243 return LSCONN_ST_CLOSED; 4244 assert(conn->fc_flags & FC_GOING_AWAY); 4245 return LSCONN_ST_GOING_AWAY; 4246} 4247 4248 4249static int 4250full_conn_ci_is_tickable (lsquic_conn_t *lconn) 4251{ 4252 struct full_conn *conn = (struct full_conn *) lconn; 4253 struct lsquic_stream *stream; 4254 4255 if (!TAILQ_EMPTY(&conn->fc_pub.service_streams)) 4256 { 4257 LSQ_DEBUG("tickable: there are streams to be serviced"); 4258 return 1; 4259 } 4260 4261 if ((conn->fc_enpub->enp_flags & ENPUB_CAN_SEND) 4262 && (should_generate_ack(conn) || 4263 !lsquic_send_ctl_sched_is_blocked(&conn->fc_send_ctl))) 4264 { 4265 const enum full_conn_flags send_flags = FC_SEND_GOAWAY 4266 |FC_SEND_STOP_WAITING|FC_SEND_PING|FC_SEND_WUF|FC_CLOSING; 4267 if (conn->fc_flags & send_flags) 4268 { 4269 LSQ_DEBUG("tickable: flags: 0x%X", conn->fc_flags & send_flags); 4270 goto check_can_send; 4271 } 4272 if (lsquic_send_ctl_has_sendable(&conn->fc_send_ctl)) 4273 { 4274 LSQ_DEBUG("tickable: has sendable packets"); 4275 return 1; /* Don't check can_send: already on scheduled queue */ 4276 } 4277 if ((conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) 4278 && lsquic_send_ctl_has_buffered(&conn->fc_send_ctl)) 4279 { 4280 LSQ_DEBUG("tickable: has buffered packets"); 4281 goto check_can_send; 4282 } 4283 if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams)) 4284 { 4285 LSQ_DEBUG("tickable: there are sending streams"); 4286 goto check_can_send; 4287 } 4288 if (handshake_done_or_doing_sess_resume(conn)) 4289 { 4290 TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, 4291 next_write_stream) 4292 if (lsquic_stream_write_avail(stream)) 4293 { 4294 LSQ_DEBUG("tickable: stream %"PRIu64" can be written to", 4295 stream->id); 4296 goto check_can_send; 4297 } 4298 } 4299 else 4300 { 4301 TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, 4302 next_write_stream) 4303 if (lsquic_stream_is_crypto(stream) 4304 && lsquic_stream_write_avail(stream)) 4305 { 4306 LSQ_DEBUG("tickable: stream %"PRIu64" can be written to", 4307 stream->id); 4308 goto check_can_send; 4309 } 4310 } 4311 goto check_readable_streams; 4312 check_can_send: 4313 if (lsquic_send_ctl_can_send(&conn->fc_send_ctl)) 4314 return 1; 4315 } 4316 4317 check_readable_streams: 4318 TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream) 4319 if (lsquic_stream_readable(stream)) 4320 { 4321 LSQ_DEBUG("tickable: stream %"PRIu64" can be read from", 4322 stream->id); 4323 return 1; 4324 } 4325 4326 LSQ_DEBUG("not tickable"); 4327 return 0; 4328} 4329 4330 4331static lsquic_time_t 4332full_conn_ci_next_tick_time (lsquic_conn_t *lconn, unsigned *why) 4333{ 4334 struct full_conn *conn = (struct full_conn *) lconn; 4335 lsquic_time_t alarm_time, pacer_time, now; 4336 enum alarm_id al_id; 4337 4338 alarm_time = lsquic_alarmset_mintime(&conn->fc_alset, &al_id); 4339 pacer_time = lsquic_send_ctl_next_pacer_time(&conn->fc_send_ctl); 4340 4341 if (pacer_time && LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)) 4342 { 4343 now = lsquic_time_now(); 4344 if (pacer_time < now) 4345 LSQ_DEBUG("%s: pacer is %"PRIu64" usec in the past", __func__, 4346 now - pacer_time); 4347 } 4348 4349 if (alarm_time && pacer_time) 4350 { 4351 if (alarm_time < pacer_time) 4352 { 4353 *why = N_AEWS + al_id; 4354 return alarm_time; 4355 } 4356 else 4357 { 4358 *why = AEW_PACER; 4359 return pacer_time; 4360 } 4361 } 4362 else if (alarm_time) 4363 { 4364 *why = N_AEWS + al_id; 4365 return alarm_time; 4366 } 4367 else if (pacer_time) 4368 { 4369 *why = AEW_PACER; 4370 return pacer_time; 4371 } 4372 else 4373 return 0; 4374} 4375 4376 4377int 4378lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn) 4379{ 4380 struct full_conn *const conn = (struct full_conn *) lconn; 4381 const unsigned cce_idx = lconn->cn_cur_cce_idx; 4382 struct conn_cid_elem *const cce = &lconn->cn_cces[ cce_idx ]; 4383 struct lsquic_stream *stream; 4384 enum lsquic_version version; 4385 4386 if (lconn->cn_esf_c->esf_is_sess_resume_enabled(conn->fc_conn.cn_enc_session)) 4387 { 4388 /* We need to do this because we do not clean up any data that may 4389 * have been already sent. This is left an optimization for the 4390 * future. 4391 */ 4392 LSQ_DEBUG("received SREJ when 0RTT was on: fail handshake and let " 4393 "caller retry"); 4394 full_conn_ci_hsk_done(lconn, LSQ_HSK_RESUMED_FAIL); 4395 return -1; 4396 } 4397 4398 LSQ_DEBUG("reinitialize CID and other state due to SREJ"); 4399 4400 /* Generate new CID and update connections hash */ 4401 if (cce->cce_hash_el.qhe_flags & QHE_HASHED) 4402 { 4403 lsquic_engine_retire_cid(conn->fc_enpub, lconn, cce_idx, 4404 0 /* OK to omit the `now' value */, 0); 4405 lconn->cn_cces_mask |= 1 << cce_idx; 4406 lsquic_generate_cid_gquic(&cce->cce_cid); 4407 if (0 != lsquic_engine_add_cid(conn->fc_enpub, lconn, cce_idx)) 4408 return -1; 4409 } 4410 else 4411 { 4412 LSQ_DEBUG("not hashed by CID, no need to reinsert"); 4413 lsquic_generate_cid_gquic(&cce->cce_cid); 4414 } 4415 lconn->cn_esf.g->esf_reset_cid(lconn->cn_enc_session, &cce->cce_cid); 4416 4417 /* Reset version negotiation */ 4418 version = highest_bit_set(conn->fc_orig_versions); 4419 init_ver_neg(conn, conn->fc_orig_versions, &version); 4420 4421 /* Reset receive history */ 4422 lsquic_rechist_cleanup(&conn->fc_rechist); 4423 lsquic_rechist_init(&conn->fc_rechist, 0, MAX_ACK_RANGES); 4424 4425 /* Reset send controller state */ 4426 lsquic_send_ctl_cleanup(&conn->fc_send_ctl); 4427 lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub, 4428 &conn->fc_ver_neg, &conn->fc_pub, 0); 4429 4430 /* Reset handshake stream state */ 4431 stream = find_stream_by_id(conn, hsk_stream_id(conn)); 4432 if (!stream) 4433 return -1; 4434 stream->n_unacked = 0; 4435 stream->tosend_off = 0; 4436 stream->read_offset = 0; 4437 stream->fc.sf_read_off = 0; 4438 stream->fc.sf_max_recv_off = 0; 4439 4440 lsquic_alarmset_unset(&conn->fc_alset, AL_RETX_APP); 4441 lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP); 4442 conn->fc_flags &= ~(FC_ACK_QUEUED|FC_ACK_HAD_MISS|FC_NSTP); 4443 conn->fc_flags |= FC_GOT_SREJ; 4444 4445 return 0; 4446} 4447 4448 4449#if LSQUIC_CONN_STATS 4450static const struct conn_stats * 4451full_conn_ci_get_stats (struct lsquic_conn *lconn) 4452{ 4453 struct full_conn *conn = (struct full_conn *) lconn; 4454 return &conn->fc_stats; 4455} 4456 4457#include "lsquic_cong_ctl.h" 4458 4459static void 4460full_conn_ci_log_stats (struct lsquic_conn *lconn) 4461{ 4462 struct full_conn *conn = (struct full_conn *) lconn; 4463 struct batch_size_stats *const bs = &conn->fc_enpub->enp_batch_size_stats; 4464 struct conn_stats diff_stats; 4465 uint64_t cwnd; 4466 char cidstr[MAX_CID_LEN * 2 + 1]; 4467 4468 if (!conn->fc_last_stats) 4469 { 4470 conn->fc_last_stats = calloc(1, sizeof(*conn->fc_last_stats)); 4471 if (!conn->fc_last_stats) 4472 return; 4473 LSQ_DEBUG("allocated last stats"); 4474 } 4475 4476 cwnd = conn->fc_send_ctl.sc_ci->cci_get_cwnd( 4477 conn->fc_send_ctl.sc_cong_ctl); 4478 lsquic_conn_stats_diff(&conn->fc_stats, conn->fc_last_stats, &diff_stats); 4479 lsquic_logger_log1(LSQ_LOG_NOTICE, LSQLM_CONN_STATS, 4480 "%s: ticks: %lu; cwnd: %"PRIu64"; conn flow: max: %"PRIu64 4481 ", avail: %"PRIu64"; packets: sent: %lu, lost: %lu, retx: %lu, rcvd: %lu" 4482 "; batch: count: %u; min: %u; max: %u; avg: %.2f", 4483 (lsquic_cid2str(LSQUIC_LOG_CONN_ID, cidstr), cidstr), 4484 diff_stats.n_ticks, cwnd, 4485 conn->fc_pub.conn_cap.cc_max, 4486 lsquic_conn_cap_avail(&conn->fc_pub.conn_cap), 4487 diff_stats.out.packets, diff_stats.out.lost_packets, 4488 diff_stats.out.retx_packets, diff_stats.in.packets, 4489 bs->count, bs->min, bs->max, bs->avg); 4490 4491 *conn->fc_last_stats = conn->fc_stats; 4492 memset(bs, 0, sizeof(*bs)); 4493} 4494#endif 4495 4496 4497static const struct headers_stream_callbacks headers_callbacks = 4498{ 4499 .hsc_on_headers = headers_stream_on_incoming_headers, 4500 .hsc_on_push_promise = headers_stream_on_push_promise, 4501 .hsc_on_priority = headers_stream_on_priority, 4502 .hsc_on_stream_error = headers_stream_on_stream_error, 4503 .hsc_on_conn_error = headers_stream_on_conn_error, 4504 .hsc_on_enable_push = headers_stream_on_enable_push, 4505}; 4506 4507static const struct headers_stream_callbacks *headers_callbacks_ptr = &headers_callbacks; 4508 4509static const struct conn_iface full_conn_iface = { 4510 .ci_abort = full_conn_ci_abort, 4511 .ci_abort_error = full_conn_ci_abort_error, 4512 .ci_ack_rollback = full_conn_ci_ack_rollback, 4513 .ci_ack_snapshot = full_conn_ci_ack_snapshot, 4514 .ci_can_write_ack = full_conn_ci_can_write_ack, 4515 .ci_cancel_pending_streams 4516 = full_conn_ci_cancel_pending_streams, 4517 .ci_client_call_on_new = full_conn_ci_client_call_on_new, 4518 .ci_close = full_conn_ci_close, 4519 .ci_destroy = full_conn_ci_destroy, 4520 .ci_get_stream_by_id = full_conn_ci_get_stream_by_id, 4521 .ci_get_engine = full_conn_ci_get_engine, 4522 .ci_get_path = full_conn_ci_get_path, 4523#if LSQUIC_CONN_STATS 4524 .ci_get_stats = full_conn_ci_get_stats, 4525 .ci_log_stats = full_conn_ci_log_stats, 4526#endif 4527 .ci_going_away = full_conn_ci_going_away, 4528 .ci_hsk_done = full_conn_ci_hsk_done, 4529 .ci_internal_error = full_conn_ci_internal_error, 4530 .ci_is_push_enabled = full_conn_ci_is_push_enabled, 4531 .ci_is_tickable = full_conn_ci_is_tickable, 4532 .ci_make_stream = full_conn_ci_make_stream, 4533 .ci_n_avail_streams = full_conn_ci_n_avail_streams, 4534 .ci_n_pending_streams = full_conn_ci_n_pending_streams, 4535 .ci_next_packet_to_send = full_conn_ci_next_packet_to_send, 4536 .ci_next_tick_time = full_conn_ci_next_tick_time, 4537 .ci_packet_in = full_conn_ci_packet_in, 4538 .ci_packet_not_sent = full_conn_ci_packet_not_sent, 4539 .ci_packet_sent = full_conn_ci_packet_sent, 4540 .ci_record_addrs = full_conn_ci_record_addrs, 4541 /* gQUIC connection does not need this functionality because it only 4542 * uses one CID and it's liveness is updated automatically by the 4543 * caller when packets come in. 4544 */ 4545 .ci_report_live = NULL, 4546 .ci_status = full_conn_ci_status, 4547 .ci_tick = full_conn_ci_tick, 4548 .ci_write_ack = full_conn_ci_write_ack, 4549 .ci_push_stream = full_conn_ci_push_stream, 4550 .ci_tls_alert = full_conn_ci_tls_alert, 4551}; 4552 4553static const struct conn_iface *full_conn_iface_ptr = &full_conn_iface; 4554