nghttp3_stream.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  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. #ifdef HAVE_CONFIG_H
  28. # include <config.h>
  29. #endif /* defined(HAVE_CONFIG_H) */
  30. #include <nghttp3/nghttp3.h>
  31. #include "nghttp3_map.h"
  32. #include "nghttp3_tnode.h"
  33. #include "nghttp3_ringbuf.h"
  34. #include "nghttp3_buf.h"
  35. #include "nghttp3_frame.h"
  36. #include "nghttp3_qpack.h"
  37. #include "nghttp3_objalloc.h"
  38. #define NGHTTP3_STREAM_MIN_CHUNK_SIZE 256
  39. /* NGHTTP3_MIN_UNSENT_BYTES is the minimum unsent bytes which is large
  40. enough to fill outgoing single QUIC packet. */
  41. #define NGHTTP3_MIN_UNSENT_BYTES 4096
  42. /* NGHTTP3_STREAM_MIN_WRITELEN is the minimum length of write to cause
  43. the stream to reschedule. */
  44. #define NGHTTP3_STREAM_MIN_WRITELEN 800
  45. /* nghttp3_stream_type is unidirectional stream type. */
  46. typedef uint64_t nghttp3_stream_type;
  47. #define NGHTTP3_STREAM_TYPE_CONTROL 0x00
  48. #define NGHTTP3_STREAM_TYPE_PUSH 0x01
  49. #define NGHTTP3_STREAM_TYPE_QPACK_ENCODER 0x02
  50. #define NGHTTP3_STREAM_TYPE_QPACK_DECODER 0x03
  51. #define NGHTTP3_STREAM_TYPE_UNKNOWN UINT64_MAX
  52. typedef enum nghttp3_ctrl_stream_state {
  53. NGHTTP3_CTRL_STREAM_STATE_FRAME_TYPE,
  54. NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH,
  55. NGHTTP3_CTRL_STREAM_STATE_SETTINGS,
  56. NGHTTP3_CTRL_STREAM_STATE_GOAWAY,
  57. NGHTTP3_CTRL_STREAM_STATE_MAX_PUSH_ID,
  58. NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME,
  59. NGHTTP3_CTRL_STREAM_STATE_SETTINGS_ID,
  60. NGHTTP3_CTRL_STREAM_STATE_SETTINGS_VALUE,
  61. NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE_PRI_ELEM_ID,
  62. NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE,
  63. } nghttp3_ctrl_stream_state;
  64. typedef enum nghttp3_req_stream_state {
  65. NGHTTP3_REQ_STREAM_STATE_FRAME_TYPE,
  66. NGHTTP3_REQ_STREAM_STATE_FRAME_LENGTH,
  67. NGHTTP3_REQ_STREAM_STATE_DATA,
  68. NGHTTP3_REQ_STREAM_STATE_HEADERS,
  69. NGHTTP3_REQ_STREAM_STATE_IGN_FRAME,
  70. NGHTTP3_REQ_STREAM_STATE_IGN_REST,
  71. } nghttp3_req_stream_state;
  72. typedef struct nghttp3_varint_read_state {
  73. int64_t acc;
  74. size_t left;
  75. } nghttp3_varint_read_state;
  76. typedef struct nghttp3_stream_read_state {
  77. nghttp3_varint_read_state rvint;
  78. nghttp3_frame fr;
  79. int64_t left;
  80. int state;
  81. } nghttp3_stream_read_state;
  82. /* NGHTTP3_STREAM_FLAG_NONE indicates that no flag is set. */
  83. #define NGHTTP3_STREAM_FLAG_NONE 0x0000u
  84. /* NGHTTP3_STREAM_FLAG_TYPE_IDENTIFIED is set when a unidirectional
  85. stream type is identified. */
  86. #define NGHTTP3_STREAM_FLAG_TYPE_IDENTIFIED 0x0001u
  87. /* NGHTTP3_STREAM_FLAG_FC_BLOCKED indicates that stream is blocked by
  88. QUIC flow control. */
  89. #define NGHTTP3_STREAM_FLAG_FC_BLOCKED 0x0002u
  90. /* NGHTTP3_STREAM_FLAG_READ_DATA_BLOCKED indicates that application is
  91. temporarily unable to provide data. */
  92. #define NGHTTP3_STREAM_FLAG_READ_DATA_BLOCKED 0x0004u
  93. /* NGHTTP3_STREAM_FLAG_WRITE_END_STREAM indicates that application
  94. finished to feed outgoing data. */
  95. #define NGHTTP3_STREAM_FLAG_WRITE_END_STREAM 0x0008u
  96. /* NGHTTP3_STREAM_FLAG_QPACK_DECODE_BLOCKED indicates that stream is
  97. blocked due to QPACK decoding. */
  98. #define NGHTTP3_STREAM_FLAG_QPACK_DECODE_BLOCKED 0x0010u
  99. /* NGHTTP3_STREAM_FLAG_READ_EOF indicates that remote endpoint sent
  100. fin. */
  101. #define NGHTTP3_STREAM_FLAG_READ_EOF 0x0020u
  102. /* NGHTTP3_STREAM_FLAG_CLOSED indicates that QUIC stream was closed.
  103. nghttp3_stream object can still alive because it might be blocked
  104. by QPACK decoder. */
  105. #define NGHTTP3_STREAM_FLAG_CLOSED 0x0040u
  106. /* NGHTTP3_STREAM_FLAG_SHUT_WR indicates that any further write
  107. operation to a stream is prohibited. */
  108. #define NGHTTP3_STREAM_FLAG_SHUT_WR 0x0100u
  109. /* NGHTTP3_STREAM_FLAG_SHUT_RD indicates that a read-side stream is
  110. closed abruptly and any incoming and pending stream data is just
  111. discarded for a stream. */
  112. #define NGHTTP3_STREAM_FLAG_SHUT_RD 0x0200u
  113. /* NGHTTP3_STREAM_FLAG_SERVER_PRIORITY_SET indicates that server
  114. overrides stream priority. */
  115. #define NGHTTP3_STREAM_FLAG_SERVER_PRIORITY_SET 0x0400u
  116. /* NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED indicates that server
  117. received PRIORITY_UPDATE frame for this stream. */
  118. #define NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED 0x0800u
  119. /* NGHTTP3_STREAM_FLAG_HTTP_ERROR indicates that
  120. NGHTTP3_ERR_MALFORMED_HTTP_HEADER error is encountered while
  121. processing incoming HTTP fields. */
  122. #define NGHTTP3_STREAM_FLAG_HTTP_ERROR 0x1000u
  123. typedef enum nghttp3_stream_http_state {
  124. NGHTTP3_HTTP_STATE_NONE,
  125. NGHTTP3_HTTP_STATE_REQ_INITIAL,
  126. NGHTTP3_HTTP_STATE_REQ_BEGIN,
  127. NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN,
  128. NGHTTP3_HTTP_STATE_REQ_HEADERS_END,
  129. NGHTTP3_HTTP_STATE_REQ_DATA_BEGIN,
  130. NGHTTP3_HTTP_STATE_REQ_DATA_END,
  131. NGHTTP3_HTTP_STATE_REQ_TRAILERS_BEGIN,
  132. NGHTTP3_HTTP_STATE_REQ_TRAILERS_END,
  133. NGHTTP3_HTTP_STATE_REQ_END,
  134. NGHTTP3_HTTP_STATE_RESP_INITIAL,
  135. NGHTTP3_HTTP_STATE_RESP_BEGIN,
  136. NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN,
  137. NGHTTP3_HTTP_STATE_RESP_HEADERS_END,
  138. NGHTTP3_HTTP_STATE_RESP_DATA_BEGIN,
  139. NGHTTP3_HTTP_STATE_RESP_DATA_END,
  140. NGHTTP3_HTTP_STATE_RESP_TRAILERS_BEGIN,
  141. NGHTTP3_HTTP_STATE_RESP_TRAILERS_END,
  142. NGHTTP3_HTTP_STATE_RESP_END,
  143. } nghttp3_stream_http_state;
  144. typedef enum nghttp3_stream_http_event {
  145. NGHTTP3_HTTP_EVENT_DATA_BEGIN,
  146. NGHTTP3_HTTP_EVENT_DATA_END,
  147. NGHTTP3_HTTP_EVENT_HEADERS_BEGIN,
  148. NGHTTP3_HTTP_EVENT_HEADERS_END,
  149. NGHTTP3_HTTP_EVENT_MSG_END,
  150. } nghttp3_stream_http_event;
  151. typedef struct nghttp3_stream nghttp3_stream;
  152. /*
  153. * nghttp3_stream_acked_data is a callback function which is invoked
  154. * when data sent on stream denoted by |stream_id| supplied from
  155. * application is acknowledged by remote endpoint. The number of
  156. * bytes acknowledged is given in |datalen|.
  157. *
  158. * The implementation of this callback must return 0 if it succeeds.
  159. * Returning NGHTTP3_ERR_CALLBACK_FAILURE will return to the caller
  160. * immediately. Any values other than 0 is treated as
  161. * NGHTTP3_ERR_CALLBACK_FAILURE.
  162. */
  163. typedef int (*nghttp3_stream_acked_data)(nghttp3_stream *stream,
  164. int64_t stream_id, uint64_t datalen,
  165. void *user_data);
  166. typedef struct nghttp3_stream_callbacks {
  167. nghttp3_stream_acked_data acked_data;
  168. } nghttp3_stream_callbacks;
  169. typedef struct nghttp3_http_state {
  170. /* content_length is the value of received content-length header
  171. field. */
  172. int64_t content_length;
  173. /* recv_content_length is the number of body bytes received so
  174. far. */
  175. int64_t recv_content_length;
  176. nghttp3_pri pri;
  177. /* status_code is HTTP status code received. This field is used
  178. if connection is initialized as client. */
  179. int32_t status_code;
  180. uint32_t flags;
  181. } nghttp3_http_state;
  182. struct nghttp3_stream {
  183. union {
  184. struct {
  185. const nghttp3_mem *mem;
  186. nghttp3_objalloc *out_chunk_objalloc;
  187. nghttp3_objalloc *stream_objalloc;
  188. nghttp3_tnode node;
  189. nghttp3_pq_entry qpack_blocked_pe;
  190. nghttp3_stream_callbacks callbacks;
  191. nghttp3_ringbuf frq;
  192. nghttp3_ringbuf chunks;
  193. nghttp3_ringbuf outq;
  194. /* inq stores the stream raw data which cannot be read because
  195. stream is blocked by QPACK decoder. */
  196. nghttp3_ringbuf inq;
  197. nghttp3_qpack_stream_context qpack_sctx;
  198. /* conn is a reference to underlying connection. It could be NULL
  199. if stream is not a request stream. */
  200. nghttp3_conn *conn;
  201. void *user_data;
  202. /* unsent_bytes is the number of bytes in outq not written yet */
  203. uint64_t unsent_bytes;
  204. /* outq_idx is an index into outq where next write is made. */
  205. size_t outq_idx;
  206. /* outq_offset is write offset relative to the element at outq_idx
  207. in outq. */
  208. uint64_t outq_offset;
  209. /* ack_base is the number of bytes acknowledged by a remote
  210. endpoint where the first element in outq is positioned at. */
  211. uint64_t ack_base;
  212. /* ack_offset is the number of bytes acknowledged by a remote
  213. endpoint so far. */
  214. uint64_t ack_offset;
  215. uint64_t unscheduled_nwrite;
  216. nghttp3_stream_type type;
  217. nghttp3_stream_read_state rstate;
  218. /* error_code indicates the reason of closure of this stream. */
  219. uint64_t error_code;
  220. struct {
  221. uint64_t offset;
  222. nghttp3_stream_http_state hstate;
  223. } tx;
  224. struct {
  225. nghttp3_stream_http_state hstate;
  226. nghttp3_http_state http;
  227. } rx;
  228. uint16_t flags;
  229. };
  230. nghttp3_opl_entry oplent;
  231. };
  232. };
  233. nghttp3_objalloc_decl(stream, nghttp3_stream, oplent)
  234. typedef struct nghttp3_frame_entry {
  235. nghttp3_frame fr;
  236. union {
  237. struct {
  238. nghttp3_settings *local_settings;
  239. } settings;
  240. struct {
  241. nghttp3_data_reader dr;
  242. } data;
  243. } aux;
  244. } nghttp3_frame_entry;
  245. int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id,
  246. const nghttp3_stream_callbacks *callbacks,
  247. nghttp3_objalloc *out_chunk_objalloc,
  248. nghttp3_objalloc *stream_objalloc,
  249. const nghttp3_mem *mem);
  250. void nghttp3_stream_del(nghttp3_stream *stream);
  251. void nghttp3_varint_read_state_reset(nghttp3_varint_read_state *rvint);
  252. void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate);
  253. nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
  254. const uint8_t *begin, const uint8_t *end,
  255. int fin);
  256. int nghttp3_stream_frq_add(nghttp3_stream *stream,
  257. const nghttp3_frame_entry *frent);
  258. int nghttp3_stream_fill_outq(nghttp3_stream *stream);
  259. int nghttp3_stream_write_stream_type(nghttp3_stream *stream);
  260. size_t nghttp3_stream_writev(nghttp3_stream *stream, int *pfin,
  261. nghttp3_vec *vec, size_t veccnt);
  262. int nghttp3_stream_write_qpack_decoder_stream(nghttp3_stream *stream);
  263. int nghttp3_stream_outq_add(nghttp3_stream *stream,
  264. const nghttp3_typed_buf *tbuf);
  265. int nghttp3_stream_write_headers(nghttp3_stream *stream,
  266. nghttp3_frame_entry *frent);
  267. int nghttp3_stream_write_header_block(nghttp3_stream *stream,
  268. nghttp3_qpack_encoder *qenc,
  269. nghttp3_stream *qenc_stream,
  270. nghttp3_buf *rbuf, nghttp3_buf *ebuf,
  271. int64_t frame_type, const nghttp3_nv *nva,
  272. size_t nvlen);
  273. int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof,
  274. nghttp3_frame_entry *frent);
  275. int nghttp3_stream_write_settings(nghttp3_stream *stream,
  276. nghttp3_frame_entry *frent);
  277. int nghttp3_stream_write_goaway(nghttp3_stream *stream,
  278. nghttp3_frame_entry *frent);
  279. int nghttp3_stream_write_priority_update(nghttp3_stream *stream,
  280. nghttp3_frame_entry *frent);
  281. int nghttp3_stream_ensure_chunk(nghttp3_stream *stream, size_t need);
  282. nghttp3_buf *nghttp3_stream_get_chunk(nghttp3_stream *stream);
  283. int nghttp3_stream_is_blocked(nghttp3_stream *stream);
  284. void nghttp3_stream_add_outq_offset(nghttp3_stream *stream, size_t n);
  285. /*
  286. * nghttp3_stream_outq_write_done returns nonzero if all contents in
  287. * outq have been written.
  288. */
  289. int nghttp3_stream_outq_write_done(nghttp3_stream *stream);
  290. /*
  291. * nghttp2_stream_update_ack_offset updates the last acknowledged
  292. * offset to |offset|.
  293. */
  294. int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset);
  295. /*
  296. * nghttp3_stream_is_active returns nonzero if |stream| is active. In
  297. * other words, it has something to send. This function does not take
  298. * into account its descendants.
  299. */
  300. int nghttp3_stream_is_active(nghttp3_stream *stream);
  301. /*
  302. * nghttp3_stream_require_schedule returns nonzero if |stream| should
  303. * be scheduled. In other words, |stream| or its descendants have
  304. * something to send.
  305. */
  306. int nghttp3_stream_require_schedule(nghttp3_stream *stream);
  307. int nghttp3_stream_buffer_data(nghttp3_stream *stream, const uint8_t *src,
  308. size_t srclen);
  309. size_t nghttp3_stream_get_buffered_datalen(nghttp3_stream *stream);
  310. int nghttp3_stream_ensure_qpack_stream_context(nghttp3_stream *stream);
  311. void nghttp3_stream_delete_qpack_stream_context(nghttp3_stream *stream);
  312. int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
  313. nghttp3_stream_http_event event);
  314. int nghttp3_stream_empty_headers_allowed(nghttp3_stream *stream);
  315. /*
  316. * nghttp3_stream_uni returns nonzero if stream identified by
  317. * |stream_id| is unidirectional.
  318. */
  319. int nghttp3_stream_uni(int64_t stream_id);
  320. /*
  321. * nghttp3_client_stream_bidi returns nonzero if stream identified by
  322. * |stream_id| is client initiated bidirectional stream.
  323. */
  324. int nghttp3_client_stream_bidi(int64_t stream_id);
  325. /*
  326. * nghttp3_client_stream_uni returns nonzero if stream identified by
  327. * |stream_id| is client initiated unidirectional stream.
  328. */
  329. int nghttp3_client_stream_uni(int64_t stream_id);
  330. /*
  331. * nghttp3_server_stream_uni returns nonzero if stream identified by
  332. * |stream_id| is server initiated unidirectional stream.
  333. */
  334. int nghttp3_server_stream_uni(int64_t stream_id);
  335. #endif /* !defined(NGHTTP3_STREAM_H) */