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