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