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