• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * nghttp3
3  *
4  * Copyright (c) 2019 nghttp3 contributors
5  * Copyright (c) 2013 nghttp2 contributors
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 #ifndef NGHTTP3_FRAME_H
27 #define NGHTTP3_FRAME_H
28 
29 #ifdef HAVE_CONFIG_H
30 #  include <config.h>
31 #endif /* HAVE_CONFIG_H */
32 
33 #include <nghttp3/nghttp3.h>
34 
35 #include "nghttp3_buf.h"
36 
37 typedef enum nghttp3_frame_type {
38   NGHTTP3_FRAME_DATA = 0x00,
39   NGHTTP3_FRAME_HEADERS = 0x01,
40   NGHTTP3_FRAME_CANCEL_PUSH = 0x03,
41   NGHTTP3_FRAME_SETTINGS = 0x04,
42   NGHTTP3_FRAME_PUSH_PROMISE = 0x05,
43   NGHTTP3_FRAME_GOAWAY = 0x07,
44   NGHTTP3_FRAME_MAX_PUSH_ID = 0x0d,
45   /* PRIORITY_UPDATE:
46      https://tools.ietf.org/html/draft-ietf-httpbis-priority-03 */
47   NGHTTP3_FRAME_PRIORITY_UPDATE = 0x0f0700,
48   NGHTTP3_FRAME_PRIORITY_UPDATE_PUSH_ID = 0x0f0701,
49 } nghttp3_frame_type;
50 
51 typedef enum nghttp3_h2_reserved_type {
52   NGHTTP3_H2_FRAME_PRIORITY = 0x02,
53   NGHTTP3_H2_FRAME_PING = 0x06,
54   NGHTTP3_H2_FRAME_WINDOW_UPDATE = 0x08,
55   NGHTTP3_H2_FRAME_CONTINUATION = 0x9,
56 } nghttp3_h2_reserved_type;
57 
58 typedef struct nghttp3_frame_hd {
59   int64_t type;
60   int64_t length;
61 } nghttp3_frame_hd;
62 
63 typedef struct nghttp3_frame_data {
64   nghttp3_frame_hd hd;
65 } nghttp3_frame_data;
66 
67 typedef struct nghttp3_frame_headers {
68   nghttp3_frame_hd hd;
69   nghttp3_nv *nva;
70   size_t nvlen;
71 } nghttp3_frame_headers;
72 
73 #define NGHTTP3_SETTINGS_ID_MAX_FIELD_SECTION_SIZE 0x06
74 #define NGHTTP3_SETTINGS_ID_QPACK_MAX_TABLE_CAPACITY 0x01
75 #define NGHTTP3_SETTINGS_ID_QPACK_BLOCKED_STREAMS 0x07
76 #define NGHTTP3_SETTINGS_ID_ENABLE_CONNECT_PROTOCOL 0x08
77 
78 #define NGHTTP3_H2_SETTINGS_ID_ENABLE_PUSH 0x2
79 #define NGHTTP3_H2_SETTINGS_ID_MAX_CONCURRENT_STREAMS 0x3
80 #define NGHTTP3_H2_SETTINGS_ID_INITIAL_WINDOW_SIZE 0x4
81 #define NGHTTP3_H2_SETTINGS_ID_MAX_FRAME_SIZE 0x5
82 
83 typedef struct nghttp3_settings_entry {
84   uint64_t id;
85   uint64_t value;
86 } nghttp3_settings_entry;
87 
88 typedef struct nghttp3_frame_settings {
89   nghttp3_frame_hd hd;
90   size_t niv;
91   nghttp3_settings_entry iv[1];
92 } nghttp3_frame_settings;
93 
94 typedef struct nghttp3_frame_goaway {
95   nghttp3_frame_hd hd;
96   int64_t id;
97 } nghttp3_frame_goaway;
98 
99 typedef struct nghttp3_frame_priority_update {
100   nghttp3_frame_hd hd;
101   /* pri_elem_id is stream ID if hd.type ==
102      NGHTTP3_FRAME_PRIORITY_UPDATE.  It is push ID if hd.type ==
103      NGHTTP3_FRAME_PRIORITY_UPDATE_PUSH_ID.  It is undefined
104      otherwise. */
105   int64_t pri_elem_id;
106   nghttp3_pri pri;
107 } nghttp3_frame_priority_update;
108 
109 typedef union nghttp3_frame {
110   nghttp3_frame_hd hd;
111   nghttp3_frame_data data;
112   nghttp3_frame_headers headers;
113   nghttp3_frame_settings settings;
114   nghttp3_frame_goaway goaway;
115   nghttp3_frame_priority_update priority_update;
116 } nghttp3_frame;
117 
118 /*
119  * nghttp3_frame_write_hd writes frame header |hd| to |dest|.  This
120  * function assumes that |dest| has enough space to write |hd|.
121  *
122  * This function returns |dest| plus the number of bytes written.
123  */
124 uint8_t *nghttp3_frame_write_hd(uint8_t *dest, const nghttp3_frame_hd *hd);
125 
126 /*
127  * nghttp3_frame_write_hd_len returns the number of bytes required to
128  * write |hd|.  hd->length must be set.
129  */
130 size_t nghttp3_frame_write_hd_len(const nghttp3_frame_hd *hd);
131 
132 /*
133  * nghttp3_frame_write_settings writes SETTINGS frame |fr| to |dest|.
134  * This function assumes that |dest| has enough space to write |fr|.
135  *
136  * This function returns |dest| plus the number of bytes written.
137  */
138 uint8_t *nghttp3_frame_write_settings(uint8_t *dest,
139                                       const nghttp3_frame_settings *fr);
140 
141 /*
142  * nghttp3_frame_write_settings_len returns the number of bytes
143  * required to write |fr|.  fr->hd.length is ignored.  This function
144  * stores payload length in |*ppayloadlen|.
145  */
146 size_t nghttp3_frame_write_settings_len(int64_t *pppayloadlen,
147                                         const nghttp3_frame_settings *fr);
148 
149 /*
150  * nghttp3_frame_write_goaway writes GOAWAY frame |fr| to |dest|.
151  * This function assumes that |dest| has enough space to write |fr|.
152  *
153  * This function returns |dest| plus the number of bytes written.
154  */
155 uint8_t *nghttp3_frame_write_goaway(uint8_t *dest,
156                                     const nghttp3_frame_goaway *fr);
157 
158 /*
159  * nghttp3_frame_write_goaway_len returns the number of bytes required
160  * to write |fr|.  fr->hd.length is ignored.  This function stores
161  * payload length in |*ppayloadlen|.
162  */
163 size_t nghttp3_frame_write_goaway_len(int64_t *ppayloadlen,
164                                       const nghttp3_frame_goaway *fr);
165 
166 /*
167  * nghttp3_frame_write_priority_update writes PRIORITY_UPDATE frame
168  * |fr| to |dest|.  This function assumes that |dest| has enough space
169  * to write |fr|.
170  *
171  * This function returns |dest| plus the number of bytes written;
172  */
173 uint8_t *
174 nghttp3_frame_write_priority_update(uint8_t *dest,
175                                     const nghttp3_frame_priority_update *fr);
176 
177 /*
178  * nghttp3_frame_write_priority_update_len returns the number of bytes
179  * required to write |fr|.  fr->hd.length is ignored.  This function
180  * stores payload length in |*ppayloadlen|.
181  */
182 size_t nghttp3_frame_write_priority_update_len(
183     int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr);
184 
185 /*
186  * nghttp3_nva_copy copies name/value pairs from |nva|, which contains
187  * |nvlen| pairs, to |*nva_ptr|, which is dynamically allocated so
188  * that all items can be stored.  The resultant name and value in
189  * nghttp2_nv are guaranteed to be NULL-terminated even if the input
190  * is not null-terminated.
191  *
192  * The |*pnva| must be freed using nghttp3_nva_del().
193  *
194  * This function returns 0 if it succeeds or one of the following
195  * negative error codes:
196  *
197  * NGHTTP3_ERR_NOMEM
198  *     Out of memory.
199  */
200 int nghttp3_nva_copy(nghttp3_nv **pnva, const nghttp3_nv *nva, size_t nvlen,
201                      const nghttp3_mem *mem);
202 
203 /*
204  * nghttp3_nva_del frees |nva|.
205  */
206 void nghttp3_nva_del(nghttp3_nv *nva, const nghttp3_mem *mem);
207 
208 /*
209  * nghttp3_frame_headers_free frees memory allocated for |fr|.  It
210  * assumes that fr->nva is created by nghttp3_nva_copy() or NULL.
211  */
212 void nghttp3_frame_headers_free(nghttp3_frame_headers *fr,
213                                 const nghttp3_mem *mem);
214 
215 #endif /* NGHTTP3_FRAME_H */
216