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_CONN_H
26#define NGHTTP3_CONN_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_stream.h"
35#include "nghttp3_map.h"
36#include "nghttp3_qpack.h"
37#include "nghttp3_tnode.h"
38#include "nghttp3_idtr.h"
39#include "nghttp3_gaptr.h"
40
41#define NGHTTP3_VARINT_MAX ((1ull << 62) - 1)
42
43/* NGHTTP3_QPACK_ENCODER_MAX_TABLE_CAPACITY is the maximum dynamic
44   table size for QPACK encoder. */
45#define NGHTTP3_QPACK_ENCODER_MAX_TABLE_CAPACITY 16384
46
47/* NGHTTP3_QPACK_ENCODER_MAX_BLOCK_STREAMS is the maximum number of
48   blocked streams for QPACK encoder. */
49#define NGHTTP3_QPACK_ENCODER_MAX_BLOCK_STREAMS 100
50
51/* NGHTTP3_CONN_FLAG_NONE indicates that no flag is set. */
52#define NGHTTP3_CONN_FLAG_NONE 0x0000u
53/* NGHTTP3_CONN_FLAG_SETTINGS_RECVED is set when SETTINGS frame has
54   been received. */
55#define NGHTTP3_CONN_FLAG_SETTINGS_RECVED 0x0001u
56/* NGHTTP3_CONN_FLAG_CONTROL_OPENED is set when a control stream has
57   opened. */
58#define NGHTTP3_CONN_FLAG_CONTROL_OPENED 0x0002u
59/* NGHTTP3_CONN_FLAG_QPACK_ENCODER_OPENED is set when a QPACK encoder
60   stream has opened. */
61#define NGHTTP3_CONN_FLAG_QPACK_ENCODER_OPENED 0x0004u
62/* NGHTTP3_CONN_FLAG_QPACK_DECODER_OPENED is set when a QPACK decoder
63   stream has opened. */
64#define NGHTTP3_CONN_FLAG_QPACK_DECODER_OPENED 0x0008u
65/* NGHTTP3_CONN_FLAG_GOAWAY_RECVED indicates that GOAWAY frame has
66   received. */
67#define NGHTTP3_CONN_FLAG_GOAWAY_RECVED 0x0020u
68/* NGHTTP3_CONN_FLAG_GOAWAY_QUEUED indicates that GOAWAY frame has
69   been submitted for transmission. */
70#define NGHTTP3_CONN_FLAG_GOAWAY_QUEUED 0x0040u
71
72typedef struct nghttp3_chunk {
73  nghttp3_opl_entry oplent;
74} nghttp3_chunk;
75
76nghttp3_objalloc_def(chunk, nghttp3_chunk, oplent);
77
78struct nghttp3_conn {
79  nghttp3_objalloc out_chunk_objalloc;
80  nghttp3_objalloc stream_objalloc;
81  nghttp3_callbacks callbacks;
82  nghttp3_map streams;
83  nghttp3_qpack_decoder qdec;
84  nghttp3_qpack_encoder qenc;
85  nghttp3_pq qpack_blocked_streams;
86  struct {
87    nghttp3_pq spq;
88  } sched[NGHTTP3_URGENCY_LEVELS];
89  const nghttp3_mem *mem;
90  void *user_data;
91  int server;
92  uint16_t flags;
93  uint64_t next_seq;
94
95  struct {
96    nghttp3_settings settings;
97    struct {
98      /* max_pushes is the number of push IDs that local endpoint can
99         issue.  This field is used by server only and used just for
100         validation */
101      uint64_t max_pushes;
102    } uni;
103  } local;
104
105  struct {
106    struct {
107      nghttp3_idtr idtr;
108      /* max_client_streams is the cumulative number of client
109         initiated bidirectional stream ID the remote endpoint can
110         issue.  This field is used on server side only. */
111      uint64_t max_client_streams;
112    } bidi;
113    nghttp3_settings settings;
114  } remote;
115
116  struct {
117    /* goaway_id is the latest ID received in GOAWAY frame. */
118    int64_t goaway_id;
119
120    int64_t max_stream_id_bidi;
121
122    /* pri_fieldbuf is a buffer to store incoming Priority Field Value
123       in PRIORITY_UPDATE frame. */
124    uint8_t pri_fieldbuf[8];
125    /* pri_fieldlen is the number of bytes written into
126       pri_fieldbuf. */
127    size_t pri_fieldbuflen;
128  } rx;
129
130  struct {
131    struct {
132      nghttp3_buf rbuf;
133      nghttp3_buf ebuf;
134    } qpack;
135    nghttp3_stream *ctrl;
136    nghttp3_stream *qenc;
137    nghttp3_stream *qdec;
138    /* goaway_id is the latest ID sent in GOAWAY frame. */
139    int64_t goaway_id;
140  } tx;
141};
142
143nghttp3_stream *nghttp3_conn_find_stream(nghttp3_conn *conn, int64_t stream_id);
144
145int nghttp3_conn_create_stream(nghttp3_conn *conn, nghttp3_stream **pstream,
146                               int64_t stream_id);
147
148nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
149                                     nghttp3_stream *stream, const uint8_t *src,
150                                     size_t srclen, int fin);
151
152nghttp3_ssize nghttp3_conn_read_uni(nghttp3_conn *conn, nghttp3_stream *stream,
153                                    const uint8_t *src, size_t srclen, int fin);
154
155nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
156                                        nghttp3_stream *stream,
157                                        const uint8_t *src, size_t srclen);
158
159nghttp3_ssize nghttp3_conn_read_qpack_encoder(nghttp3_conn *conn,
160                                              const uint8_t *src,
161                                              size_t srclen);
162
163nghttp3_ssize nghttp3_conn_read_qpack_decoder(nghttp3_conn *conn,
164                                              const uint8_t *src,
165                                              size_t srclen);
166
167int nghttp3_conn_on_data(nghttp3_conn *conn, nghttp3_stream *stream,
168                         const uint8_t *data, size_t datalen);
169
170int nghttp3_conn_on_priority_update(nghttp3_conn *conn,
171                                    const nghttp3_frame_priority_update *fr);
172
173nghttp3_ssize nghttp3_conn_on_headers(nghttp3_conn *conn,
174                                      nghttp3_stream *stream,
175                                      const uint8_t *data, size_t datalen,
176                                      int fin);
177
178int nghttp3_conn_on_settings_entry_received(nghttp3_conn *conn,
179                                            const nghttp3_frame_settings *fr);
180
181int nghttp3_conn_qpack_blocked_streams_push(nghttp3_conn *conn,
182                                            nghttp3_stream *stream);
183
184void nghttp3_conn_qpack_blocked_streams_pop(nghttp3_conn *conn);
185
186int nghttp3_conn_schedule_stream(nghttp3_conn *conn, nghttp3_stream *stream);
187
188int nghttp3_conn_ensure_stream_scheduled(nghttp3_conn *conn,
189                                         nghttp3_stream *stream);
190
191void nghttp3_conn_unschedule_stream(nghttp3_conn *conn, nghttp3_stream *stream);
192
193int nghttp3_conn_reject_stream(nghttp3_conn *conn, nghttp3_stream *stream);
194
195/*
196 * nghttp3_conn_get_next_tx_stream returns next stream to send.  It
197 * returns NULL if there is no such stream.
198 */
199nghttp3_stream *nghttp3_conn_get_next_tx_stream(nghttp3_conn *conn);
200
201#endif /* NGHTTP3_CONN_H */
202