• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2012 Tatsuhiro Tsujikawa
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 NGHTTP2_SESSION_H
26 #define NGHTTP2_SESSION_H
27 
28 #ifdef HAVE_CONFIG_H
29 #  include <config.h>
30 #endif /* HAVE_CONFIG_H */
31 
32 #include <nghttp2/nghttp2.h>
33 #include "nghttp2_map.h"
34 #include "nghttp2_frame.h"
35 #include "nghttp2_hd.h"
36 #include "nghttp2_stream.h"
37 #include "nghttp2_outbound_item.h"
38 #include "nghttp2_int.h"
39 #include "nghttp2_buf.h"
40 #include "nghttp2_callbacks.h"
41 #include "nghttp2_mem.h"
42 #include "nghttp2_ratelim.h"
43 
44 /* The global variable for tests where we want to disable strict
45    preface handling. */
46 extern int nghttp2_enable_strict_preface;
47 
48 /*
49  * Option flags.
50  */
51 typedef enum {
52   NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
53   NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
54   NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
55   NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3,
56   NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4,
57   NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5,
58   NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6,
59 } nghttp2_optmask;
60 
61 /*
62  * bitmask for built-in type to enable the default handling for that
63  * type of the frame.
64  */
65 typedef enum {
66   NGHTTP2_TYPEMASK_NONE = 0,
67   NGHTTP2_TYPEMASK_ALTSVC = 1 << 0,
68   NGHTTP2_TYPEMASK_ORIGIN = 1 << 1,
69   NGHTTP2_TYPEMASK_PRIORITY_UPDATE = 1 << 2
70 } nghttp2_typemask;
71 
72 typedef enum {
73   NGHTTP2_OB_POP_ITEM,
74   NGHTTP2_OB_SEND_DATA,
75   NGHTTP2_OB_SEND_NO_COPY,
76   NGHTTP2_OB_SEND_CLIENT_MAGIC
77 } nghttp2_outbound_state;
78 
79 typedef struct {
80   nghttp2_outbound_item *item;
81   nghttp2_bufs framebufs;
82   nghttp2_outbound_state state;
83 } nghttp2_active_outbound_item;
84 
85 /* Buffer length for inbound raw byte stream used in
86    nghttp2_session_recv(). */
87 #define NGHTTP2_INBOUND_BUFFER_LENGTH 16384
88 
89 /* The default maximum number of incoming reserved streams */
90 #define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200
91 
92 /* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this
93    number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */
94 #define NGHTTP2_MIN_IDLE_STREAMS 16
95 
96 /* The maximum number of items in outbound queue, which is considered
97    as flooding caused by peer.  All frames are not considered here.
98    We only consider PING + ACK and SETTINGS + ACK.  This is because
99    they both are response to the frame initiated by peer and peer can
100    send as many of them as they want.  If peer does not read network,
101    response frames are stacked up, which leads to memory exhaustion.
102    The value selected here is arbitrary, but safe value and if we have
103    these frames in this number, it is considered suspicious. */
104 #define NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM 1000
105 
106 /* The default value of maximum number of concurrent streams. */
107 #define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
108 
109 /* The default values for stream reset rate limiter. */
110 #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
111 #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
112 
113 /* Internal state when receiving incoming frame */
114 typedef enum {
115   /* Receiving frame header */
116   NGHTTP2_IB_READ_CLIENT_MAGIC,
117   NGHTTP2_IB_READ_FIRST_SETTINGS,
118   NGHTTP2_IB_READ_HEAD,
119   NGHTTP2_IB_READ_NBYTE,
120   NGHTTP2_IB_READ_HEADER_BLOCK,
121   NGHTTP2_IB_IGN_HEADER_BLOCK,
122   NGHTTP2_IB_IGN_PAYLOAD,
123   NGHTTP2_IB_FRAME_SIZE_ERROR,
124   NGHTTP2_IB_READ_SETTINGS,
125   NGHTTP2_IB_READ_GOAWAY_DEBUG,
126   NGHTTP2_IB_EXPECT_CONTINUATION,
127   NGHTTP2_IB_IGN_CONTINUATION,
128   NGHTTP2_IB_READ_PAD_DATA,
129   NGHTTP2_IB_READ_DATA,
130   NGHTTP2_IB_IGN_DATA,
131   NGHTTP2_IB_IGN_ALL,
132   NGHTTP2_IB_READ_ALTSVC_PAYLOAD,
133   NGHTTP2_IB_READ_ORIGIN_PAYLOAD,
134   NGHTTP2_IB_READ_EXTENSION_PAYLOAD
135 } nghttp2_inbound_state;
136 
137 typedef struct {
138   nghttp2_frame frame;
139   /* Storage for extension frame payload.  frame->ext.payload points
140      to this structure to avoid frequent memory allocation. */
141   nghttp2_ext_frame_payload ext_frame_payload;
142   /* The received SETTINGS entry.  For the standard settings entries,
143      we only keep the last seen value.  For
144      SETTINGS_HEADER_TABLE_SIZE, we also keep minimum value in the
145      last index. */
146   nghttp2_settings_entry *iv;
147   /* buffer pointers to small buffer, raw_sbuf */
148   nghttp2_buf sbuf;
149   /* buffer pointers to large buffer, raw_lbuf */
150   nghttp2_buf lbuf;
151   /* Large buffer, malloced on demand */
152   uint8_t *raw_lbuf;
153   /* The number of entry filled in |iv| */
154   size_t niv;
155   /* The number of entries |iv| can store. */
156   size_t max_niv;
157   /* How many bytes we still need to receive for current frame */
158   size_t payloadleft;
159   /* padding length for the current frame */
160   size_t padlen;
161   nghttp2_inbound_state state;
162   /* Small fixed sized buffer. */
163   uint8_t raw_sbuf[32];
164 } nghttp2_inbound_frame;
165 
166 typedef struct {
167   uint32_t header_table_size;
168   uint32_t enable_push;
169   uint32_t max_concurrent_streams;
170   uint32_t initial_window_size;
171   uint32_t max_frame_size;
172   uint32_t max_header_list_size;
173   uint32_t enable_connect_protocol;
174   uint32_t no_rfc7540_priorities;
175 } nghttp2_settings_storage;
176 
177 typedef enum {
178   NGHTTP2_GOAWAY_NONE = 0,
179   /* Flag means that connection should be terminated after sending GOAWAY. */
180   NGHTTP2_GOAWAY_TERM_ON_SEND = 0x1,
181   /* Flag means GOAWAY to terminate session has been sent */
182   NGHTTP2_GOAWAY_TERM_SENT = 0x2,
183   /* Flag means GOAWAY was sent */
184   NGHTTP2_GOAWAY_SENT = 0x4,
185   /* Flag means GOAWAY was received */
186   NGHTTP2_GOAWAY_RECV = 0x8,
187   /* Flag means GOAWAY has been submitted at least once */
188   NGHTTP2_GOAWAY_SUBMITTED = 0x10
189 } nghttp2_goaway_flag;
190 
191 /* nghttp2_inflight_settings stores the SETTINGS entries which local
192    endpoint has sent to the remote endpoint, and has not received ACK
193    yet. */
194 struct nghttp2_inflight_settings {
195   struct nghttp2_inflight_settings *next;
196   nghttp2_settings_entry *iv;
197   size_t niv;
198 };
199 
200 typedef struct nghttp2_inflight_settings nghttp2_inflight_settings;
201 
202 struct nghttp2_session {
203   nghttp2_map /* <nghttp2_stream*> */ streams;
204   /* root of dependency tree*/
205   nghttp2_stream root;
206   /* Queue for outbound urgent frames (PING and SETTINGS) */
207   nghttp2_outbound_queue ob_urgent;
208   /* Queue for non-DATA frames */
209   nghttp2_outbound_queue ob_reg;
210   /* Queue for outbound stream-creating HEADERS (request or push
211      response) frame, which are subject to
212      SETTINGS_MAX_CONCURRENT_STREAMS limit. */
213   nghttp2_outbound_queue ob_syn;
214   /* Queues for DATA frames which is used when
215      SETTINGS_NO_RFC7540_PRIORITIES is enabled.  This implements RFC
216      9218 extensible prioritization scheme. */
217   struct {
218     nghttp2_pq ob_data;
219   } sched[NGHTTP2_EXTPRI_URGENCY_LEVELS];
220   nghttp2_active_outbound_item aob;
221   nghttp2_inbound_frame iframe;
222   nghttp2_hd_deflater hd_deflater;
223   nghttp2_hd_inflater hd_inflater;
224   nghttp2_session_callbacks callbacks;
225   /* Memory allocator */
226   nghttp2_mem mem;
227   void *user_data;
228   /* Points to the latest incoming closed stream.  NULL if there is no
229      closed stream.  Only used when session is initialized as
230      server. */
231   nghttp2_stream *closed_stream_head;
232   /* Points to the oldest incoming closed stream.  NULL if there is no
233      closed stream.  Only used when session is initialized as
234      server. */
235   nghttp2_stream *closed_stream_tail;
236   /* Points to the latest idle stream.  NULL if there is no idle
237      stream.  Only used when session is initialized as server .*/
238   nghttp2_stream *idle_stream_head;
239   /* Points to the oldest idle stream.  NULL if there is no idle
240      stream.  Only used when session is initialized as erver. */
241   nghttp2_stream *idle_stream_tail;
242   /* Queue of In-flight SETTINGS values.  SETTINGS bearing ACK is not
243      considered as in-flight. */
244   nghttp2_inflight_settings *inflight_settings_head;
245   /* Stream reset rate limiter.  If receiving excessive amount of
246      stream resets, GOAWAY will be sent. */
247   nghttp2_ratelim stream_reset_ratelim;
248   /* Sequential number across all streams to process streams in
249      FIFO. */
250   uint64_t stream_seq;
251   /* The number of outgoing streams. This will be capped by
252      remote_settings.max_concurrent_streams. */
253   size_t num_outgoing_streams;
254   /* The number of incoming streams. This will be capped by
255      local_settings.max_concurrent_streams. */
256   size_t num_incoming_streams;
257   /* The number of incoming reserved streams.  This is the number of
258      streams in reserved (remote) state.  RFC 7540 does not limit this
259      number.  nghttp2 offers
260      nghttp2_option_set_max_reserved_remote_streams() to achieve this.
261      If it is used, num_incoming_streams is capped by
262      max_incoming_reserved_streams.  Client application should
263      consider to set this because without that server can send
264      arbitrary number of PUSH_PROMISE, and exhaust client's memory. */
265   size_t num_incoming_reserved_streams;
266   /* The maximum number of incoming reserved streams (reserved
267      (remote) state).  RST_STREAM will be sent for the pushed stream
268      which exceeds this limit. */
269   size_t max_incoming_reserved_streams;
270   /* The number of closed streams still kept in |streams| hash.  The
271      closed streams can be accessed through single linked list
272      |closed_stream_head|.  The current implementation only keeps
273      incoming streams and session is initialized as server. */
274   size_t num_closed_streams;
275   /* The number of idle streams kept in |streams| hash.  The idle
276      streams can be accessed through doubly linked list
277      |idle_stream_head|.  The current implementation only keeps idle
278      streams if session is initialized as server. */
279   size_t num_idle_streams;
280   /* The number of bytes allocated for nvbuf */
281   size_t nvbuflen;
282   /* Counter for detecting flooding in outbound queue.  If it exceeds
283      max_outbound_ack, session will be closed. */
284   size_t obq_flood_counter_;
285   /* The maximum number of outgoing SETTINGS ACK and PING ACK in
286      outbound queue. */
287   size_t max_outbound_ack;
288   /* The maximum length of header block to send.  Calculated by the
289      same way as nghttp2_hd_deflate_bound() does. */
290   size_t max_send_header_block_length;
291   /* The maximum number of settings accepted per SETTINGS frame. */
292   size_t max_settings;
293   /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
294   uint32_t next_stream_id;
295   /* The last stream ID this session initiated.  For client session,
296      this is the last stream ID it has sent.  For server session, it
297      is the last promised stream ID sent in PUSH_PROMISE. */
298   int32_t last_sent_stream_id;
299   /* The largest stream ID received so far */
300   int32_t last_recv_stream_id;
301   /* The largest stream ID which has been processed in some way. This
302      value will be used as last-stream-id when sending GOAWAY
303      frame. */
304   int32_t last_proc_stream_id;
305   /* Counter of unique ID of PING. Wraps when it exceeds
306      NGHTTP2_MAX_UNIQUE_ID */
307   uint32_t next_unique_id;
308   /* This is the last-stream-ID we have sent in GOAWAY */
309   int32_t local_last_stream_id;
310   /* This is the value in GOAWAY frame received from remote endpoint. */
311   int32_t remote_last_stream_id;
312   /* Current sender window size. This value is computed against the
313      current initial window size of remote endpoint. */
314   int32_t remote_window_size;
315   /* Keep track of the number of bytes received without
316      WINDOW_UPDATE. This could be negative after submitting negative
317      value to WINDOW_UPDATE. */
318   int32_t recv_window_size;
319   /* The number of bytes consumed by the application and now is
320      subject to WINDOW_UPDATE.  This is only used when auto
321      WINDOW_UPDATE is turned off. */
322   int32_t consumed_size;
323   /* The amount of recv_window_size cut using submitting negative
324      value to WINDOW_UPDATE */
325   int32_t recv_reduction;
326   /* window size for local flow control. It is initially set to
327      NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE and could be
328      increased/decreased by submitting WINDOW_UPDATE. See
329      nghttp2_submit_window_update(). */
330   int32_t local_window_size;
331   /* This flag is used to indicate that the local endpoint received initial
332      SETTINGS frame from the remote endpoint. */
333   uint8_t remote_settings_received;
334   /* Settings value received from the remote endpoint. */
335   nghttp2_settings_storage remote_settings;
336   /* Settings value of the local endpoint. */
337   nghttp2_settings_storage local_settings;
338   /* Option flags. This is bitwise-OR of 0 or more of nghttp2_optmask. */
339   uint32_t opt_flags;
340   /* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this
341      to refuse the incoming stream if it exceeds this value. */
342   uint32_t pending_local_max_concurrent_stream;
343   /* The bitwise OR of zero or more of nghttp2_typemask to indicate
344      that the default handling of extension frame is enabled. */
345   uint32_t builtin_recv_ext_types;
346   /* Unacked local ENABLE_PUSH value.  We use this to refuse
347      PUSH_PROMISE before SETTINGS ACK is received. */
348   uint8_t pending_enable_push;
349   /* Unacked local ENABLE_CONNECT_PROTOCOL value.  We use this to
350      accept :protocol header field before SETTINGS_ACK is received. */
351   uint8_t pending_enable_connect_protocol;
352   /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is
353      effective before it is acknowledged. */
354   uint8_t pending_no_rfc7540_priorities;
355   /* Turn on fallback to RFC 7540 priorities; for server use only. */
356   uint8_t fallback_rfc7540_priorities;
357   /* Nonzero if the session is server side. */
358   uint8_t server;
359   /* Flags indicating GOAWAY is sent and/or received. The flags are
360      composed by bitwise OR-ing nghttp2_goaway_flag. */
361   uint8_t goaway_flags;
362   /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
363      this session.  The nonzero does not necessarily mean
364      WINDOW_UPDATE is not queued. */
365   uint8_t window_update_queued;
366   /* Bitfield of extension frame types that application is willing to
367      receive.  To designate the bit of given frame type i, use
368      user_recv_ext_types[i / 8] & (1 << (i & 0x7)).  First 10 frame
369      types are standard frame types and not used in this bitfield.  If
370      bit is set, it indicates that incoming frame with that type is
371      passed to user defined callbacks, otherwise they are ignored. */
372   uint8_t user_recv_ext_types[32];
373 };
374 
375 /* Struct used when updating initial window size of each active
376    stream. */
377 typedef struct {
378   nghttp2_session *session;
379   int32_t new_window_size, old_window_size;
380 } nghttp2_update_window_size_arg;
381 
382 typedef struct {
383   nghttp2_session *session;
384   /* linked list of streams to close */
385   nghttp2_stream *head;
386   int32_t last_stream_id;
387   /* nonzero if GOAWAY is sent to peer, which means we are going to
388      close incoming streams.  zero if GOAWAY is received from peer and
389      we are going to close outgoing streams. */
390   int incoming;
391 } nghttp2_close_stream_on_goaway_arg;
392 
393 /* TODO stream timeout etc */
394 
395 /*
396  * Returns nonzero value if |stream_id| is initiated by local
397  * endpoint.
398  */
399 int nghttp2_session_is_my_stream_id(nghttp2_session *session,
400                                     int32_t stream_id);
401 
402 /*
403  * Adds |item| to the outbound queue in |session|.  When this function
404  * succeeds, it takes ownership of |item|. So caller must not free it
405  * on success.
406  *
407  * This function returns 0 if it succeeds, or one of the following
408  * negative error codes:
409  *
410  * NGHTTP2_ERR_NOMEM
411  *     Out of memory.
412  * NGHTTP2_ERR_STREAM_CLOSED
413  *     Stream already closed (DATA and PUSH_PROMISE frame only)
414  */
415 int nghttp2_session_add_item(nghttp2_session *session,
416                              nghttp2_outbound_item *item);
417 
418 /*
419  * Adds RST_STREAM frame for the stream |stream_id| with the error
420  * code |error_code|. This is a convenient function built on top of
421  * nghttp2_session_add_frame() to add RST_STREAM easily.
422  *
423  * This function simply returns 0 without adding RST_STREAM frame if
424  * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
425  * RST_STREAM for a stream is redundant.
426  *
427  * This function returns 0 if it succeeds, or one of the following
428  * negative error codes:
429  *
430  * NGHTTP2_ERR_NOMEM
431  *     Out of memory.
432  */
433 int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
434                                    uint32_t error_code);
435 
436 /*
437  * Adds PING frame. This is a convenient function built on top of
438  * nghttp2_session_add_frame() to add PING easily.
439  *
440  * If the |opaque_data| is not NULL, it must point to 8 bytes memory
441  * region of data. The data pointed by |opaque_data| is copied. It can
442  * be NULL. In this case, 8 bytes NULL is used.
443  *
444  * This function returns 0 if it succeeds, or one of the following
445  * negative error codes:
446  *
447  * NGHTTP2_ERR_NOMEM
448  *     Out of memory.
449  * NGHTTP2_ERR_FLOODED
450  *     There are too many items in outbound queue; this only happens
451  *     if NGHTTP2_FLAG_ACK is set in |flags|
452  */
453 int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
454                              const uint8_t *opaque_data);
455 
456 /*
457  * Adds GOAWAY frame with the last-stream-ID |last_stream_id| and the
458  * error code |error_code|. This is a convenient function built on top
459  * of nghttp2_session_add_frame() to add GOAWAY easily.  The
460  * |aux_flags| are bitwise-OR of one or more of
461  * nghttp2_goaway_aux_flag.
462  *
463  * This function returns 0 if it succeeds, or one of the following
464  * negative error codes:
465  *
466  * NGHTTP2_ERR_NOMEM
467  *     Out of memory.
468  * NGHTTP2_ERR_INVALID_ARGUMENT
469  *     The |opaque_data_len| is too large.
470  */
471 int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
472                                uint32_t error_code, const uint8_t *opaque_data,
473                                size_t opaque_data_len, uint8_t aux_flags);
474 
475 /*
476  * Adds WINDOW_UPDATE frame with stream ID |stream_id| and
477  * window-size-increment |window_size_increment|. This is a convenient
478  * function built on top of nghttp2_session_add_frame() to add
479  * WINDOW_UPDATE easily.
480  *
481  * This function returns 0 if it succeeds, or one of the following
482  * negative error codes:
483  *
484  * NGHTTP2_ERR_NOMEM
485  *     Out of memory.
486  */
487 int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags,
488                                       int32_t stream_id,
489                                       int32_t window_size_increment);
490 
491 /*
492  * Adds SETTINGS frame.
493  *
494  * This function returns 0 if it succeeds, or one of the following
495  * negative error codes:
496  *
497  * NGHTTP2_ERR_NOMEM
498  *     Out of memory.
499  * NGHTTP2_ERR_FLOODED
500  *     There are too many items in outbound queue; this only happens
501  *     if NGHTTP2_FLAG_ACK is set in |flags|
502  */
503 int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
504                                  const nghttp2_settings_entry *iv, size_t niv);
505 
506 /*
507  * Creates new stream in |session| with stream ID |stream_id|,
508  * priority |pri_spec| and flags |flags|.  The |flags| is bitwise OR
509  * of nghttp2_stream_flag.  Since this function is called when initial
510  * HEADERS is sent or received, these flags are taken from it.  The
511  * state of stream is set to |initial_state|. The |stream_user_data|
512  * is a pointer to the arbitrary user supplied data to be associated
513  * to this stream.
514  *
515  * If |initial_state| is NGHTTP2_STREAM_RESERVED, this function sets
516  * NGHTTP2_STREAM_FLAG_PUSH flag set.
517  *
518  * This function returns a pointer to created new stream object, or
519  * NULL.
520  *
521  * This function adjusts neither the number of closed streams or idle
522  * streams.  The caller should manually call
523  * nghttp2_session_adjust_closed_stream() or
524  * nghttp2_session_adjust_idle_stream() respectively.
525  */
526 nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
527                                             int32_t stream_id, uint8_t flags,
528                                             nghttp2_priority_spec *pri_spec,
529                                             nghttp2_stream_state initial_state,
530                                             void *stream_user_data);
531 
532 /*
533  * Closes stream whose stream ID is |stream_id|. The reason of closure
534  * is indicated by the |error_code|. When closing the stream,
535  * on_stream_close_callback will be called.
536  *
537  * If the session is initialized as server and |stream| is incoming
538  * stream, stream is just marked closed and this function calls
539  * nghttp2_session_keep_closed_stream() with |stream|.  Otherwise,
540  * |stream| will be deleted from memory.
541  *
542  * This function returns 0 if it succeeds, or one the following
543  * negative error codes:
544  *
545  * NGHTTP2_ERR_NOMEM
546  *     Out of memory
547  * NGHTTP2_ERR_INVALID_ARGUMENT
548  *     The specified stream does not exist.
549  * NGHTTP2_ERR_CALLBACK_FAILURE
550  *     The callback function failed.
551  */
552 int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
553                                  uint32_t error_code);
554 
555 /*
556  * Deletes |stream| from memory.  After this function returns, stream
557  * cannot be accessed.
558  *
559  * This function returns 0 if it succeeds, or one the following
560  * negative error codes:
561  *
562  * NGHTTP2_ERR_NOMEM
563  *     Out of memory
564  */
565 int nghttp2_session_destroy_stream(nghttp2_session *session,
566                                    nghttp2_stream *stream);
567 
568 /*
569  * Tries to keep incoming closed stream |stream|.  Due to the
570  * limitation of maximum number of streams in memory, |stream| is not
571  * closed and just deleted from memory (see
572  * nghttp2_session_destroy_stream).
573  */
574 void nghttp2_session_keep_closed_stream(nghttp2_session *session,
575                                         nghttp2_stream *stream);
576 
577 /*
578  * Appends |stream| to linked list |session->idle_stream_head|.  We
579  * apply fixed limit for list size.  To fit into that limit, one or
580  * more oldest streams are removed from list as necessary.
581  */
582 void nghttp2_session_keep_idle_stream(nghttp2_session *session,
583                                       nghttp2_stream *stream);
584 
585 /*
586  * Detaches |stream| from idle streams linked list.
587  */
588 void nghttp2_session_detach_idle_stream(nghttp2_session *session,
589                                         nghttp2_stream *stream);
590 
591 /*
592  * Deletes closed stream to ensure that number of incoming streams
593  * including active and closed is in the maximum number of allowed
594  * stream.
595  *
596  * This function returns 0 if it succeeds, or one the following
597  * negative error codes:
598  *
599  * NGHTTP2_ERR_NOMEM
600  *     Out of memory
601  */
602 int nghttp2_session_adjust_closed_stream(nghttp2_session *session);
603 
604 /*
605  * Deletes idle stream to ensure that number of idle streams is in
606  * certain limit.
607  *
608  * This function returns 0 if it succeeds, or one the following
609  * negative error codes:
610  *
611  * NGHTTP2_ERR_NOMEM
612  *     Out of memory
613  */
614 int nghttp2_session_adjust_idle_stream(nghttp2_session *session);
615 
616 /*
617  * If further receptions and transmissions over the stream |stream_id|
618  * are disallowed, close the stream with error code NGHTTP2_NO_ERROR.
619  *
620  * This function returns 0 if it
621  * succeeds, or one of the following negative error codes:
622  *
623  * NGHTTP2_ERR_INVALID_ARGUMENT
624  *     The specified stream does not exist.
625  */
626 int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session,
627                                               nghttp2_stream *stream);
628 
629 int nghttp2_session_on_request_headers_received(nghttp2_session *session,
630                                                 nghttp2_frame *frame);
631 
632 int nghttp2_session_on_response_headers_received(nghttp2_session *session,
633                                                  nghttp2_frame *frame,
634                                                  nghttp2_stream *stream);
635 
636 int nghttp2_session_on_push_response_headers_received(nghttp2_session *session,
637                                                       nghttp2_frame *frame,
638                                                       nghttp2_stream *stream);
639 
640 /*
641  * Called when HEADERS is received, assuming |frame| is properly
642  * initialized.  This function does first validate received frame and
643  * then open stream and call callback functions.
644  *
645  * This function returns 0 if it succeeds, or one of the following
646  * negative error codes:
647  *
648  * NGHTTP2_ERR_NOMEM
649  *     Out of memory.
650  * NGHTTP2_ERR_IGN_HEADER_BLOCK
651  *     Frame was rejected and header block must be decoded but
652  *     result must be ignored.
653  * NGHTTP2_ERR_CALLBACK_FAILURE
654  *     The read_callback failed
655  */
656 int nghttp2_session_on_headers_received(nghttp2_session *session,
657                                         nghttp2_frame *frame,
658                                         nghttp2_stream *stream);
659 
660 /*
661  * Called when PRIORITY is received, assuming |frame| is properly
662  * initialized.
663  *
664  * This function returns 0 if it succeeds, or one of the following
665  * negative error codes:
666  *
667  * NGHTTP2_ERR_NOMEM
668  *     Out of memory.
669  * NGHTTP2_ERR_CALLBACK_FAILURE
670  *     The read_callback failed
671  */
672 int nghttp2_session_on_priority_received(nghttp2_session *session,
673                                          nghttp2_frame *frame);
674 
675 /*
676  * Called when RST_STREAM is received, assuming |frame| is properly
677  * initialized.
678  *
679  * This function returns 0 if it succeeds, or one the following
680  * negative error codes:
681  *
682  * NGHTTP2_ERR_NOMEM
683  *     Out of memory
684  * NGHTTP2_ERR_CALLBACK_FAILURE
685  *     The read_callback failed
686  */
687 int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
688                                            nghttp2_frame *frame);
689 
690 /*
691  * Called when SETTINGS is received, assuming |frame| is properly
692  * initialized. If |noack| is non-zero, SETTINGS with ACK will not be
693  * submitted. If |frame| has NGHTTP2_FLAG_ACK flag set, no SETTINGS
694  * with ACK will not be submitted regardless of |noack|.
695  *
696  * This function returns 0 if it succeeds, or one the following
697  * negative error codes:
698  *
699  * NGHTTP2_ERR_NOMEM
700  *     Out of memory
701  * NGHTTP2_ERR_CALLBACK_FAILURE
702  *     The read_callback failed
703  * NGHTTP2_ERR_FLOODED
704  *     There are too many items in outbound queue, and this is most
705  *     likely caused by misbehaviour of peer.
706  */
707 int nghttp2_session_on_settings_received(nghttp2_session *session,
708                                          nghttp2_frame *frame, int noack);
709 
710 /*
711  * Called when PUSH_PROMISE is received, assuming |frame| is properly
712  * initialized.
713  *
714  * This function returns 0 if it succeeds, or one of the following
715  * negative error codes:
716  *
717  * NGHTTP2_ERR_NOMEM
718  *     Out of memory.
719  * NGHTTP2_ERR_IGN_HEADER_BLOCK
720  *     Frame was rejected and header block must be decoded but
721  *     result must be ignored.
722  * NGHTTP2_ERR_CALLBACK_FAILURE
723  *     The read_callback failed
724  */
725 int nghttp2_session_on_push_promise_received(nghttp2_session *session,
726                                              nghttp2_frame *frame);
727 
728 /*
729  * Called when PING is received, assuming |frame| is properly
730  * initialized.
731  *
732  * This function returns 0 if it succeeds, or one of the following
733  * negative error codes:
734  *
735  * NGHTTP2_ERR_NOMEM
736  *     Out of memory.
737  * NGHTTP2_ERR_CALLBACK_FAILURE
738  *     The callback function failed.
739  * NGHTTP2_ERR_FLOODED
740  *     There are too many items in outbound queue, and this is most
741  *     likely caused by misbehaviour of peer.
742  */
743 int nghttp2_session_on_ping_received(nghttp2_session *session,
744                                      nghttp2_frame *frame);
745 
746 /*
747  * Called when GOAWAY is received, assuming |frame| is properly
748  * initialized.
749  *
750  * This function returns 0 if it succeeds, or one of the following
751  * negative error codes:
752  *
753  * NGHTTP2_ERR_NOMEM
754  *     Out of memory.
755  * NGHTTP2_ERR_CALLBACK_FAILURE
756  *     The callback function failed.
757  */
758 int nghttp2_session_on_goaway_received(nghttp2_session *session,
759                                        nghttp2_frame *frame);
760 
761 /*
762  * Called when WINDOW_UPDATE is received, assuming |frame| is properly
763  * initialized.
764  *
765  * This function returns 0 if it succeeds, or one of the following
766  * negative error codes:
767  *
768  * NGHTTP2_ERR_NOMEM
769  *     Out of memory.
770  * NGHTTP2_ERR_CALLBACK_FAILURE
771  *     The callback function failed.
772  */
773 int nghttp2_session_on_window_update_received(nghttp2_session *session,
774                                               nghttp2_frame *frame);
775 
776 /*
777  * Called when ALTSVC is received, assuming |frame| is properly
778  * initialized.
779  *
780  * This function returns 0 if it succeeds, or one of the following
781  * negative error codes:
782  *
783  * NGHTTP2_ERR_CALLBACK_FAILURE
784  *     The callback function failed.
785  */
786 int nghttp2_session_on_altsvc_received(nghttp2_session *session,
787                                        nghttp2_frame *frame);
788 
789 /*
790  * Called when ORIGIN is received, assuming |frame| is properly
791  * initialized.
792  *
793  * This function returns 0 if it succeeds, or one of the following
794  * negative error codes:
795  *
796  * NGHTTP2_ERR_CALLBACK_FAILURE
797  *     The callback function failed.
798  */
799 int nghttp2_session_on_origin_received(nghttp2_session *session,
800                                        nghttp2_frame *frame);
801 
802 /*
803  * Called when PRIORITY_UPDATE is received, assuming |frame| is
804  * properly initialized.
805  *
806  * This function returns 0 if it succeeds, or one of the following
807  * negative error codes:
808  *
809  * NGHTTP2_ERR_CALLBACK_FAILURE
810  *     The callback function failed.
811  */
812 int nghttp2_session_on_priority_update_received(nghttp2_session *session,
813                                                 nghttp2_frame *frame);
814 
815 /*
816  * Called when DATA is received, assuming |frame| is properly
817  * initialized.
818  *
819  * This function returns 0 if it succeeds, or one of the following
820  * negative error codes:
821  *
822  * NGHTTP2_ERR_NOMEM
823  *     Out of memory.
824  * NGHTTP2_ERR_CALLBACK_FAILURE
825  *     The callback function failed.
826  */
827 int nghttp2_session_on_data_received(nghttp2_session *session,
828                                      nghttp2_frame *frame);
829 
830 /*
831  * Returns nghttp2_stream* object whose stream ID is |stream_id|.  It
832  * could be NULL if such stream does not exist.  This function returns
833  * NULL if stream is marked as closed.
834  */
835 nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session,
836                                            int32_t stream_id);
837 
838 /*
839  * This function behaves like nghttp2_session_get_stream(), but it
840  * returns stream object even if it is marked as closed or in
841  * NGHTTP2_STREAM_IDLE state.
842  */
843 nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session,
844                                                int32_t stream_id);
845 
846 /*
847  * Packs DATA frame |frame| in wire frame format and stores it in
848  * |bufs|.  Payload will be read using |aux_data->data_prd|.  The
849  * length of payload is at most |datamax| bytes.
850  *
851  * This function returns 0 if it succeeds, or one of the following
852  * negative error codes:
853  *
854  * NGHTTP2_ERR_DEFERRED
855  *     The DATA frame is postponed.
856  * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
857  *     The read_callback failed (stream error).
858  * NGHTTP2_ERR_NOMEM
859  *     Out of memory.
860  * NGHTTP2_ERR_CALLBACK_FAILURE
861  *     The read_callback failed (session error).
862  */
863 int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
864                               size_t datamax, nghttp2_frame *frame,
865                               nghttp2_data_aux_data *aux_data,
866                               nghttp2_stream *stream);
867 
868 /*
869  * Pops and returns next item to send.  If there is no such item,
870  * returns NULL.  This function takes into account max concurrent
871  * streams.  That means if session->ob_syn has item and max concurrent
872  * streams is reached, the even if other queues contain items, then
873  * this function returns NULL.
874  */
875 nghttp2_outbound_item *
876 nghttp2_session_pop_next_ob_item(nghttp2_session *session);
877 
878 /*
879  * Returns next item to send.  If there is no such item, this function
880  * returns NULL.  This function takes into account max concurrent
881  * streams.  That means if session->ob_syn has item and max concurrent
882  * streams is reached, the even if other queues contain items, then
883  * this function returns NULL.
884  */
885 nghttp2_outbound_item *
886 nghttp2_session_get_next_ob_item(nghttp2_session *session);
887 
888 /*
889  * Updates local settings with the |iv|. The number of elements in the
890  * array pointed by the |iv| is given by the |niv|.  This function
891  * assumes that the all settings_id member in |iv| are in range 1 to
892  * NGHTTP2_SETTINGS_MAX, inclusive.
893  *
894  * While updating individual stream's local window size, if the window
895  * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
896  * RST_STREAM is issued against such a stream.
897  *
898  * This function returns 0 if it succeeds, or one of the following
899  * negative error codes:
900  *
901  * NGHTTP2_ERR_NOMEM
902  *     Out of memory
903  */
904 int nghttp2_session_update_local_settings(nghttp2_session *session,
905                                           nghttp2_settings_entry *iv,
906                                           size_t niv);
907 
908 /*
909  * Re-prioritize |stream|. The new priority specification is
910  * |pri_spec|.  Caller must ensure that stream->hd.stream_id !=
911  * pri_spec->stream_id.
912  *
913  * This function does not adjust the number of idle streams.  The
914  * caller should call nghttp2_session_adjust_idle_stream() later.
915  *
916  * This function returns 0 if it succeeds, or one of the following
917  * negative error codes:
918  *
919  * NGHTTP2_ERR_NOMEM
920  *     Out of memory
921  */
922 int nghttp2_session_reprioritize_stream(nghttp2_session *session,
923                                         nghttp2_stream *stream,
924                                         const nghttp2_priority_spec *pri_spec);
925 
926 /*
927  * Terminates current |session| with the |error_code|.  The |reason|
928  * is NULL-terminated debug string.
929  *
930  * This function returns 0 if it succeeds, or one of the following
931  * negative error codes:
932  *
933  * NGHTTP2_ERR_NOMEM
934  *     Out of memory.
935  * NGHTTP2_ERR_INVALID_ARGUMENT
936  *     The |reason| is too long.
937  */
938 int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
939                                                   uint32_t error_code,
940                                                   const char *reason);
941 
942 /*
943  * Accumulates received bytes |delta_size| for connection-level flow
944  * control and decides whether to send WINDOW_UPDATE to the
945  * connection.  If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
946  * WINDOW_UPDATE will not be sent.
947  *
948  * This function returns 0 if it succeeds, or one of the following
949  * negative error codes:
950  *
951  * NGHTTP2_ERR_NOMEM
952  *     Out of memory.
953  */
954 int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session,
955                                                        size_t delta_size);
956 
957 /*
958  * Accumulates received bytes |delta_size| for stream-level flow
959  * control and decides whether to send WINDOW_UPDATE to that stream.
960  * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
961  * be sent.
962  *
963  * This function returns 0 if it succeeds, or one of the following
964  * negative error codes:
965  *
966  * NGHTTP2_ERR_NOMEM
967  *     Out of memory.
968  */
969 int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
970                                                    nghttp2_stream *stream,
971                                                    size_t delta_size,
972                                                    int send_window_update);
973 
974 #endif /* NGHTTP2_SESSION_H */
975