lsquic_conn.h revision a74702c6
1/* Copyright (c) 2017 - 2022 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 (void *, 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