lsquic_stream.h revision 50aadb33
1/* Copyright (c) 2017 LiteSpeed Technologies Inc.  See LICENSE. */
2#ifndef __LSQUIC_STREAM_H__
3#define __LSQUIC_STREAM_H__
4
5#include <lsquic_types.h>
6
7#define LSQUIC_STREAM_HANDSHAKE 1
8#define LSQUIC_STREAM_HEADERS   3
9
10#define LSQUIC_STREAM_DEFAULT_PRIO 16   /* RFC 7540, Section 5.3.5 */
11
12struct lsquic_stream_if;
13struct lsquic_stream_ctx;
14struct lsquic_conn_public;
15struct stream_frame;
16struct uncompressed_headers;
17
18TAILQ_HEAD(lsquic_streams_tailq, lsquic_stream);
19TAILQ_HEAD(sbts_tailq, stream_buf_tosend);
20
21#ifndef LSQUIC_KEEP_STREAM_HISTORY
22#   ifdef NDEBUG
23#       define LSQUIC_KEEP_STREAM_HISTORY 0
24#   else
25#       define LSQUIC_KEEP_STREAM_HISTORY 1
26#   endif
27#endif
28
29#if LSQUIC_KEEP_STREAM_HISTORY
30#define SM_HIST_BITS 6
31#define SM_HIST_IDX_MASK ((1 << SM_HIST_BITS) - 1)
32typedef unsigned char sm_hist_idx_t;
33#endif
34
35struct lsquic_stream
36{
37    uint32_t                        id;
38    enum stream_flags {
39        STREAM_WANT_READ    = (1 << 0),
40        STREAM_WANT_WRITE   = (1 << 1),
41        STREAM_FIN_RECVD    = (1 << 2),     /* Received STREAM frame with FIN bit set */
42        STREAM_RST_RECVD    = (1 << 3),     /* Received RST frame */
43        STREAM_SEND_WUF     = (1 << 4),     /* WUF: Window Update Frame */
44        STREAM_SEND_DATA    = (1 << 5),
45        STREAM_SEND_BLOCKED = (1 << 6),
46        STREAM_SEND_RST     = (1 << 7),     /* Error: want to send RST_STREAM */
47        STREAM_U_READ_DONE  = (1 << 8),     /* User is done reading (shutdown was called) */
48        STREAM_U_WRITE_DONE = (1 << 9),     /* User is done writing (shutdown was called) */
49        STREAM_FIN_SENT     = (1 <<10),     /* FIN was written to network */
50        STREAM_RST_SENT     = (1 <<11),     /* RST_STREAM was written to network */
51        STREAM_UNUSED12     = (1 <<12),     /* Free bit, can be used */
52        STREAM_FIN_REACHED  = (1 <<13),     /* User read data up to FIN */
53        STREAM_FINISHED     = (1 <<14),     /* Stream is finished */
54        STREAM_ONCLOSE_DONE = (1 <<15),     /* on_close has been called */
55        STREAM_CALL_ONCLOSE = (1 <<16),
56        STREAM_FREE_STREAM  = (1 <<17),
57        STREAM_USE_HEADERS  = (1 <<18),
58        STREAM_HEADERS_SENT = (1 <<19),
59        STREAM_HAVE_UH      = (1 <<20),     /* Have uncompressed headers */
60        STREAM_CONN_LIMITED = (1 <<21),
61        STREAM_HEAD_IN_FIN  = (1 <<22),     /* Incoming headers has FIN bit set */
62        STREAM_SAVED_WANTWR = (1 <<23),
63        STREAM_CLOSE_FILE   = (1 <<24),
64        STREAM_FORCE_FINISH = (1 <<25),     /* Replaces FIN sent and received */
65        STREAM_ONNEW_DONE   = (1 <<26),     /* on_new_stream has been called */
66        STREAM_AUTOSWITCH   = (1 <<27),
67        STREAM_RW_ONCE      = (1 <<28),     /* When set, read/write events are dispatched once per call */
68    }                               stream_flags;
69
70    /* There are more than one reason that a stream may be put onto
71     * connections's sending_streams queue:
72     */
73    #define STREAM_SENDING_FLAGS (STREAM_SEND_WUF|STREAM_SEND_DATA| \
74                                          STREAM_SEND_RST|STREAM_SEND_BLOCKED)
75
76    #define STREAM_RW_EVENT_FLAGS (STREAM_WANT_READ|STREAM_WANT_WRITE)
77
78    /* Any of these flags will cause user-facing read and write and
79     * shutdown calls to return an error.  They also make the stream
80     * both readable and writeable, as we want the user to collect
81     * the error.
82     */
83    #define STREAM_RST_FLAGS (STREAM_RST_RECVD|STREAM_RST_SENT|\
84                                                        STREAM_SEND_RST)
85
86    #define STREAM_SERVICE_FLAGS (STREAM_CALL_ONCLOSE|STREAM_FREE_STREAM)
87
88    const struct lsquic_stream_if  *stream_if;
89    struct lsquic_stream_ctx       *st_ctx;
90    struct lsquic_conn_public      *conn_pub;
91    TAILQ_ENTRY(lsquic_stream)      next_send_stream, next_rw_stream,
92                                        next_service_stream, next_prio_stream;
93
94    /* These fields are dealing with data going from user to connection
95     * (out to the network).
96     */
97    struct sbts_tailq               bufs_tosend;
98    uint32_t                        error_code;
99    size_t                          tosend_sz;      /* Data size in bufs_tosend */
100    uint64_t                        tosend_off;
101    uint64_t                        max_send_off;
102
103    /* From the network, we get frames, which we keep on a list ordered
104     * by offset.
105     */
106    struct data_in                 *data_in;
107    uint64_t                        read_offset;
108    lsquic_sfcw_t                   fc;
109
110    /* Last offset sent in BLOCKED frame */
111    uint64_t                        blocked_off;
112
113    /* To write files, user-supplied on_write callback gets swapped out
114     * temporarily.
115     */
116    void                          (*on_write_cb)(struct lsquic_stream *,
117                                                struct lsquic_stream_ctx *);
118
119    struct uncompressed_headers    *uh,
120                                   *push_req;
121
122    /* To let other streams write even as we schedule a large file, it is
123     * written out to sbt queue in chunks.  Intermediate state is stored in
124     * this structure.  Obviously, only one file can be scheduled at a time.
125     * When the file is all written out, the file descriptor is closed and
126     * user-supplied on_write callback gets installed again.
127     */
128    off_t                           file_size;
129    off_t                           file_off;
130    int                             file_fd;
131    unsigned char                   file_byte;
132
133    unsigned char                   sm_priority;  /* 0: high; 255: low */
134#if LSQUIC_KEEP_STREAM_HISTORY
135    sm_hist_idx_t                   sm_hist_idx;
136#endif
137
138    unsigned                        n_unacked;
139
140#if LSQUIC_KEEP_STREAM_HISTORY
141    /* Stream history: see enum stream_history_event */
142    unsigned char                   sm_hist_buf[ 1 << SM_HIST_BITS ];
143#endif
144};
145
146enum stream_ctor_flags
147{
148    SCF_CALL_ON_NEW   = (1 << 0), /* Call on_new_stream() immediately */
149    SCF_USE_DI_HASH   = (1 << 1), /* Use hash-based data input.  If not set,
150                                   * the nocopy data input is used.
151                                   */
152    SCF_DI_AUTOSWITCH = (1 << 2), /* Automatically switch between nocopy
153                                   * and hash-based to data input for optimal
154                                   * performance.
155                                   */
156    SCF_DISP_RW_ONCE  = (1 << 3),
157};
158
159lsquic_stream_t *
160lsquic_stream_new_ext (uint32_t id, struct lsquic_conn_public *conn_pub,
161                       const struct lsquic_stream_if *, void *stream_if_ctx,
162                       unsigned initial_sfrw, unsigned initial_send_off,
163                       enum stream_ctor_flags);
164
165#define lsquic_stream_new(id, pub, sm_if, sm_if_ctx, cfcw, send_off)        \
166        lsquic_stream_new_ext(id, pub, sm_if, sm_if_ctx, cfcw, send_off,    \
167                              (SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH))
168
169void
170lsquic_stream_call_on_new (lsquic_stream_t *, void *stream_if_ctx);
171
172void
173lsquic_stream_destroy (lsquic_stream_t *);
174
175#define lsquic_stream_is_reset(stream) \
176    (!!((stream)->stream_flags & STREAM_RST_FLAGS))
177
178/* Data that from the network gets inserted into the stream using
179 * lsquic_stream_frame_in() function.  Returns 0 on success, -1 on
180 * failure.  The latter may be caused by flow control violation or
181 * invalid stream frame data, e.g. overlapping segments.
182 *
183 * Note that the caller does gives up control of `frame' no matter
184 * what this function returns.
185 *
186 * This data is read by the user using lsquic_stream_read() function.
187 */
188int
189lsquic_stream_frame_in (lsquic_stream_t *, struct stream_frame *frame);
190
191/* Only one (at least for now) uncompressed header structure is allowed to be
192 * passed in, and only in HTTP mode.
193 */
194int
195lsquic_stream_uh_in (lsquic_stream_t *, struct uncompressed_headers *);
196
197void
198lsquic_stream_push_req (lsquic_stream_t *,
199                        struct uncompressed_headers *push_req);
200
201int
202lsquic_stream_rst_in (lsquic_stream_t *, uint64_t offset, uint32_t error_code);
203
204ssize_t
205lsquic_stream_read (lsquic_stream_t *stream, void *buf, size_t len);
206
207uint64_t
208lsquic_stream_read_offset (const lsquic_stream_t *stream);
209
210/* Return true if we sent all available data to the network and write
211 * end of the stream was closed.
212 */
213int
214lsquic_stream_tosend_fin (const lsquic_stream_t *stream);
215
216/* Data to be sent out to the network is written using lsquic_stream_write().
217 */
218ssize_t
219lsquic_stream_write (lsquic_stream_t *stream, const void *buf, size_t len);
220
221void
222lsquic_stream_window_update (lsquic_stream_t *stream, uint64_t offset);
223
224int
225lsquic_stream_set_max_send_off (lsquic_stream_t *stream, unsigned offset);
226
227size_t
228lsquic_stream_tosend_sz (const lsquic_stream_t *);
229
230/* Read data inserted by the client using lsquic_stream_write().
231 */
232size_t
233lsquic_stream_tosend_read (lsquic_stream_t *, void *, size_t, int *);
234
235/* Return current offset associated with data written to network
236 * stream.
237 */
238uint64_t
239lsquic_stream_tosend_offset (const lsquic_stream_t *stream);
240
241/* The caller should only call this function if STREAM_SEND_WUF is set and
242 * it must generate a window update frame using this value.
243 */
244uint64_t
245lsquic_stream_fc_recv_off (lsquic_stream_t *stream);
246
247void
248lsquic_stream_dispatch_rw_events (lsquic_stream_t *);
249
250void
251lsquic_stream_blocked_frame_sent (lsquic_stream_t *);
252
253void
254lsquic_stream_rst_frame_sent (lsquic_stream_t *);
255
256void
257lsquic_stream_stream_frame_sent (lsquic_stream_t *);
258
259void
260lsquic_stream_reset (lsquic_stream_t *, uint32_t error_code);
261
262void
263lsquic_stream_reset_ext (lsquic_stream_t *, uint32_t error_code, int close);
264
265void
266lsquic_stream_call_on_close (lsquic_stream_t *);
267
268void
269lsquic_stream_shutdown_internal (lsquic_stream_t *);
270
271void
272lsquic_stream_received_goaway (lsquic_stream_t *);
273
274void
275lsquic_stream_acked (lsquic_stream_t *);
276
277#define lsquic_stream_is_closed(s)                                          \
278    (((s)->stream_flags & (STREAM_U_READ_DONE|STREAM_U_WRITE_DONE))         \
279                            == (STREAM_U_READ_DONE|STREAM_U_WRITE_DONE))
280int
281lsquic_stream_update_sfcw (lsquic_stream_t *, uint64_t max_off);
282
283int
284lsquic_stream_set_priority_internal (lsquic_stream_t *, unsigned priority);
285
286/* The following flags are checked to see whether progress was made: */
287#define STREAM_RW_PROG_FLAGS (                                              \
288    STREAM_U_READ_DONE  /* User closed read side of the stream */           \
289   |STREAM_FIN_REACHED  /* User reached FIN.  We check this because it */   \
290                        /*   may have been a result of zero-byte read. */   \
291)
292
293/* Stream progress status is used to judge whether a connection made progress
294 * during Pending RW Queue processing.  We only check for stream read progress,
295 * as the write progress is defined as any new data packetized for sending.
296 */
297struct stream_rw_prog_status
298{
299    uint64_t                srps_read_offset;
300    enum stream_flags       srps_flags;
301};
302
303#define lsquic_stream_get_rw_prog_status(stream, stats) do {                \
304    (stats)->srps_read_offset = (stream)->read_offset;                      \
305    (stats)->srps_flags       =                                             \
306                        (stream)->stream_flags & STREAM_RW_PROG_FLAGS;      \
307} while (0)
308
309#define lsquic_stream_progress_was_made(stream, stats) (                    \
310    (stats)->srps_read_offset != (stream)->read_offset                      \
311 || (stats)->srps_flags       !=                                            \
312                        ((stream)->stream_flags & STREAM_RW_PROG_FLAGS)     \
313)
314
315#endif //__LSQUIC_STREAM_H__
316
317