lsquic_mini_conn.h revision a74702c6
1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_mini_conn.h -- Mini-connection
4 *
5 * Before a connection is established, the server keeps a "mini" connection
6 * object where it keeps track of stream 1 offsets and so on.
7 */
8
9#ifndef LSQUIC_MINI_CONN_H
10#define LSQUIC_MINI_CONN_H
11
12#include <stdint.h>
13#include <sys/queue.h>
14
15#define MAX_MINI_CONN_LIFESPAN_IN_USEC \
16    ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) - 1)
17
18struct lsquic_packet_in;
19struct lsquic_packet_out;
20struct lsquic_engine_public;
21
22#ifndef LSQUIC_KEEP_MINICONN_HISTORY
23#   if !defined(NDEBUG) && !defined(_MSC_VER)
24#       define LSQUIC_KEEP_MINICONN_HISTORY 1
25#   else
26#       define LSQUIC_KEEP_MINICONN_HISTORY 0
27#   endif
28#endif
29
30#if LSQUIC_KEEP_MINICONN_HISTORY
31
32#define MCHIST_BITS 4
33#define MCHIST_MASK ((1 << MCHIST_BITS) - 1)
34typedef unsigned char mchist_idx_t;
35
36enum miniconn_history_event
37{
38    MCHE_EMPTY              =  '\0',
39    MCHE_PLUS               =  '+',
40    MCHE_HANDLE_1RTT        =  '1',
41    MCHE_HANDLE_SREJ        =  '2',
42    MCHE_PACKET2LARGE_IN    =  'a',
43    MCHE_CONN_CLOSE         =  'c',
44    MCHE_CREATED            =  'C',
45    MCHE_2HSK_1STREAM       =  'd',
46    MCHE_DUP_HSK            =  'D',
47    MCHE_HANDLE_ERROR       =  'e',
48    MCHE_EFRAME             =  'f',
49    MCHE_UNDECR_DEFER       =  'F',
50    MCHE_HANDLE_NOT_ENOUGH  =  'g',
51    MCHE_NEW_HSK            =  'H',
52    MCHE_INVALID_FRAME      =  'I',
53    MCHE_DECRYPTED          =  'K',
54    MCHE_PACKET_LOST        =  'L',
55    MCHE_HELLO_TOO_MUCH     =  'm',
56    MCHE_ENOMEM             =  'M',
57    MCHE_NEW_PACKET_OUT     =  'N',
58    MCHE_HELLO_HOLE         =  'o',
59    MCHE_PACKET_DUP_IN      =  'p',
60    MCHE_UNDECR_DROP        =  'P',
61    MCHE_PRST_IN            =  'R',
62    MCHE_HANDLE_SHLO        =  's',
63    MCHE_NEW_ENC_SESS       =  'S',
64    MCHE_PACKET_SENT        =  'T',
65    MCHE_HAHDLE_UNKNOWN     =  'u',
66    MCHE_UNSENT_ACKED       =  'U',
67    MCHE_HANDLE_DELAYED     =  'y',
68    MCHE_PACKET_DELAYED     =  'Y',
69    MCHE_PACKET0_IN         =  'z',
70    MCHE_OUT_OF_PACKNOS     =  '#',
71};
72
73#endif
74
75#ifndef LSQUIC_RECORD_INORD_HIST
76#   if __GNUC__
77#       define LSQUIC_RECORD_INORD_HIST 1
78#   else
79#       define LSQUIC_RECORD_INORD_HIST 0
80#   endif
81#endif
82
83typedef uint64_t mconn_packno_set_t;
84
85#define MINICONN_MAX_PACKETS (sizeof(mconn_packno_set_t) * 8)
86
87TAILQ_HEAD(head_packet_in, lsquic_packet_in);
88
89struct mini_conn {
90    struct lsquic_conn     mc_conn;
91    struct conn_cid_elem   mc_cces[1];
92    struct head_packet_in  mc_deferred,
93                           mc_packets_in;
94    TAILQ_HEAD(, lsquic_packet_out)
95                           mc_packets_out;
96    struct lsquic_engine_public
97                          *mc_enpub;
98    lsquic_time_t          mc_created;
99    struct lsquic_rtt_stats
100                           mc_rtt_stats;
101    mconn_packno_set_t     mc_received_packnos,
102                           mc_sent_packnos,
103                           mc_deferred_packnos,                                 /* Informational */
104                           mc_dropped_packnos,                                  /* Informational */
105                           mc_lost_packnos, /* Packets that were deemed lost */ /* Informational */
106                           mc_acked_packnos;
107#if LSQUIC_RECORD_INORD_HIST
108    unsigned long long     mc_inord_hist[2];                                    /* Informational */
109#endif
110    uint32_t               mc_error_code;   /* From CONNECTION_CLOSE frame */   /* Informational */
111    unsigned short         mc_n_ticks;  /* Number of times mini conn ticked. */ /* Informational */
112    unsigned short         mc_read_off, /* Read offset for stream 1 */
113                           mc_write_off;/* Write offset for stream 1 */
114    unsigned char          mc_max_ack_packno,
115                           mc_cutoff,
116                           mc_cur_packno;
117    unsigned char          mc_hsk_count;
118#define MINI_CONN_MAX_DEFERRED 10
119    unsigned char          mc_n_deferred;
120#if LSQUIC_RECORD_INORD_HIST
121    unsigned char          mc_inord_idx;
122#endif
123    /* mc_largest_recv is the timestamp of when packet with the largest
124     * number was received; it is necessary to generate ACK frames.  24
125     * bits holds about 16.5 seconds worth of microseconds, which is
126     * larger than the maximum amount of time a mini connection object
127     * is allowed to live.  To get the timestamp, add this value to
128     * mc_created.
129     */
130    unsigned char          mc_largest_recv[3];
131    enum {
132        MC_HAVE_NEW_HSK  = (1 << 0),
133        MC_PROMOTE       = (1 << 1),
134        MC_HAVE_SHLO     = (1 << 2),
135        MC_WR_OFF_RESET  = (1 << 3),
136        MC_ERROR         = (1 << 4),
137        MC_UNSENT_ACK    = (1 << 5),
138        MC_GEN_ACK       = (1 << 6),
139        MC_HSK_ERR       = (1 << 7),
140        MC_OO_PACKNOS    = (1 << 8),
141        MC_STOP_WAIT_ON  = (1 << 9),
142    }                      mc_flags:16;
143    struct network_path    mc_path;
144#if LSQUIC_KEEP_MINICONN_HISTORY
145    mchist_idx_t           mc_hist_idx;
146    unsigned char          mc_hist_buf[1 << MCHIST_BITS];
147#endif
148};
149
150lsquic_conn_t *
151lsquic_mini_conn_new (struct lsquic_engine_public *,
152            const struct lsquic_packet_in *, enum lsquic_version version);
153
154/* Packet numbers start with 1.  By subtracting 1, we can utilize the full
155 * length of the bitmask.
156 */
157#define MCONN_PACKET_MASK(packno) (1ULL << (packno - 1))
158
159#endif
160