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