1 /* 2 * nghttp3 3 * 4 * Copyright (c) 2019 nghttp3 contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef NGHTTP3_STREAM_H 26 #define NGHTTP3_STREAM_H 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif /* HAVE_CONFIG_H */ 31 32 #include <nghttp3/nghttp3.h> 33 34 #include "nghttp3_map.h" 35 #include "nghttp3_tnode.h" 36 #include "nghttp3_ringbuf.h" 37 #include "nghttp3_buf.h" 38 #include "nghttp3_frame.h" 39 #include "nghttp3_qpack.h" 40 41 #define NGHTTP3_STREAM_MIN_CHUNK_SIZE 256 42 43 /* NGHTTP3_MIN_UNSENT_BYTES is the minimum unsent bytes which is large 44 enough to fill outgoing single QUIC packet. */ 45 #define NGHTTP3_MIN_UNSENT_BYTES 4096 46 47 /* NGHTTP3_STREAM_MIN_WRITELEN is the minimum length of write to cause 48 the stream to reschedule. */ 49 #define NGHTTP3_STREAM_MIN_WRITELEN 800 50 51 /* nghttp3_stream_type is unidirectional stream type. */ 52 typedef enum nghttp3_stream_type { 53 NGHTTP3_STREAM_TYPE_CONTROL = 0x00, 54 NGHTTP3_STREAM_TYPE_PUSH = 0x01, 55 NGHTTP3_STREAM_TYPE_QPACK_ENCODER = 0x02, 56 NGHTTP3_STREAM_TYPE_QPACK_DECODER = 0x03, 57 NGHTTP3_STREAM_TYPE_UNKNOWN = UINT64_MAX, 58 } nghttp3_stream_type; 59 60 typedef enum nghttp3_ctrl_stream_state { 61 NGHTTP3_CTRL_STREAM_STATE_FRAME_TYPE, 62 NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH, 63 NGHTTP3_CTRL_STREAM_STATE_SETTINGS, 64 NGHTTP3_CTRL_STREAM_STATE_GOAWAY, 65 NGHTTP3_CTRL_STREAM_STATE_MAX_PUSH_ID, 66 NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME, 67 NGHTTP3_CTRL_STREAM_STATE_SETTINGS_ID, 68 NGHTTP3_CTRL_STREAM_STATE_SETTINGS_VALUE, 69 NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE_PRI_ELEM_ID, 70 NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE, 71 } nghttp3_ctrl_stream_state; 72 73 typedef enum nghttp3_req_stream_state { 74 NGHTTP3_REQ_STREAM_STATE_FRAME_TYPE, 75 NGHTTP3_REQ_STREAM_STATE_FRAME_LENGTH, 76 NGHTTP3_REQ_STREAM_STATE_DATA, 77 NGHTTP3_REQ_STREAM_STATE_HEADERS, 78 NGHTTP3_REQ_STREAM_STATE_IGN_FRAME, 79 NGHTTP3_REQ_STREAM_STATE_IGN_REST, 80 } nghttp3_req_stream_state; 81 82 typedef struct nghttp3_varint_read_state { 83 int64_t acc; 84 size_t left; 85 } nghttp3_varint_read_state; 86 87 typedef struct nghttp3_stream_read_state { 88 nghttp3_varint_read_state rvint; 89 nghttp3_frame fr; 90 int state; 91 int64_t left; 92 } nghttp3_stream_read_state; 93 94 /* NGHTTP3_STREAM_FLAG_NONE indicates that no flag is set. */ 95 #define NGHTTP3_STREAM_FLAG_NONE 0x0000 96 /* NGHTTP3_STREAM_FLAG_TYPE_IDENTIFIED is set when a unidirectional 97 stream type is identified. */ 98 #define NGHTTP3_STREAM_FLAG_TYPE_IDENTIFIED 0x0001 99 /* NGHTTP3_STREAM_FLAG_FC_BLOCKED indicates that stream is blocked by 100 QUIC flow control. */ 101 #define NGHTTP3_STREAM_FLAG_FC_BLOCKED 0x0002 102 /* NGHTTP3_STREAM_FLAG_READ_DATA_BLOCKED indicates that application is 103 temporarily unable to provide data. */ 104 #define NGHTTP3_STREAM_FLAG_READ_DATA_BLOCKED 0x0004 105 /* NGHTTP3_STREAM_FLAG_WRITE_END_STREAM indicates that application 106 finished to feed outgoing data. */ 107 #define NGHTTP3_STREAM_FLAG_WRITE_END_STREAM 0x0008 108 /* NGHTTP3_STREAM_FLAG_QPACK_DECODE_BLOCKED indicates that stream is 109 blocked due to QPACK decoding. */ 110 #define NGHTTP3_STREAM_FLAG_QPACK_DECODE_BLOCKED 0x0010 111 /* NGHTTP3_STREAM_FLAG_READ_EOF indicates that remote endpoint sent 112 fin. */ 113 #define NGHTTP3_STREAM_FLAG_READ_EOF 0x0020 114 /* NGHTTP3_STREAM_FLAG_CLOSED indicates that QUIC stream was closed. 115 nghttp3_stream object can still alive because it might be blocked 116 by QPACK decoder. */ 117 #define NGHTTP3_STREAM_FLAG_CLOSED 0x0040 118 /* NGHTTP3_STREAM_FLAG_SHUT_WR indicates that any further write 119 operation to a stream is prohibited. */ 120 #define NGHTTP3_STREAM_FLAG_SHUT_WR 0x0100 121 /* NGHTTP3_STREAM_FLAG_SHUT_RD indicates that a read-side stream is 122 closed abruptly and any incoming and pending stream data is just 123 discarded for a stream. */ 124 #define NGHTTP3_STREAM_FLAG_SHUT_RD 0x0200 125 /* NGHTTP3_STREAM_FLAG_SERVER_PRIORITY_SET indicates that server 126 overrides stream priority. */ 127 #define NGHTTP3_STREAM_FLAG_SERVER_PRIORITY_SET 0x0400 128 129 typedef enum nghttp3_stream_http_state { 130 NGHTTP3_HTTP_STATE_NONE, 131 NGHTTP3_HTTP_STATE_REQ_INITIAL, 132 NGHTTP3_HTTP_STATE_REQ_BEGIN, 133 NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN, 134 NGHTTP3_HTTP_STATE_REQ_HEADERS_END, 135 NGHTTP3_HTTP_STATE_REQ_DATA_BEGIN, 136 NGHTTP3_HTTP_STATE_REQ_DATA_END, 137 NGHTTP3_HTTP_STATE_REQ_TRAILERS_BEGIN, 138 NGHTTP3_HTTP_STATE_REQ_TRAILERS_END, 139 NGHTTP3_HTTP_STATE_REQ_END, 140 NGHTTP3_HTTP_STATE_RESP_INITIAL, 141 NGHTTP3_HTTP_STATE_RESP_BEGIN, 142 NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN, 143 NGHTTP3_HTTP_STATE_RESP_HEADERS_END, 144 NGHTTP3_HTTP_STATE_RESP_DATA_BEGIN, 145 NGHTTP3_HTTP_STATE_RESP_DATA_END, 146 NGHTTP3_HTTP_STATE_RESP_TRAILERS_BEGIN, 147 NGHTTP3_HTTP_STATE_RESP_TRAILERS_END, 148 NGHTTP3_HTTP_STATE_RESP_END, 149 } nghttp3_stream_http_state; 150 151 typedef enum nghttp3_stream_http_event { 152 NGHTTP3_HTTP_EVENT_DATA_BEGIN, 153 NGHTTP3_HTTP_EVENT_DATA_END, 154 NGHTTP3_HTTP_EVENT_HEADERS_BEGIN, 155 NGHTTP3_HTTP_EVENT_HEADERS_END, 156 NGHTTP3_HTTP_EVENT_MSG_END, 157 } nghttp3_stream_http_event; 158 159 typedef struct nghttp3_stream nghttp3_stream; 160 161 /* 162 * nghttp3_stream_acked_data is a callback function which is invoked 163 * when data sent on stream denoted by |stream_id| supplied from 164 * application is acknowledged by remote endpoint. The number of 165 * bytes acknowledged is given in |datalen|. 166 * 167 * The implementation of this callback must return 0 if it succeeds. 168 * Returning NGHTTP3_ERR_CALLBACK_FAILURE will return to the caller 169 * immediately. Any values other than 0 is treated as 170 * NGHTTP3_ERR_CALLBACK_FAILURE. 171 */ 172 typedef int (*nghttp3_stream_acked_data)(nghttp3_stream *stream, 173 int64_t stream_id, uint64_t datalen, 174 void *user_data); 175 176 typedef struct nghttp3_stream_callbacks { 177 nghttp3_stream_acked_data acked_data; 178 } nghttp3_stream_callbacks; 179 180 typedef struct nghttp3_http_state { 181 /* status_code is HTTP status code received. This field is used 182 if connection is initialized as client. */ 183 int32_t status_code; 184 /* content_length is the value of received content-length header 185 field. */ 186 int64_t content_length; 187 /* recv_content_length is the number of body bytes received so 188 far. */ 189 int64_t recv_content_length; 190 uint16_t flags; 191 /* pri is a stream priority produced by nghttp3_pri_to_uint8. */ 192 uint8_t pri; 193 } nghttp3_http_state; 194 195 struct nghttp3_stream { 196 const nghttp3_mem *mem; 197 nghttp3_tnode node; 198 nghttp3_pq_entry qpack_blocked_pe; 199 nghttp3_stream_callbacks callbacks; 200 nghttp3_ringbuf frq; 201 nghttp3_ringbuf chunks; 202 nghttp3_ringbuf outq; 203 /* inq stores the stream raw data which cannot be read because 204 stream is blocked by QPACK decoder. */ 205 nghttp3_ringbuf inq; 206 nghttp3_qpack_stream_context qpack_sctx; 207 /* conn is a reference to underlying connection. It could be NULL 208 if stream is not a request stream. */ 209 nghttp3_conn *conn; 210 void *user_data; 211 /* unsent_bytes is the number of bytes in outq not written yet */ 212 uint64_t unsent_bytes; 213 /* outq_idx is an index into outq where next write is made. */ 214 size_t outq_idx; 215 /* outq_offset is write offset relative to the element at outq_idx 216 in outq. */ 217 uint64_t outq_offset; 218 /* ack_offset is offset acknowledged by peer relative to the first 219 element in outq. */ 220 uint64_t ack_offset; 221 /* ack_done is the number of bytes notified to an application that 222 they are acknowledged inside the first outq element if it is of 223 type NGHTTP3_BUF_TYPE_ALIEN. */ 224 uint64_t ack_done; 225 uint64_t unscheduled_nwrite; 226 nghttp3_stream_type type; 227 nghttp3_stream_read_state rstate; 228 /* error_code indicates the reason of closure of this stream. */ 229 uint64_t error_code; 230 231 struct { 232 uint64_t offset; 233 nghttp3_stream_http_state hstate; 234 } tx; 235 236 struct { 237 nghttp3_stream_http_state hstate; 238 nghttp3_http_state http; 239 } rx; 240 241 uint16_t flags; 242 }; 243 244 typedef struct nghttp3_frame_entry { 245 nghttp3_frame fr; 246 union { 247 struct { 248 nghttp3_settings *local_settings; 249 } settings; 250 struct { 251 nghttp3_data_reader dr; 252 } data; 253 } aux; 254 } nghttp3_frame_entry; 255 256 int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id, 257 uint64_t seq, const nghttp3_stream_callbacks *callbacks, 258 const nghttp3_mem *mem); 259 260 void nghttp3_stream_del(nghttp3_stream *stream); 261 262 void nghttp3_varint_read_state_reset(nghttp3_varint_read_state *rvint); 263 264 void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate); 265 266 nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint, 267 const uint8_t *src, size_t srclen, int fin); 268 269 int nghttp3_stream_frq_add(nghttp3_stream *stream, 270 const nghttp3_frame_entry *frent); 271 272 int nghttp3_stream_fill_outq(nghttp3_stream *stream); 273 274 int nghttp3_stream_write_stream_type(nghttp3_stream *stream); 275 276 nghttp3_ssize nghttp3_stream_writev(nghttp3_stream *stream, int *pfin, 277 nghttp3_vec *vec, size_t veccnt); 278 279 int nghttp3_stream_write_qpack_decoder_stream(nghttp3_stream *stream); 280 281 int nghttp3_stream_outq_is_full(nghttp3_stream *stream); 282 283 int nghttp3_stream_outq_add(nghttp3_stream *stream, 284 const nghttp3_typed_buf *tbuf); 285 286 int nghttp3_stream_write_headers(nghttp3_stream *stream, 287 nghttp3_frame_entry *frent); 288 289 int nghttp3_stream_write_header_block(nghttp3_stream *stream, 290 nghttp3_qpack_encoder *qenc, 291 nghttp3_stream *qenc_stream, 292 nghttp3_buf *rbuf, nghttp3_buf *ebuf, 293 int64_t frame_type, const nghttp3_nv *nva, 294 size_t nvlen); 295 296 int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof, 297 nghttp3_frame_entry *frent); 298 299 int nghttp3_stream_write_settings(nghttp3_stream *stream, 300 nghttp3_frame_entry *frent); 301 302 int nghttp3_stream_write_goaway(nghttp3_stream *stream, 303 nghttp3_frame_entry *frent); 304 305 int nghttp3_stream_write_priority_update(nghttp3_stream *stream, 306 nghttp3_frame_entry *frent); 307 308 int nghttp3_stream_ensure_chunk(nghttp3_stream *stream, size_t need); 309 310 nghttp3_buf *nghttp3_stream_get_chunk(nghttp3_stream *stream); 311 312 int nghttp3_stream_is_blocked(nghttp3_stream *stream); 313 314 int nghttp3_stream_add_outq_offset(nghttp3_stream *stream, size_t n); 315 316 /* 317 * nghttp3_stream_outq_write_done returns nonzero if all contents in 318 * outq have been written. 319 */ 320 int nghttp3_stream_outq_write_done(nghttp3_stream *stream); 321 322 int nghttp3_stream_add_ack_offset(nghttp3_stream *stream, uint64_t n); 323 324 /* 325 * nghttp3_stream_is_active returns nonzero if |stream| is active. In 326 * other words, it has something to send. This function does not take 327 * into account its descendants. 328 */ 329 int nghttp3_stream_is_active(nghttp3_stream *stream); 330 331 /* 332 * nghttp3_stream_require_schedule returns nonzero if |stream| should 333 * be scheduled. In other words, |stream| or its descendants have 334 * something to send. 335 */ 336 int nghttp3_stream_require_schedule(nghttp3_stream *stream); 337 338 int nghttp3_stream_buffer_data(nghttp3_stream *stream, const uint8_t *src, 339 size_t srclen); 340 341 size_t nghttp3_stream_get_buffered_datalen(nghttp3_stream *stream); 342 343 int nghttp3_stream_ensure_qpack_stream_context(nghttp3_stream *stream); 344 345 void nghttp3_stream_delete_qpack_stream_context(nghttp3_stream *stream); 346 347 int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, 348 nghttp3_stream_http_event event); 349 350 int nghttp3_stream_empty_headers_allowed(nghttp3_stream *stream); 351 352 /* 353 * nghttp3_stream_uni returns nonzero if stream identified by 354 * |stream_id| is unidirectional. 355 */ 356 int nghttp3_stream_uni(int64_t stream_id); 357 358 /* 359 * nghttp3_client_stream_bidi returns nonzero if stream identified by 360 * |stream_id| is client initiated bidirectional stream. 361 */ 362 int nghttp3_client_stream_bidi(int64_t stream_id); 363 364 /* 365 * nghttp3_client_stream_uni returns nonzero if stream identified by 366 * |stream_id| is client initiated unidirectional stream. 367 */ 368 int nghttp3_client_stream_uni(int64_t stream_id); 369 370 /* 371 * nghttp3_server_stream_uni returns nonzero if stream identified by 372 * |stream_id| is server initiated unidirectional stream. 373 */ 374 int nghttp3_server_stream_uni(int64_t stream_id); 375 376 #endif /* NGHTTP3_STREAM_H */ 377