private-lib-roles-h2.h 11 KB

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