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