lsquic_conn.h revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_conn.h -- Connection interface 4 * 5 * There are two types of connections: full (lsquic_full_conn.h) and mini 6 * (lsquic_mini_conn.h). The function pointers and struct in this header 7 * file provide a unified interface engine.c can use to interact with 8 * either of the connection types. For this to work, struct lsquic_conn 9 * must be the first element of struct full_conn and struct mini_conn. 10 */ 11#ifndef LSQUIC_CONN_H 12#define LSQUIC_CONN_H 13 14#include <sys/queue.h> 15#ifndef WIN32 16#include <sys/socket.h> 17#include <netinet/in.h> 18#else 19#include <ws2ipdef.h> 20#endif 21 22#ifndef LSQUIC_TEST 23#define LSQUIC_TEST 0 24#endif 25 26struct lsquic_conn; 27struct lsquic_engine_public; 28struct lsquic_packet_out; 29struct lsquic_packet_in; 30struct sockaddr; 31struct parse_funcs; 32struct attq_elem; 33#if LSQUIC_CONN_STATS 34struct conn_stats; 35#endif 36 37enum lsquic_conn_flags { 38 LSCONN_TICKED = (1 << 0), 39 LSCONN_HAS_OUTGOING = (1 << 1), 40 LSCONN_HASHED = (1 << 2), 41 LSCONN_MINI = (1 << 3), /* This is a mini connection */ 42 LSCONN_IMMED_CLOSE = (1 << 4), 43 LSCONN_UNUSED_5 = (1 << 5), 44 LSCONN_HANDSHAKE_DONE = (1 << 6), 45 LSCONN_CLOSING = (1 << 7), 46 LSCONN_PEER_GOING_AWAY= (1 << 8), 47 LSCONN_TCID0 = (1 << 9), 48 LSCONN_VER_SET = (1 <<10), /* cn_version is set */ 49 LSCONN_EVANESCENT = (1 <<11), /* evanescent connection */ 50 LSCONN_TICKABLE = (1 <<12), /* Connection is in the Tickable Queue */ 51 LSCONN_COI_ACTIVE = (1 <<13), 52 LSCONN_COI_INACTIVE = (1 <<14), 53 LSCONN_SEND_BLOCKED = (1 <<15), /* Send connection blocked frame */ 54 LSCONN_PROMOTED = (1 <<16), /* Promoted. Only set if LSCONN_MINI is set */ 55 LSCONN_NEVER_TICKABLE = (1 <<17), /* Do not put onto the Tickable Queue */ 56 LSCONN_UNUSED_18 = (1 <<18), 57 LSCONN_ATTQ = (1 <<19), 58 LSCONN_SKIP_ON_PROC = (1 <<20), 59 LSCONN_UNUSED_21 = (1 <<21), 60 LSCONN_SERVER = (1 <<22), 61 LSCONN_IETF = (1 <<23), 62 LSCONN_RETRY_CONN = (1 <<24), /* This is a retry connection */ 63}; 64 65/* A connection may have things to send and be closed at the same time. 66 */ 67enum tick_st { 68 TICK_SEND = (1 << 0), 69 TICK_CLOSE = (1 << 1), 70 TICK_PROMOTE = (1 << 2), /* Promote mini connection to full connection */ 71}; 72 73#define TICK_QUIET 0 74 75struct network_path 76{ 77 union { 78 unsigned char buf[sizeof(struct sockaddr_in6)]; 79 struct sockaddr sockaddr; 80 } np_local_addr_u; 81#define np_local_addr np_local_addr_u.buf 82 unsigned char np_peer_addr[sizeof(struct sockaddr_in6)]; 83 void *np_peer_ctx; 84 lsquic_cid_t np_dcid; 85 unsigned short np_pack_size; 86 unsigned char np_path_id; 87}; 88 89#define NP_LOCAL_SA(path_) (&(path_)->np_local_addr_u.sockaddr) 90#define NP_PEER_SA(path_) ((struct sockaddr *) (path_)->np_peer_addr) 91#define NP_IS_IPv6(path_) (AF_INET6 == NP_LOCAL_SA(path_)->sa_family) 92 93struct ack_state 94{ 95 uint32_t arr[6]; 96}; 97 98struct to_coal 99{ 100 const struct lsquic_packet_out *prev_packet; 101 size_t prev_sz_sum; 102}; 103 104struct conn_iface 105{ 106 enum tick_st 107 (*ci_tick) (struct lsquic_conn *, lsquic_time_t now); 108 109 void 110 (*ci_packet_in) (struct lsquic_conn *, struct lsquic_packet_in *); 111 112 /* Note: all packets "checked out" by calling this method should be 113 * returned back to the connection via ci_packet_sent() or 114 * ci_packet_not_sent() calls before the connection is ticked next. 115 * The connection, in turn, should not perform any extra processing 116 * (especially schedule more packets) during any of these method 117 * calls. This is because the checked out packets are not accounted 118 * for by the congestion controller. 119 */ 120 struct lsquic_packet_out * 121 (*ci_next_packet_to_send) (struct lsquic_conn *, const struct to_coal *); 122 123 void 124 (*ci_packet_sent) (struct lsquic_conn *, struct lsquic_packet_out *); 125 126 void 127 (*ci_packet_not_sent) (struct lsquic_conn *, struct lsquic_packet_out *); 128 129 void 130 (*ci_packet_too_large) (struct lsquic_conn *, struct lsquic_packet_out *); 131 132 void 133 (*ci_hsk_done) (struct lsquic_conn *, enum lsquic_hsk_status); 134 135 void 136 (*ci_destroy) (struct lsquic_conn *); 137 138 int 139 (*ci_is_tickable) (struct lsquic_conn *); 140 141 lsquic_time_t 142 (*ci_next_tick_time) (struct lsquic_conn *, unsigned *why); 143 144 int 145 (*ci_can_write_ack) (struct lsquic_conn *); 146 147 /* No return status: best effort */ 148 void 149 (*ci_write_ack) (struct lsquic_conn *, struct lsquic_packet_out *); 150 151#if LSQUIC_CONN_STATS 152 const struct conn_stats * 153 (*ci_get_stats) (struct lsquic_conn *); 154 155 void 156 (*ci_log_stats) (struct lsquic_conn *); 157#endif 158 159 void 160 (*ci_client_call_on_new) (struct lsquic_conn *); 161 162 enum LSQUIC_CONN_STATUS 163 (*ci_status) (struct lsquic_conn *, char *errbuf, size_t bufsz); 164 165 unsigned 166 (*ci_n_avail_streams) (const struct lsquic_conn *); 167 168 unsigned 169 (*ci_n_pending_streams) (const struct lsquic_conn *); 170 171 unsigned 172 (*ci_cancel_pending_streams) (struct lsquic_conn *, unsigned n); 173 174 void 175 (*ci_going_away) (struct lsquic_conn *); 176 177 int 178 (*ci_is_push_enabled) (struct lsquic_conn *); 179 180 /* Optional: only used by gQUIC frames reader */ 181 /* If stream is already closed, NULL is returned */ 182 struct lsquic_stream * 183 (*ci_get_stream_by_id) (struct lsquic_conn *, lsquic_stream_id_t stream_id); 184 185 struct lsquic_engine * 186 (*ci_get_engine) (struct lsquic_conn *); 187 188 void 189 (*ci_make_stream) (struct lsquic_conn *); 190 191 void 192 (*ci_abort) (struct lsquic_conn *); 193 194 void 195 (*ci_retire_cid) (struct lsquic_conn *); 196 197 void 198 (*ci_close) (struct lsquic_conn *); 199 200 void 201 (*ci_stateless_reset) (struct lsquic_conn *); 202 203 int 204 (*ci_crypto_keysize) (const struct lsquic_conn *); 205 206 int 207 (*ci_crypto_alg_keysize) (const struct lsquic_conn *); 208 209 enum lsquic_crypto_ver 210 (*ci_crypto_ver) (const struct lsquic_conn *); 211 212 const char * 213 (*ci_crypto_cipher) (const struct lsquic_conn *); 214 215 int 216 (*ci_push_stream) (struct lsquic_conn *, void *hset, struct lsquic_stream *, 217 const struct lsquic_http_headers *headers); 218 219 /* Use this to abort the connection when unlikely errors occur */ 220 void 221 (*ci_internal_error) (struct lsquic_conn *, const char *format, ...) 222#if __GNUC__ 223 __attribute__((format(printf, 2, 3))) 224#endif 225 ; 226 227 /* Abort connection with error */ 228 void 229 (*ci_abort_error) (struct lsquic_conn *, int is_app, unsigned error_code, 230 const char *format, ...) 231#if __GNUC__ 232 __attribute__((format(printf, 4, 5))) 233#endif 234 ; 235 236 void 237 (*ci_tls_alert) (struct lsquic_conn *, uint8_t); 238 239 /* Returns 0 if connection is to be deleted immediately */ 240 lsquic_time_t 241 (*ci_drain_time) (const struct lsquic_conn *); 242 243 /* Returns true if it's time to report the connection's CIDs' liveness */ 244 int 245 (*ci_report_live) (struct lsquic_conn *, lsquic_time_t now); 246 247 /* If `local_sa' is NULL, return default path */ 248 struct network_path * 249 (*ci_get_path) (struct lsquic_conn *, const struct sockaddr *local_sa); 250 251 unsigned char 252 (*ci_record_addrs) (struct lsquic_conn *, void *peer_ctx, 253 const struct sockaddr *local_sa, const struct sockaddr *peer_sa); 254 255 const lsquic_cid_t * 256 (*ci_get_log_cid) (const struct lsquic_conn *); 257 258 /* Optional method. Only used by the IETF client code. */ 259 void 260 (*ci_drop_crypto_streams) (struct lsquic_conn *); 261 262 /* Optional method. Only used by IETF connections */ 263 void 264 (*ci_count_garbage) (struct lsquic_conn *, size_t); 265 266 /* Optional method. Must be implemented if connection sends MTU probes */ 267 void 268 (*ci_mtu_probe_acked) (struct lsquic_conn *, 269 const struct lsquic_packet_out *); 270 271 /* Optional method. It is called when RTO occurs. */ 272 void 273 (*ci_retx_timeout) (struct lsquic_conn *); 274 275 void 276 (*ci_ack_snapshot) (struct lsquic_conn *, struct ack_state *); 277 278 void 279 (*ci_ack_rollback) (struct lsquic_conn *, struct ack_state *); 280 281 /* Optional method. */ 282 int 283 (*ci_want_datagram_write) (struct lsquic_conn *, int); 284 285 /* Optional method */ 286 int 287 (*ci_set_min_datagram_size) (struct lsquic_conn *, size_t); 288 289 /* Optional method */ 290 size_t 291 (*ci_get_min_datagram_size) (struct lsquic_conn *); 292 293 /* Optional method */ 294 void 295 (*ci_early_data_failed) (struct lsquic_conn *); 296}; 297 298#define LSCONN_CCE_BITS 3 299#define LSCONN_MAX_CCES (1 << LSCONN_CCE_BITS) 300 301struct conn_cid_elem 302{ 303 struct lsquic_hash_elem cce_hash_el; /* Must be first element */ 304 lsquic_cid_t cce_cid; 305 union { 306 unsigned seqno; 307 unsigned short port; 308 } cce_u; 309#define cce_seqno cce_u.seqno 310#define cce_port cce_u.port 311 enum conn_cce_flags { 312 CCE_USED = 1 << 0, /* Connection ID has been used */ 313 CCE_SEQNO = 1 << 1, /* cce_seqno is set (CIDs in Initial 314 * packets have no sequence number). 315 */ 316 CCE_REG = 1 << 2, /* CID has been registered */ 317 CCE_PORT = 1 << 3, /* It's not a CID element at all: 318 * cce_port is the hash value. 319 */ 320 } cce_flags; 321}; 322 323struct lsquic_conn 324{ 325 void *cn_enc_session; 326 const struct enc_session_funcs_common 327 *cn_esf_c; 328 union { 329 const struct enc_session_funcs_gquic *g; 330 const struct enc_session_funcs_iquic *i; 331 } cn_esf; 332#define cn_cid cn_cces[0].cce_cid 333 STAILQ_ENTRY(lsquic_conn) cn_next_closed_conn; 334 /* This and cn_next_closed_conn could be made into a union, as new full 335 * connections are never closed. 336 */ 337 STAILQ_ENTRY(lsquic_conn) cn_next_new_full; 338 TAILQ_ENTRY(lsquic_conn) cn_next_ticked; 339 TAILQ_ENTRY(lsquic_conn) cn_next_out; 340 TAILQ_ENTRY(lsquic_conn) cn_next_pr; 341 const struct conn_iface *cn_if; 342 const struct parse_funcs *cn_pf; 343 struct attq_elem *cn_attq_elem; 344 lsquic_time_t cn_last_sent; 345 lsquic_time_t cn_last_ticked; 346 struct conn_cid_elem *cn_cces; /* At least one is available */ 347 lsquic_conn_ctx_t *cn_conn_ctx; 348 enum lsquic_conn_flags cn_flags; 349 enum lsquic_version cn_version:8; 350 unsigned char cn_cces_mask; /* Those that are set */ 351 unsigned char cn_n_cces; /* Number of CCEs in cn_cces */ 352 unsigned char cn_cur_cce_idx; 353#if LSQUIC_TEST 354 struct conn_cid_elem cn_cces_buf[8]; 355#define LSCONN_INITIALIZER_CID(lsconn_, cid_) { \ 356 .cn_cces = (lsconn_).cn_cces_buf, \ 357 .cn_cces_buf[0].cce_seqno = 0, \ 358 .cn_cces_buf[0].cce_flags = CCE_SEQNO, \ 359 .cn_cces_buf[0].cce_cid = (cid_), \ 360 .cn_n_cces = 8, .cn_cces_mask = 1, } 361#define LSCONN_INITIALIZER_CIDLEN(lsconn_, len_) { \ 362 .cn_cces = (lsconn_).cn_cces_buf, \ 363 .cn_cces_buf[0].cce_seqno = 0, \ 364 .cn_cces_buf[0].cce_flags = CCE_SEQNO, \ 365 .cn_cces_buf[0].cce_cid = { .len = len_ }, \ 366 .cn_n_cces = 8, .cn_cces_mask = 1, } 367#define LSCONN_INITIALIZE(lsconn_) do { \ 368 (lsconn_)->cn_cces = (lsconn_)->cn_cces_buf; \ 369 (lsconn_)->cn_n_cces = 8; (lsconn_)->cn_cces_mask = 1; } while (0) 370#endif 371}; 372 373#define END_OF_CCES(conn) ((conn)->cn_cces + (conn)->cn_n_cces) 374 375#define CN_SCID(conn) (&(conn)->cn_cces[(conn)->cn_cur_cce_idx].cce_cid) 376 377unsigned char 378lsquic_conn_record_sockaddr (lsquic_conn_t *lconn, void *peer_ctx, 379 const struct sockaddr *local_sa, const struct sockaddr *peer_sa); 380 381int 382lsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 383 struct lsquic_engine_public *, struct lsquic_packet_in *); 384 385int 386lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 387 struct lsquic_engine_public *, struct lsquic_packet_in *); 388 389void 390lsquic_generate_cid (lsquic_cid_t *cid, size_t len); 391 392void 393lsquic_generate_cid_gquic (lsquic_cid_t *cid); 394 395void 396lsquic_generate_scid (struct lsquic_conn *lconn, lsquic_cid_t *scid, 397 unsigned len); 398 399void 400lsquic_conn_retire_cid (lsquic_conn_t *lconn); 401 402#define lsquic_conn_adv_time(c) ((c)->cn_attq_elem->ae_adv_time) 403 404#if LSQUIC_CONN_STATS 405struct conn_stats { 406 /* All counters are of the same type, unsigned long, because we cast the 407 * struct to an array to update the aggregate. 408 */ 409 unsigned long n_ticks; /* How many time connection was ticked */ 410 struct { 411 unsigned long stream_data_sz; /* Sum of all STREAM frames payload */ 412 unsigned long stream_frames; /* Number of STREAM frames */ 413 unsigned long packets, /* Incoming packets */ 414 undec_packets, /* Undecryptable packets */ 415 dup_packets, /* Duplicate packets */ 416 err_packets; /* Error packets(?) */ 417 unsigned long n_acks, 418 n_acks_proc, 419 n_acks_merged; 420 unsigned long bytes; /* Overall bytes in */ 421 unsigned long headers_uncomp; /* Sum of uncompressed header bytes */ 422 unsigned long headers_comp; /* Sum of compressed header bytes */ 423 } in; 424 struct { 425 unsigned long stream_data_sz; 426 unsigned long stream_frames; 427 unsigned long acks; 428 unsigned long packets; /* Number of sent packets */ 429 unsigned long acked_via_loss; /* Number of packets acked via loss record */ 430 unsigned long lost_packets; 431 unsigned long retx_packets; /* Number of retransmitted packets */ 432 unsigned long bytes; /* Overall bytes out */ 433 unsigned long headers_uncomp; /* Sum of uncompressed header bytes */ 434 unsigned long headers_comp; /* Sum of compressed header bytes */ 435 } out; 436}; 437 438void 439lsquic_conn_stats_diff (const struct conn_stats *cumulative, 440 const struct conn_stats *previous, 441 struct conn_stats *new); 442#endif 443 444#endif 445