lsquic_stream.h revision 92f6e17b
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2#ifndef LSQUIC_STREAM_H
3#define LSQUIC_STREAM_H
4
5#define LSQUIC_GQUIC_STREAM_HANDSHAKE 1
6#define LSQUIC_GQUIC_STREAM_HEADERS   3
7
8#define LSQUIC_STREAM_DEFAULT_PRIO 16   /* RFC 7540, Section 5.3.5 */
9
10
11struct lsquic_stream_if;
12struct lsquic_stream_ctx;
13struct lsquic_conn_public;
14struct stream_frame;
15struct uncompressed_headers;
16enum enc_level;
17enum swtp_status;
18struct frame_gen_ctx;
19struct data_frame;
20enum quic_frame_type;
21struct push_promise;
22
23TAILQ_HEAD(lsquic_streams_tailq, lsquic_stream);
24
25
26#ifndef LSQUIC_KEEP_STREAM_HISTORY
27#   ifdef NDEBUG
28#       define LSQUIC_KEEP_STREAM_HISTORY 0
29#   else
30#       define LSQUIC_KEEP_STREAM_HISTORY 1
31#   endif
32#endif
33
34
35#if LSQUIC_KEEP_STREAM_HISTORY
36#define SM_HIST_BITS 6
37#define SM_HIST_IDX_MASK ((1 << SM_HIST_BITS) - 1)
38typedef unsigned char sm_hist_idx_t;
39#endif
40
41
42/*
43 *  +----------+----------------------------------+
44 *  | Low Bits | Stream Type                      |
45 *  +----------+----------------------------------+
46 *  | 0x0      | Client-Initiated, Bidirectional  |
47 *  |          |                                  |
48 *  | 0x1      | Server-Initiated, Bidirectional  |
49 *  |          |                                  |
50 *  | 0x2      | Client-Initiated, Unidirectional |
51 *  |          |                                  |
52 *  | 0x3      | Server-Initiated, Unidirectional |
53 *  +----------+----------------------------------+
54 */
55
56enum stream_id_type
57{
58    SIT_BIDI_CLIENT,
59    SIT_BIDI_SERVER,
60    SIT_UNI_CLIENT,
61    SIT_UNI_SERVER,
62    N_SITS
63};
64
65#define SIT_MASK (N_SITS - 1)
66
67#define SIT_SHIFT 2
68#define SD_SHIFT 1
69
70enum stream_dir { SD_BIDI, SD_UNI, N_SDS };
71
72
73struct stream_hq_frame
74{
75    STAILQ_ENTRY(stream_hq_frame)
76                        shf_next;
77    /* At which point in the stream (sm_payload) to insert the HQ frame. */
78    uint64_t            shf_off;
79    union {
80        /* Points to the frame if SHF_FIXED_SIZE is not set */
81        unsigned char  *frame_ptr;
82        /* If SHF_FIXED_SIZE is set, the size of the frame to follow.
83         * Non-fixed frame size gets calculated using sm_payload when they
84         * are closed.
85         */
86        size_t          frame_size;
87    }                   shf_u;
88#define shf_frame_ptr shf_u.frame_ptr
89#define shf_frame_size shf_u.frame_size
90    enum hq_frame_type  shf_frame_type:8;
91    enum shf_flags {
92        SHF_TWO_BYTES   = 1 << 0,   /* Use two byte to encode frame length */
93        SHF_FIXED_SIZE  = 1 << 1,   /* Payload size guaranteed */
94        SHF_ACTIVE      = 1 << 2,   /* On sm_hq_frames list */
95        SHF_WRITTEN     = 1 << 3,   /* Framing bytes have been packetized */
96        SHF_CC_PAID     = 1 << 4,   /* Paid connection cap */
97        SHF_PHANTOM     = 1 << 5,   /* Phantom frame headers are not written */
98    }                   shf_flags:8;
99};
100
101
102struct hq_filter
103{
104    struct varint_read2_state   hqfi_vint_state;
105    /* No need to copy the values: use it directly */
106#define hqfi_left hqfi_vint_state.vr2s_two
107#define hqfi_type hqfi_vint_state.vr2s_one
108    enum {
109        HQFI_FLAG_GOT_HEADERS   = 1 << 0,
110        HQFI_FLAG_ERROR         = 1 << 1,
111        HQFI_FLAG_BEGIN         = 1 << 2,
112        HQFI_FLAG_BLOCKED       = 1 << 3,
113    }                           hqfi_flags:8;
114    enum {
115        HQFI_STATE_FRAME_HEADER_BEGIN,
116        HQFI_STATE_FRAME_HEADER_CONTINUE,
117        HQFI_STATE_READING_PAYLOAD,
118    }                           hqfi_state:8;
119    unsigned char               hqfi_hist_idx;
120#define MAX_HQFI_ENTRIES (sizeof(unsigned) * 8 / 3)
121    unsigned                    hqfi_hist_buf;
122};
123
124
125struct stream_filter_if
126{
127    int         (*sfi_readable)(struct lsquic_stream *);
128    size_t      (*sfi_filter_df)(struct lsquic_stream *, struct data_frame *);
129    void        (*sfi_decr_left)(struct lsquic_stream *, size_t);
130};
131
132
133/* These flags indicate which queues -- or other entities -- currently
134 * reference the stream.
135 */
136enum stream_q_flags
137{
138    /* read_streams: */
139    SMQF_WANT_READ    = 1 << 0,
140
141    /* write_streams: */
142#define SMQF_WRITE_Q_FLAGS (SMQF_WANT_FLUSH|SMQF_WANT_WRITE)
143    SMQF_WANT_WRITE   = 1 << 1,
144    SMQF_WANT_FLUSH   = 1 << 2,     /* Flush until sm_flush_to is hit */
145
146    /* There are more than one reason that a stream may be put onto
147     * connections's sending_streams queue.  Note that writing STREAM
148     * frames is done separately.
149     */
150#define SMQF_SENDING_FLAGS (SMQF_SEND_WUF|SMQF_SEND_RST|SMQF_SEND_BLOCKED)
151    /* sending_streams: */
152    SMQF_SEND_WUF     = 1 << 3,     /* WUF: Window Update Frame */
153    SMQF_SEND_BLOCKED = 1 << 4,
154    SMQF_SEND_RST     = 1 << 5,     /* Error: want to send RST_STREAM */
155
156    /* The equivalent of WINDOW_UPDATE frame for streams in IETF QUIC is
157     * the MAX_STREAM_DATA frame.  Define an alias for use in the IETF
158     * QUIC code:
159     */
160#define SMQF_SEND_MAX_STREAM_DATA SMQF_SEND_WUF
161
162#define SMQF_SERVICE_FLAGS (SMQF_CALL_ONCLOSE|SMQF_FREE_STREAM|SMQF_ABORT_CONN)
163    SMQF_CALL_ONCLOSE = 1 << 6,
164    SMQF_FREE_STREAM  = 1 << 7,
165    SMQF_ABORT_CONN   = 1 << 8,     /* Unrecoverable error occurred */
166
167    SMQF_QPACK_DEC    = 1 << 9,     /* QPACK decoder is holding a reference to this stream */
168};
169
170
171/* Stream behavior flags */
172enum stream_b_flags
173{
174    SMBF_SERVER       = 1 << 0,
175    SMBF_IETF         = 1 << 1,
176    SMBF_USE_HEADERS  = 1 << 2,
177    SMBF_CRYPTO       = 1 << 3,
178    SMBF_CRITICAL     = 1 << 4,  /* This is a critical stream */
179    SMBF_AUTOSWITCH   = 1 << 5,
180    SMBF_RW_ONCE      = 1 << 6,  /* When set, read/write events are dispatched once per call */
181    SMBF_CONN_LIMITED = 1 << 7,
182#define N_SMBF_FLAGS 8
183};
184
185
186enum stream_flags {
187    STREAM_FIN_RECVD    = 1 << 0,   /* Received STREAM frame with FIN bit set */
188    STREAM_RST_RECVD    = 1 << 1,   /* Received RST frame */
189    STREAM_LAST_WRITE_OK= 1 << 2,   /* Used to break out of write event dispatch loop */
190    STREAM_U_READ_DONE  = 1 << 3,   /* User is done reading (shutdown was called) */
191    STREAM_U_WRITE_DONE = 1 << 4,   /* User is done writing (shutdown was called) */
192    STREAM_FIN_SENT     = 1 << 5,   /* FIN was written to network */
193    STREAM_RST_SENT     = 1 << 6,   /* RST_STREAM was written to network */
194    STREAM_FIN_REACHED  = 1 << 7,   /* User read data up to FIN */
195    STREAM_FINISHED     = 1 << 8,   /* Stream is finished */
196    STREAM_ONCLOSE_DONE = 1 << 9,   /* on_close has been called */
197    STREAM_UNUSED10     = 1 << 10,  /* Unused */
198    STREAM_HEADERS_SENT = 1 << 11,
199    STREAM_HAVE_UH      = 1 << 12,  /* Have uncompressed headers */
200    STREAM_UNUSED13     = 1 << 13,  /* Unused */
201    STREAM_HEAD_IN_FIN  = 1 << 14,  /* Incoming headers has FIN bit set */
202    STREAM_FRAMES_ELIDED= 1 << 15,
203    STREAM_FORCE_FINISH = 1 << 16,  /* Replaces FIN sent and received */
204    STREAM_ONNEW_DONE   = 1 << 17,  /* on_new_stream has been called */
205    STREAM_PUSHING      = 1 << 18,
206    STREAM_NOPUSH       = 1 << 19,  /* Disallow further push promises */
207    STREAM_UNUSED20     = 1 << 20,  /* Unused */
208    STREAM_UNUSED21     = 1 << 21,  /* Unused */
209    STREAM_RST_ACKED    = 1 << 22,  /* Packet containing RST has been acked */
210    STREAM_BLOCKED_SENT = 1 << 23,  /* Stays set once a STREAM_BLOCKED frame is sent */
211    STREAM_RST_READ     = 1 << 24,  /* User code collected the error */
212    STREAM_DATA_RECVD   = 1 << 25,  /* Cache stream state calculation */
213    STREAM_UNUSED26     = 1 << 26,  /* Unused */
214    STREAM_HDRS_FLUSHED = 1 << 27,  /* Only used in buffered packets mode */
215    STREAM_SS_RECVD     = 1 << 28,  /* Received STOP_SENDING frame */
216    STREAM_DELAYED_SW   = 1 << 29,  /* Delayed shutdown_write call */
217};
218
219
220/* By keeping this number low, we make sure that the code to allocate HQ
221 * frames dynamically gets exercised whenever push promises are sent.
222 */
223#define NUM_ALLOCED_HQ_FRAMES 2
224
225
226struct lsquic_stream
227{
228    struct lsquic_hash_elem         sm_hash_el;
229    lsquic_stream_id_t              id;
230    enum stream_flags               stream_flags;
231    enum stream_b_flags             sm_bflags;
232    enum stream_q_flags             sm_qflags;
233    unsigned                        n_unacked;
234
235    const struct lsquic_stream_if  *stream_if;
236    struct lsquic_stream_ctx       *st_ctx;
237    struct lsquic_conn_public      *conn_pub;
238    TAILQ_ENTRY(lsquic_stream)      next_send_stream, next_read_stream,
239                                        next_write_stream, next_service_stream,
240                                        next_prio_stream;
241
242    uint64_t                        tosend_off;
243    uint64_t                        sm_payload;     /* Not counting HQ frames */
244    uint64_t                        max_send_off;
245    uint64_t                        sm_last_recv_off;
246    uint64_t                        error_code;
247
248    /* From the network, we get frames, which we keep on a list ordered
249     * by offset.
250     */
251    struct data_in                 *data_in;
252    uint64_t                        read_offset;
253    lsquic_sfcw_t                   fc;
254
255    /* List of active HQ frames */
256    STAILQ_HEAD(, stream_hq_frame)  sm_hq_frames;
257
258    /* For efficiency, several frames are allocated as part of the stream
259     * itself.  If more frames are needed, they are allocated.
260     */
261    struct stream_hq_frame          sm_hq_frame_arr[NUM_ALLOCED_HQ_FRAMES];
262
263    struct hq_filter                sm_hq_filter;
264
265    /* We can safely use sm_hq_filter */
266#define sm_uni_type_state sm_hq_filter.hqfi_vint_state.vr2s_varint_state
267
268    /** If @ref SMQF_WANT_FLUSH is set, flush until this offset. */
269    uint64_t                        sm_flush_to;
270
271    /**
272     * If @ref SMQF_WANT_FLUSH is set, this indicates payload offset
273     * to flush to.  Used to adjust @ref sm_flush_to when H3 frame
274     * size grows.
275     */
276    uint64_t                        sm_flush_to_payload;
277
278    /* Last offset sent in BLOCKED frame */
279    uint64_t                        blocked_off;
280
281    struct uncompressed_headers    *uh,
282                                   *push_req;
283
284    unsigned char                  *sm_buf;
285    void                           *sm_onnew_arg;
286
287    unsigned char                  *sm_header_block;
288    uint64_t                        sm_hb_compl;
289
290    /* Valid if STREAM_FIN_RECVD is set: */
291    uint64_t                        sm_fin_off;
292
293    /* A stream may be generating STREAM or CRYPTO frames */
294    size_t                        (*sm_frame_header_sz)(
295                                        const struct lsquic_stream *, unsigned);
296    enum swtp_status              (*sm_write_to_packet)(struct frame_gen_ctx *,
297                                                const size_t);
298    size_t                        (*sm_write_avail)(struct lsquic_stream *);
299    int                           (*sm_readable)(struct lsquic_stream *);
300
301    /* This element is optional */
302    const struct stream_filter_if  *sm_sfi;
303
304    /* sm_promise and sm_promises are never used at the same time and can
305     * be combined into a union should space in this struct become tight.
306     */
307    /* Push promise that engendered this push stream */
308    struct push_promise            *sm_promise;
309
310    /* Push promises sent on this stream */
311    SLIST_HEAD(, push_promise)      sm_promises;
312
313    /* How much data there is in sm_header_block and how much of it has been
314     * sent:
315     */
316    unsigned                        sm_hblock_sz,
317                                    sm_hblock_off;
318
319    unsigned short                  sm_n_buffered;  /* Amount of data in sm_buf */
320    unsigned short                  sm_n_allocated;  /* Size of sm_buf */
321
322    unsigned char                   sm_priority;  /* 0: high; 255: low */
323    unsigned char                   sm_enc_level;
324    enum {
325        SSHS_BEGIN,         /* Nothing has happened yet */
326        SSHS_ENC_SENDING,   /* Sending encoder stream data */
327        SSHS_HBLOCK_SENDING,/* Sending header block data */
328    }                               sm_send_headers_state:8;
329    signed char                     sm_saved_want_write;
330
331    unsigned char                   sm_dup_push_off;
332    unsigned char                   sm_dup_push_len;
333    unsigned char                   sm_dup_push_buf[8];
334
335#if LSQUIC_KEEP_STREAM_HISTORY
336    sm_hist_idx_t                   sm_hist_idx;
337#endif
338
339#if LSQUIC_KEEP_STREAM_HISTORY
340    /* Stream history: see enum stream_history_event */
341    unsigned char                   sm_hist_buf[ 1 << SM_HIST_BITS ];
342#endif
343};
344
345
346enum stream_ctor_flags
347{
348    SCF_CALL_ON_NEW   = (1 << (N_SMBF_FLAGS + 0)), /* Call on_new_stream() immediately */
349    SCF_USE_DI_HASH   = (1 << (N_SMBF_FLAGS + 1)), /* Use hash-based data input.  If not set,
350                                   * the nocopy data input is used.
351                                   */
352    SCF_DI_AUTOSWITCH = SMBF_AUTOSWITCH, /* Automatically switch between nocopy
353                                   * and hash-based to data input for optimal
354                                   * performance.
355                                   */
356    SCF_DISP_RW_ONCE  = SMBF_RW_ONCE,
357    SCF_CRITICAL      = SMBF_CRITICAL, /* This is a critical stream */
358    SCF_IETF          = SMBF_IETF,
359    SCF_HTTP          = SMBF_USE_HEADERS,
360};
361
362
363lsquic_stream_t *
364lsquic_stream_new (lsquic_stream_id_t id, struct lsquic_conn_public *,
365                   const struct lsquic_stream_if *, void *stream_if_ctx,
366                   unsigned initial_sfrw, uint64_t initial_send_off,
367                   enum stream_ctor_flags);
368
369struct lsquic_stream *
370lsquic_stream_new_crypto (enum enc_level,
371        struct lsquic_conn_public *conn_pub,
372        const struct lsquic_stream_if *stream_if, void *stream_if_ctx,
373        enum stream_ctor_flags ctor_flags);
374
375void
376lsquic_stream_call_on_new (lsquic_stream_t *);
377
378void
379lsquic_stream_destroy (lsquic_stream_t *);
380
381/* Any of these flags will cause user-facing read and write and
382 * shutdown calls to return an error.  They also make the stream
383 * both readable and writeable, as we want the user to collect
384 * the error.
385 */
386#define lsquic_stream_is_reset(stream) \
387    (((stream)->stream_flags & \
388                    (STREAM_RST_RECVD|STREAM_RST_SENT|STREAM_SS_RECVD)) \
389        || ((stream)->sm_qflags & SMQF_SEND_RST))
390
391/* Data that from the network gets inserted into the stream using
392 * lsquic_stream_frame_in() function.  Returns 0 on success, -1 on
393 * failure.  The latter may be caused by flow control violation or
394 * invalid stream frame data, e.g. overlapping segments.
395 *
396 * Note that the caller does gives up control of `frame' no matter
397 * what this function returns.
398 *
399 * This data is read by the user using lsquic_stream_read() function.
400 */
401int
402lsquic_stream_frame_in (lsquic_stream_t *, struct stream_frame *frame);
403
404/* Only one (at least for now) uncompressed header structure is allowed to be
405 * passed in, and only in HTTP mode.
406 */
407int
408lsquic_stream_uh_in (lsquic_stream_t *, struct uncompressed_headers *);
409
410void
411lsquic_stream_push_req (lsquic_stream_t *,
412                        struct uncompressed_headers *push_req);
413
414int
415lsquic_stream_rst_in (lsquic_stream_t *, uint64_t offset, uint64_t error_code);
416
417void
418lsquic_stream_stop_sending_in (struct lsquic_stream *, uint64_t error_code);
419
420ssize_t
421lsquic_stream_read (lsquic_stream_t *stream, void *buf, size_t len);
422
423uint64_t
424lsquic_stream_read_offset (const lsquic_stream_t *stream);
425
426/* Return true if we sent all available data to the network and write
427 * end of the stream was closed.
428 */
429int
430lsquic_stream_tosend_fin (const lsquic_stream_t *stream);
431
432/* Data to be sent out to the network is written using lsquic_stream_write().
433 */
434ssize_t
435lsquic_stream_write (lsquic_stream_t *stream, const void *buf, size_t len);
436
437void
438lsquic_stream_window_update (lsquic_stream_t *stream, uint64_t offset);
439
440int
441lsquic_stream_set_max_send_off (lsquic_stream_t *stream, uint64_t offset);
442
443/* The caller should only call this function if SMQF_SEND_WUF is set and
444 * it must generate a window update frame using this value.
445 */
446uint64_t
447lsquic_stream_fc_recv_off (lsquic_stream_t *stream);
448
449void
450lsquic_stream_peer_blocked (struct lsquic_stream *, uint64_t);
451
452void
453lsquic_stream_peer_blocked_gquic (struct lsquic_stream *);
454
455void
456lsquic_stream_dispatch_read_events (lsquic_stream_t *);
457
458void
459lsquic_stream_dispatch_write_events (lsquic_stream_t *);
460
461void
462lsquic_stream_blocked_frame_sent (lsquic_stream_t *);
463
464void
465lsquic_stream_rst_frame_sent (lsquic_stream_t *);
466
467void
468lsquic_stream_stream_frame_sent (lsquic_stream_t *);
469
470void
471lsquic_stream_reset (lsquic_stream_t *, uint64_t error_code);
472
473void
474lsquic_stream_reset_ext (lsquic_stream_t *, uint64_t error_code, int close);
475
476void
477lsquic_stream_call_on_close (lsquic_stream_t *);
478
479void
480lsquic_stream_shutdown_internal (lsquic_stream_t *);
481
482void
483lsquic_stream_received_goaway (lsquic_stream_t *);
484
485void
486lsquic_stream_acked (struct lsquic_stream *, enum quic_frame_type);
487
488#define lsquic_stream_is_closed(s)                                          \
489    (((s)->stream_flags & (STREAM_U_READ_DONE|STREAM_U_WRITE_DONE))         \
490                            == (STREAM_U_READ_DONE|STREAM_U_WRITE_DONE))
491int
492lsquic_stream_update_sfcw (lsquic_stream_t *, uint64_t max_off);
493
494int
495lsquic_stream_set_priority_internal (lsquic_stream_t *, unsigned priority);
496
497int
498lsquic_stream_id_is_critical (int use_http, lsquic_stream_id_t);
499
500int
501lsquic_stream_is_critical (const struct lsquic_stream *);
502
503size_t
504lsquic_stream_mem_used (const struct lsquic_stream *);
505
506const lsquic_cid_t *
507lsquic_stream_cid (const struct lsquic_stream *);
508
509#define lsquic_stream_has_data_to_flush(stream) ((stream)->sm_n_buffered > 0)
510
511int
512lsquic_stream_readable (struct lsquic_stream *);
513
514size_t
515lsquic_stream_write_avail (struct lsquic_stream *);
516
517void
518lsquic_stream_dump_state (const struct lsquic_stream *);
519
520#ifndef NDEBUG
521size_t
522lsquic_stream_flush_threshold (const struct lsquic_stream *, unsigned);
523#endif
524
525#define crypto_level(stream) (~0ULL - (stream)->id)
526
527void
528lsquic_stream_set_stream_if (struct lsquic_stream *,
529                   const struct lsquic_stream_if *, void *stream_if_ctx);
530
531struct qpack_dec_hdl *
532lsquic_stream_get_qdh (const struct lsquic_stream *);
533
534uint64_t
535lsquic_stream_combined_send_off (const struct lsquic_stream *);
536
537/* [draft-ietf-quic-transport-16] Section 3.1 */
538enum stream_state_sending
539{
540    SSS_READY,
541    SSS_SEND,
542    SSS_DATA_SENT,
543    SSS_RESET_SENT,
544    SSS_DATA_RECVD,
545    SSS_RESET_RECVD,
546};
547
548extern const char *const lsquic_sss2str[];
549
550enum stream_state_sending
551lsquic_stream_sending_state (const struct lsquic_stream *);
552
553/* [draft-ietf-quic-transport-16] Section 3.2 */
554enum stream_state_receiving
555{
556    SSR_RECV,
557    SSR_SIZE_KNOWN,
558    SSR_DATA_RECVD,
559    SSR_RESET_RECVD,
560    SSR_DATA_READ,
561    SSR_RESET_READ,
562};
563
564extern const char *const lsquic_ssr2str[];
565
566enum stream_state_receiving
567lsquic_stream_receiving_state (struct lsquic_stream *);
568
569uint64_t
570lsquic_stream_fc_recv_off_const (const struct lsquic_stream *);
571
572void
573lsquic_stream_max_stream_data_sent (struct lsquic_stream *);
574
575void
576lsquic_stream_qdec_unblocked (struct lsquic_stream *);
577
578int
579lsquic_stream_can_push (const struct lsquic_stream *);
580
581int
582lsquic_stream_duplicate_push (struct lsquic_stream *, uint64_t push_id);
583
584int
585lsquic_stream_push_promise (struct lsquic_stream *, struct push_promise *);
586
587#endif
588