lsquic_full_conn.c revision 5d77f141
1/* Copyright (c) 2017 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 "lsquic_types.h" 20#include "lsquic.h" 21#include "lsquic_alarmset.h" 22#include "lsquic_packet_common.h" 23#include "lsquic_parse.h" 24#include "lsquic_packet_in.h" 25#include "lsquic_packet_out.h" 26#include "lsquic_rechist.h" 27#include "lsquic_util.h" 28#include "lsquic_conn_flow.h" 29#include "lsquic_sfcw.h" 30#include "lsquic_stream.h" 31#include "lsquic_senhist.h" 32#include "lsquic_rtt.h" 33#include "lsquic_cubic.h" 34#include "lsquic_pacer.h" 35#include "lsquic_send_ctl.h" 36#include "lsquic_set.h" 37#include "lsquic_malo.h" 38#include "lsquic_chsk_stream.h" 39#include "lsquic_str.h" 40#include "lsquic_qtags.h" 41#include "lsquic_handshake.h" 42#include "lsquic_headers_stream.h" 43#include "lsquic_frame_common.h" 44#include "lsquic_frame_reader.h" 45#include "lsquic_mm.h" 46#include "lsquic_engine_public.h" 47#include "lsquic_spi.h" 48#include "lsquic_ev_log.h" 49#include "lsquic_version.h" 50#include "lsquic_hash.h" 51 52#include "lsquic_conn.h" 53#include "lsquic_conn_public.h" 54#include "lsquic_ver_neg.h" 55#include "lsquic_full_conn.h" 56 57#define LSQUIC_LOGGER_MODULE LSQLM_CONN 58#define LSQUIC_LOG_CONN_ID conn->fc_conn.cn_cid 59#include "lsquic_logger.h" 60 61enum { STREAM_IF_STD, STREAM_IF_HSK, STREAM_IF_HDR, N_STREAM_IFS }; 62 63#define MAX_ANY_PACKETS_SINCE_LAST_ACK 20 64#define MAX_RETR_PACKETS_SINCE_LAST_ACK 2 65#define ACK_TIMEOUT 25000 66#define TIME_BETWEEN_PINGS 15000000 67#define IDLE_TIMEOUT 30000000 68 69/* IMPORTANT: Keep values of FC_SERVER and FC_HTTP same as LSENG_SERVER 70 * and LSENG_HTTP. 71 */ 72enum full_conn_flags { 73 FC_SERVER = LSENG_SERVER, /* Server mode */ 74 FC_HTTP = LSENG_HTTP, /* HTTP mode */ 75 FC_TIMED_OUT = (1 << 2), 76#define FC_BIT_ERROR 3 77 FC_ERROR = (1 << FC_BIT_ERROR), 78 FC_ABORTED = (1 << 4), 79 FC_CLOSING = (1 << 5), /* Closing */ 80 FC_SEND_PING = (1 << 6), /* PING frame scheduled */ 81 FC_NSTP = (1 << 7), /* NSTP mode */ 82 FC_SEND_GOAWAY = (1 << 8), 83 FC_SEND_WUF = (1 << 9), 84 FC_SEND_STOP_WAITING 85 = (1 <<10), 86 FC_ACK_QUEUED = (1 <<11), 87 FC_ACK_HAD_MISS = (1 <<12), /* Last ACK frame had missing packets. */ 88 FC_CREATED_OK = (1 <<13), 89 FC_RECV_CLOSE = (1 <<14), /* Received CONNECTION_CLOSE frame */ 90 FC_GOING_AWAY = (1 <<15), /* Do not accept or create new streams */ 91 FC_GOAWAY_SENT = (1 <<16), /* Only send GOAWAY once */ 92 FC_SUPPORT_PUSH = (1 <<17), 93 FC_GOT_PRST = (1 <<18), /* Received public reset packet */ 94 FC_FIRST_TICK = (1 <<19), 95 FC_TICK_CLOSE = (1 <<20), /* We returned TICK_CLOSE */ 96 FC_HSK_FAILED = (1 <<21), 97 FC_HAVE_SAVED_ACK = (1 <<22), 98}; 99 100#define FC_IMMEDIATE_CLOSE_FLAGS \ 101 (FC_TIMED_OUT|FC_ERROR|FC_ABORTED|FC_HSK_FAILED) 102 103#if LSQUIC_KEEP_STREAM_HISTORY 104#define KEEP_CLOSED_STREAM_HISTORY 0 105#endif 106 107#if KEEP_CLOSED_STREAM_HISTORY 108struct stream_history 109{ 110 uint32_t shist_stream_id; 111 enum stream_flags shist_stream_flags; 112 unsigned char shist_hist_buf[1 << SM_HIST_BITS]; 113}; 114#define SHIST_BITS 5 115#define SHIST_MASK ((1 << SHIST_BITS) - 1) 116#endif 117 118#ifndef KEEP_PACKET_HISTORY 119#ifdef NDEBUG 120#define KEEP_PACKET_HISTORY 0 121#else 122#define KEEP_PACKET_HISTORY 16 123#endif 124#endif 125 126#if KEEP_PACKET_HISTORY 127struct packet_el 128{ 129 lsquic_time_t time; 130 enum quic_ft_bit frame_types; 131}; 132 133struct recent_packets 134{ 135 struct packet_el els[KEEP_PACKET_HISTORY]; 136 unsigned idx; 137}; 138#endif 139 140struct stream_id_to_reset 141{ 142 STAILQ_ENTRY(stream_id_to_reset) sitr_next; 143 uint32_t sitr_stream_id; 144}; 145 146 147struct full_conn 148{ 149 struct lsquic_conn fc_conn; 150 struct lsquic_rechist fc_rechist; 151 struct { 152 const struct lsquic_stream_if *stream_if; 153 void *stream_if_ctx; 154 } fc_stream_ifs[N_STREAM_IFS]; 155 lsquic_conn_ctx_t *fc_conn_ctx; 156 struct lsquic_send_ctl fc_send_ctl; 157 struct lsquic_conn_public fc_pub; 158 lsquic_alarmset_t fc_alset; 159 lsquic_set32_t fc_closed_stream_ids[2]; 160 const struct lsquic_engine_settings 161 *fc_settings; 162 struct lsquic_engine_public *fc_enpub; 163 lsquic_packno_t fc_max_ack_packno; 164 lsquic_packno_t fc_max_swf_packno; 165 lsquic_time_t fc_mem_logged_last; 166 struct { 167 unsigned max_streams_in; 168 unsigned max_streams_out; 169 unsigned max_conn_send; 170 unsigned max_stream_send; 171 } fc_cfg; 172 enum full_conn_flags fc_flags; 173 /* Number of packets received since last ACK sent: */ 174 unsigned fc_n_slack_all; 175 /* Number ackable packets received since last ACK was sent: */ 176 unsigned fc_n_slack_akbl; 177 unsigned fc_n_delayed_streams; 178 unsigned fc_n_cons_unretx; 179 uint32_t fc_last_stream_id; 180 uint32_t fc_max_peer_stream_id; 181 uint32_t fc_goaway_stream_id; 182 struct ver_neg fc_ver_neg; 183 union { 184 struct client_hsk_ctx client; 185 } fc_hsk_ctx; 186#if FULL_CONN_STATS 187 struct { 188 unsigned n_all_packets_in, 189 n_packets_out, 190 n_undec_packets, 191 n_dup_packets, 192 n_err_packets; 193 unsigned long stream_data_sz; 194 unsigned long n_ticks; 195 unsigned n_acks_in, 196 n_acks_proc, 197 n_acks_merged[2]; 198 } fc_stats; 199#endif 200#if KEEP_CLOSED_STREAM_HISTORY 201 /* Rolling log of histories of closed streams. Older entries are 202 * overwritten. 203 */ 204 struct stream_history fc_stream_histories[1 << SHIST_BITS]; 205 unsigned fc_stream_hist_idx; 206#endif 207 char *fc_errmsg; 208#if KEEP_PACKET_HISTORY 209 struct recent_packets fc_recent_packets[2]; /* 0: in; 1: out */ 210#endif 211 STAILQ_HEAD(, stream_id_to_reset) 212 fc_stream_ids_to_reset; 213 struct short_ack_info fc_saved_ack_info; 214 lsquic_time_t fc_saved_ack_received; 215}; 216 217 218#define MAX_ERRMSG 256 219 220#define SET_ERRMSG(conn, ...) do { \ 221 if (!(conn)->fc_errmsg) \ 222 (conn)->fc_errmsg = malloc(MAX_ERRMSG); \ 223 if ((conn)->fc_errmsg) \ 224 snprintf((conn)->fc_errmsg, MAX_ERRMSG, __VA_ARGS__); \ 225} while (0) 226 227#define ABORT_WITH_FLAG(conn, flag, ...) do { \ 228 SET_ERRMSG(conn, __VA_ARGS__); \ 229 (conn)->fc_flags |= flag; \ 230 LSQ_ERROR("Abort connection: " __VA_ARGS__); \ 231} while (0) 232 233#define ABORT_ERROR(...) ABORT_WITH_FLAG(conn, FC_ERROR, __VA_ARGS__) 234 235#define ABORT_TIMEOUT(...) ABORT_WITH_FLAG(conn, FC_TIMED_OUT, __VA_ARGS__) 236 237static void 238idle_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now); 239 240static void 241ping_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now); 242 243static void 244handshake_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now); 245 246static void 247ack_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now); 248 249static lsquic_stream_t * 250new_stream (struct full_conn *conn, uint32_t stream_id, enum stream_ctor_flags); 251 252static void 253reset_ack_state (struct full_conn *conn); 254 255static int 256write_is_possible (struct full_conn *); 257 258static int 259dispatch_stream_read_events (struct full_conn *, struct lsquic_stream *); 260 261 262#if KEEP_CLOSED_STREAM_HISTORY 263 264static void 265save_stream_history (struct full_conn *conn, const lsquic_stream_t *stream) 266{ 267 sm_hist_idx_t idx; 268 struct stream_history *const shist = 269 &conn->fc_stream_histories[ conn->fc_stream_hist_idx++ & SHIST_MASK ]; 270 271 shist->shist_stream_id = stream->id; 272 shist->shist_stream_flags = stream->stream_flags; 273 274 idx = stream->sm_hist_idx & SM_HIST_IDX_MASK; 275 if ('\0' == stream->sm_hist_buf[ idx ]) 276 memcpy(shist->shist_hist_buf, stream->sm_hist_buf, idx + 1); 277 else 278 { 279 memcpy(shist->shist_hist_buf, 280 stream->sm_hist_buf + idx, sizeof(stream->sm_hist_buf) - idx); 281 memcpy(shist->shist_hist_buf + sizeof(shist->shist_hist_buf) - idx, 282 stream->sm_hist_buf, idx); 283 } 284} 285 286 287static const struct stream_history * 288find_stream_history (const struct full_conn *conn, uint32_t stream_id) 289{ 290 const struct stream_history *shist; 291 const struct stream_history *const shist_end = 292 conn->fc_stream_histories + (1 << SHIST_BITS); 293 for (shist = conn->fc_stream_histories; shist < shist_end; ++shist) 294 if (shist->shist_stream_id == stream_id) 295 return shist; 296 return NULL; 297} 298 299 300# define SAVE_STREAM_HISTORY(conn, stream) save_stream_history(conn, stream) 301#else 302# define SAVE_STREAM_HISTORY(conn, stream) 303#endif 304 305#if KEEP_PACKET_HISTORY 306static void 307recent_packet_hist_new (struct full_conn *conn, unsigned out, 308 lsquic_time_t time) 309{ 310 unsigned idx; 311 idx = conn->fc_recent_packets[out].idx++ % KEEP_PACKET_HISTORY; 312 conn->fc_recent_packets[out].els[idx].time = time; 313} 314 315 316static void 317recent_packet_hist_frames (struct full_conn *conn, unsigned out, 318 enum quic_ft_bit frame_types) 319{ 320 unsigned idx; 321 idx = (conn->fc_recent_packets[out].idx - 1) % KEEP_PACKET_HISTORY; 322 conn->fc_recent_packets[out].els[idx].frame_types |= frame_types; 323} 324 325 326#else 327#define recent_packet_hist_new(conn, out, time) 328#define recent_packet_hist_frames(conn, out, frames) 329#endif 330 331static unsigned 332highest_bit_set (unsigned sz) 333{ 334#if __GNUC__ 335 unsigned clz = __builtin_clz(sz); 336 return 31 - clz; 337#else 338 unsigned n, y; 339 n = 32; 340 y = sz >> 16; if (y) { n -= 16; sz = y; } 341 y = sz >> 8; if (y) { n -= 8; sz = y; } 342 y = sz >> 4; if (y) { n -= 4; sz = y; } 343 y = sz >> 2; if (y) { n -= 2; sz = y; } 344 y = sz >> 1; if (y) return 31 - n + 2; 345 return 31 - n + sz; 346#endif 347} 348 349 350static size_t 351calc_mem_used (const struct full_conn *conn) 352{ 353 const lsquic_stream_t *stream; 354 const struct lsquic_hash_elem *el; 355 size_t size; 356 357 size = sizeof(*conn); 358 size -= sizeof(conn->fc_send_ctl); 359 size += lsquic_send_ctl_mem_used(&conn->fc_send_ctl); 360 size += lsquic_hash_mem_used(conn->fc_pub.all_streams); 361 size += lsquic_malo_mem_used(conn->fc_pub.packet_out_malo); 362 if (conn->fc_pub.hs) 363 size += lsquic_headers_stream_mem_used(conn->fc_pub.hs); 364 365 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 366 el = lsquic_hash_next(conn->fc_pub.all_streams)) 367 { 368 stream = lsquic_hashelem_getdata(el); 369 size += lsquic_stream_mem_used(stream); 370 } 371 size += conn->fc_conn.cn_esf->esf_mem_used(conn->fc_conn.cn_enc_session); 372 373 return size; 374} 375 376 377static void 378set_versions (struct full_conn *conn, unsigned versions) 379{ 380 conn->fc_ver_neg.vn_supp = versions; 381 conn->fc_ver_neg.vn_ver = highest_bit_set(versions); 382 conn->fc_ver_neg.vn_buf = lsquic_ver2tag(conn->fc_ver_neg.vn_ver); 383 conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver; 384 LSQ_DEBUG("negotiating version %s", 385 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 386} 387 388 389static void 390init_ver_neg (struct full_conn *conn, unsigned versions) 391{ 392 set_versions(conn, versions); 393 conn->fc_ver_neg.vn_tag = &conn->fc_ver_neg.vn_buf; 394 conn->fc_ver_neg.vn_state = VN_START; 395} 396 397 398/* If peer supplies odd values, we abort the connection immediately rather 399 * that wait for it to finish "naturally" due to inability to send things. 400 */ 401static void 402conn_on_peer_config (struct full_conn *conn, unsigned peer_cfcw, 403 unsigned peer_sfcw, unsigned max_streams_out) 404{ 405 lsquic_stream_t *stream; 406 struct lsquic_hash_elem *el; 407 408 LSQ_INFO("Applying peer config: cfcw: %u; sfcw: %u; # streams: %u", 409 peer_cfcw, peer_sfcw, max_streams_out); 410 411 if (peer_cfcw < conn->fc_pub.conn_cap.cc_sent) 412 { 413 ABORT_ERROR("peer specified CFCW=%u bytes, which is smaller than " 414 "the amount of data already sent on this connection (%"PRIu64 415 " bytes)", peer_cfcw, conn->fc_pub.conn_cap.cc_sent); 416 return; 417 } 418 419 conn->fc_cfg.max_streams_out = max_streams_out; 420 conn->fc_pub.conn_cap.cc_max = peer_cfcw; 421 422 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 423 el = lsquic_hash_next(conn->fc_pub.all_streams)) 424 { 425 stream = lsquic_hashelem_getdata(el); 426 if (0 != lsquic_stream_set_max_send_off(stream, peer_sfcw)) 427 { 428 ABORT_ERROR("cannot set peer-supplied SFCW=%u on stream %u", 429 peer_sfcw, stream->id); 430 return; 431 } 432 } 433 434 conn->fc_cfg.max_stream_send = peer_sfcw; 435} 436 437 438static int 439send_smhl (const struct full_conn *conn) 440{ 441 uint32_t smhl; 442 return conn->fc_conn.cn_enc_session 443 && (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) 444 && 0 == conn->fc_conn.cn_esf->esf_get_peer_setting( 445 conn->fc_conn.cn_enc_session, QTAG_SMHL, &smhl) 446 && 1 == smhl; 447} 448 449 450/* Once handshake has been completed, send settings to peer if appropriate. 451 */ 452static void 453maybe_send_settings (struct full_conn *conn) 454{ 455 struct lsquic_http2_setting settings[2]; 456 unsigned n_settings = 0; 457 458 if (conn->fc_settings->es_max_header_list_size && send_smhl(conn)) 459 { 460 settings[n_settings].id = SETTINGS_MAX_HEADER_LIST_SIZE; 461 settings[n_settings].value = conn->fc_settings->es_max_header_list_size; 462 LSQ_DEBUG("sending settings SETTINGS_MAX_HEADER_LIST_SIZE=%u", 463 settings[n_settings].value); 464 ++n_settings; 465 } 466 if (!(conn->fc_flags & FC_SERVER) && !conn->fc_settings->es_support_push) 467 { 468 settings[n_settings].id = SETTINGS_ENABLE_PUSH; 469 settings[n_settings].value = 0; 470 LSQ_DEBUG("sending settings SETTINGS_ENABLE_PUSH=%u", 471 settings[n_settings].value); 472 ++n_settings; 473 } 474 475 if (n_settings) 476 { 477 if (0 != lsquic_headers_stream_send_settings(conn->fc_pub.hs, 478 settings, n_settings)) 479 ABORT_ERROR("could not send settings"); 480 } 481 else 482 LSQ_DEBUG("not sending any settings"); 483} 484 485 486static int 487apply_peer_settings (struct full_conn *conn) 488{ 489 uint32_t cfcw, sfcw, mids; 490 unsigned n; 491 const struct { 492 uint32_t tag; 493 uint32_t *val; 494 const char *tag_str; 495 } tags[] = { 496 { QTAG_CFCW, &cfcw, "CFCW", }, 497 { QTAG_SFCW, &sfcw, "SFCW", }, 498 { QTAG_MIDS, &mids, "MIDS", }, 499 }; 500 501#ifndef NDEBUG 502 if (getenv("LSQUIC_TEST_ENGINE_DTOR")) 503 return 0; 504#endif 505 506 for (n = 0; n < sizeof(tags) / sizeof(tags[0]); ++n) 507 if (0 != conn->fc_conn.cn_esf->esf_get_peer_setting( 508 conn->fc_conn.cn_enc_session, tags[n].tag, tags[n].val)) 509 { 510 LSQ_INFO("peer did not supply value for %s", tags[n].tag_str); 511 return -1; 512 } 513 514 LSQ_DEBUG("peer settings: CFCW: %u; SFCW: %u; MIDS: %u", 515 cfcw, sfcw, mids); 516 conn_on_peer_config(conn, cfcw, sfcw, mids); 517 if (conn->fc_flags & FC_HTTP) 518 maybe_send_settings(conn); 519 return 0; 520} 521 522 523 524 525 526 527 528void 529full_conn_client_call_on_new (struct lsquic_conn *lconn) 530{ 531 struct full_conn *const conn = (struct full_conn *) lconn; 532 assert(conn->fc_flags & FC_CREATED_OK); 533 conn->fc_conn_ctx = conn->fc_stream_ifs[STREAM_IF_STD].stream_if 534 ->on_new_conn(conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, lconn); 535} 536 537 538static int 539is_our_stream (const struct full_conn *conn, const lsquic_stream_t *stream) 540{ 541 int is_server = !!(conn->fc_flags & FC_SERVER); 542 return (1 & stream->id) ^ is_server; 543} 544 545 546static unsigned 547count_streams (const struct full_conn *conn, int peer) 548{ 549 const lsquic_stream_t *stream; 550 unsigned count; 551 int ours; 552 int is_server; 553 struct lsquic_hash_elem *el; 554 555 peer = !!peer; 556 is_server = !!(conn->fc_flags & FC_SERVER); 557 count = 0; 558 559 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 560 el = lsquic_hash_next(conn->fc_pub.all_streams)) 561 { 562 stream = lsquic_hashelem_getdata(el); 563 ours = (1 & stream->id) ^ is_server; 564 if (ours ^ peer) 565 count += !lsquic_stream_is_closed(stream); 566 } 567 568 return count; 569} 570 571 572static void 573full_conn_ci_destroy (lsquic_conn_t *lconn) 574{ 575 struct full_conn *conn = (struct full_conn *) lconn; 576 struct lsquic_hash_elem *el; 577 struct lsquic_stream *stream; 578 struct stream_id_to_reset *sitr; 579 580 LSQ_DEBUG("destroy connection"); 581 conn->fc_flags |= FC_CLOSING; 582 lsquic_set32_cleanup(&conn->fc_closed_stream_ids[0]); 583 lsquic_set32_cleanup(&conn->fc_closed_stream_ids[1]); 584 while ((el = lsquic_hash_first(conn->fc_pub.all_streams))) 585 { 586 stream = lsquic_hashelem_getdata(el); 587 lsquic_hash_erase(conn->fc_pub.all_streams, el); 588 lsquic_stream_destroy(stream); 589 } 590 lsquic_hash_destroy(conn->fc_pub.all_streams); 591 if (conn->fc_flags & FC_CREATED_OK) 592 conn->fc_stream_ifs[STREAM_IF_STD].stream_if 593 ->on_conn_closed(&conn->fc_conn); 594 if (conn->fc_pub.hs) 595 lsquic_headers_stream_destroy(conn->fc_pub.hs); 596 597 lsquic_send_ctl_cleanup(&conn->fc_send_ctl); 598 lsquic_rechist_cleanup(&conn->fc_rechist); 599 if (conn->fc_conn.cn_enc_session) 600 conn->fc_conn.cn_esf->esf_destroy(conn->fc_conn.cn_enc_session); 601 lsquic_malo_destroy(conn->fc_pub.packet_out_malo); 602#if FULL_CONN_STATS 603 LSQ_NOTICE("# ticks: %lu", conn->fc_stats.n_ticks); 604 LSQ_NOTICE("received %u packets, of which %u were not decryptable, %u were " 605 "dups and %u were errors; sent %u packets, avg stream data per outgoing" 606 " packet is %lu bytes", 607 conn->fc_stats.n_all_packets_in, conn->fc_stats.n_undec_packets, 608 conn->fc_stats.n_dup_packets, conn->fc_stats.n_err_packets, 609 conn->fc_stats.n_packets_out, 610 conn->fc_stats.stream_data_sz / conn->fc_stats.n_packets_out); 611 LSQ_NOTICE("ACKs: in: %u; processed: %u; merged to: new %u, old %u", 612 conn->fc_stats.n_acks_in, conn->fc_stats.n_acks_proc, 613 conn->fc_stats.n_acks_merged[0], conn->fc_stats.n_acks_merged[1]); 614#endif 615 while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset))) 616 { 617 STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next); 618 free(sitr); 619 } 620 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "full connection destroyed"); 621 free(conn->fc_errmsg); 622 free(conn); 623} 624 625 626static void 627conn_mark_stream_closed (struct full_conn *conn, uint32_t stream_id) 628{ /* Because stream IDs are distributed unevenly -- there is a set of odd 629 * stream IDs and a set of even stream IDs -- it is more efficient to 630 * maintain two sets of closed stream IDs. 631 */ 632 int idx = stream_id & 1; 633 stream_id >>= 1; 634 if (0 != lsquic_set32_add(&conn->fc_closed_stream_ids[idx], stream_id)) 635 ABORT_ERROR("could not add element to set: %s", strerror(errno)); 636} 637 638 639static int 640conn_is_stream_closed (struct full_conn *conn, uint32_t stream_id) 641{ 642 int idx = stream_id & 1; 643 stream_id >>= 1; 644 return lsquic_set32_has(&conn->fc_closed_stream_ids[idx], stream_id); 645} 646 647 648static void 649set_ack_timer (struct full_conn *conn, lsquic_time_t now) 650{ 651 lsquic_alarmset_set(&conn->fc_alset, AL_ACK, now + ACK_TIMEOUT); 652 LSQ_DEBUG("ACK alarm set to %"PRIu64, now + ACK_TIMEOUT); 653} 654 655 656static void 657ack_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now) 658{ 659 struct full_conn *conn = ctx; 660 LSQ_DEBUG("ACK timer expired (%"PRIu64" < %"PRIu64"): ACK queued", 661 expiry, now); 662 conn->fc_flags |= FC_ACK_QUEUED; 663} 664 665 666static void 667try_queueing_ack (struct full_conn *conn, int was_missing, lsquic_time_t now) 668{ 669 if (conn->fc_n_slack_akbl >= MAX_RETR_PACKETS_SINCE_LAST_ACK || 670 (conn->fc_conn.cn_version < LSQVER_039 /* Since Q039 do not ack ACKs */ 671 && conn->fc_n_slack_all >= MAX_ANY_PACKETS_SINCE_LAST_ACK) || 672 ((conn->fc_flags & FC_ACK_HAD_MISS) && was_missing) || 673 lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl) > 1) 674 { 675 lsquic_alarmset_unset(&conn->fc_alset, AL_ACK); 676 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 677 conn->fc_flags |= FC_ACK_QUEUED; 678 LSQ_DEBUG("ACK queued: ackable: %u; all: %u; had_miss: %d; " 679 "was_missing: %d; n_stop_waiting: %u", 680 conn->fc_n_slack_akbl, conn->fc_n_slack_all, 681 !!(conn->fc_flags & FC_ACK_HAD_MISS), was_missing, 682 lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl)); 683 } 684 else if (conn->fc_n_slack_akbl > 0) 685 set_ack_timer(conn, now); 686} 687 688 689static void 690reset_ack_state (struct full_conn *conn) 691{ 692 conn->fc_n_slack_all = 0; 693 conn->fc_n_slack_akbl = 0; 694 lsquic_send_ctl_n_stop_waiting_reset(&conn->fc_send_ctl); 695 conn->fc_flags &= ~FC_ACK_QUEUED; 696 lsquic_alarmset_unset(&conn->fc_alset, AL_ACK); 697 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 698 LSQ_DEBUG("ACK state reset"); 699} 700 701 702static lsquic_stream_t * 703new_stream_ext (struct full_conn *conn, uint32_t stream_id, int if_idx, 704 enum stream_ctor_flags stream_ctor_flags) 705{ 706 lsquic_stream_t *stream = lsquic_stream_new_ext(stream_id, &conn->fc_pub, 707 conn->fc_stream_ifs[if_idx].stream_if, 708 conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw, 709 conn->fc_cfg.max_stream_send, stream_ctor_flags); 710 if (stream) 711 lsquic_hash_insert(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id), 712 stream); 713 return stream; 714} 715 716 717static lsquic_stream_t * 718new_stream (struct full_conn *conn, uint32_t stream_id, 719 enum stream_ctor_flags flags) 720{ 721 int idx; 722 switch (stream_id) 723 { 724 case LSQUIC_STREAM_HANDSHAKE: 725 idx = STREAM_IF_HSK; 726 flags |= SCF_DI_AUTOSWITCH; 727 break; 728 case LSQUIC_STREAM_HEADERS: 729 idx = STREAM_IF_HDR; 730 flags |= SCF_DI_AUTOSWITCH; 731 if (!(conn->fc_flags & FC_HTTP) && 732 conn->fc_enpub->enp_settings.es_rw_once) 733 flags |= SCF_DISP_RW_ONCE; 734 break; 735 default: 736 idx = STREAM_IF_STD; 737 flags |= SCF_DI_AUTOSWITCH; 738 if (conn->fc_enpub->enp_settings.es_rw_once) 739 flags |= SCF_DISP_RW_ONCE; 740 break; 741 } 742 return new_stream_ext(conn, stream_id, idx, flags); 743} 744 745 746static uint32_t 747generate_stream_id (struct full_conn *conn) 748{ 749 conn->fc_last_stream_id += 2; 750 return conn->fc_last_stream_id; 751} 752 753 754unsigned 755lsquic_conn_n_pending_streams (const lsquic_conn_t *lconn) 756{ 757 struct full_conn *conn = (struct full_conn *) lconn; 758 return conn->fc_n_delayed_streams; 759} 760 761 762unsigned 763lsquic_conn_cancel_pending_streams (lsquic_conn_t *lconn, unsigned n) 764{ 765 struct full_conn *conn = (struct full_conn *) lconn; 766 if (n > conn->fc_n_delayed_streams) 767 conn->fc_n_delayed_streams = 0; 768 else 769 conn->fc_n_delayed_streams -= n; 770 return conn->fc_n_delayed_streams; 771} 772 773 774static int 775either_side_going_away (const struct full_conn *conn) 776{ 777 return (conn->fc_flags & FC_GOING_AWAY) 778 || (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY); 779} 780 781 782void 783lsquic_conn_make_stream (lsquic_conn_t *lconn) 784{ 785 struct full_conn *conn = (struct full_conn *) lconn; 786 unsigned stream_count = count_streams(conn, 0); 787 if (stream_count < conn->fc_cfg.max_streams_out) 788 { 789 if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW)) 790 ABORT_ERROR("could not create new stream: %s", strerror(errno)); 791 } 792 else if (either_side_going_away(conn)) 793 (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream( 794 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL); 795 else 796 { 797 ++conn->fc_n_delayed_streams; 798 LSQ_DEBUG("delayed stream creation. Backlog size: %u", 799 conn->fc_n_delayed_streams); 800 } 801} 802 803 804static lsquic_stream_t * 805find_stream_by_id (struct full_conn *conn, uint32_t stream_id) 806{ 807 struct lsquic_hash_elem *el; 808 el = lsquic_hash_find(conn->fc_pub.all_streams, &stream_id, sizeof(stream_id)); 809 if (el) 810 return lsquic_hashelem_getdata(el); 811 else 812 return NULL; 813} 814 815 816lsquic_stream_t * 817lsquic_conn_get_stream_by_id (lsquic_conn_t *lconn, uint32_t stream_id) 818{ 819 struct full_conn *conn = (struct full_conn *) lconn; 820 return find_stream_by_id(conn, stream_id); 821} 822 823 824lsquic_engine_t * 825lsquic_conn_get_engine (lsquic_conn_t *lconn) 826{ 827 struct full_conn *conn = (struct full_conn *) lconn; 828 return conn->fc_enpub->enp_engine; 829} 830 831 832static ssize_t 833count_zero_bytes (const unsigned char *p, size_t len) 834{ 835 const unsigned char *const end = p + len; 836 while (p < end && 0 == *p) 837 ++p; 838 return len - (end - p); 839} 840 841 842static unsigned 843process_padding_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 844 const unsigned char *p, size_t len) 845{ 846 if (conn->fc_conn.cn_version >= LSQVER_038) 847 return (unsigned)count_zero_bytes(p, len); 848 if (lsquic_is_zero(p, len)) 849 { 850 EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len); 851 return (unsigned )len; 852 } 853 else 854 return 0; 855} 856 857 858static unsigned 859process_ping_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 860 const unsigned char *p, size_t len) 861{ /* This frame causes ACK frame to be queued, but nothing to do here; 862 * return the length of this frame. 863 */ 864 EV_LOG_PING_FRAME_IN(LSQUIC_LOG_CONN_ID); 865 LSQ_DEBUG("received PING"); 866 return 1; 867} 868 869 870static int 871is_peer_initiated (const struct full_conn *conn, uint32_t stream_id) 872{ 873 unsigned is_server = !!(conn->fc_flags & FC_SERVER); 874 int peer_initiated = (stream_id & 1) == is_server; 875 return peer_initiated; 876} 877 878 879static void 880maybe_schedule_reset_for_stream (struct full_conn *conn, uint32_t stream_id) 881{ 882 struct stream_id_to_reset *sitr; 883 884 if (conn_is_stream_closed(conn, stream_id)) 885 return; 886 887 sitr = malloc(sizeof(*sitr)); 888 if (!sitr) 889 return; 890 891 sitr->sitr_stream_id = stream_id; 892 STAILQ_INSERT_TAIL(&conn->fc_stream_ids_to_reset, sitr, sitr_next); 893 conn_mark_stream_closed(conn, stream_id); 894} 895 896 897static unsigned 898process_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 899 const unsigned char *p, size_t len) 900{ 901 stream_frame_t *stream_frame; 902 lsquic_stream_t *stream; 903 enum enc_level enc_level; 904 int parsed_len; 905 906 stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame); 907 if (!stream_frame) 908 { 909 LSQ_WARN("could not allocate stream frame: %s", strerror(errno)); 910 return 0; 911 } 912 913 parsed_len = conn->fc_conn.cn_pf->pf_parse_stream_frame(p, len, 914 stream_frame); 915 if (parsed_len < 0) { 916 lsquic_malo_put(stream_frame); 917 return 0; 918 } 919 EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame); 920 LSQ_DEBUG("Got stream frame for stream #%u", stream_frame->stream_id); 921 922 enc_level = lsquic_packet_in_enc_level(packet_in); 923 if (stream_frame->stream_id != LSQUIC_STREAM_HANDSHAKE 924 && enc_level != ENC_LEV_FORW 925 && enc_level != ENC_LEV_INIT) 926 { 927 lsquic_malo_put(stream_frame); 928 ABORT_ERROR("received unencrypted data for stream %u", 929 stream_frame->stream_id); 930 return 0; 931 } 932 933 if (conn->fc_flags & FC_CLOSING) 934 { 935 LSQ_DEBUG("Connection closing: ignore frame"); 936 lsquic_malo_put(stream_frame); 937 return parsed_len; 938 } 939 940 stream = find_stream_by_id(conn, stream_frame->stream_id); 941 if (!stream) 942 { 943 if (conn_is_stream_closed(conn, stream_frame->stream_id)) 944 { 945 LSQ_DEBUG("drop frame for closed stream %u", stream_frame->stream_id); 946 lsquic_malo_put(stream_frame); 947 return parsed_len; 948 } 949 if (is_peer_initiated(conn, stream_frame->stream_id)) 950 { 951 unsigned in_count = count_streams(conn, 1); 952 LSQ_DEBUG("number of peer-initiated streams: %u", in_count); 953 if (in_count >= conn->fc_cfg.max_streams_in) 954 { 955 ABORT_ERROR("incoming stream would exceed limit: %u", 956 conn->fc_cfg.max_streams_in); 957 lsquic_malo_put(stream_frame); 958 return 0; 959 } 960 if ((conn->fc_flags & FC_GOING_AWAY) && 961 stream_frame->stream_id > conn->fc_max_peer_stream_id) 962 { 963 LSQ_DEBUG("going away: reset new incoming stream %"PRIu32, 964 stream_frame->stream_id); 965 maybe_schedule_reset_for_stream(conn, stream_frame->stream_id); 966 lsquic_malo_put(stream_frame); 967 return parsed_len; 968 } 969 } 970 else 971 { 972 ABORT_ERROR("frame for never-initiated stream"); 973 lsquic_malo_put(stream_frame); 974 return 0; 975 } 976 stream = new_stream(conn, stream_frame->stream_id, SCF_CALL_ON_NEW); 977 if (!stream) 978 { 979 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 980 lsquic_malo_put(stream_frame); 981 return 0; 982 } 983 if (stream_frame->stream_id > conn->fc_max_peer_stream_id) 984 conn->fc_max_peer_stream_id = stream_frame->stream_id; 985 } 986 987 stream_frame->packet_in = lsquic_packet_in_get(packet_in); 988 if (0 != lsquic_stream_frame_in(stream, stream_frame)) 989 { 990 ABORT_ERROR("cannot insert stream frame"); 991 return 0; 992 } 993 994 if (stream->id == LSQUIC_STREAM_HANDSHAKE 995 && !(conn->fc_flags & FC_SERVER) 996 && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)) 997 { /* To enable decryption, process handshake stream as soon as its 998 * data frames are received. 999 * 1000 * TODO: this does not work when packets are reordered. A more 1001 * flexible solution would defer packet decryption if handshake 1002 * has not been completed yet. Nevertheless, this is good enough 1003 * for now. 1004 */ 1005 dispatch_stream_read_events(conn, stream); 1006 } 1007 1008 return parsed_len; 1009} 1010 1011 1012static unsigned 1013process_invalid_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1014 const unsigned char *p, size_t len) 1015{ 1016 ABORT_ERROR("invalid frame"); 1017 return 0; 1018} 1019 1020 1021/* Reset locally-initiated streams whose IDs is larger than the stream ID 1022 * specified in received GOAWAY frame. 1023 */ 1024static void 1025reset_local_streams_over_goaway (struct full_conn *conn) 1026{ 1027 const unsigned is_server = !!(conn->fc_flags & FC_SERVER); 1028 lsquic_stream_t *stream; 1029 struct lsquic_hash_elem *el; 1030 1031 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 1032 el = lsquic_hash_next(conn->fc_pub.all_streams)) 1033 { 1034 stream = lsquic_hashelem_getdata(el); 1035 if (stream->id > conn->fc_goaway_stream_id && 1036 ((stream->id & 1) ^ is_server /* Locally initiated? */)) 1037 { 1038 lsquic_stream_received_goaway(stream); 1039 } 1040 } 1041} 1042 1043 1044static unsigned 1045process_goaway_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1046 const unsigned char *p, size_t len) 1047{ 1048 uint32_t error_code, stream_id; 1049 uint16_t reason_length; 1050 const char *reason; 1051 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_goaway_frame(p, len, 1052 &error_code, &stream_id, &reason_length, &reason); 1053 if (parsed_len < 0) 1054 return 0; 1055 EV_LOG_GOAWAY_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, stream_id, 1056 reason_length, reason); 1057 LSQ_DEBUG("received GOAWAY frame, last good stream ID: %u, error code: 0x%X," 1058 " reason: `%.*s'", stream_id, error_code, reason_length, reason); 1059 if (0 == (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY)) 1060 { 1061 conn->fc_conn.cn_flags |= LSCONN_PEER_GOING_AWAY; 1062 conn->fc_goaway_stream_id = stream_id; 1063 if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received) 1064 { 1065 LSQ_DEBUG("calling on_goaway_received"); 1066 conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received( 1067 &conn->fc_conn); 1068 } 1069 else 1070 LSQ_DEBUG("on_goaway_received not registered"); 1071 reset_local_streams_over_goaway(conn); 1072 } 1073 else 1074 LSQ_DEBUG("ignore duplicate GOAWAY frame"); 1075 return parsed_len; 1076} 1077 1078 1079static void 1080log_invalid_ack_frame (struct full_conn *conn, const unsigned char *p, 1081 int parsed_len, const struct ack_info *acki) 1082{ 1083 char *buf; 1084 size_t sz; 1085 1086 buf = malloc(0x1000); 1087 if (buf) 1088 { 1089 lsquic_senhist_tostr(&conn->fc_send_ctl.sc_senhist, buf, 0x1000); 1090 LSQ_WARN("send history: %s", buf); 1091 hexdump(p, parsed_len, buf, 0x1000); 1092 LSQ_WARN("raw ACK frame:\n%s", buf); 1093 free(buf); 1094 } 1095 else 1096 LSQ_WARN("malloc failed"); 1097 1098 buf = acki2str(acki, &sz); 1099 if (buf) 1100 { 1101 LSQ_WARN("parsed ACK frame: %.*s", (int) sz, buf); 1102 free(buf); 1103 } 1104 else 1105 LSQ_WARN("malloc failed"); 1106} 1107 1108 1109static int 1110process_ack (struct full_conn *conn, struct ack_info *acki, 1111 lsquic_time_t received) 1112{ 1113#if FULL_CONN_STATS 1114 ++conn->fc_stats.n_acks_proc; 1115#endif 1116 LSQ_DEBUG("Processing ACK"); 1117 if (0 == lsquic_send_ctl_got_ack(&conn->fc_send_ctl, acki, received)) 1118 { 1119 if (lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl)) 1120 lsquic_rechist_stop_wait(&conn->fc_rechist, 1121 lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl) + 1); 1122 return 0; 1123 } 1124 else 1125 { 1126 ABORT_ERROR("Received invalid ACK"); 1127 return -1; 1128 } 1129} 1130 1131 1132static int 1133process_saved_ack (struct full_conn *conn, int restore_parsed_ack) 1134{ 1135 struct ack_info *const acki = conn->fc_pub.mm->acki; 1136 struct lsquic_packno_range range = { 0 }; 1137 unsigned n_ranges = 0, n_timestamps = 0; 1138 lsquic_time_t lack_delta = 0; 1139 int retval; 1140 1141 if (restore_parsed_ack) 1142 { 1143 n_ranges = acki->n_ranges; 1144 n_timestamps = acki->n_timestamps; 1145 lack_delta = acki->lack_delta; 1146 range = acki->ranges[0]; 1147 } 1148 1149 acki->n_ranges = 1; 1150 acki->n_timestamps = conn->fc_saved_ack_info.sai_n_timestamps; 1151 acki->lack_delta = conn->fc_saved_ack_info.sai_lack_delta; 1152 acki->ranges[0] = conn->fc_saved_ack_info.sai_range; 1153 1154 retval = process_ack(conn, acki, conn->fc_saved_ack_received); 1155 1156 if (restore_parsed_ack) 1157 { 1158 acki->n_ranges = n_ranges; 1159 acki->n_timestamps = n_timestamps; 1160 acki->lack_delta = lack_delta; 1161 acki->ranges[0] = range; 1162 } 1163 1164 return retval; 1165} 1166 1167 1168static int 1169new_ack_is_superset (const struct short_ack_info *old, const struct ack_info *new) 1170{ 1171 const struct lsquic_packno_range *new_range; 1172 1173 new_range = &new->ranges[ new->n_ranges - 1 ]; 1174 return new_range->low <= old->sai_range.low 1175 && new_range->high >= old->sai_range.high; 1176} 1177 1178 1179static int 1180merge_saved_to_new (const struct short_ack_info *old, struct ack_info *new) 1181{ 1182 struct lsquic_packno_range *smallest_range; 1183 1184 assert(new->n_ranges > 1); 1185 smallest_range = &new->ranges[ new->n_ranges - 1 ]; 1186 if (old->sai_range.high <= smallest_range->high 1187 && old->sai_range.high >= smallest_range->low 1188 && old->sai_range.low < smallest_range->low) 1189 { 1190 smallest_range->low = old->sai_range.low; 1191 return 1; 1192 } 1193 else 1194 return 0; 1195} 1196 1197 1198static int 1199merge_new_to_saved (struct short_ack_info *old, const struct ack_info *new) 1200{ 1201 const struct lsquic_packno_range *new_range; 1202 1203 assert(new->n_ranges == 1); 1204 new_range = &new->ranges[0]; 1205 /* Only merge if new is higher, for simplicity. This is also the 1206 * expected case. 1207 */ 1208 if (new_range->high > old->sai_range.high 1209 && new_range->low > old->sai_range.low) 1210 { 1211 old->sai_range.high = new_range->high; 1212 return 1; 1213 } 1214 else 1215 return 0; 1216} 1217 1218 1219static unsigned 1220process_ack_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1221 const unsigned char *p, size_t len) 1222{ 1223 struct ack_info *const new_acki = conn->fc_pub.mm->acki; 1224 int parsed_len; 1225 1226#if FULL_CONN_STATS 1227 ++conn->fc_stats.n_acks_in; 1228#endif 1229 1230 parsed_len = conn->fc_conn.cn_pf->pf_parse_ack_frame(p, len, new_acki); 1231 if (parsed_len < 0) 1232 goto err; 1233 1234 if (packet_in->pi_packno <= conn->fc_max_ack_packno) 1235 { 1236 LSQ_DEBUG("Ignore old ack (max %"PRIu64")", conn->fc_max_ack_packno); 1237 return parsed_len; 1238 } 1239 1240 EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, new_acki); 1241 conn->fc_max_ack_packno = packet_in->pi_packno; 1242 1243 if (conn->fc_flags & FC_HAVE_SAVED_ACK) 1244 { 1245 LSQ_DEBUG("old ack [%"PRIu64"-%"PRIu64"]", 1246 conn->fc_saved_ack_info.sai_range.high, 1247 conn->fc_saved_ack_info.sai_range.low); 1248 const int is_superset = new_ack_is_superset(&conn->fc_saved_ack_info, 1249 new_acki); 1250 const int is_1range = new_acki->n_ranges == 1; 1251 switch ( 1252 (is_superset << 1) 1253 | (is_1range << 0)) 1254 /* | | 1255 | | 1256 V V */ { 1257 case (0 << 1) | (0 << 0): 1258 if (merge_saved_to_new(&conn->fc_saved_ack_info, new_acki)) 1259 { 1260#if FULL_CONN_STATS 1261 ++conn->fc_stats.n_acks_merged[0] 1262#endif 1263 ; 1264 } 1265 else 1266 process_saved_ack(conn, 1); 1267 conn->fc_flags &= ~FC_HAVE_SAVED_ACK; 1268 if (0 != process_ack(conn, new_acki, packet_in->pi_received)) 1269 goto err; 1270 break; 1271 case (0 << 1) | (1 << 0): 1272 if (merge_new_to_saved(&conn->fc_saved_ack_info, new_acki)) 1273 { 1274#if FULL_CONN_STATS 1275 ++conn->fc_stats.n_acks_merged[1] 1276#endif 1277 ; 1278 } 1279 else 1280 { 1281 process_saved_ack(conn, 1); 1282 conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps; 1283 conn->fc_saved_ack_info.sai_range = new_acki->ranges[0]; 1284 } 1285 conn->fc_saved_ack_info.sai_lack_delta = new_acki->lack_delta; 1286 conn->fc_saved_ack_received = packet_in->pi_received; 1287 break; 1288 case (1 << 1) | (0 << 0): 1289 conn->fc_flags &= ~FC_HAVE_SAVED_ACK; 1290 if (0 != process_ack(conn, new_acki, packet_in->pi_received)) 1291 goto err; 1292 break; 1293 case (1 << 1) | (1 << 0): 1294 conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps; 1295 conn->fc_saved_ack_info.sai_lack_delta = new_acki->lack_delta; 1296 conn->fc_saved_ack_info.sai_range = new_acki->ranges[0]; 1297 conn->fc_saved_ack_received = packet_in->pi_received; 1298 break; 1299 } 1300 } 1301 else if (new_acki->n_ranges == 1) 1302 { 1303 conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps; 1304 conn->fc_saved_ack_info.sai_lack_delta = new_acki->lack_delta; 1305 conn->fc_saved_ack_info.sai_range = new_acki->ranges[0]; 1306 conn->fc_saved_ack_received = packet_in->pi_received; 1307 conn->fc_flags |= FC_HAVE_SAVED_ACK; 1308 } 1309 else if (0 != process_ack(conn, new_acki, packet_in->pi_received)) 1310 goto err; 1311 1312 return parsed_len; 1313 1314 err: 1315 log_invalid_ack_frame(conn, p, parsed_len, new_acki); 1316 return 0; 1317} 1318 1319 1320static unsigned 1321process_stop_waiting_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1322 const unsigned char *p, size_t len) 1323{ 1324 lsquic_packno_t least, cutoff; 1325 enum lsquic_packno_bits bits; 1326 int parsed_len; 1327 1328 bits = lsquic_packet_in_packno_bits(packet_in); 1329 1330 if (conn->fc_flags & FC_NSTP) 1331 { 1332 LSQ_DEBUG("NSTP on: ignore STOP_WAITING frame"); 1333 parsed_len = conn->fc_conn.cn_pf->pf_skip_stop_waiting_frame(len, bits); 1334 if (parsed_len > 0) 1335 return (unsigned) parsed_len; 1336 else 1337 return 0; 1338 } 1339 1340 parsed_len = conn->fc_conn.cn_pf->pf_parse_stop_waiting_frame(p, len, 1341 packet_in->pi_packno, bits, &least); 1342 if (parsed_len < 0) 1343 return 0; 1344 1345 if (packet_in->pi_packno <= conn->fc_max_swf_packno) 1346 { 1347 LSQ_DEBUG("ignore old STOP_WAITING frame"); 1348 return parsed_len; 1349 } 1350 1351 LSQ_DEBUG("Got STOP_WAITING frame, least unacked: %"PRIu64, least); 1352 EV_LOG_STOP_WAITING_FRAME_IN(LSQUIC_LOG_CONN_ID, least); 1353 1354 if (least > packet_in->pi_packno) 1355 { 1356 ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is larger " 1357 "than the packet number%"PRIu64, least, packet_in->pi_packno); 1358 return 0; 1359 } 1360 1361 cutoff = lsquic_rechist_cutoff(&conn->fc_rechist); 1362 if (cutoff && least < cutoff) 1363 { 1364 ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is smaller " 1365 "than the cutoff %"PRIu64, least, cutoff); 1366 return 0; 1367 } 1368 1369 conn->fc_max_swf_packno = packet_in->pi_packno; 1370 lsquic_rechist_stop_wait(&conn->fc_rechist, least); 1371 return parsed_len; 1372} 1373 1374 1375static unsigned 1376process_blocked_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1377 const unsigned char *p, size_t len) 1378{ 1379 uint32_t stream_id; 1380 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_blocked_frame(p, len, 1381 &stream_id); 1382 if (parsed_len < 0) 1383 return 0; 1384 EV_LOG_BLOCKED_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id); 1385 LSQ_DEBUG("Peer reports stream %u as blocked", stream_id); 1386 return parsed_len; 1387} 1388 1389 1390static unsigned 1391process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1392 const unsigned char *p, size_t len) 1393{ 1394 lsquic_stream_t *stream; 1395 struct lsquic_hash_elem *el; 1396 uint32_t error_code; 1397 uint16_t reason_len; 1398 uint8_t reason_off; 1399 int parsed_len; 1400 1401 parsed_len = conn->fc_conn.cn_pf->pf_parse_connect_close_frame(p, len, 1402 &error_code, &reason_len, &reason_off); 1403 if (parsed_len < 0) 1404 return 0; 1405 EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, 1406 (int) reason_len, (const char *) p + reason_off); 1407 LSQ_INFO("Received CONNECTION_CLOSE frame (code: %u; reason: %.*s)", 1408 error_code, (int) reason_len, (const char *) p + reason_off); 1409 conn->fc_flags |= FC_RECV_CLOSE; 1410 if (!(conn->fc_flags & FC_CLOSING)) 1411 { 1412 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 1413 el = lsquic_hash_next(conn->fc_pub.all_streams)) 1414 { 1415 stream = lsquic_hashelem_getdata(el); 1416 lsquic_stream_shutdown_internal(stream); 1417 } 1418 conn->fc_flags |= FC_CLOSING; 1419 } 1420 return parsed_len; 1421} 1422 1423 1424static unsigned 1425process_rst_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1426 const unsigned char *p, size_t len) 1427{ 1428 uint32_t stream_id, error_code; 1429 uint64_t offset; 1430 lsquic_stream_t *stream; 1431 const int parsed_len = conn->fc_conn.cn_pf->pf_parse_rst_frame(p, len, 1432 &stream_id, &offset, &error_code); 1433 if (parsed_len < 0) 1434 return 0; 1435 1436 EV_LOG_RST_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset, 1437 error_code); 1438 LSQ_DEBUG("Got RST_STREAM; stream: %u; offset: 0x%"PRIX64, stream_id, 1439 offset); 1440 if (0 == stream_id) 1441 { /* Follow reference implementation and ignore this apparently 1442 * invalid frame. 1443 */ 1444 return parsed_len; 1445 } 1446 1447 if (LSQUIC_STREAM_HANDSHAKE == stream_id || 1448 ((conn->fc_flags & FC_HTTP) && LSQUIC_STREAM_HEADERS == stream_id)) 1449 { 1450 ABORT_ERROR("received reset on static stream %u", stream_id); 1451 return 0; 1452 } 1453 1454 stream = find_stream_by_id(conn, stream_id); 1455 if (!stream) 1456 { 1457 if (conn_is_stream_closed(conn, stream_id)) 1458 { 1459 LSQ_DEBUG("got reset frame for closed stream %u", stream_id); 1460 return parsed_len; 1461 } 1462 if (!is_peer_initiated(conn, stream_id)) 1463 { 1464 ABORT_ERROR("received reset for never-initiated stream %u", 1465 stream_id); 1466 return 0; 1467 } 1468 stream = new_stream(conn, stream_id, SCF_CALL_ON_NEW); 1469 if (!stream) 1470 { 1471 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 1472 return 0; 1473 } 1474 if (stream_id > conn->fc_max_peer_stream_id) 1475 conn->fc_max_peer_stream_id = stream_id; 1476 } 1477 1478 if (0 != lsquic_stream_rst_in(stream, offset, error_code)) 1479 { 1480 ABORT_ERROR("received invalid RST_STREAM"); 1481 return 0; 1482 } 1483 return parsed_len; 1484} 1485 1486 1487static unsigned 1488process_window_update_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1489 const unsigned char *p, size_t len) 1490{ 1491 uint32_t stream_id; 1492 uint64_t offset; 1493 const int parsed_len = 1494 conn->fc_conn.cn_pf->pf_parse_window_update_frame(p, len, 1495 &stream_id, &offset); 1496 if (parsed_len < 0) 1497 return 0; 1498 EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset); 1499 if (stream_id) 1500 { 1501 lsquic_stream_t *stream = find_stream_by_id(conn, stream_id); 1502 if (stream) 1503 { 1504 LSQ_DEBUG("Got window update frame, stream: %u; offset: 0x%"PRIX64, 1505 stream_id, offset); 1506 lsquic_stream_window_update(stream, offset); 1507 } 1508 else /* Perhaps a result of lost packets? */ 1509 LSQ_DEBUG("Got window update frame for non-existing stream %u " 1510 "(offset: 0x%"PRIX64")", stream_id, offset); 1511 } 1512 else if (offset > conn->fc_pub.conn_cap.cc_max) 1513 { 1514 conn->fc_pub.conn_cap.cc_max = offset; 1515 assert(conn->fc_pub.conn_cap.cc_max >= conn->fc_pub.conn_cap.cc_sent); 1516 LSQ_DEBUG("Connection WUF, new offset 0x%"PRIX64, offset); 1517 } 1518 else 1519 LSQ_DEBUG("Throw ouw duplicate connection WUF"); 1520 return parsed_len; 1521} 1522 1523 1524typedef unsigned (*process_frame_f)( 1525 struct full_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t); 1526 1527static process_frame_f const process_frames[N_QUIC_FRAMES] = 1528{ 1529 [QUIC_FRAME_ACK] = process_ack_frame, 1530 [QUIC_FRAME_BLOCKED] = process_blocked_frame, 1531 [QUIC_FRAME_CONNECTION_CLOSE] = process_connection_close_frame, 1532 [QUIC_FRAME_GOAWAY] = process_goaway_frame, 1533 [QUIC_FRAME_INVALID] = process_invalid_frame, 1534 [QUIC_FRAME_PADDING] = process_padding_frame, 1535 [QUIC_FRAME_PING] = process_ping_frame, 1536 [QUIC_FRAME_RST_STREAM] = process_rst_stream_frame, 1537 [QUIC_FRAME_STOP_WAITING] = process_stop_waiting_frame, 1538 [QUIC_FRAME_STREAM] = process_stream_frame, 1539 [QUIC_FRAME_WINDOW_UPDATE] = process_window_update_frame, 1540}; 1541 1542static unsigned 1543process_packet_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in, 1544 const unsigned char *p, size_t len) 1545{ 1546 enum QUIC_FRAME_TYPE type = conn->fc_conn.cn_pf->pf_parse_frame_type(p[0]); 1547 packet_in->pi_frame_types |= 1 << type; 1548 recent_packet_hist_frames(conn, 0, 1 << type); 1549 return process_frames[type](conn, packet_in, p, len); 1550} 1551 1552 1553static void 1554process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1555{ 1556 int s; 1557 struct ver_iter vi; 1558 lsquic_ver_tag_t ver_tag; 1559 enum lsquic_version version; 1560 unsigned versions = 0; 1561 1562 LSQ_DEBUG("Processing version-negotiation packet"); 1563 1564 if (conn->fc_ver_neg.vn_state != VN_START) 1565 { 1566 LSQ_DEBUG("ignore a likely duplicate version negotiation packet"); 1567 return; 1568 } 1569 1570 for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s; 1571 s = packet_in_ver_next(&vi, &ver_tag)) 1572 { 1573 version = lsquic_tag2ver(ver_tag); 1574 if (version < N_LSQVER) 1575 { 1576 versions |= 1 << version; 1577 LSQ_DEBUG("server supports version %s", lsquic_ver2str[version]); 1578 } 1579 } 1580 1581 if (versions & (1 << conn->fc_ver_neg.vn_ver)) 1582 { 1583 ABORT_ERROR("server replied with version we support: %s", 1584 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 1585 return; 1586 } 1587 1588 versions &= conn->fc_ver_neg.vn_supp; 1589 if (0 == versions) 1590 { 1591 ABORT_ERROR("client does not support any of the server-specified " 1592 "versions"); 1593 return; 1594 } 1595 1596 set_versions(conn, versions); 1597 conn->fc_ver_neg.vn_state = VN_IN_PROGRESS; 1598 lsquic_send_ctl_expire_all(&conn->fc_send_ctl); 1599} 1600 1601 1602static void 1603reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1604{ 1605 lsquic_packno_t cur_packno, max_packno; 1606 enum lsquic_packno_bits bits; 1607 1608 cur_packno = packet_in->pi_packno; 1609 max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist); 1610 bits = lsquic_packet_in_packno_bits(packet_in); 1611 packet_in->pi_packno = restore_packno(cur_packno, bits, max_packno); 1612 LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") " 1613 "to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno); 1614} 1615 1616 1617static int 1618conn_decrypt_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1619{ 1620 return lsquic_conn_decrypt_packet(&conn->fc_conn, conn->fc_enpub, 1621 packet_in); 1622} 1623 1624 1625static void 1626parse_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1627{ 1628 const unsigned char *p, *pend; 1629 unsigned len; 1630 1631 p = packet_in->pi_data + packet_in->pi_header_sz; 1632 pend = packet_in->pi_data + packet_in->pi_data_sz; 1633 1634 while (p < pend) 1635 { 1636 len = process_packet_frame(conn, packet_in, p, pend - p); 1637 if (len > 0) 1638 p += len; 1639 else 1640 { 1641 ABORT_ERROR("Error parsing frame"); 1642 break; 1643 } 1644 } 1645} 1646 1647 1648static int 1649process_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1650{ 1651 enum received_st st; 1652 enum quic_ft_bit frame_types; 1653 int was_missing; 1654 1655 reconstruct_packet_number(conn, packet_in); 1656 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 1657 1658#if FULL_CONN_STATS 1659 ++conn->fc_stats.n_all_packets_in; 1660#endif 1661 1662 /* The packet is decrypted before receive history is updated. This is 1663 * done to make sure that a bad packet won't occupy a slot in receive 1664 * history and subsequent good packet won't be marked as a duplicate. 1665 */ 1666 if (0 == (packet_in->pi_flags & PI_DECRYPTED) && 1667 0 != conn_decrypt_packet(conn, packet_in)) 1668 { 1669 LSQ_INFO("could not decrypt packet"); 1670#if FULL_CONN_STATS 1671 ++conn->fc_stats.n_undec_packets; 1672#endif 1673 return 0; 1674 } 1675 1676 st = lsquic_rechist_received(&conn->fc_rechist, packet_in->pi_packno, 1677 packet_in->pi_received); 1678 switch (st) { 1679 case REC_ST_OK: 1680 parse_regular_packet(conn, packet_in); 1681 if (0 == (conn->fc_flags & FC_ACK_QUEUED)) 1682 { 1683 frame_types = packet_in->pi_frame_types; 1684 was_missing = packet_in->pi_packno != 1685 lsquic_rechist_largest_packno(&conn->fc_rechist); 1686 conn->fc_n_slack_all += 1; 1687 conn->fc_n_slack_akbl += !!(frame_types & QFRAME_ACKABLE_MASK); 1688 try_queueing_ack(conn, was_missing, packet_in->pi_received); 1689 } 1690 return 0; 1691 case REC_ST_DUP: 1692#if FULL_CONN_STATS 1693 ++conn->fc_stats.n_dup_packets; 1694#endif 1695 LSQ_INFO("packet %"PRIu64" is a duplicate", packet_in->pi_packno); 1696 return 0; 1697 default: 1698 assert(0); 1699 /* Fall through */ 1700 case REC_ST_ERR: 1701#if FULL_CONN_STATS 1702 ++conn->fc_stats.n_err_packets; 1703#endif 1704 LSQ_INFO("error processing packet %"PRIu64, packet_in->pi_packno); 1705 return -1; 1706 } 1707} 1708 1709 1710static int 1711process_incoming_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in) 1712{ 1713 recent_packet_hist_new(conn, 0, packet_in->pi_received); 1714 LSQ_DEBUG("Processing packet %"PRIu64, packet_in->pi_packno); 1715 /* See flowchart in Section 4.1 of [draft-ietf-quic-transport-00]. We test 1716 * for the common case first. 1717 */ 1718 const unsigned flags = lsquic_packet_in_public_flags(packet_in); 1719 if (0 == (flags & (PACKET_PUBLIC_FLAGS_RST|PACKET_PUBLIC_FLAGS_VERSION))) 1720 { 1721 if (conn->fc_ver_neg.vn_tag) 1722 { 1723 assert(conn->fc_ver_neg.vn_state != VN_END); 1724 conn->fc_ver_neg.vn_state = VN_END; 1725 conn->fc_ver_neg.vn_tag = NULL; 1726 conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver; 1727 conn->fc_conn.cn_flags |= LSCONN_VER_SET; 1728 if (conn->fc_conn.cn_version >= LSQVER_037) 1729 { 1730 assert(!(conn->fc_flags & FC_NSTP)); /* This bit off at start */ 1731 if (conn->fc_settings->es_support_nstp) 1732 { 1733 conn->fc_flags |= FC_NSTP; 1734 lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl); 1735 } 1736 } 1737 LSQ_DEBUG("end of version negotiation: agreed upon %s", 1738 lsquic_ver2str[conn->fc_ver_neg.vn_ver]); 1739 } 1740 return process_regular_packet(conn, packet_in); 1741 } 1742 else if (flags & PACKET_PUBLIC_FLAGS_RST) 1743 { 1744 LSQ_INFO("received public reset packet: aborting connection"); 1745 conn->fc_flags |= FC_GOT_PRST; 1746 return -1; 1747 } 1748 else 1749 { 1750 if (conn->fc_flags & FC_SERVER) 1751 return process_regular_packet(conn, packet_in); 1752 else if (conn->fc_ver_neg.vn_tag) 1753 { 1754 process_ver_neg_packet(conn, packet_in); 1755 return 0; 1756 } 1757 else 1758 { 1759 LSQ_DEBUG("unexpected version negotiation packet: ignore it"); 1760 return 0; 1761 } 1762 } 1763} 1764 1765 1766static void 1767idle_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now) 1768{ 1769 struct full_conn *conn = ctx; 1770 LSQ_DEBUG("connection timed out"); 1771 conn->fc_flags |= FC_TIMED_OUT; 1772} 1773 1774 1775static void 1776handshake_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now) 1777{ 1778 struct full_conn *conn = ctx; 1779 LSQ_DEBUG("connection timed out: handshake timed out"); 1780 conn->fc_flags |= FC_TIMED_OUT; 1781} 1782 1783 1784static void 1785ping_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now) 1786{ 1787 struct full_conn *conn = ctx; 1788 LSQ_DEBUG("Ping alarm rang: schedule PING frame to be generated"); 1789 conn->fc_flags |= FC_SEND_PING; 1790} 1791 1792 1793static lsquic_packet_out_t * 1794get_writeable_packet (struct full_conn *conn, unsigned need_at_least) 1795{ 1796 lsquic_packet_out_t *packet_out; 1797 int is_err; 1798 1799 assert(need_at_least <= QUIC_MAX_PAYLOAD_SZ); 1800 packet_out = lsquic_send_ctl_get_writeable_packet(&conn->fc_send_ctl, 1801 need_at_least, &is_err); 1802 if (!packet_out && is_err) 1803 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 1804 return packet_out; 1805} 1806 1807 1808static int 1809generate_wuf_stream (struct full_conn *conn, lsquic_stream_t *stream) 1810{ 1811 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, QUIC_WUF_SZ); 1812 if (!packet_out) 1813 return 0; 1814 const uint64_t recv_off = lsquic_stream_fc_recv_off(stream); 1815 int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame( 1816 packet_out->po_data + packet_out->po_data_sz, 1817 lsquic_packet_out_avail(packet_out), stream->id, recv_off); 1818 if (sz < 0) { 1819 ABORT_ERROR("gen_window_update_frame failed"); 1820 return 0; 1821 } 1822 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1823 packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE; 1824 LSQ_DEBUG("wrote WUF: stream %u; offset 0x%"PRIX64, stream->id, recv_off); 1825 return 1; 1826} 1827 1828 1829static void 1830generate_wuf_conn (struct full_conn *conn) 1831{ 1832 assert(conn->fc_flags & FC_SEND_WUF); 1833 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, QUIC_WUF_SZ); 1834 if (!packet_out) 1835 return; 1836 const uint64_t recv_off = lsquic_cfcw_get_fc_recv_off(&conn->fc_pub.cfcw); 1837 int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame( 1838 packet_out->po_data + packet_out->po_data_sz, 1839 lsquic_packet_out_avail(packet_out), 0, recv_off); 1840 if (sz < 0) { 1841 ABORT_ERROR("gen_window_update_frame failed"); 1842 return; 1843 } 1844 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1845 packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE; 1846 conn->fc_flags &= ~FC_SEND_WUF; 1847 LSQ_DEBUG("wrote connection WUF: offset 0x%"PRIX64, recv_off); 1848} 1849 1850 1851static void 1852generate_goaway_frame (struct full_conn *conn) 1853{ 1854 int reason_len = 0; 1855 lsquic_packet_out_t *packet_out = 1856 get_writeable_packet(conn, QUIC_GOAWAY_FRAME_SZ + reason_len); 1857 if (!packet_out) 1858 return; 1859 int sz = conn->fc_conn.cn_pf->pf_gen_goaway_frame( 1860 packet_out->po_data + packet_out->po_data_sz, 1861 lsquic_packet_out_avail(packet_out), 0, conn->fc_max_peer_stream_id, 1862 NULL, reason_len); 1863 if (sz < 0) { 1864 ABORT_ERROR("gen_goaway_frame failed"); 1865 return; 1866 } 1867 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1868 packet_out->po_frame_types |= 1 << QUIC_FRAME_GOAWAY; 1869 conn->fc_flags &= ~FC_SEND_GOAWAY; 1870 conn->fc_flags |= FC_GOAWAY_SENT; 1871 LSQ_DEBUG("wrote GOAWAY frame: stream id: %u", conn->fc_max_peer_stream_id); 1872} 1873 1874 1875static void 1876generate_connection_close_packet (struct full_conn *conn) 1877{ 1878 lsquic_packet_out_t *packet_out; 1879 1880 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0); 1881 if (!packet_out) 1882 { 1883 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 1884 return; 1885 } 1886 1887 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 1888 int sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(packet_out->po_data + packet_out->po_data_sz, 1889 lsquic_packet_out_avail(packet_out), 16 /* PEER_GOING_AWAY */, 1890 NULL, 0); 1891 if (sz < 0) { 1892 ABORT_ERROR("generate_connection_close_packet failed"); 1893 return; 1894 } 1895 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1896 packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE; 1897 LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet"); 1898} 1899 1900 1901static int 1902generate_blocked_frame (struct full_conn *conn, uint32_t stream_id) 1903{ 1904 lsquic_packet_out_t *packet_out = 1905 get_writeable_packet(conn, QUIC_BLOCKED_FRAME_SZ); 1906 if (!packet_out) 1907 return 0; 1908 int sz = conn->fc_conn.cn_pf->pf_gen_blocked_frame( 1909 packet_out->po_data + packet_out->po_data_sz, 1910 lsquic_packet_out_avail(packet_out), stream_id); 1911 if (sz < 0) { 1912 ABORT_ERROR("gen_blocked_frame failed"); 1913 return 0; 1914 } 1915 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1916 packet_out->po_frame_types |= 1 << QUIC_FRAME_BLOCKED; 1917 LSQ_DEBUG("wrote blocked frame: stream %u", stream_id); 1918 return 1; 1919} 1920 1921 1922static int 1923generate_stream_blocked_frame (struct full_conn *conn, lsquic_stream_t *stream) 1924{ 1925 if (generate_blocked_frame(conn, stream->id)) 1926 { 1927 lsquic_stream_blocked_frame_sent(stream); 1928 return 1; 1929 } 1930 else 1931 return 0; 1932} 1933 1934 1935static int 1936generate_rst_stream_frame (struct full_conn *conn, lsquic_stream_t *stream) 1937{ 1938 lsquic_packet_out_t *packet_out; 1939 int sz, s; 1940 1941 packet_out = get_writeable_packet(conn, QUIC_RST_STREAM_SZ); 1942 if (!packet_out) 1943 return 0; 1944 /* TODO Possible optimization: instead of using stream->tosend_off as the 1945 * offset, keep track of the offset that was actually sent: include it 1946 * into stream_rec and update a new per-stream "maximum offset actually 1947 * sent" field. Then, if a stream is reset, the connection cap can be 1948 * increased. 1949 */ 1950 sz = conn->fc_conn.cn_pf->pf_gen_rst_frame( 1951 packet_out->po_data + packet_out->po_data_sz, 1952 lsquic_packet_out_avail(packet_out), stream->id, 1953 stream->tosend_off, stream->error_code); 1954 if (sz < 0) { 1955 ABORT_ERROR("gen_rst_frame failed"); 1956 return 0; 1957 } 1958 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1959 packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM; 1960 s = lsquic_packet_out_add_stream(packet_out, conn->fc_pub.mm, stream, 1961 QUIC_FRAME_RST_STREAM, 0, 0); 1962 if (s != 0) 1963 { 1964 ABORT_ERROR("adding stream to packet failed: %s", strerror(errno)); 1965 return 0; 1966 } 1967 lsquic_stream_rst_frame_sent(stream); 1968 LSQ_DEBUG("wrote RST: stream %u; offset 0x%"PRIX64"; error code 0x%X", 1969 stream->id, stream->tosend_off, stream->error_code); 1970 return 1; 1971} 1972 1973 1974static void 1975generate_ping_frame (struct full_conn *conn) 1976{ 1977 lsquic_packet_out_t *packet_out = get_writeable_packet(conn, 1); 1978 if (!packet_out) 1979 { 1980 LSQ_DEBUG("cannot get writeable packet for PING frame"); 1981 return; 1982 } 1983 int sz = conn->fc_conn.cn_pf->pf_gen_ping_frame( 1984 packet_out->po_data + packet_out->po_data_sz, 1985 lsquic_packet_out_avail(packet_out)); 1986 if (sz < 0) { 1987 ABORT_ERROR("gen_blocked_frame failed"); 1988 return; 1989 } 1990 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 1991 packet_out->po_frame_types |= 1 << QUIC_FRAME_PING; 1992 LSQ_DEBUG("wrote PING frame"); 1993} 1994 1995 1996static void 1997generate_stop_waiting_frame (struct full_conn *conn) 1998{ 1999 assert(conn->fc_flags & FC_SEND_STOP_WAITING); 2000 2001 int sz; 2002 unsigned packnum_len; 2003 lsquic_packno_t least_unacked; 2004 lsquic_packet_out_t *packet_out; 2005 2006 /* Get packet that has room for the minimum size STOP_WAITING frame: */ 2007 packet_out = get_writeable_packet(conn, 1 + packno_bits2len(PACKNO_LEN_1)); 2008 if (!packet_out) 2009 return; 2010 2011 /* Now calculate number of bytes we really need. If there is not enough 2012 * room in the current packet, get a new one. 2013 */ 2014 packnum_len = packno_bits2len(lsquic_packet_out_packno_bits(packet_out)); 2015 if ((unsigned) lsquic_packet_out_avail(packet_out) < 1 + packnum_len) 2016 { 2017 packet_out = get_writeable_packet(conn, 1 + packnum_len); 2018 if (!packet_out) 2019 return; 2020 /* Here, a new packet has been allocated, The number of bytes needed 2021 * to represent packet number in the STOP_WAITING frame may have 2022 * increased. However, this does not matter, because the newly 2023 * allocated packet must have room for a STOP_WAITING frame of any 2024 * size. 2025 */ 2026 } 2027 2028 least_unacked = lsquic_send_ctl_smallest_unacked(&conn->fc_send_ctl); 2029 sz = conn->fc_conn.cn_pf->pf_gen_stop_waiting_frame( 2030 packet_out->po_data + packet_out->po_data_sz, 2031 lsquic_packet_out_avail(packet_out), packet_out->po_packno, 2032 lsquic_packet_out_packno_bits(packet_out), least_unacked); 2033 if (sz < 0) { 2034 ABORT_ERROR("gen_stop_waiting_frame failed"); 2035 return; 2036 } 2037 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2038 packet_out->po_regen_sz += sz; 2039 packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING; 2040 conn->fc_flags &= ~FC_SEND_STOP_WAITING; 2041 LSQ_DEBUG("wrote STOP_WAITING frame: least unacked: %"PRIu64, 2042 least_unacked); 2043 EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, least_unacked); 2044} 2045 2046 2047static int 2048process_stream_ready_to_send (struct full_conn *conn, lsquic_stream_t *stream) 2049{ 2050 int r = 1; 2051 if (stream->stream_flags & STREAM_SEND_WUF) 2052 r &= generate_wuf_stream(conn, stream); 2053 if (stream->stream_flags & STREAM_SEND_BLOCKED) 2054 r &= generate_stream_blocked_frame(conn, stream); 2055 if (stream->stream_flags & STREAM_SEND_RST) 2056 r &= generate_rst_stream_frame(conn, stream); 2057 return r; 2058} 2059 2060 2061static void 2062process_streams_ready_to_send (struct full_conn *conn) 2063{ 2064 lsquic_stream_t *stream; 2065 struct stream_prio_iter spi; 2066 2067 assert(!TAILQ_EMPTY(&conn->fc_pub.sending_streams)); 2068 2069 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.sending_streams), 2070 TAILQ_LAST(&conn->fc_pub.sending_streams, lsquic_streams_tailq), 2071 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_send_stream), 2072 STREAM_SENDING_FLAGS, conn->fc_conn.cn_cid, "send"); 2073 2074 for (stream = lsquic_spi_first(&spi); stream; 2075 stream = lsquic_spi_next(&spi)) 2076 if (!process_stream_ready_to_send(conn, stream)) 2077 break; 2078} 2079 2080 2081/* Return true if packetized, false otherwise */ 2082static int 2083packetize_standalone_stream_reset (struct full_conn *conn, uint32_t stream_id) 2084{ 2085 lsquic_packet_out_t *packet_out; 2086 int sz; 2087 2088 packet_out = get_writeable_packet(conn, QUIC_RST_STREAM_SZ); 2089 if (!packet_out) 2090 return 0; 2091 2092 sz = conn->fc_conn.cn_pf->pf_gen_rst_frame( 2093 packet_out->po_data + packet_out->po_data_sz, 2094 lsquic_packet_out_avail(packet_out), stream_id, 2095 0, 0x10 /* QUIC_PEER_GOING_AWAY */); 2096 if (sz < 0) { 2097 ABORT_ERROR("gen_rst_frame failed"); 2098 return 0; 2099 } 2100 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2101 packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM; 2102 LSQ_DEBUG("generated standaloen RST_STREAM frame for stream %"PRIu32, 2103 stream_id); 2104 return 1; 2105} 2106 2107 2108static void 2109packetize_standalone_stream_resets (struct full_conn *conn) 2110{ 2111 struct stream_id_to_reset *sitr; 2112 2113 while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset))) 2114 if (packetize_standalone_stream_reset(conn, sitr->sitr_stream_id)) 2115 { 2116 STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next); 2117 free(sitr); 2118 } 2119 else 2120 break; 2121} 2122 2123 2124static void 2125service_streams (struct full_conn *conn) 2126{ 2127 struct lsquic_hash_elem *el; 2128 lsquic_stream_t *stream, *next; 2129 int n_our_destroyed = 0; 2130 2131 for (stream = TAILQ_FIRST(&conn->fc_pub.service_streams); stream; stream = next) 2132 { 2133 next = TAILQ_NEXT(stream, next_service_stream); 2134 if (stream->stream_flags & STREAM_ABORT_CONN) 2135 /* No need to unset this flag or remove this stream: the connection 2136 * is about to be aborted. 2137 */ 2138 ABORT_ERROR("aborted due to error in stream %"PRIu32, stream->id); 2139 if (stream->stream_flags & STREAM_CALL_ONCLOSE) 2140 lsquic_stream_call_on_close(stream); 2141 if (stream->stream_flags & STREAM_FREE_STREAM) 2142 { 2143 n_our_destroyed += is_our_stream(conn, stream); 2144 TAILQ_REMOVE(&conn->fc_pub.service_streams, stream, next_service_stream); 2145 el = lsquic_hash_find(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id)); 2146 if (el) 2147 lsquic_hash_erase(conn->fc_pub.all_streams, el); 2148 conn_mark_stream_closed(conn, stream->id); 2149 SAVE_STREAM_HISTORY(conn, stream); 2150 lsquic_stream_destroy(stream); 2151 } 2152 } 2153 2154 if (either_side_going_away(conn)) 2155 while (conn->fc_n_delayed_streams) 2156 { 2157 --conn->fc_n_delayed_streams; 2158 LSQ_DEBUG("goaway mode: delayed stream results in null ctor"); 2159 (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream( 2160 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL); 2161 } 2162 else 2163 while (n_our_destroyed && conn->fc_n_delayed_streams) 2164 { 2165 --n_our_destroyed; 2166 --conn->fc_n_delayed_streams; 2167 LSQ_DEBUG("creating delayed stream"); 2168 if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW)) 2169 { 2170 ABORT_ERROR("%s: cannot create new stream: %s", __func__, 2171 strerror(errno)); 2172 break; 2173 } 2174 assert(count_streams(conn, 0) <= conn->fc_cfg.max_streams_out); 2175 } 2176} 2177 2178 2179static int 2180dispatch_stream_read_events (struct full_conn *conn, lsquic_stream_t *stream) 2181{ 2182 struct stream_read_prog_status saved_status; 2183 int progress_made; 2184 2185 lsquic_stream_get_read_prog_status(stream, &saved_status); 2186 lsquic_stream_dispatch_read_events(stream); 2187 progress_made = lsquic_stream_progress_was_made(stream, &saved_status); 2188 2189 return progress_made; 2190} 2191 2192 2193/* Return 1 if progress was made, 0 otherwise */ 2194static int 2195process_streams_read_events (struct full_conn *conn) 2196{ 2197 lsquic_stream_t *stream; 2198 struct stream_prio_iter spi; 2199 int progress_count; 2200 2201 if (TAILQ_EMPTY(&conn->fc_pub.read_streams)) 2202 return 0; 2203 2204 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams), 2205 TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq), 2206 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream), 2207 STREAM_WANT_READ, conn->fc_conn.cn_cid, "read"); 2208 2209 progress_count = 0; 2210 for (stream = lsquic_spi_first(&spi); stream; 2211 stream = lsquic_spi_next(&spi)) 2212 progress_count += 2213 dispatch_stream_read_events(conn, stream); 2214 2215 return progress_count > 0; 2216} 2217 2218 2219static void 2220maybe_conn_flush_headers_stream (struct full_conn *conn) 2221{ 2222 lsquic_stream_t *stream; 2223 2224 if (conn->fc_flags & FC_HTTP) 2225 { 2226 stream = lsquic_headers_stream_get_stream(conn->fc_pub.hs); 2227 if (lsquic_stream_has_data_to_flush(stream)) 2228 (void) lsquic_stream_flush(stream); 2229 } 2230} 2231 2232 2233static void 2234process_streams_write_events (struct full_conn *conn, int high_prio) 2235{ 2236 lsquic_stream_t *stream; 2237 struct stream_prio_iter spi; 2238 2239 lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.write_streams), 2240 TAILQ_LAST(&conn->fc_pub.write_streams, lsquic_streams_tailq), 2241 (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_write_stream), 2242 STREAM_WANT_WRITE|STREAM_WANT_FLUSH, conn->fc_conn.cn_cid, 2243 high_prio ? "write-high" : "write-low"); 2244 2245 if (high_prio) 2246 lsquic_spi_drop_non_high(&spi); 2247 else 2248 lsquic_spi_drop_high(&spi); 2249 2250 for (stream = lsquic_spi_first(&spi); stream && write_is_possible(conn); 2251 stream = lsquic_spi_next(&spi)) 2252 lsquic_stream_dispatch_write_events(stream); 2253 2254 maybe_conn_flush_headers_stream(conn); 2255} 2256 2257 2258/* Return 1 if progress was made, 0 otherwise. */ 2259static int 2260process_hsk_stream_read_events (struct full_conn *conn) 2261{ 2262 lsquic_stream_t *stream; 2263 TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream) 2264 if (LSQUIC_STREAM_HANDSHAKE == stream->id) 2265 return dispatch_stream_read_events(conn, stream); 2266 return 0; 2267} 2268 2269 2270static void 2271process_hsk_stream_write_events (struct full_conn *conn) 2272{ 2273 lsquic_stream_t *stream; 2274 TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, next_write_stream) 2275 if (LSQUIC_STREAM_HANDSHAKE == stream->id) 2276 { 2277 lsquic_stream_dispatch_write_events(stream); 2278 break; 2279 } 2280} 2281 2282 2283#if 1 2284# define verify_ack_frame(a, b, c) 2285#else 2286static void 2287verify_ack_frame (struct full_conn *conn, const unsigned char *buf, int bufsz) 2288{ 2289 unsigned i; 2290 int parsed_len; 2291 struct ack_info *ack_info; 2292 const struct lsquic_packno_range *range; 2293 char ack_buf[512]; 2294 unsigned buf_off = 0; 2295 int nw; 2296 2297 ack_info = conn->fc_pub.mm->acki; 2298 parsed_len = parse_ack_frame(buf, bufsz, ack_info); 2299 assert(parsed_len == bufsz); 2300 2301 for (range = lsquic_rechist_first(&conn->fc_rechist), i = 0; range; 2302 range = lsquic_rechist_next(&conn->fc_rechist), ++i) 2303 { 2304 assert(i < ack_info->n_ranges); 2305 assert(range->high == ack_info->ranges[i].high); 2306 assert(range->low == ack_info->ranges[i].low); 2307 if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)) 2308 { 2309 nw = snprintf(ack_buf + buf_off, sizeof(ack_buf) - buf_off, 2310 "[%"PRIu64"-%"PRIu64"]", range->high, range->low); 2311 assert(nw >= 0); 2312 buf_off += nw; 2313 } 2314 } 2315 assert(i == ack_info->n_ranges); 2316 LSQ_DEBUG("Sent ACK frame %s", ack_buf); 2317} 2318 2319 2320#endif 2321 2322 2323static void 2324generate_ack_frame (struct full_conn *conn) 2325{ 2326 lsquic_packet_out_t *packet_out; 2327 lsquic_time_t now; 2328 int has_missing, w; 2329 2330 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0); 2331 if (!packet_out) 2332 { 2333 ABORT_ERROR("cannot allocate packet: %s", strerror(errno)); 2334 return; 2335 } 2336 2337 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 2338 now = lsquic_time_now(); 2339 w = conn->fc_conn.cn_pf->pf_gen_ack_frame( 2340 packet_out->po_data + packet_out->po_data_sz, 2341 lsquic_packet_out_avail(packet_out), 2342 (gaf_rechist_first_f) lsquic_rechist_first, 2343 (gaf_rechist_next_f) lsquic_rechist_next, 2344 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 2345 &conn->fc_rechist, now, &has_missing, &packet_out->po_ack2ed); 2346 if (w < 0) { 2347 ABORT_ERROR("generating ACK frame failed: %d", errno); 2348 return; 2349 } 2350 EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, conn->fc_conn.cn_pf, 2351 packet_out->po_data + packet_out->po_data_sz, w); 2352 verify_ack_frame(conn, packet_out->po_data + packet_out->po_data_sz, w); 2353 lsquic_send_ctl_scheduled_ack(&conn->fc_send_ctl); 2354 packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK; 2355 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, w); 2356 packet_out->po_regen_sz += w; 2357 if (has_missing) 2358 conn->fc_flags |= FC_ACK_HAD_MISS; 2359 else 2360 conn->fc_flags &= ~FC_ACK_HAD_MISS; 2361 LSQ_DEBUG("Put %d bytes of ACK frame into packet on outgoing queue", w); 2362 if (conn->fc_conn.cn_version >= LSQVER_039 && 2363 conn->fc_n_cons_unretx >= 20 && 2364 !lsquic_send_ctl_have_outgoing_retx_frames(&conn->fc_send_ctl)) 2365 { 2366 LSQ_DEBUG("schedule WINDOW_UPDATE frame after %u non-retx " 2367 "packets sent", conn->fc_n_cons_unretx); 2368 conn->fc_flags |= FC_SEND_WUF; 2369 } 2370} 2371 2372 2373static int 2374conn_ok_to_close (const struct full_conn *conn) 2375{ 2376 assert(conn->fc_flags & FC_CLOSING); 2377 return !(conn->fc_flags & FC_SERVER) 2378 || (conn->fc_flags & FC_RECV_CLOSE) 2379 || ( 2380 !lsquic_send_ctl_have_outgoing_stream_frames(&conn->fc_send_ctl) 2381 && lsquic_hash_count(conn->fc_pub.all_streams) == 0 2382 && lsquic_send_ctl_have_unacked_stream_frames(&conn->fc_send_ctl) == 0); 2383} 2384 2385 2386static enum tick_st 2387immediate_close (struct full_conn *conn) 2388{ 2389 lsquic_packet_out_t *packet_out; 2390 const char *error_reason; 2391 unsigned error_code; 2392 int sz; 2393 2394 if (conn->fc_flags & (FC_TICK_CLOSE|FC_GOT_PRST)) 2395 return TICK_CLOSE; 2396 2397 conn->fc_flags |= FC_TICK_CLOSE; 2398 2399 /* No reason to send anything that's been scheduled if connection is 2400 * being closed immedately. This also ensures that packet numbers 2401 * sequence is always increasing. 2402 */ 2403 lsquic_send_ctl_drop_scheduled(&conn->fc_send_ctl); 2404 2405 if ((conn->fc_flags & FC_TIMED_OUT) && conn->fc_settings->es_silent_close) 2406 return TICK_CLOSE; 2407 2408 packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0); 2409 if (!packet_out) 2410 { 2411 LSQ_WARN("cannot allocate packet: %s", strerror(errno)); 2412 return TICK_CLOSE; 2413 } 2414 2415 assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT)); 2416 if (conn->fc_flags & FC_ERROR) 2417 { 2418 error_code = 0x01; /* QUIC_INTERNAL_ERROR */ 2419 error_reason = "connection error"; 2420 } 2421 else if (conn->fc_flags & FC_ABORTED) 2422 { 2423 error_code = 0x10; /* QUIC_PEER_GOING_AWAY */ 2424 error_reason = "user aborted connection"; 2425 } 2426 else if (conn->fc_flags & FC_TIMED_OUT) 2427 { 2428 error_code = 0x19; /* QUIC_NETWORK_IDLE_TIMEOUT */ 2429 error_reason = "connection timed out"; 2430 } 2431 else 2432 { 2433 error_code = 0x10; /* QUIC_PEER_GOING_AWAY */ 2434 error_reason = NULL; 2435 } 2436 2437 lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out); 2438 sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame( 2439 packet_out->po_data + packet_out->po_data_sz, 2440 lsquic_packet_out_avail(packet_out), error_code, 2441 error_reason, error_reason ? strlen(error_reason) : 0); 2442 if (sz < 0) { 2443 LSQ_WARN("%s failed", __func__); 2444 return TICK_CLOSE; 2445 } 2446 lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz); 2447 packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE; 2448 LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet"); 2449 return TICK_SEND|TICK_CLOSE; 2450} 2451 2452 2453static int 2454write_is_possible (struct full_conn *conn) 2455{ 2456 const lsquic_packet_out_t *packet_out; 2457 2458 packet_out = lsquic_send_ctl_last_scheduled(&conn->fc_send_ctl); 2459 return (packet_out && lsquic_packet_out_avail(packet_out) > 10) 2460 || lsquic_send_ctl_can_send(&conn->fc_send_ctl); 2461} 2462 2463 2464static enum tick_st 2465full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now) 2466{ 2467 struct full_conn *conn = (struct full_conn *) lconn; 2468 int have_delayed_packets; 2469 unsigned n; 2470 int progress_made, s; 2471 enum tick_st progress_tick = 0; 2472 2473#define CLOSE_IF_NECESSARY() do { \ 2474 if (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS) \ 2475 { \ 2476 progress_tick |= immediate_close(conn); \ 2477 goto end; \ 2478 } \ 2479} while (0) 2480 2481#define RETURN_IF_OUT_OF_PACKETS() do { \ 2482 if (!lsquic_send_ctl_can_send(&conn->fc_send_ctl)) \ 2483 { \ 2484 if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl)) \ 2485 { \ 2486 LSQ_DEBUG("used up packet allowance, quiet now (line %d)", \ 2487 __LINE__); \ 2488 progress_tick |= TICK_QUIET; \ 2489 } \ 2490 else \ 2491 { \ 2492 LSQ_DEBUG("used up packet allowance, sending now (line %d)",\ 2493 __LINE__); \ 2494 progress_tick |= TICK_SEND; \ 2495 } \ 2496 goto end; \ 2497 } \ 2498} while (0) 2499 2500#if FULL_CONN_STATS 2501 ++conn->fc_stats.n_ticks; 2502#endif 2503 2504 if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG) 2505 && conn->fc_mem_logged_last + 1000000 <= now) 2506 { 2507 conn->fc_mem_logged_last = now; 2508 LSQ_DEBUG("memory used: %zd bytes", calc_mem_used(conn)); 2509 } 2510 2511 assert(!(conn->fc_conn.cn_flags & LSCONN_RW_PENDING)); 2512 2513 if (conn->fc_flags & FC_HAVE_SAVED_ACK) 2514 { 2515 (void) /* If there is an error, we'll fail shortly */ 2516 process_saved_ack(conn, 0); 2517 conn->fc_flags &= ~FC_HAVE_SAVED_ACK; 2518 } 2519 2520 lsquic_send_ctl_tick(&conn->fc_send_ctl, now); 2521 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1); 2522 CLOSE_IF_NECESSARY(); 2523 2524 if (!(conn->fc_flags & FC_SERVER)) 2525 { 2526 lsquic_alarmset_unset(&conn->fc_alset, AL_PING); 2527 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 2528 } 2529 2530 lsquic_alarmset_ring_expired(&conn->fc_alset, now); 2531 CLOSE_IF_NECESSARY(); 2532 2533 /* To make things simple, only stream 1 is active until the handshake 2534 * has been completed. This will be adjusted in the future: the client 2535 * does not want to wait if it has the server information. 2536 */ 2537 if (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) 2538 progress_made = process_streams_read_events(conn); 2539 else 2540 progress_made = process_hsk_stream_read_events(conn); 2541 progress_tick |= progress_made << TICK_BIT_PROGRESS; 2542 CLOSE_IF_NECESSARY(); 2543 2544 if (lsquic_send_ctl_pacer_blocked(&conn->fc_send_ctl)) 2545 goto skip_write; 2546 2547 if (conn->fc_flags & FC_FIRST_TICK) 2548 { 2549 conn->fc_flags &= ~FC_FIRST_TICK; 2550 have_delayed_packets = 0; 2551 } 2552 else 2553 /* If there are any scheduled packets at this point, it means that 2554 * they were not sent during previous tick; in other words, they 2555 * are delayed. When there are delayed packets, the only packet 2556 * we sometimes add is a packet with an ACK frame, and we add it 2557 * to the *front* of the queue. 2558 */ 2559 have_delayed_packets = lsquic_send_ctl_maybe_squeeze_sched( 2560 &conn->fc_send_ctl); 2561 2562 if ((conn->fc_flags & FC_ACK_QUEUED) || 2563 lsquic_send_ctl_lost_ack(&conn->fc_send_ctl)) 2564 { 2565 if (have_delayed_packets) 2566 lsquic_send_ctl_reset_packnos(&conn->fc_send_ctl); 2567 2568 /* ACK frame generation fails with an error if it does not fit into 2569 * a single packet (it always should fit). 2570 */ 2571 generate_ack_frame(conn); 2572 CLOSE_IF_NECESSARY(); 2573 reset_ack_state(conn); 2574 2575 /* Try to send STOP_WAITING frame at the same time we send an ACK 2576 * This follows reference implementation. 2577 */ 2578 if (!(conn->fc_flags & FC_NSTP)) 2579 conn->fc_flags |= FC_SEND_STOP_WAITING; 2580 2581 if (have_delayed_packets) 2582 { 2583 if (conn->fc_flags & FC_SEND_STOP_WAITING) 2584 { 2585 /* TODO: ensure that STOP_WAITING frame is in the same packet 2586 * as the ACK frame in delayed packet mode. 2587 */ 2588 generate_stop_waiting_frame(conn); 2589 CLOSE_IF_NECESSARY(); 2590 } 2591 lsquic_send_ctl_ack_to_front(&conn->fc_send_ctl); 2592 } 2593 } 2594 2595 if (have_delayed_packets) 2596 { 2597 /* The reason for not adding STOP_WAITING and other frames below 2598 * to the packet carrying ACK frame generated when there are delayed 2599 * packets is so that if the ACK packet itself is delayed, it can be 2600 * dropped and replaced by new ACK packet. This way, we are never 2601 * more than 1 packet over CWND. 2602 */ 2603 progress_tick |= TICK_SEND; 2604 goto end; 2605 } 2606 2607 /* Try to fit any of the following three frames -- STOP_WAITING, 2608 * WINDOW_UPDATE, and GOAWAY -- before checking if we have run 2609 * out of packets. If either of them does not fit, it will be 2610 * tried next time around. 2611 */ 2612 if (conn->fc_flags & FC_SEND_STOP_WAITING) 2613 { 2614 generate_stop_waiting_frame(conn); 2615 CLOSE_IF_NECESSARY(); 2616 } 2617 2618 if (lsquic_cfcw_fc_offsets_changed(&conn->fc_pub.cfcw) || 2619 (conn->fc_flags & FC_SEND_WUF)) 2620 { 2621 conn->fc_flags |= FC_SEND_WUF; 2622 generate_wuf_conn(conn); 2623 CLOSE_IF_NECESSARY(); 2624 } 2625 2626 if (conn->fc_flags & FC_SEND_GOAWAY) 2627 { 2628 generate_goaway_frame(conn); 2629 CLOSE_IF_NECESSARY(); 2630 } 2631 2632 n = lsquic_send_ctl_reschedule_packets(&conn->fc_send_ctl); 2633 if (n > 0) 2634 CLOSE_IF_NECESSARY(); 2635 2636 RETURN_IF_OUT_OF_PACKETS(); 2637 2638 if (conn->fc_conn.cn_flags & LSCONN_SEND_BLOCKED) 2639 { 2640 if (generate_blocked_frame(conn, 0)) 2641 conn->fc_conn.cn_flags &= ~LSCONN_SEND_BLOCKED; 2642 else 2643 RETURN_IF_OUT_OF_PACKETS(); 2644 } 2645 2646 if (!STAILQ_EMPTY(&conn->fc_stream_ids_to_reset)) 2647 { 2648 packetize_standalone_stream_resets(conn); 2649 CLOSE_IF_NECESSARY(); 2650 } 2651 2652 if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams)) 2653 { 2654 process_streams_ready_to_send(conn); 2655 CLOSE_IF_NECESSARY(); 2656 } 2657 2658 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0); 2659 const unsigned n_sched = lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl); 2660 if (!(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)) 2661 { 2662 process_hsk_stream_write_events(conn); 2663 goto end_write; 2664 } 2665 2666 maybe_conn_flush_headers_stream(conn); 2667 2668 s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_HIGHEST_PRIO); 2669 conn->fc_flags |= (s < 0) << FC_BIT_ERROR; 2670 if (!write_is_possible(conn)) 2671 goto end_write; 2672 2673 if (!TAILQ_EMPTY(&conn->fc_pub.write_streams)) 2674 { 2675 process_streams_write_events(conn, 1); 2676 if (!write_is_possible(conn)) 2677 goto end_write; 2678 } 2679 2680 s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_OTHER_PRIO); 2681 conn->fc_flags |= (s < 0) << FC_BIT_ERROR; 2682 if (!write_is_possible(conn)) 2683 goto end_write; 2684 2685 if (!TAILQ_EMPTY(&conn->fc_pub.write_streams)) 2686 process_streams_write_events(conn, 0); 2687 2688 end_write: 2689 progress_made = (n_sched < lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl)); 2690 progress_tick |= progress_made << TICK_BIT_PROGRESS; 2691 2692 skip_write: 2693 service_streams(conn); 2694 CLOSE_IF_NECESSARY(); 2695 2696 RETURN_IF_OUT_OF_PACKETS(); 2697 2698 if ((conn->fc_flags & FC_CLOSING) && conn_ok_to_close(conn)) 2699 { 2700 LSQ_DEBUG("connection is OK to close"); 2701 /* This is normal termination sequence. 2702 * 2703 * Generate CONNECTION_CLOSE frame if we are responding to one, have 2704 * packets scheduled to send, or silent close flag is not set. 2705 */ 2706 conn->fc_flags |= FC_TICK_CLOSE; 2707 if ((conn->fc_flags & FC_RECV_CLOSE) || 2708 0 != lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) || 2709 !conn->fc_settings->es_silent_close) 2710 { 2711 generate_connection_close_packet(conn); 2712 progress_tick |= TICK_SEND|TICK_CLOSE; 2713 } 2714 else 2715 progress_tick |= TICK_CLOSE; 2716 goto end; 2717 } 2718 2719 if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl)) 2720 { 2721 if (conn->fc_flags & FC_SEND_PING) 2722 { 2723 conn->fc_flags &= ~FC_SEND_PING; 2724 generate_ping_frame(conn); 2725 CLOSE_IF_NECESSARY(); 2726 assert(lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) != 0); 2727 } 2728 else 2729 { 2730 progress_tick |= TICK_QUIET; 2731 goto end; 2732 } 2733 } 2734 else if (!(conn->fc_flags & FC_SERVER)) 2735 { 2736 lsquic_alarmset_unset(&conn->fc_alset, AL_PING); 2737 lsquic_send_ctl_sanity_check(&conn->fc_send_ctl); 2738 conn->fc_flags &= ~FC_SEND_PING; /* It may have rung */ 2739 } 2740 2741 now = lsquic_time_now(); 2742 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, 2743 now + conn->fc_settings->es_idle_conn_to); 2744 2745 /* From the spec: 2746 * " The PING frame should be used to keep a connection alive when 2747 * " a stream is open. 2748 */ 2749 if (0 == (conn->fc_flags & FC_SERVER) && 2750 lsquic_hash_count(conn->fc_pub.all_streams) > 0) 2751 lsquic_alarmset_set(&conn->fc_alset, AL_PING, now + TIME_BETWEEN_PINGS); 2752 2753 progress_tick |= TICK_SEND; 2754 2755 end: 2756 lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1); 2757 return progress_tick; 2758} 2759 2760 2761static void 2762full_conn_ci_packet_in (lsquic_conn_t *lconn, lsquic_packet_in_t *packet_in) 2763{ 2764 struct full_conn *conn = (struct full_conn *) lconn; 2765 2766 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, 2767 packet_in->pi_received + conn->fc_settings->es_idle_conn_to); 2768 if (0 == (conn->fc_flags & FC_ERROR)) 2769 if (0 != process_incoming_packet(conn, packet_in)) 2770 conn->fc_flags |= FC_ERROR; 2771} 2772 2773 2774static lsquic_packet_out_t * 2775full_conn_ci_next_packet_to_send (lsquic_conn_t *lconn) 2776{ 2777 struct full_conn *conn = (struct full_conn *) lconn; 2778 return lsquic_send_ctl_next_packet_to_send(&conn->fc_send_ctl); 2779} 2780 2781 2782static void 2783full_conn_ci_packet_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out) 2784{ 2785 struct full_conn *conn = (struct full_conn *) lconn; 2786 int s; 2787 2788 recent_packet_hist_new(conn, 1, packet_out->po_sent); 2789 recent_packet_hist_frames(conn, 1, packet_out->po_frame_types); 2790 2791 if (packet_out->po_frame_types & QFRAME_RETRANSMITTABLE_MASK) 2792 { 2793 conn->fc_n_cons_unretx = 0; 2794 lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, 2795 packet_out->po_sent + conn->fc_settings->es_idle_conn_to); 2796 } 2797 else 2798 ++conn->fc_n_cons_unretx; 2799 s = lsquic_send_ctl_sent_packet(&conn->fc_send_ctl, packet_out, 1); 2800 if (s != 0) 2801 ABORT_ERROR("sent packet failed: %s", strerror(errno)); 2802#if FULL_CONN_STATS 2803 ++conn->fc_stats.n_packets_out; 2804#endif 2805} 2806 2807 2808static void 2809full_conn_ci_packet_not_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out) 2810{ 2811 struct full_conn *conn = (struct full_conn *) lconn; 2812 lsquic_send_ctl_delayed_one(&conn->fc_send_ctl, packet_out); 2813} 2814 2815 2816static void 2817full_conn_ci_handshake_ok (lsquic_conn_t *lconn) 2818{ 2819 struct full_conn *conn = (struct full_conn *) lconn; 2820 LSQ_DEBUG("handshake reportedly done"); 2821 lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE); 2822 if (0 == apply_peer_settings(conn)) 2823 lconn->cn_flags |= LSCONN_HANDSHAKE_DONE; 2824 else 2825 conn->fc_flags |= FC_ERROR; 2826} 2827 2828 2829static void 2830full_conn_ci_handshake_failed (lsquic_conn_t *lconn) 2831{ 2832 struct full_conn *conn = (struct full_conn *) lconn; 2833 LSQ_DEBUG("handshake failed"); 2834 lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE); 2835 conn->fc_flags |= FC_HSK_FAILED; 2836} 2837 2838 2839static int 2840full_conn_ci_user_wants_read (lsquic_conn_t *lconn) 2841{ 2842 struct full_conn *conn = (struct full_conn *) lconn; 2843 return !TAILQ_EMPTY(&conn->fc_pub.read_streams); 2844} 2845 2846 2847void 2848lsquic_conn_abort (lsquic_conn_t *lconn) 2849{ 2850 struct full_conn *conn = (struct full_conn *) lconn; 2851 LSQ_INFO("User aborted connection"); 2852 conn->fc_flags |= FC_ABORTED; 2853} 2854 2855 2856void 2857lsquic_conn_close (lsquic_conn_t *lconn) 2858{ 2859 struct full_conn *conn = (struct full_conn *) lconn; 2860 lsquic_stream_t *stream; 2861 struct lsquic_hash_elem *el; 2862 2863 if (!(conn->fc_flags & FC_CLOSING)) 2864 { 2865 for (el = lsquic_hash_first(conn->fc_pub.all_streams); el; 2866 el = lsquic_hash_next(conn->fc_pub.all_streams)) 2867 { 2868 stream = lsquic_hashelem_getdata(el); 2869 lsquic_stream_shutdown_internal(stream); 2870 } 2871 conn->fc_flags |= FC_CLOSING; 2872 if (!(conn->fc_flags & FC_GOAWAY_SENT)) 2873 conn->fc_flags |= FC_SEND_GOAWAY; 2874 } 2875} 2876 2877 2878void 2879lsquic_conn_going_away (lsquic_conn_t *lconn) 2880{ 2881 struct full_conn *conn = (struct full_conn *) lconn; 2882 if (!(conn->fc_flags & (FC_CLOSING|FC_GOING_AWAY))) 2883 { 2884 LSQ_INFO("connection marked as going away"); 2885 assert(!(conn->fc_flags & FC_SEND_GOAWAY)); 2886 conn->fc_flags |= FC_GOING_AWAY; 2887 if (!(conn->fc_flags & FC_GOAWAY_SENT)) 2888 conn->fc_flags |= FC_SEND_GOAWAY; 2889 } 2890} 2891 2892 2893/* Find stream when stream ID is read from something other than a STREAM 2894 * frame. If the stream cannot be found or created, the connection is 2895 * aborted. 2896 */ 2897#if __GNUC__ 2898__attribute__((nonnull(4))) 2899#endif 2900static lsquic_stream_t * 2901find_stream_on_non_stream_frame (struct full_conn *conn, uint32_t stream_id, 2902 enum stream_ctor_flags stream_ctor_flags, 2903 const char *what) 2904{ 2905 lsquic_stream_t *stream; 2906 unsigned in_count; 2907 2908 stream = find_stream_by_id(conn, stream_id); 2909 if (stream) 2910 return stream; 2911 2912 if (conn_is_stream_closed(conn, stream_id)) 2913 { 2914 LSQ_DEBUG("drop incoming %s for closed stream %u", what, stream_id); 2915 return NULL; 2916 } 2917 2918 /* XXX It seems that if we receive a priority frame for a stream, the 2919 * stream should exist or have existed at some point. Thus, if 2920 * it does not exist, we should return an error here. 2921 */ 2922 2923 if (!is_peer_initiated(conn, stream_id)) 2924 { 2925 ABORT_ERROR("frame for never-initiated stream (push promise?)"); 2926 return NULL; 2927 } 2928 2929 in_count = count_streams(conn, 1); 2930 LSQ_DEBUG("number of peer-initiated streams: %u", in_count); 2931 if (in_count >= conn->fc_cfg.max_streams_in) 2932 { 2933 ABORT_ERROR("incoming %s for stream %u would exceed " 2934 "limit: %u", what, stream_id, conn->fc_cfg.max_streams_in); 2935 return NULL; 2936 } 2937 if ((conn->fc_flags & FC_GOING_AWAY) && 2938 stream_id > conn->fc_max_peer_stream_id) 2939 { 2940 maybe_schedule_reset_for_stream(conn, stream_id); 2941 LSQ_DEBUG("going away: reset new incoming stream %u", stream_id); 2942 return NULL; 2943 } 2944 2945 stream = new_stream(conn, stream_id, stream_ctor_flags); 2946 if (!stream) 2947 { 2948 ABORT_ERROR("cannot create new stream: %s", strerror(errno)); 2949 return NULL; 2950 } 2951 if (stream_id > conn->fc_max_peer_stream_id) 2952 conn->fc_max_peer_stream_id = stream_id; 2953 2954 return stream; 2955} 2956 2957 2958static void 2959headers_stream_on_conn_error (void *ctx) 2960{ 2961 struct full_conn *conn = ctx; 2962 ABORT_ERROR("connection error reported by HEADERS stream"); 2963} 2964 2965 2966static void 2967headers_stream_on_stream_error (void *ctx, uint32_t stream_id) 2968{ 2969 struct full_conn *conn = ctx; 2970 lsquic_stream_t *stream; 2971 2972 stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW, 2973 "error"); 2974 if (stream) 2975 { 2976 LSQ_DEBUG("resetting stream %u due to error", stream_id); 2977 /* We use code 1, which is QUIC_INTERNAL_ERROR (see 2978 * [draft-hamilton-quic-transport-protocol-01], Section 10), for all 2979 * errors. There does not seem to be a good reason to figure out 2980 * and send more specific error codes. 2981 */ 2982 lsquic_stream_reset_ext(stream, 1, 0); 2983 } 2984} 2985 2986 2987static void 2988headers_stream_on_enable_push (void *ctx, int enable_push) 2989{ 2990 struct full_conn *conn = ctx; 2991 if (0 == enable_push) 2992 { 2993 LSQ_DEBUG("server push %d -> 0", !!(conn->fc_flags & FC_SUPPORT_PUSH)); 2994 conn->fc_flags &= ~FC_SUPPORT_PUSH; 2995 } 2996 else if (conn->fc_settings->es_support_push) 2997 { 2998 LSQ_DEBUG("server push %d -> 1", !!(conn->fc_flags & FC_SUPPORT_PUSH)); 2999 conn->fc_flags |= FC_SUPPORT_PUSH; 3000 } 3001 else 3002 LSQ_INFO("not enabling server push that's disabled in engine settings"); 3003} 3004 3005 3006static void 3007headers_stream_on_incoming_headers (void *ctx, struct uncompressed_headers *uh) 3008{ 3009 struct full_conn *conn = ctx; 3010 lsquic_stream_t *stream; 3011 3012 LSQ_DEBUG("incoming headers for stream %u", uh->uh_stream_id); 3013 3014 stream = find_stream_on_non_stream_frame(conn, uh->uh_stream_id, 0, 3015 "headers"); 3016 if (!stream) 3017 { 3018 free(uh); 3019 return; 3020 } 3021 3022 if (0 != lsquic_stream_uh_in(stream, uh)) 3023 { 3024 ABORT_ERROR("stream %u refused incoming headers", uh->uh_stream_id); 3025 free(uh); 3026 } 3027 3028 if (!(stream->stream_flags & STREAM_ONNEW_DONE)) 3029 lsquic_stream_call_on_new(stream); 3030} 3031 3032 3033static void 3034headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh) 3035{ 3036 struct full_conn *conn = ctx; 3037 lsquic_stream_t *stream; 3038 3039 assert(!(conn->fc_flags & FC_SERVER)); 3040 3041 LSQ_DEBUG("push promise for stream %u in response to %u", 3042 uh->uh_oth_stream_id, uh->uh_stream_id); 3043 3044 if (0 == (uh->uh_stream_id & 1) || 3045 0 != (uh->uh_oth_stream_id & 1)) 3046 { 3047 ABORT_ERROR("invalid push promise stream IDs: %u, %u", 3048 uh->uh_oth_stream_id, uh->uh_stream_id); 3049 free(uh); 3050 return; 3051 } 3052 3053 if (!(conn_is_stream_closed(conn, uh->uh_stream_id) || 3054 find_stream_by_id(conn, uh->uh_stream_id))) 3055 { 3056 ABORT_ERROR("invalid push promise original stream ID %u never " 3057 "initiated", uh->uh_stream_id); 3058 free(uh); 3059 return; 3060 } 3061 3062 if (conn_is_stream_closed(conn, uh->uh_oth_stream_id) || 3063 find_stream_by_id(conn, uh->uh_oth_stream_id)) 3064 { 3065 ABORT_ERROR("invalid promised stream ID %u already used", 3066 uh->uh_oth_stream_id); 3067 free(uh); 3068 return; 3069 } 3070 3071 stream = new_stream_ext(conn, uh->uh_oth_stream_id, STREAM_IF_STD, 3072 SCF_DI_AUTOSWITCH|(conn->fc_enpub->enp_settings.es_rw_once ? 3073 SCF_DISP_RW_ONCE : 0)); 3074 if (!stream) 3075 { 3076 ABORT_ERROR("cannot create stream: %s", strerror(errno)); 3077 free(uh); 3078 return; 3079 } 3080 lsquic_stream_push_req(stream, uh); 3081 lsquic_stream_call_on_new(stream); 3082 return; 3083} 3084 3085 3086static void 3087headers_stream_on_priority (void *ctx, uint32_t stream_id, int exclusive, 3088 uint32_t dep_stream_id, unsigned weight) 3089{ 3090 struct full_conn *conn = ctx; 3091 lsquic_stream_t *stream; 3092 LSQ_DEBUG("got priority frame for stream %u: (ex: %d; dep stream: %u; " 3093 "weight: %u)", stream_id, exclusive, dep_stream_id, weight); 3094 stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW, 3095 "priority"); 3096 if (stream) 3097 lsquic_stream_set_priority_internal(stream, weight); 3098} 3099 3100 3101int lsquic_conn_is_push_enabled(lsquic_conn_t *c) 3102{ 3103 return ((struct full_conn *)c)->fc_flags & FC_SUPPORT_PUSH; 3104} 3105 3106 3107lsquic_conn_ctx_t * 3108lsquic_conn_get_ctx (const lsquic_conn_t *lconn) 3109{ 3110 struct full_conn *const conn = (struct full_conn *) lconn; 3111 return conn->fc_conn_ctx; 3112} 3113 3114 3115void lsquic_conn_set_ctx (lsquic_conn_t *lconn, lsquic_conn_ctx_t *ctx) 3116{ 3117 struct full_conn *const conn = (struct full_conn *) lconn; 3118 conn->fc_conn_ctx = ctx; 3119} 3120 3121 3122enum LSQUIC_CONN_STATUS 3123lsquic_conn_status (lsquic_conn_t *lconn, char *errbuf, size_t bufsz) 3124{ 3125 struct full_conn *const conn = (struct full_conn *) lconn; 3126 size_t n; 3127 3128 /* Test the common case first: */ 3129 if (!(conn->fc_flags & (FC_ERROR 3130 |FC_TIMED_OUT 3131 |FC_ABORTED 3132 |FC_GOT_PRST 3133 |FC_HSK_FAILED 3134 |FC_CLOSING 3135 |FC_GOING_AWAY))) 3136 { 3137 if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE) 3138 return LSCONN_ST_CONNECTED; 3139 else 3140 return LSCONN_ST_HSK_IN_PROGRESS; 3141 } 3142 3143 if (errbuf && bufsz) 3144 { 3145 if (conn->fc_errmsg) 3146 { 3147 n = bufsz < MAX_ERRMSG ? bufsz : MAX_ERRMSG; 3148 strncpy(errbuf, conn->fc_errmsg, n); 3149 errbuf[n - 1] = '\0'; 3150 } 3151 else 3152 errbuf[0] = '\0'; 3153 } 3154 3155 if (conn->fc_flags & FC_ERROR) 3156 return LSCONN_ST_ERROR; 3157 if (conn->fc_flags & FC_TIMED_OUT) 3158 return LSCONN_ST_TIMED_OUT; 3159 if (conn->fc_flags & FC_ABORTED) 3160 return LSCONN_ST_USER_ABORTED; 3161 if (conn->fc_flags & FC_GOT_PRST) 3162 return LSCONN_ST_RESET; 3163 if (conn->fc_flags & FC_HSK_FAILED) 3164 return LSCONN_ST_HSK_FAILURE; 3165 if (conn->fc_flags & FC_CLOSING) 3166 return LSCONN_ST_CLOSED; 3167 assert(conn->fc_flags & FC_GOING_AWAY); 3168 return LSCONN_ST_GOING_AWAY; 3169} 3170 3171 3172static const struct headers_stream_callbacks headers_callbacks = 3173{ 3174 .hsc_on_headers = headers_stream_on_incoming_headers, 3175 .hsc_on_push_promise = headers_stream_on_push_promise, 3176 .hsc_on_priority = headers_stream_on_priority, 3177 .hsc_on_stream_error = headers_stream_on_stream_error, 3178 .hsc_on_conn_error = headers_stream_on_conn_error, 3179 .hsc_on_enable_push = headers_stream_on_enable_push, 3180}; 3181 3182 3183 3184static const struct conn_iface full_conn_iface = { 3185 .ci_destroy = full_conn_ci_destroy, 3186 .ci_handshake_failed = full_conn_ci_handshake_failed, 3187 .ci_handshake_ok = full_conn_ci_handshake_ok, 3188 .ci_next_packet_to_send = full_conn_ci_next_packet_to_send, 3189 .ci_packet_in = full_conn_ci_packet_in, 3190 .ci_packet_not_sent = full_conn_ci_packet_not_sent, 3191 .ci_packet_sent = full_conn_ci_packet_sent, 3192 .ci_tick = full_conn_ci_tick, 3193 .ci_user_wants_read = full_conn_ci_user_wants_read, 3194}; 3195static struct full_conn * 3196new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub, 3197 const struct lsquic_stream_if *stream_if, 3198 void *stream_if_ctx, unsigned flags, 3199 unsigned short max_packet_size) 3200{ 3201 struct full_conn *conn; 3202 lsquic_stream_t *headers_stream; 3203 int saved_errno; 3204 3205 assert(0 == (flags & ~(FC_SERVER|FC_HTTP))); 3206 3207 conn = calloc(1, sizeof(*conn)); 3208 if (!conn) 3209 return NULL; 3210 headers_stream = NULL; 3211 conn->fc_conn.cn_cid = cid; 3212 conn->fc_conn.cn_pack_size = max_packet_size; 3213 conn->fc_flags = flags; 3214 conn->fc_enpub = enpub; 3215 conn->fc_pub.enpub = enpub; 3216 conn->fc_pub.mm = &enpub->enp_mm; 3217 conn->fc_pub.lconn = &conn->fc_conn; 3218 conn->fc_pub.send_ctl = &conn->fc_send_ctl; 3219 conn->fc_pub.packet_out_malo = 3220 lsquic_malo_create(sizeof(struct lsquic_packet_out)); 3221 conn->fc_stream_ifs[STREAM_IF_STD].stream_if = stream_if; 3222 conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = stream_if_ctx; 3223 conn->fc_settings = &enpub->enp_settings; 3224 /* Calculate maximum number of incoming streams using the same mechanism 3225 * and parameters as found in Chrome: 3226 */ 3227 conn->fc_cfg.max_streams_in = 3228 (unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f); 3229 if (conn->fc_cfg.max_streams_in < 3230 enpub->enp_settings.es_max_streams_in + 10) 3231 conn->fc_cfg.max_streams_in = 3232 enpub->enp_settings.es_max_streams_in + 10; 3233 /* `max_streams_out' gets reset when handshake is complete and we 3234 * learn of peer settings. 100 seems like a sane default value 3235 * because it is what other implementations use. In server mode, 3236 * we do not open any streams until the handshake is complete; in 3237 * client mode, we are limited to 98 outgoing requests alongside 3238 * handshake and headers streams. 3239 */ 3240 conn->fc_cfg.max_streams_out = 100; 3241 TAILQ_INIT(&conn->fc_pub.sending_streams); 3242 TAILQ_INIT(&conn->fc_pub.read_streams); 3243 TAILQ_INIT(&conn->fc_pub.write_streams); 3244 TAILQ_INIT(&conn->fc_pub.service_streams); 3245 STAILQ_INIT(&conn->fc_stream_ids_to_reset); 3246 lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW); 3247 lsquic_alarmset_init(&conn->fc_alset, cid); 3248 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn); 3249 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK, ack_alarm_expired, conn); 3250 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn); 3251 lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn); 3252 lsquic_set32_init(&conn->fc_closed_stream_ids[0]); 3253 lsquic_set32_init(&conn->fc_closed_stream_ids[1]); 3254 lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw); 3255 lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub, 3256 &conn->fc_ver_neg, &conn->fc_pub, conn->fc_conn.cn_pack_size); 3257 3258 conn->fc_pub.all_streams = lsquic_hash_create(); 3259 if (!conn->fc_pub.all_streams) 3260 goto cleanup_on_error; 3261 lsquic_rechist_init(&conn->fc_rechist, cid); 3262 if (conn->fc_flags & FC_HTTP) 3263 { 3264 conn->fc_pub.hs = lsquic_headers_stream_new( 3265 !!(conn->fc_flags & FC_SERVER), conn->fc_pub.mm, conn->fc_settings, 3266 &headers_callbacks, conn); 3267 if (!conn->fc_pub.hs) 3268 goto cleanup_on_error; 3269 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = lsquic_headers_stream_if; 3270 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.hs; 3271 headers_stream = new_stream(conn, LSQUIC_STREAM_HEADERS, 3272 SCF_CALL_ON_NEW); 3273 if (!headers_stream) 3274 goto cleanup_on_error; 3275 } 3276 else 3277 { 3278 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = stream_if; 3279 conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = stream_if_ctx; 3280 } 3281 if (conn->fc_settings->es_support_push) 3282 conn->fc_flags |= FC_SUPPORT_PUSH; 3283 conn->fc_conn.cn_if = &full_conn_iface; 3284 return conn; 3285 3286 cleanup_on_error: 3287 saved_errno = errno; 3288 3289 if (conn->fc_pub.all_streams) 3290 lsquic_hash_destroy(conn->fc_pub.all_streams); 3291 lsquic_rechist_cleanup(&conn->fc_rechist); 3292 if (conn->fc_flags & FC_HTTP) 3293 { 3294 if (conn->fc_pub.hs) 3295 lsquic_headers_stream_destroy(conn->fc_pub.hs); 3296 if (headers_stream) 3297 lsquic_stream_destroy(headers_stream); 3298 } 3299 memset(conn, 0, sizeof(*conn)); 3300 free(conn); 3301 3302 errno = saved_errno; 3303 return NULL; 3304} 3305struct lsquic_conn * 3306full_conn_client_new (struct lsquic_engine_public *enpub, 3307 const struct lsquic_stream_if *stream_if, 3308 void *stream_if_ctx, unsigned flags, 3309 const char *hostname, unsigned short max_packet_size) 3310{ 3311 struct full_conn *conn; 3312 enum lsquic_version version; 3313 lsquic_cid_t cid; 3314 const struct enc_session_funcs *esf; 3315 3316 version = highest_bit_set(enpub->enp_settings.es_versions); 3317 esf = select_esf_by_ver(version); 3318 cid = esf->esf_generate_cid(); 3319 conn = new_conn_common(cid, enpub, stream_if, stream_if_ctx, flags, 3320 max_packet_size); 3321 if (!conn) 3322 return NULL; 3323 conn->fc_conn.cn_esf = esf; 3324 conn->fc_conn.cn_enc_session = 3325 conn->fc_conn.cn_esf->esf_create_client(hostname, cid, conn->fc_enpub); 3326 if (!conn->fc_conn.cn_enc_session) 3327 { 3328 LSQ_WARN("could not create enc session: %s", strerror(errno)); 3329 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 3330 return NULL; 3331 } 3332 3333 if (conn->fc_flags & FC_HTTP) 3334 conn->fc_last_stream_id = LSQUIC_STREAM_HEADERS; /* Client goes 5, 7, 9.... */ 3335 else 3336 conn->fc_last_stream_id = LSQUIC_STREAM_HANDSHAKE; 3337 conn->fc_hsk_ctx.client.lconn = &conn->fc_conn; 3338 conn->fc_hsk_ctx.client.mm = &enpub->enp_mm; 3339 conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg; 3340 conn->fc_stream_ifs[STREAM_IF_HSK] 3341 .stream_if = &lsquic_client_hsk_stream_if; 3342 conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client; 3343 init_ver_neg(conn, conn->fc_settings->es_versions); 3344 conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver); 3345 if (conn->fc_settings->es_handshake_to) 3346 lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE, 3347 lsquic_time_now() + conn->fc_settings->es_handshake_to); 3348 if (!new_stream(conn, LSQUIC_STREAM_HANDSHAKE, SCF_CALL_ON_NEW)) 3349 { 3350 LSQ_WARN("could not create handshake stream: %s", strerror(errno)); 3351 conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn); 3352 return NULL; 3353 } 3354 conn->fc_flags |= FC_CREATED_OK; 3355 LSQ_INFO("Created new client connection"); 3356 EV_LOG_CONN_EVENT(cid, "created full connection"); 3357 return &conn->fc_conn; 3358} 3359