1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 extern const struct lws_role_ops role_ops_h2; 26 #define lwsi_role_h2(wsi) (wsi->role_ops == &role_ops_h2) 27 28 struct http2_settings { 29 uint32_t s[H2SET_COUNT]; 30 }; 31 32 struct lws_vhost_role_h2 { 33 struct http2_settings set; 34 }; 35 36 enum lws_h2_wellknown_frame_types { 37 LWS_H2_FRAME_TYPE_DATA, 38 LWS_H2_FRAME_TYPE_HEADERS, 39 LWS_H2_FRAME_TYPE_PRIORITY, 40 LWS_H2_FRAME_TYPE_RST_STREAM, 41 LWS_H2_FRAME_TYPE_SETTINGS, 42 LWS_H2_FRAME_TYPE_PUSH_PROMISE, 43 LWS_H2_FRAME_TYPE_PING, 44 LWS_H2_FRAME_TYPE_GOAWAY, 45 LWS_H2_FRAME_TYPE_WINDOW_UPDATE, 46 LWS_H2_FRAME_TYPE_CONTINUATION, 47 48 LWS_H2_FRAME_TYPE_COUNT /* always last */ 49 }; 50 51 enum lws_h2_flags { 52 LWS_H2_FLAG_END_STREAM = 1, 53 LWS_H2_FLAG_END_HEADERS = 4, 54 LWS_H2_FLAG_PADDED = 8, 55 LWS_H2_FLAG_PRIORITY = 0x20, 56 57 LWS_H2_FLAG_SETTINGS_ACK = 1, 58 }; 59 60 enum lws_h2_errors { 61 H2_ERR_NO_ERROR, /* Graceful shutdown */ 62 H2_ERR_PROTOCOL_ERROR, /* Protocol error detected */ 63 H2_ERR_INTERNAL_ERROR, /* Implementation fault */ 64 H2_ERR_FLOW_CONTROL_ERROR, /* Flow-control limits exceeded */ 65 H2_ERR_SETTINGS_TIMEOUT, /* Settings not acknowledged */ 66 H2_ERR_STREAM_CLOSED, /* Frame received for closed stream */ 67 H2_ERR_FRAME_SIZE_ERROR, /* Frame size incorrect */ 68 H2_ERR_REFUSED_STREAM, /* Stream not processed */ 69 H2_ERR_CANCEL, /* Stream cancelled */ 70 H2_ERR_COMPRESSION_ERROR, /* Compression state not updated */ 71 H2_ERR_CONNECT_ERROR, /* TCP connection error for CONNECT method */ 72 H2_ERR_ENHANCE_YOUR_CALM, /* Processing capacity exceeded */ 73 H2_ERR_INADEQUATE_SECURITY, /* Negotiated TLS parameters not acceptable */ 74 H2_ERR_HTTP_1_1_REQUIRED, /* Use HTTP/1.1 for the request */ 75 }; 76 77 enum lws_h2_states { 78 LWS_H2_STATE_IDLE, 79 /* 80 * Send PUSH_PROMISE -> LWS_H2_STATE_RESERVED_LOCAL 81 * Recv PUSH_PROMISE -> LWS_H2_STATE_RESERVED_REMOTE 82 * Send HEADERS -> LWS_H2_STATE_OPEN 83 * Recv HEADERS -> LWS_H2_STATE_OPEN 84 * 85 * - Only PUSH_PROMISE + HEADERS valid to send 86 * - Only HEADERS or PRIORITY valid to receive 87 */ 88 LWS_H2_STATE_RESERVED_LOCAL, 89 /* 90 * Send RST_STREAM -> LWS_H2_STATE_CLOSED 91 * Recv RST_STREAM -> LWS_H2_STATE_CLOSED 92 * Send HEADERS -> LWS_H2_STATE_HALF_CLOSED_REMOTE 93 * 94 * - Only HEADERS, RST_STREAM, or PRIORITY valid to send 95 * - Only RST_STREAM, PRIORITY, or WINDOW_UPDATE valid to receive 96 */ 97 LWS_H2_STATE_RESERVED_REMOTE, 98 /* 99 * Send RST_STREAM -> LWS_H2_STATE_CLOSED 100 * Recv RST_STREAM -> LWS_H2_STATE_CLOSED 101 * Recv HEADERS -> LWS_H2_STATE_HALF_CLOSED_LOCAL 102 * 103 * - Only RST_STREAM, WINDOW_UPDATE, or PRIORITY valid to send 104 * - Only HEADERS, RST_STREAM, or PRIORITY valid to receive 105 */ 106 LWS_H2_STATE_OPEN, 107 /* 108 * Send RST_STREAM -> LWS_H2_STATE_CLOSED 109 * Recv RST_STREAM -> LWS_H2_STATE_CLOSED 110 * Send END_STREAM flag -> LWS_H2_STATE_HALF_CLOSED_LOCAL 111 * Recv END_STREAM flag -> LWS_H2_STATE_HALF_CLOSED_REMOTE 112 */ 113 LWS_H2_STATE_HALF_CLOSED_REMOTE, 114 /* 115 * Send RST_STREAM -> LWS_H2_STATE_CLOSED 116 * Recv RST_STREAM -> LWS_H2_STATE_CLOSED 117 * Send END_STREAM flag -> LWS_H2_STATE_CLOSED 118 * 119 * - Any frame valid to send 120 * - Only WINDOW_UPDATE, PRIORITY, or RST_STREAM valid to receive 121 */ 122 LWS_H2_STATE_HALF_CLOSED_LOCAL, 123 /* 124 * Send RST_STREAM -> LWS_H2_STATE_CLOSED 125 * Recv RST_STREAM -> LWS_H2_STATE_CLOSED 126 * Recv END_STREAM flag -> LWS_H2_STATE_CLOSED 127 * 128 * - Only WINDOW_UPDATE, PRIORITY, and RST_STREAM valid to send 129 * - Any frame valid to receive 130 */ 131 LWS_H2_STATE_CLOSED, 132 /* 133 * - Only PRIORITY, WINDOW_UPDATE (IGNORE) and RST_STREAM (IGNORE) 134 * may be received 135 * 136 * - Only PRIORITY valid to send 137 */ 138 }; 139 140 void 141 lws_h2_state(struct lws *wsi, enum lws_h2_states s); 142 143 #define LWS_H2_STREAM_ID_MASTER 0 144 #define LWS_H2_SETTINGS_LEN 6 145 #define LWS_H2_FLAG_SETTINGS_ACK 1 146 147 enum http2_hpack_state { 148 HPKS_TYPE, 149 150 HPKS_IDX_EXT, 151 152 HPKS_HLEN, 153 HPKS_HLEN_EXT, 154 155 HPKS_DATA, 156 }; 157 158 /* 159 * lws general parsimonious header strategy is only store values from known 160 * headers, and refer to them by index. 161 * 162 * That means if we can't map the peer header name to one that lws knows, we 163 * will drop the content but track the indexing with associated_lws_hdr_idx = 164 * LWS_HPACK_IGNORE_ENTRY. 165 */ 166 167 enum http2_hpack_type { 168 HPKT_INDEXED_HDR_7, /* 1xxxxxxx: just "header field" */ 169 HPKT_INDEXED_HDR_6_VALUE_INCR, /* 01xxxxxx: NEW indexed hdr with value */ 170 HPKT_LITERAL_HDR_VALUE_INCR, /* 01000000: NEW literal hdr with value */ 171 HPKT_INDEXED_HDR_4_VALUE, /* 0000xxxx: indexed hdr with value */ 172 HPKT_INDEXED_HDR_4_VALUE_NEVER, /* 0001xxxx: indexed hdr with value NEVER NEW */ 173 HPKT_LITERAL_HDR_VALUE, /* 00000000: literal hdr with value */ 174 HPKT_LITERAL_HDR_VALUE_NEVER, /* 00010000: literal hdr with value NEVER NEW */ 175 HPKT_SIZE_5 176 }; 177 178 #define LWS_HPACK_IGNORE_ENTRY 0xffff 179 180 181 struct hpack_dt_entry { 182 char *value; /* malloc'd */ 183 uint16_t value_len; 184 uint16_t hdr_len; /* virtual, for accounting */ 185 uint16_t lws_hdr_idx; /* LWS_HPACK_IGNORE_ENTRY = IGNORE */ 186 }; 187 188 struct hpack_dynamic_table { 189 struct hpack_dt_entry *entries; /* malloc'd */ 190 uint32_t virtual_payload_usage; 191 uint32_t virtual_payload_max; 192 uint16_t pos; 193 uint16_t used_entries; 194 uint16_t num_entries; 195 }; 196 197 enum lws_h2_protocol_send_type { 198 LWS_PPS_NONE, 199 LWS_H2_PPS_MY_SETTINGS, 200 LWS_H2_PPS_ACK_SETTINGS, 201 LWS_H2_PPS_PING, 202 LWS_H2_PPS_PONG, 203 LWS_H2_PPS_GOAWAY, 204 LWS_H2_PPS_RST_STREAM, 205 LWS_H2_PPS_UPDATE_WINDOW, 206 LWS_H2_PPS_SETTINGS_INITIAL_UPDATE_WINDOW 207 }; 208 209 struct lws_h2_protocol_send { 210 struct lws_h2_protocol_send *next; /* linked list */ 211 enum lws_h2_protocol_send_type type; 212 213 union uu { 214 struct { 215 char str[32]; 216 uint32_t highest_sid; 217 uint32_t err; 218 } ga; 219 struct { 220 uint32_t sid; 221 uint32_t err; 222 } rs; 223 struct { 224 uint8_t ping_payload[8]; 225 } ping; 226 struct { 227 uint32_t sid; 228 uint32_t credit; 229 } update_window; 230 } u; 231 }; 232 233 struct lws_h2_ghost_sid { 234 struct lws_h2_ghost_sid *next; 235 uint32_t sid; 236 }; 237 238 /* 239 * http/2 connection info that is only used by the root connection that has 240 * the network connection. 241 * 242 * h2 tends to spawn many child connections from one network connection, so 243 * it's necessary to make members only needed by the network connection 244 * distinct and only malloc'd on network connections. 245 * 246 * There's only one HPACK parser per network connection. 247 * 248 * But there is an ah per logical child connection... the network connection 249 * fills it but it belongs to the logical child. 250 */ 251 struct lws_h2_netconn { 252 struct http2_settings our_set; 253 struct http2_settings peer_set; 254 struct hpack_dynamic_table hpack_dyn_table; 255 uint8_t ping_payload[8]; 256 uint8_t one_setting[LWS_H2_SETTINGS_LEN]; 257 char goaway_str[32]; /* for rx */ 258 struct lws *swsi; 259 struct lws_h2_protocol_send *pps; /* linked list */ 260 261 enum http2_hpack_state hpack; 262 enum http2_hpack_type hpack_type; 263 264 unsigned int huff:1; 265 unsigned int value:1; 266 unsigned int unknown_header:1; 267 unsigned int cont_exp:1; 268 unsigned int cont_exp_headers:1; 269 unsigned int we_told_goaway:1; 270 unsigned int pad_length:1; 271 unsigned int collected_priority:1; 272 unsigned int is_first_header_char:1; 273 unsigned int zero_huff_padding:1; 274 unsigned int last_action_dyntable_resize:1; 275 276 uint32_t hdr_idx; 277 uint32_t hpack_len; 278 uint32_t hpack_e_dep; 279 uint32_t count; 280 uint32_t preamble; 281 uint32_t length; 282 uint32_t sid; 283 uint32_t inside; 284 uint32_t highest_sid; 285 uint32_t highest_sid_opened; 286 uint32_t cont_exp_sid; 287 uint32_t dep; 288 uint32_t goaway_last_sid; 289 uint32_t goaway_err; 290 uint32_t hpack_hdr_len; 291 292 uint16_t hpack_pos; 293 294 uint8_t frame_state; 295 uint8_t type; 296 uint8_t flags; 297 uint8_t padding; 298 uint8_t weight_temp; 299 uint8_t huff_pad; 300 char first_hdr_char; 301 uint8_t hpack_m; 302 uint8_t ext_count; 303 }; 304 305 struct _lws_h2_related { 306 307 struct lws_h2_netconn *h2n; /* malloc'd for root net conn */ 308 309 char *pending_status_body; 310 311 uint8_t h2_state; /* RFC7540 state of the connection */ 312 313 uint8_t END_STREAM:1; 314 uint8_t END_HEADERS:1; 315 uint8_t send_END_STREAM:1; 316 uint8_t long_poll:1; 317 uint8_t initialized:1; 318 }; 319 320 #define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->mux.parent_wsi) 321 322 int 323 lws_h2_rst_stream(struct lws *wsi, uint32_t err, const char *reason); 324 struct lws * lws_h2_get_nth_child(struct lws *wsi, int n); 325 LWS_EXTERN void lws_h2_init(struct lws *wsi); 326 LWS_EXTERN int 327 lws_h2_settings(struct lws *nwsi, struct http2_settings *settings, 328 unsigned char *buf, int len); 329 LWS_EXTERN int 330 lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen, 331 lws_filepos_t *inused); 332 LWS_EXTERN int 333 lws_h2_do_pps_send(struct lws *wsi); 334 LWS_EXTERN int 335 lws_h2_frame_write(struct lws *wsi, int type, int flags, unsigned int sid, 336 unsigned int len, unsigned char *buf); 337 LWS_EXTERN struct lws * 338 lws_wsi_mux_from_id(struct lws *wsi, unsigned int sid); 339 LWS_EXTERN int 340 lws_hpack_interpret(struct lws *wsi, unsigned char c); 341 LWS_EXTERN int 342 lws_add_http2_header_by_name(struct lws *wsi, 343 const unsigned char *name, 344 const unsigned char *value, int length, 345 unsigned char **p, unsigned char *end); 346 LWS_EXTERN int 347 lws_add_http2_header_by_token(struct lws *wsi, 348 enum lws_token_indexes token, 349 const unsigned char *value, int length, 350 unsigned char **p, unsigned char *end); 351 LWS_EXTERN int 352 lws_add_http2_header_status(struct lws *wsi, 353 unsigned int code, unsigned char **p, 354 unsigned char *end); 355 LWS_EXTERN void 356 lws_hpack_destroy_dynamic_header(struct lws *wsi); 357 LWS_EXTERN int 358 lws_hpack_dynamic_size(struct lws *wsi, int size); 359 LWS_EXTERN int 360 lws_h2_goaway(struct lws *wsi, uint32_t err, const char *reason); 361 LWS_EXTERN int 362 lws_h2_tx_cr_get(struct lws *wsi); 363 LWS_EXTERN void 364 lws_h2_tx_cr_consume(struct lws *wsi, int consumed); 365 LWS_EXTERN int 366 lws_hdr_extant(struct lws *wsi, enum lws_token_indexes h); 367 LWS_EXTERN void 368 lws_pps_schedule(struct lws *wsi, struct lws_h2_protocol_send *pss); 369 370 LWS_EXTERN const struct http2_settings lws_h2_defaults; 371 LWS_EXTERN int 372 lws_h2_ws_handshake(struct lws *wsi); 373 LWS_EXTERN int lws_h2_issue_preface(struct lws *wsi); 374 LWS_EXTERN int 375 lws_h2_client_handshake(struct lws *wsi); 376 LWS_EXTERN struct lws * 377 lws_wsi_h2_adopt(struct lws *parent_wsi, struct lws *wsi); 378 int 379 lws_handle_POLLOUT_event_h2(struct lws *wsi); 380 int 381 lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len); 382 struct lws_h2_protocol_send * 383 lws_h2_new_pps(enum lws_h2_protocol_send_type type); 384