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