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