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