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