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