• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "private-lib-core.h"
26 
27 /*
28  * bitmap of control messages that are valid to receive for each http2 state
29  */
30 
31 static const uint16_t http2_rx_validity[] = {
32 	/* LWS_H2S_IDLE */
33 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
34 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
35 //		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE)| /* ignore */
36 		(1 << LWS_H2_FRAME_TYPE_HEADERS) |
37 		(1 << LWS_H2_FRAME_TYPE_CONTINUATION),
38 	/* LWS_H2S_RESERVED_LOCAL */
39 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
40 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM) |
41 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
42 		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE),
43 	/* LWS_H2S_RESERVED_REMOTE */
44 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
45 		(1 << LWS_H2_FRAME_TYPE_HEADERS) |
46 		(1 << LWS_H2_FRAME_TYPE_CONTINUATION) |
47 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM) |
48 		(1 << LWS_H2_FRAME_TYPE_PRIORITY),
49 	/* LWS_H2S_OPEN */
50 		(1 << LWS_H2_FRAME_TYPE_DATA) |
51 		(1 << LWS_H2_FRAME_TYPE_HEADERS) |
52 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
53 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM) |
54 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
55 		(1 << LWS_H2_FRAME_TYPE_PUSH_PROMISE) |
56 		(1 << LWS_H2_FRAME_TYPE_PING) |
57 		(1 << LWS_H2_FRAME_TYPE_GOAWAY) |
58 		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE) |
59 		(1 << LWS_H2_FRAME_TYPE_CONTINUATION),
60 	/* LWS_H2S_HALF_CLOSED_REMOTE */
61 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
62 		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE) |
63 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
64 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM),
65 	/* LWS_H2S_HALF_CLOSED_LOCAL */
66 		(1 << LWS_H2_FRAME_TYPE_DATA) |
67 		(1 << LWS_H2_FRAME_TYPE_HEADERS) |
68 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
69 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM) |
70 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
71 		(1 << LWS_H2_FRAME_TYPE_PUSH_PROMISE) |
72 		(1 << LWS_H2_FRAME_TYPE_PING) |
73 		(1 << LWS_H2_FRAME_TYPE_GOAWAY) |
74 		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE) |
75 		(1 << LWS_H2_FRAME_TYPE_CONTINUATION),
76 	/* LWS_H2S_CLOSED */
77 		(1 << LWS_H2_FRAME_TYPE_SETTINGS) |
78 		(1 << LWS_H2_FRAME_TYPE_PRIORITY) |
79 		(1 << LWS_H2_FRAME_TYPE_WINDOW_UPDATE) |
80 		(1 << LWS_H2_FRAME_TYPE_RST_STREAM),
81 };
82 
83 static const char *preface = "PRI * HTTP/2.0\x0d\x0a\x0d\x0aSM\x0d\x0a\x0d\x0a";
84 
85 static const char * const h2_state_names[] = {
86 	"LWS_H2S_IDLE",
87 	"LWS_H2S_RESERVED_LOCAL",
88 	"LWS_H2S_RESERVED_REMOTE",
89 	"LWS_H2S_OPEN",
90 	"LWS_H2S_HALF_CLOSED_REMOTE",
91 	"LWS_H2S_HALF_CLOSED_LOCAL",
92 	"LWS_H2S_CLOSED",
93 };
94 
95 #if 0
96 static const char * const h2_setting_names[] = {
97 	"",
98 	"H2SET_HEADER_TABLE_SIZE",
99 	"H2SET_ENABLE_PUSH",
100 	"H2SET_MAX_CONCURRENT_STREAMS",
101 	"H2SET_INITIAL_WINDOW_SIZE",
102 	"H2SET_MAX_FRAME_SIZE",
103 	"H2SET_MAX_HEADER_LIST_SIZE",
104 	"reserved",
105 	"H2SET_ENABLE_CONNECT_PROTOCOL"
106 };
107 
108 void
109 lws_h2_dump_settings(struct http2_settings *set)
110 {
111 	int n;
112 
113 	for (n = 1; n < H2SET_COUNT; n++)
114 		lwsl_notice("   %30s: %10d\n", h2_setting_names[n], set->s[n]);
115 }
116 #else
117 void
lws_h2_dump_settings(struct http2_settings * set)118 lws_h2_dump_settings(struct http2_settings *set)
119 {
120 }
121 #endif
122 
123 struct lws_h2_protocol_send *
lws_h2_new_pps(enum lws_h2_protocol_send_type type)124 lws_h2_new_pps(enum lws_h2_protocol_send_type type)
125 {
126 	struct lws_h2_protocol_send *pps = lws_malloc(sizeof(*pps), "pps");
127 
128 	if (pps)
129 		pps->type = type;
130 
131 	return pps;
132 }
133 
lws_h2_init(struct lws * wsi)134 void lws_h2_init(struct lws *wsi)
135 {
136 	wsi->h2.h2n->our_set = wsi->vhost->h2.set;
137 	wsi->h2.h2n->peer_set = lws_h2_defaults;
138 }
139 
140 void
lws_h2_state(struct lws * wsi,enum lws_h2_states s)141 lws_h2_state(struct lws *wsi, enum lws_h2_states s)
142 {
143 	if (!wsi)
144 		return;
145 	lwsl_info("%s: wsi %p: state %s -> %s\n", __func__, wsi,
146 			h2_state_names[wsi->h2.h2_state],
147 			h2_state_names[s]);
148 
149 	(void)h2_state_names;
150 	wsi->h2.h2_state = (uint8_t)s;
151 }
152 
153 int
lws_h2_update_peer_txcredit(struct lws * wsi,int sid,int bump)154 lws_h2_update_peer_txcredit(struct lws *wsi, int sid, int bump)
155 {
156 	struct lws *nwsi = lws_get_network_wsi(wsi);
157 	struct lws_h2_protocol_send *pps;
158 
159 	assert(wsi);
160 
161 	if (!bump)
162 		return 0;
163 
164 	if (sid == -1)
165 		sid = wsi->mux.my_sid;
166 
167 	lwsl_info("%s: sid %d: bump %d -> %d\n", __func__, sid, bump,
168 			(int)wsi->txc.peer_tx_cr_est + bump);
169 
170 	pps = lws_h2_new_pps(LWS_H2_PPS_UPDATE_WINDOW);
171 	if (!pps)
172 		return 1;
173 
174 	pps->u.update_window.sid = sid;
175 	pps->u.update_window.credit = bump;
176 	wsi->txc.peer_tx_cr_est += bump;
177 
178 	lws_wsi_txc_describe(&wsi->txc, __func__, wsi->mux.my_sid);
179 
180 	lws_pps_schedule(wsi, pps);
181 
182 	pps = lws_h2_new_pps(LWS_H2_PPS_UPDATE_WINDOW);
183 	if (!pps)
184 		return 1;
185 
186 	pps->u.update_window.sid = 0;
187 	pps->u.update_window.credit = bump;
188 	nwsi->txc.peer_tx_cr_est += bump;
189 
190 	lws_wsi_txc_describe(&nwsi->txc, __func__, nwsi->mux.my_sid);
191 
192 	lws_pps_schedule(nwsi, pps);
193 
194 	return 0;
195 }
196 
197 int
lws_h2_get_peer_txcredit_estimate(struct lws * wsi)198 lws_h2_get_peer_txcredit_estimate(struct lws *wsi)
199 {
200 	lws_wsi_txc_describe(&wsi->txc, __func__, wsi->mux.my_sid);
201 	return (int)wsi->txc.peer_tx_cr_est;
202 }
203 
204 static int
lws_h2_update_peer_txcredit_thresh(struct lws * wsi,int sid,int threshold,int bump)205 lws_h2_update_peer_txcredit_thresh(struct lws *wsi, int sid, int threshold, int bump)
206 {
207 	if (wsi->txc.peer_tx_cr_est > threshold)
208 		return 0;
209 
210 	return lws_h2_update_peer_txcredit(wsi, sid, bump);
211 }
212 
213 struct lws *
lws_wsi_server_new(struct lws_vhost * vh,struct lws * parent_wsi,unsigned int sid)214 lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi,
215 			    unsigned int sid)
216 {
217 	struct lws *wsi;
218 	struct lws *nwsi = lws_get_network_wsi(parent_wsi);
219 	struct lws_h2_netconn *h2n = nwsi->h2.h2n;
220 
221 	/*
222 	 * The identifier of a newly established stream MUST be numerically
223    	 * greater than all streams that the initiating endpoint has opened or
224    	 * reserved.  This governs streams that are opened using a HEADERS frame
225    	 * and streams that are reserved using PUSH_PROMISE.  An endpoint that
226    	 * receives an unexpected stream identifier MUST respond with a
227    	 * connection error (Section 5.4.1) of type PROTOCOL_ERROR.
228 	 */
229 	if (sid <= h2n->highest_sid_opened) {
230 		lwsl_info("%s: tried to open lower sid %d (%d)\n", __func__,
231 				sid, (int)h2n->highest_sid_opened);
232 		lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR, "Bad sid");
233 		return NULL;
234 	}
235 
236 	/* no more children allowed by parent */
237 	if (parent_wsi->mux.child_count + 1 >
238 	    parent_wsi->h2.h2n->our_set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
239 		lwsl_notice("reached concurrent stream limit\n");
240 		return NULL;
241 	}
242 	wsi = lws_create_new_server_wsi(vh, parent_wsi->tsi);
243 	if (!wsi) {
244 		lwsl_notice("new server wsi failed (vh %p)\n", vh);
245 		return NULL;
246 	}
247 
248 	h2n->highest_sid_opened = sid;
249 
250 	lws_wsi_mux_insert(wsi, parent_wsi, sid);
251 	if (sid >= h2n->highest_sid)
252 		h2n->highest_sid = sid + 2;
253 
254 	wsi->mux_substream = 1;
255 	wsi->seen_nonpseudoheader = 0;
256 
257 	wsi->txc.tx_cr = nwsi->h2.h2n->peer_set.s[H2SET_INITIAL_WINDOW_SIZE];
258 	wsi->txc.peer_tx_cr_est =
259 			nwsi->h2.h2n->our_set.s[H2SET_INITIAL_WINDOW_SIZE];
260 
261 	lwsi_set_state(wsi, LRS_ESTABLISHED);
262 	lwsi_set_role(wsi, lwsi_role(parent_wsi));
263 
264 	wsi->protocol = &vh->protocols[0];
265 	if (lws_ensure_user_space(wsi))
266 		goto bail1;
267 
268 #if defined(LWS_WITH_SERVER_STATUS)
269 	wsi->vhost->conn_stats.h2_subs++;
270 #endif
271 
272 	/* get the ball rolling */
273 	lws_validity_confirmed(wsi);
274 
275 	lwsl_info("%s: %p new ch %p, sid %d, usersp=%p\n", __func__,
276 		  parent_wsi, wsi, sid, wsi->user_space);
277 
278 	lws_wsi_txc_describe(&wsi->txc, __func__, wsi->mux.my_sid);
279 	lws_wsi_txc_describe(&nwsi->txc, __func__, 0);
280 
281 	return wsi;
282 
283 bail1:
284 	/* undo the insert */
285 	parent_wsi->mux.child_list = wsi->mux.sibling_list;
286 	parent_wsi->mux.child_count--;
287 
288 	vh->context->count_wsi_allocated--;
289 
290 	if (wsi->user_space)
291 		lws_free_set_NULL(wsi->user_space);
292 	vh->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY, NULL, NULL, 0);
293 	lws_vhost_unbind_wsi(wsi);
294 	lws_free(wsi);
295 
296 	return NULL;
297 }
298 
299 struct lws *
lws_wsi_h2_adopt(struct lws * parent_wsi,struct lws * wsi)300 lws_wsi_h2_adopt(struct lws *parent_wsi, struct lws *wsi)
301 {
302 	struct lws *nwsi = lws_get_network_wsi(parent_wsi);
303 
304 	/* no more children allowed by parent */
305 	if (parent_wsi->mux.child_count + 1 >
306 	    parent_wsi->h2.h2n->our_set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
307 		lwsl_notice("reached concurrent stream limit\n");
308 		return NULL;
309 	}
310 
311 	/* sid is set just before issuing the headers, ensuring monoticity */
312 
313 	wsi->seen_nonpseudoheader = 0;
314 #if defined(LWS_WITH_CLIENT)
315 	wsi->client_mux_substream = 1;
316 #endif
317 	wsi->h2.initialized = 1;
318 
319 #if 0
320 	/* only assign sid at header send time when we know it */
321 	if (!wsi->mux.my_sid) {
322 		wsi->mux.my_sid = nwsi->h2.h2n->highest_sid;
323 		nwsi->h2.h2n->highest_sid += 2;
324 	}
325 #endif
326 
327 	lwsl_info("%s: binding wsi %p to sid %d (next %d)\n", __func__,
328 			wsi, (int)wsi->mux.my_sid, (int)nwsi->h2.h2n->highest_sid);
329 
330 	lws_wsi_mux_insert(wsi, parent_wsi, wsi->mux.my_sid);
331 
332 	wsi->txc.tx_cr = nwsi->h2.h2n->peer_set.s[H2SET_INITIAL_WINDOW_SIZE];
333 	wsi->txc.peer_tx_cr_est =
334 			nwsi->h2.h2n->our_set.s[H2SET_INITIAL_WINDOW_SIZE];
335 
336 	lws_wsi_txc_describe(&wsi->txc, __func__, wsi->mux.my_sid);
337 
338 	if (lws_ensure_user_space(wsi))
339 		goto bail1;
340 
341 	lws_role_transition(wsi, LWSIFR_CLIENT, LRS_H2_WAITING_TO_SEND_HEADERS,
342 			    &role_ops_h2);
343 
344 	lws_callback_on_writable(wsi);
345 
346 #if defined(LWS_WITH_SERVER_STATUS)
347 	wsi->vhost->conn_stats.h2_subs++;
348 #endif
349 
350 	return wsi;
351 
352 bail1:
353 	/* undo the insert */
354 	parent_wsi->mux.child_list = wsi->mux.sibling_list;
355 	parent_wsi->mux.child_count--;
356 
357 	if (wsi->user_space)
358 		lws_free_set_NULL(wsi->user_space);
359 	wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_DESTROY, NULL, NULL, 0);
360 	lws_free(wsi);
361 
362 	return NULL;
363 }
364 
365 
lws_h2_issue_preface(struct lws * wsi)366 int lws_h2_issue_preface(struct lws *wsi)
367 {
368 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
369 	struct lws_h2_protocol_send *pps;
370 
371 	if (lws_issue_raw(wsi, (uint8_t *)preface, strlen(preface)) !=
372 		(int)strlen(preface))
373 		return 1;
374 
375 	lws_role_transition(wsi, LWSIFR_CLIENT, LRS_H2_WAITING_TO_SEND_HEADERS,
376 			    &role_ops_h2);
377 
378 	h2n->count = 0;
379 	wsi->txc.tx_cr = 65535;
380 
381 	/*
382 	 * we must send a settings frame
383 	 */
384 	pps = lws_h2_new_pps(LWS_H2_PPS_MY_SETTINGS);
385 	if (!pps)
386 		return 1;
387 	lws_pps_schedule(wsi, pps);
388 	lwsl_info("%s: h2 client sending settings\n", __func__);
389 
390 	return 0;
391 }
392 
393 void
lws_pps_schedule(struct lws * wsi,struct lws_h2_protocol_send * pps)394 lws_pps_schedule(struct lws *wsi, struct lws_h2_protocol_send *pps)
395 {
396 	struct lws *nwsi = lws_get_network_wsi(wsi);
397 	struct lws_h2_netconn *h2n = nwsi->h2.h2n;
398 
399 	pps->next = h2n->pps;
400 	h2n->pps = pps;
401 	lws_rx_flow_control(wsi, LWS_RXFLOW_REASON_APPLIES_DISABLE |
402 				 LWS_RXFLOW_REASON_H2_PPS_PENDING);
403 	lws_callback_on_writable(wsi);
404 }
405 
406 int
lws_h2_goaway(struct lws * wsi,uint32_t err,const char * reason)407 lws_h2_goaway(struct lws *wsi, uint32_t err, const char *reason)
408 {
409 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
410 	struct lws_h2_protocol_send *pps;
411 
412 	if (h2n->type == LWS_H2_FRAME_TYPE_COUNT)
413 		return 0;
414 
415 	pps = lws_h2_new_pps(LWS_H2_PPS_GOAWAY);
416 	if (!pps)
417 		return 1;
418 
419 	lwsl_info("%s: %p: ERR 0x%x, '%s'\n", __func__, wsi, (int)err, reason);
420 
421 	pps->u.ga.err = err;
422 	pps->u.ga.highest_sid = h2n->highest_sid;
423 	lws_strncpy(pps->u.ga.str, reason, sizeof(pps->u.ga.str));
424 	lws_pps_schedule(wsi, pps);
425 
426 	h2n->type = LWS_H2_FRAME_TYPE_COUNT; /* ie, IGNORE */
427 
428 	return 0;
429 }
430 
431 int
lws_h2_rst_stream(struct lws * wsi,uint32_t err,const char * reason)432 lws_h2_rst_stream(struct lws *wsi, uint32_t err, const char *reason)
433 {
434 	struct lws *nwsi = lws_get_network_wsi(wsi);
435 	struct lws_h2_netconn *h2n = nwsi->h2.h2n;
436 	struct lws_h2_protocol_send *pps;
437 
438 	if (!h2n)
439 		return 0;
440 
441 	if (!wsi->h2_stream_carries_ws && h2n->type == LWS_H2_FRAME_TYPE_COUNT)
442 		return 0;
443 
444 	pps = lws_h2_new_pps(LWS_H2_PPS_RST_STREAM);
445 	if (!pps)
446 		return 1;
447 
448 	lwsl_info("%s: RST_STREAM 0x%x, sid %d, REASON '%s'\n", __func__,
449 		  (int)err, wsi->mux.my_sid, reason);
450 
451 	pps->u.rs.sid = wsi->mux.my_sid;
452 	pps->u.rs.err = err;
453 
454 	lws_pps_schedule(wsi, pps);
455 
456 	h2n->type = LWS_H2_FRAME_TYPE_COUNT; /* ie, IGNORE */
457 	lws_h2_state(wsi, LWS_H2_STATE_CLOSED);
458 
459 	return 0;
460 }
461 
462 int
lws_h2_settings(struct lws * wsi,struct http2_settings * settings,unsigned char * buf,int len)463 lws_h2_settings(struct lws *wsi, struct http2_settings *settings,
464 		unsigned char *buf, int len)
465 {
466 	struct lws *nwsi = lws_get_network_wsi(wsi);
467 	unsigned int a, b;
468 
469 	if (!len)
470 		return 0;
471 
472 	if (len < LWS_H2_SETTINGS_LEN)
473 		return 1;
474 
475 	while (len >= LWS_H2_SETTINGS_LEN) {
476 		a = (buf[0] << 8) | buf[1];
477 		if (!a || a >= H2SET_COUNT)
478 			goto skip;
479 		b = buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5];
480 
481 		switch (a) {
482 		case H2SET_HEADER_TABLE_SIZE:
483 			break;
484 		case H2SET_ENABLE_PUSH:
485 			if (b > 1) {
486 				lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
487 					      "ENABLE_PUSH invalid arg");
488 				return 1;
489 			}
490 			break;
491 		case H2SET_MAX_CONCURRENT_STREAMS:
492 			break;
493 		case H2SET_INITIAL_WINDOW_SIZE:
494 			if (b > 0x7fffffff) {
495 				lws_h2_goaway(nwsi, H2_ERR_FLOW_CONTROL_ERROR,
496 					      "Inital Window beyond max");
497 				return 1;
498 			}
499 
500 #if defined(LWS_WITH_CLIENT)
501 #if defined(LWS_AMAZON_RTOS) || defined(LWS_AMAZON_LINUX)
502 			if (
503 #else
504 			if (wsi->flags & LCCSCF_H2_QUIRK_OVERFLOWS_TXCR &&
505 #endif
506 			    b == 0x7fffffff) {
507 				b >>= 4;
508 
509 				break;
510 			}
511 #endif
512 
513 			/*
514 			 * In addition to changing the flow-control window for
515 			 * streams that are not yet active, a SETTINGS frame
516 			 * can alter the initial flow-control window size for
517 			 * streams with active flow-control windows (that is,
518 			 * streams in the "open" or "half-closed (remote)"
519 			 * state).  When the value of
520 			 * SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver
521 			 * MUST adjust the size of all stream flow-control
522 			 * windows that it maintains by the difference between
523 			 * the new value and the old value.
524 			 */
525 
526 			lws_start_foreach_ll(struct lws *, w,
527 					     nwsi->mux.child_list) {
528 				lwsl_info("%s: adi child tc cr %d +%d -> %d",
529 					  __func__, (int)w->txc.tx_cr,
530 					  b - (unsigned int)settings->s[a],
531 					  (int)w->txc.tx_cr + b -
532 						  (unsigned int)settings->s[a]);
533 				w->txc.tx_cr += b - settings->s[a];
534 				if (w->txc.tx_cr > 0 &&
535 				    w->txc.tx_cr <=
536 						  (int32_t)(b - settings->s[a]))
537 
538 					lws_callback_on_writable(w);
539 			} lws_end_foreach_ll(w, mux.sibling_list);
540 
541 			break;
542 		case H2SET_MAX_FRAME_SIZE:
543 			if (b < wsi->vhost->h2.set.s[H2SET_MAX_FRAME_SIZE]) {
544 				lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
545 					      "Frame size < initial");
546 				return 1;
547 			}
548 			if (b > 0x00ffffff) {
549 				lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
550 					      "Settings Frame size above max");
551 				return 1;
552 			}
553 			break;
554 		case H2SET_MAX_HEADER_LIST_SIZE:
555 			break;
556 		}
557 		settings->s[a] = b;
558 		lwsl_info("http2 settings %d <- 0x%x\n", a, b);
559 skip:
560 		len -= LWS_H2_SETTINGS_LEN;
561 		buf += LWS_H2_SETTINGS_LEN;
562 	}
563 
564 	if (len)
565 		return 1;
566 
567 	lws_h2_dump_settings(settings);
568 
569 	return 0;
570 }
571 
572 /* RFC7640 Sect 6.9
573  *
574  * The WINDOW_UPDATE frame can be specific to a stream or to the entire
575  * connection.  In the former case, the frame's stream identifier
576  * indicates the affected stream; in the latter, the value "0" indicates
577  * that the entire connection is the subject of the frame.
578  *
579  * ...
580  *
581  * Two flow-control windows are applicable: the stream flow-control
582  * window and the connection flow-control window.  The sender MUST NOT
583  * send a flow-controlled frame with a length that exceeds the space
584  * available in either of the flow-control windows advertised by the
585  * receiver.  Frames with zero length with the END_STREAM flag set (that
586  * is, an empty DATA frame) MAY be sent if there is no available space
587  * in either flow-control window.
588  */
589 
590 int
lws_h2_tx_cr_get(struct lws * wsi)591 lws_h2_tx_cr_get(struct lws *wsi)
592 {
593 	int c = wsi->txc.tx_cr;
594 	struct lws *nwsi = lws_get_network_wsi(wsi);
595 
596 	if (!wsi->mux_substream && !nwsi->upgraded_to_http2)
597 		return ~0x80000000;
598 
599 	lwsl_info ("%s: %p: own tx credit %d: nwsi credit %d\n",
600 		     __func__, wsi, c, (int)nwsi->txc.tx_cr);
601 
602 	if (nwsi->txc.tx_cr < c)
603 		c = nwsi->txc.tx_cr;
604 
605 	if (c < 0)
606 		return 0;
607 
608 	return c;
609 }
610 
611 void
lws_h2_tx_cr_consume(struct lws * wsi,int consumed)612 lws_h2_tx_cr_consume(struct lws *wsi, int consumed)
613 {
614 	struct lws *nwsi = lws_get_network_wsi(wsi);
615 
616 	wsi->txc.tx_cr -= consumed;
617 
618 	if (nwsi != wsi)
619 		nwsi->txc.tx_cr -= consumed;
620 }
621 
lws_h2_frame_write(struct lws * wsi,int type,int flags,unsigned int sid,unsigned int len,unsigned char * buf)622 int lws_h2_frame_write(struct lws *wsi, int type, int flags,
623 		       unsigned int sid, unsigned int len, unsigned char *buf)
624 {
625 	struct lws *nwsi = lws_get_network_wsi(wsi);
626 	unsigned char *p = &buf[-LWS_H2_FRAME_HEADER_LENGTH];
627 	int n;
628 
629 	//if (wsi->h2_stream_carries_ws)
630 	// lwsl_hexdump_level(LLL_NOTICE, buf, len);
631 
632 	*p++ = len >> 16;
633 	*p++ = len >> 8;
634 	*p++ = len;
635 	*p++ = type;
636 	*p++ = flags;
637 	*p++ = sid >> 24;
638 	*p++ = sid >> 16;
639 	*p++ = sid >> 8;
640 	*p++ = sid;
641 
642 	lwsl_debug("%s: %p (eff %p). typ %d, fl 0x%x, sid=%d, len=%d, "
643 		   "txcr=%d, nwsi->txcr=%d\n", __func__, wsi, nwsi, type, flags,
644 		   sid, len, (int)wsi->txc.tx_cr, (int)nwsi->txc.tx_cr);
645 
646 	if (type == LWS_H2_FRAME_TYPE_DATA) {
647 		if (wsi->txc.tx_cr < (int)len)
648 			lwsl_info("%s: %p: sending payload len %d"
649 				 " but tx_cr only %d!\n", __func__, wsi,
650 				 len, (int)wsi->txc.tx_cr);
651 		lws_h2_tx_cr_consume(wsi, len);
652 	}
653 
654 	n = lws_issue_raw(nwsi, &buf[-LWS_H2_FRAME_HEADER_LENGTH],
655 			  len + LWS_H2_FRAME_HEADER_LENGTH);
656 	if (n < 0)
657 		return n;
658 
659 	if (n >= LWS_H2_FRAME_HEADER_LENGTH)
660 		return n - LWS_H2_FRAME_HEADER_LENGTH;
661 
662 	return n;
663 }
664 
lws_h2_set_bin(struct lws * wsi,int n,unsigned char * buf)665 static void lws_h2_set_bin(struct lws *wsi, int n, unsigned char *buf)
666 {
667 	*buf++ = n >> 8;
668 	*buf++ = n;
669 	*buf++ = wsi->h2.h2n->our_set.s[n] >> 24;
670 	*buf++ = wsi->h2.h2n->our_set.s[n] >> 16;
671 	*buf++ = wsi->h2.h2n->our_set.s[n] >> 8;
672 	*buf = wsi->h2.h2n->our_set.s[n];
673 }
674 
675 /* we get called on the network connection */
676 
lws_h2_do_pps_send(struct lws * wsi)677 int lws_h2_do_pps_send(struct lws *wsi)
678 {
679 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
680 	struct lws_h2_protocol_send *pps = NULL;
681 	struct lws *cwsi;
682 	uint8_t set[LWS_PRE + 64], *p = &set[LWS_PRE], *q;
683 	int n, m = 0, flags = 0;
684 
685 	if (!h2n)
686 		return 1;
687 
688 	/* get the oldest pps */
689 
690 	lws_start_foreach_llp(struct lws_h2_protocol_send **, pps1, h2n->pps) {
691 		if ((*pps1)->next == NULL) { /* we are the oldest in the list */
692 			pps = *pps1; /* remove us from the list */
693 			*pps1 = NULL;
694 			continue;
695 		}
696 	} lws_end_foreach_llp(pps1, next);
697 
698 	if (!pps)
699 		return 1;
700 
701 	lwsl_info("%s: %p: %d\n", __func__, wsi, pps->type);
702 
703 	switch (pps->type) {
704 
705 	case LWS_H2_PPS_MY_SETTINGS:
706 
707 		/*
708 		 * if any of our settings varies from h2 "default defaults"
709 		 * then we must inform the peer
710 		 */
711 		for (n = 1; n < H2SET_COUNT; n++)
712 			if (h2n->our_set.s[n] != lws_h2_defaults.s[n]) {
713 				lwsl_debug("sending SETTING %d 0x%x\n", n,
714 					   (unsigned int)
715 						   wsi->h2.h2n->our_set.s[n]);
716 
717 				lws_h2_set_bin(wsi, n, &set[LWS_PRE + m]);
718 				m += sizeof(h2n->one_setting);
719 			}
720 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_SETTINGS,
721 				       flags, LWS_H2_STREAM_ID_MASTER, m,
722 		     		       &set[LWS_PRE]);
723 		if (n != m) {
724 			lwsl_info("send %d %d\n", n, m);
725 			goto bail;
726 		}
727 		break;
728 
729 	case LWS_H2_PPS_SETTINGS_INITIAL_UPDATE_WINDOW:
730 		q = &set[LWS_PRE];
731 		*q++ = H2SET_INITIAL_WINDOW_SIZE >> 8;
732 		*q++ = H2SET_INITIAL_WINDOW_SIZE;
733 		*q++ = pps->u.update_window.credit >> 24;
734 		*q++ = pps->u.update_window.credit >> 16;
735 		*q++ = pps->u.update_window.credit >> 8;
736 		*q = pps->u.update_window.credit;
737 
738 		lwsl_debug("%s: resetting initial window to %d\n", __func__,
739 				(int)pps->u.update_window.credit);
740 
741 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_SETTINGS,
742 				       flags, LWS_H2_STREAM_ID_MASTER, 6,
743 		     		       &set[LWS_PRE]);
744 		if (n != 6) {
745 			lwsl_info("send %d %d\n", n, m);
746 			goto bail;
747 		}
748 		break;
749 
750 	case LWS_H2_PPS_ACK_SETTINGS:
751 		/* send ack ... always empty */
752 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_SETTINGS, 1,
753 				       LWS_H2_STREAM_ID_MASTER, 0,
754 				       &set[LWS_PRE]);
755 		if (n) {
756 			lwsl_err("ack tells %d\n", n);
757 			goto bail;
758 		}
759 		wsi->h2_acked_settings = 0;
760 		/* this is the end of the preface dance then? */
761 		if (lwsi_state(wsi) == LRS_H2_AWAIT_SETTINGS) {
762 			lwsi_set_state(wsi, LRS_ESTABLISHED);
763 #if defined(LWS_WITH_FILE_OPS)
764 			wsi->http.fop_fd = NULL;
765 #endif
766 			if (lws_is_ssl(lws_get_network_wsi(wsi)))
767 				break;
768 			/*
769 			 * we need to treat the headers from the upgrade as the
770 			 * first job.  So these need to get shifted to sid 1.
771 			 */
772 			h2n->swsi = lws_wsi_server_new(wsi->vhost, wsi, 1);
773 			if (!h2n->swsi)
774 				goto bail;
775 
776 			/* pass on the initial headers to SID 1 */
777 			h2n->swsi->http.ah = wsi->http.ah;
778 			wsi->http.ah = NULL;
779 
780 			lwsl_info("%s: inherited headers %p\n", __func__,
781 				  h2n->swsi->http.ah);
782 			h2n->swsi->txc.tx_cr =
783 				h2n->our_set.s[H2SET_INITIAL_WINDOW_SIZE];
784 			lwsl_info("initial tx credit on conn %p: %d\n",
785 				  h2n->swsi, (int)h2n->swsi->txc.tx_cr);
786 			h2n->swsi->h2.initialized = 1;
787 			/* demanded by HTTP2 */
788 			h2n->swsi->h2.END_STREAM = 1;
789 			lwsl_info("servicing initial http request\n");
790 
791 #if defined(LWS_WITH_SERVER_STATUS)
792 			wsi->vhost->conn_stats.h2_trans++;
793 #endif
794 #if defined(LWS_WITH_SERVER)
795 			if (lws_http_action(h2n->swsi))
796 				goto bail;
797 #endif
798 			break;
799 		}
800 		break;
801 
802 	/*
803 	 * h2 only has PING... ACK = 0 = ping, ACK = 1 = pong
804 	 */
805 
806 	case LWS_H2_PPS_PING:
807 	case LWS_H2_PPS_PONG:
808 		if (pps->type == LWS_H2_PPS_PING)
809 			lwsl_info("sending PING\n");
810 		else {
811 			lwsl_info("sending PONG\n");
812 			flags = LWS_H2_FLAG_SETTINGS_ACK;
813 		}
814 
815 		memcpy(&set[LWS_PRE], pps->u.ping.ping_payload, 8);
816 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_PING, flags,
817 				       LWS_H2_STREAM_ID_MASTER, 8,
818 				       &set[LWS_PRE]);
819 		if (n != 8)
820 			goto bail;
821 
822 		break;
823 
824 	case LWS_H2_PPS_GOAWAY:
825 		lwsl_info("LWS_H2_PPS_GOAWAY\n");
826 		*p++ = pps->u.ga.highest_sid >> 24;
827 		*p++ = pps->u.ga.highest_sid >> 16;
828 		*p++ = pps->u.ga.highest_sid >> 8;
829 		*p++ = pps->u.ga.highest_sid;
830 		*p++ = pps->u.ga.err >> 24;
831 		*p++ = pps->u.ga.err >> 16;
832 		*p++ = pps->u.ga.err >> 8;
833 		*p++ = pps->u.ga.err;
834 		q = (unsigned char *)pps->u.ga.str;
835 		n = 0;
836 		while (*q && n++ < (int)sizeof(pps->u.ga.str))
837 			*p++ = *q++;
838 		h2n->we_told_goaway = 1;
839 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_GOAWAY, 0,
840 				       LWS_H2_STREAM_ID_MASTER,
841 				       lws_ptr_diff(p, &set[LWS_PRE]),
842 				       &set[LWS_PRE]);
843 		if (n != 4) {
844 			lwsl_info("send %d %d\n", n, m);
845 			goto bail;
846 		}
847 		goto bail;
848 
849 	case LWS_H2_PPS_RST_STREAM:
850 		lwsl_info("LWS_H2_PPS_RST_STREAM\n");
851 		*p++ = pps->u.rs.err >> 24;
852 		*p++ = pps->u.rs.err >> 16;
853 		*p++ = pps->u.rs.err >> 8;
854 		*p++ = pps->u.rs.err;
855 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_RST_STREAM,
856 				       0, pps->u.rs.sid, 4, &set[LWS_PRE]);
857 		if (n != 4) {
858 			lwsl_info("send %d %d\n", n, m);
859 			goto bail;
860 		}
861 		cwsi = lws_wsi_mux_from_id(wsi, pps->u.rs.sid);
862 		if (cwsi) {
863 			lwsl_debug("%s: closing cwsi %p %s %s (wsi %p)\n",
864 				   __func__, cwsi, cwsi->role_ops->name,
865 				   cwsi->protocol->name, wsi);
866 			lws_close_free_wsi(cwsi, 0, "reset stream");
867 		}
868 		break;
869 
870 	case LWS_H2_PPS_UPDATE_WINDOW:
871 		lwsl_info("Issuing LWS_H2_PPS_UPDATE_WINDOW: sid %d: add %d\n",
872 			    (int)pps->u.update_window.sid,
873 			    (int)pps->u.update_window.credit);
874 		*p++ = (pps->u.update_window.credit >> 24) & 0x7f; /* 31b */
875 		*p++ = pps->u.update_window.credit >> 16;
876 		*p++ = pps->u.update_window.credit >> 8;
877 		*p++ = pps->u.update_window.credit;
878 		n = lws_h2_frame_write(wsi, LWS_H2_FRAME_TYPE_WINDOW_UPDATE,
879 				       0, pps->u.update_window.sid, 4,
880 				       &set[LWS_PRE]);
881 		if (n != 4) {
882 			lwsl_info("send %d %d\n", n, m);
883 			goto bail;
884 		}
885 		break;
886 
887 	default:
888 		break;
889 	}
890 
891 	lws_free(pps);
892 
893 	return 0;
894 
895 bail:
896 	lws_free(pps);
897 
898 	return 1;
899 }
900 
901 static int
902 lws_h2_parse_end_of_frame(struct lws *wsi);
903 
904 /*
905  * The frame header part has just completely arrived.
906  * Perform actions for header completion.
907  */
908 static int
lws_h2_parse_frame_header(struct lws * wsi)909 lws_h2_parse_frame_header(struct lws *wsi)
910 {
911 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
912 	struct lws_h2_protocol_send *pps;
913 	int n;
914 
915 	/*
916 	 * We just got the frame header
917 	 */
918 	h2n->count = 0;
919 	h2n->swsi = wsi;
920 	/* b31 is a reserved bit */
921 	h2n->sid = h2n->sid & 0x7fffffff;
922 
923 	if (h2n->sid && !(h2n->sid & 1)) {
924 		lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "Even Stream ID");
925 
926 		return 0;
927 	}
928 
929 	/* let the network wsi live a bit longer if subs are active */
930 
931 	if (!wsi->immortal_substream_count)
932 		lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE,
933 				wsi->vhost->keepalive_timeout ?
934 					wsi->vhost->keepalive_timeout : 31);
935 
936 	if (h2n->sid)
937 		h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
938 
939 	lwsl_debug("%p (%p): fr hdr: typ 0x%x, fla 0x%x, sid 0x%x, len 0x%x\n",
940 		  wsi, h2n->swsi, h2n->type, h2n->flags, (unsigned int)h2n->sid,
941 		  (unsigned int)h2n->length);
942 
943 	if (h2n->we_told_goaway && h2n->sid > h2n->highest_sid)
944 		h2n->type = LWS_H2_FRAME_TYPE_COUNT; /* ie, IGNORE */
945 
946 	if (h2n->type == LWS_H2_FRAME_TYPE_COUNT)
947 		return 0;
948 
949 	if (h2n->length > h2n->our_set.s[H2SET_MAX_FRAME_SIZE]) {
950 		/*
951 		 * peer sent us something bigger than we told
952 		 * it we would allow
953 		 */
954 		lwsl_info("%s: received oversize frame %d\n", __func__,
955 			  (unsigned int)h2n->length);
956 		lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
957 			      "Peer ignored our frame size setting");
958 		return 1;
959 	}
960 
961 	if (h2n->swsi)
962 		lwsl_info("%s: wsi %p, State: %s, received cmd %d\n",
963 		  __func__, h2n->swsi,
964 		  h2_state_names[h2n->swsi->h2.h2_state], h2n->type);
965 	else {
966 		/* if it's data, either way no swsi means CLOSED state */
967 		if (h2n->type == LWS_H2_FRAME_TYPE_DATA) {
968 			if (h2n->sid <= h2n->highest_sid_opened
969 #if defined(LWS_WITH_CLIENT)
970 					&& wsi->client_h2_alpn
971 #endif
972 			) {
973 				lwsl_notice("ignoring straggling data fl 0x%x\n",
974 						h2n->flags);
975 				/* ie, IGNORE */
976 				h2n->type = LWS_H2_FRAME_TYPE_COUNT;
977 			} else {
978 				lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED,
979 				      "Data for nonexistent sid");
980 				return 0;
981 			}
982 		}
983 		/* if the sid is credible, treat as wsi for it closed */
984 		if (h2n->sid > h2n->highest_sid_opened &&
985 		    h2n->type != LWS_H2_FRAME_TYPE_HEADERS &&
986 		    h2n->type != LWS_H2_FRAME_TYPE_PRIORITY) {
987 			/* if not credible, reject it */
988 			lwsl_info("%s: wsi %p, No child for sid %d, rxcmd %d\n",
989 			  __func__, h2n->swsi, (unsigned int)h2n->sid, h2n->type);
990 			lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED,
991 				     "Data for nonexistent sid");
992 			return 0;
993 		}
994 	}
995 
996 	if (h2n->swsi && h2n->sid &&
997 	    !(http2_rx_validity[h2n->swsi->h2.h2_state] & (1 << h2n->type))) {
998 		lwsl_info("%s: wsi %p, State: %s, ILLEGAL cmdrx %d (OK 0x%x)\n",
999 			  __func__, h2n->swsi,
1000 			  h2_state_names[h2n->swsi->h2.h2_state], h2n->type,
1001 			  http2_rx_validity[h2n->swsi->h2.h2_state]);
1002 
1003 		if (h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED ||
1004 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE)
1005 			n = H2_ERR_STREAM_CLOSED;
1006 		else
1007 			n = H2_ERR_PROTOCOL_ERROR;
1008 		lws_h2_goaway(wsi, n, "invalid rx for state");
1009 
1010 		return 0;
1011 	}
1012 
1013 	if (h2n->cont_exp && (h2n->cont_exp_sid != h2n->sid ||
1014 			      h2n->type != LWS_H2_FRAME_TYPE_CONTINUATION)) {
1015 		lwsl_info("%s: expected cont on sid %u (got %d on sid %u)\n",
1016 			  __func__, (unsigned int)h2n->cont_exp_sid, h2n->type,
1017 			  (unsigned int)h2n->sid);
1018 		h2n->cont_exp = 0;
1019 		if (h2n->cont_exp_headers)
1020 			n = H2_ERR_COMPRESSION_ERROR;
1021 		else
1022 			n = H2_ERR_PROTOCOL_ERROR;
1023 		lws_h2_goaway(wsi, n, "Continuation hdrs State");
1024 
1025 		return 0;
1026 	}
1027 
1028 	switch (h2n->type) {
1029 	case LWS_H2_FRAME_TYPE_DATA:
1030 		lwsl_info("seen incoming LWS_H2_FRAME_TYPE_DATA start\n");
1031 		if (!h2n->sid) {
1032 			lwsl_info("DATA: 0 sid\n");
1033 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "DATA 0 sid");
1034 			break;
1035 		}
1036 		lwsl_info("Frame header DATA: sid %u, flags 0x%x, len %u\n",
1037 				(unsigned int)h2n->sid, h2n->flags,
1038 				(unsigned int)h2n->length);
1039 
1040 		if (!h2n->swsi) {
1041 			lwsl_notice("DATA: NULL swsi\n");
1042 			break;
1043 		}
1044 
1045 		lwsl_info("DATA rx on state %d\n", h2n->swsi->h2.h2_state);
1046 
1047 		if (
1048 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE ||
1049 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED) {
1050 			lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED, "conn closed");
1051 			break;
1052 		}
1053 
1054 		if (h2n->length == 0)
1055 			lws_h2_parse_end_of_frame(wsi);
1056 
1057 		break;
1058 
1059 	case LWS_H2_FRAME_TYPE_PRIORITY:
1060 		lwsl_info("LWS_H2_FRAME_TYPE_PRIORITY complete frame\n");
1061 		if (!h2n->sid) {
1062 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1063 				      "Priority has 0 sid");
1064 			break;
1065 		}
1066 		if (h2n->length != 5) {
1067 			lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1068 				      "Priority has length other than 5");
1069 			break;
1070 		}
1071 		break;
1072 	case LWS_H2_FRAME_TYPE_PUSH_PROMISE:
1073 		lwsl_info("LWS_H2_FRAME_TYPE_PUSH_PROMISE complete frame\n");
1074 		lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "Server only");
1075 		break;
1076 
1077 	case LWS_H2_FRAME_TYPE_GOAWAY:
1078 		lwsl_debug("LWS_H2_FRAME_TYPE_GOAWAY received\n");
1079 		break;
1080 
1081 	case LWS_H2_FRAME_TYPE_RST_STREAM:
1082 		if (!h2n->sid)
1083 			return 1;
1084 		if (!h2n->swsi) {
1085 			if (h2n->sid <= h2n->highest_sid_opened)
1086 				break;
1087 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1088 				      "crazy sid on RST_STREAM");
1089 			return 1;
1090 		}
1091 		if (h2n->length != 4) {
1092 			lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1093 				      "RST_STREAM can only be length 4");
1094 			break;
1095 		}
1096 		lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED);
1097 		break;
1098 
1099 	case LWS_H2_FRAME_TYPE_SETTINGS:
1100 		lwsl_info("LWS_H2_FRAME_TYPE_SETTINGS complete frame\n");
1101 		/* nonzero sid on settings is illegal */
1102 		if (h2n->sid) {
1103 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1104 					 "Settings has nonzero sid");
1105 			break;
1106 		}
1107 
1108 		if (!(h2n->flags & LWS_H2_FLAG_SETTINGS_ACK)) {
1109 			if ((!h2n->length) || h2n->length % 6) {
1110 				lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1111 						 "Settings length error");
1112 				break;
1113 			}
1114 
1115 			if (h2n->type == LWS_H2_FRAME_TYPE_COUNT)
1116 				return 0;
1117 
1118 			if (wsi->upgraded_to_http2 &&
1119 #if defined(LWS_WITH_CLIENT)
1120 			    (!(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM) ||
1121 #else
1122 			    (
1123 #endif
1124 					    !wsi->h2_acked_settings)) {
1125 
1126 				pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS);
1127 				if (!pps)
1128 					return 1;
1129 				lws_pps_schedule(wsi, pps);
1130 				wsi->h2_acked_settings = 1;
1131 			}
1132 			break;
1133 		}
1134 		/* came to us with ACK set... not allowed to have payload */
1135 
1136 		if (h2n->length) {
1137 			lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1138 				      "Settings with ACK not allowed payload");
1139 			break;
1140 		}
1141 		break;
1142 	case LWS_H2_FRAME_TYPE_PING:
1143 		if (h2n->sid) {
1144 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1145 				      "Ping has nonzero sid");
1146 			break;
1147 		}
1148 		if (h2n->length != 8) {
1149 			lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1150 				      "Ping payload can only be 8");
1151 			break;
1152 		}
1153 		break;
1154 	case LWS_H2_FRAME_TYPE_CONTINUATION:
1155 		lwsl_info("LWS_H2_FRAME_TYPE_CONTINUATION: sid = %u %d %d\n",
1156 			  (unsigned int)h2n->sid, (int)h2n->cont_exp,
1157 			  (int)h2n->cont_exp_sid);
1158 
1159 		if (!h2n->cont_exp ||
1160 		     h2n->cont_exp_sid != h2n->sid ||
1161 		     !h2n->sid ||
1162 		     !h2n->swsi) {
1163 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1164 				      "unexpected CONTINUATION");
1165 			break;
1166 		}
1167 
1168 		if (h2n->swsi->h2.END_HEADERS) {
1169 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1170 				      "END_HEADERS already seen");
1171 			break;
1172 		}
1173 		/* END_STREAM is in HEADERS, skip resetting it */
1174 		goto update_end_headers;
1175 
1176 	case LWS_H2_FRAME_TYPE_HEADERS:
1177 		lwsl_info("HEADERS: frame header: sid = %u\n",
1178 				(unsigned int)h2n->sid);
1179 		if (!h2n->sid) {
1180 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "sid 0");
1181 			return 1;
1182 		}
1183 
1184 		if (h2n->swsi && !h2n->swsi->h2.END_STREAM &&
1185 		    h2n->swsi->h2.END_HEADERS &&
1186 		    !(h2n->flags & LWS_H2_FLAG_END_STREAM)) {
1187 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1188 				      "extra HEADERS together");
1189 			return 1;
1190 		}
1191 
1192 #if defined(LWS_WITH_CLIENT)
1193 		if (wsi->client_h2_alpn) {
1194 			if (h2n->sid) {
1195 				h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
1196 				lwsl_info("HEADERS: nwsi %p: sid %u mapped "
1197 					  "to wsi %p\n", wsi,
1198 					  (unsigned int)h2n->sid, h2n->swsi);
1199 				if (!h2n->swsi)
1200 					break;
1201 			}
1202 			goto update_end_headers;
1203 		}
1204 #endif
1205 
1206 		if (!h2n->swsi) {
1207 			/* no more children allowed by parent */
1208 			if (wsi->mux.child_count + 1 >
1209 			    wsi->h2.h2n->our_set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
1210 				lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1211 				"Another stream not allowed");
1212 
1213 				return 1;
1214 			}
1215 
1216 			/*
1217 			 * The peer has sent us a HEADERS implying the creation
1218 			 * of a new stream
1219 			 */
1220 
1221 			h2n->swsi = lws_wsi_server_new(wsi->vhost, wsi,
1222 						       h2n->sid);
1223 			if (!h2n->swsi) {
1224 				lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1225 					      "OOM");
1226 
1227 				return 1;
1228 			}
1229 
1230 			if (h2n->sid >= h2n->highest_sid)
1231 				h2n->highest_sid = h2n->sid + 2;
1232 
1233 			h2n->swsi->h2.initialized = 1;
1234 
1235 			if (lws_h2_update_peer_txcredit(h2n->swsi,
1236 					h2n->swsi->mux.my_sid, 4 * 65536))
1237 				goto cleanup_wsi;
1238 		}
1239 
1240 		/*
1241 		 * ah needs attaching to child wsi, even though
1242 		 * we only fill it from network wsi
1243 		 */
1244 		if (!h2n->swsi->http.ah)
1245 			if (lws_header_table_attach(h2n->swsi, 0)) {
1246 				lwsl_err("%s: Failed to get ah\n", __func__);
1247 				return 1;
1248 			}
1249 
1250 		/*
1251 		 * The first use of a new stream identifier implicitly closes
1252 		 * all streams in the "idle" state that might have been
1253 		 * initiated by that peer with a lower-valued stream identifier.
1254 		 *
1255 		 * For example, if a client sends a HEADERS frame on stream 7
1256 		 * without ever sending a frame on stream 5, then stream 5
1257 		 * transitions to the "closed" state when the first frame for
1258 		 * stream 7 is sent or received.
1259 		 */
1260 		lws_start_foreach_ll(struct lws *, w, wsi->mux.child_list) {
1261 			if (w->mux.my_sid < h2n->sid &&
1262 			    w->h2.h2_state == LWS_H2_STATE_IDLE)
1263 				lws_close_free_wsi(w, 0, "h2 sid close");
1264 			assert(w->mux.sibling_list != w);
1265 		} lws_end_foreach_ll(w, mux.sibling_list);
1266 
1267 		if (lws_check_opt(h2n->swsi->vhost->options,
1268 			       LWS_SERVER_OPTION_VH_H2_HALF_CLOSED_LONG_POLL)) {
1269 
1270 			/*
1271 			 * We don't directly timeout streams that enter the
1272 			 * half-closed remote state, allowing immortal long
1273 			 * poll
1274 			 */
1275 			lws_mux_mark_immortal(h2n->swsi);
1276 			lwsl_info("%s: %p: h2 stream entering long poll\n",
1277 					__func__, h2n->swsi);
1278 
1279 		} else {
1280 			h2n->swsi->h2.END_STREAM =
1281 					!!(h2n->flags & LWS_H2_FLAG_END_STREAM);
1282 			lwsl_debug("%s: hdr END_STREAM = %d\n",__func__,
1283 			  h2n->swsi->h2.END_STREAM);
1284 		}
1285 
1286 		h2n->cont_exp = !(h2n->flags & LWS_H2_FLAG_END_HEADERS);
1287 		h2n->cont_exp_sid = h2n->sid;
1288 		h2n->cont_exp_headers = 1;
1289 	//	lws_header_table_reset(h2n->swsi, 0);
1290 
1291 update_end_headers:
1292 		/* no END_HEADERS means CONTINUATION must come */
1293 		h2n->swsi->h2.END_HEADERS =
1294 				!!(h2n->flags & LWS_H2_FLAG_END_HEADERS);
1295 		lwsl_info("%p: END_HEADERS %d\n", h2n->swsi,
1296 			  h2n->swsi->h2.END_HEADERS);
1297 		if (h2n->swsi->h2.END_HEADERS)
1298 			h2n->cont_exp = 0;
1299 		lwsl_debug("END_HEADERS %d\n", h2n->swsi->h2.END_HEADERS);
1300 		break;
1301 
1302 cleanup_wsi:
1303 
1304 		return 1;
1305 
1306 	case LWS_H2_FRAME_TYPE_WINDOW_UPDATE:
1307 		if (h2n->length != 4) {
1308 			lws_h2_goaway(wsi, H2_ERR_FRAME_SIZE_ERROR,
1309 				      "window update frame not 4");
1310 			break;
1311 		}
1312 		lwsl_info("LWS_H2_FRAME_TYPE_WINDOW_UPDATE\n");
1313 		break;
1314 	case LWS_H2_FRAME_TYPE_COUNT:
1315 		break;
1316 	default:
1317 		lwsl_info("%s: ILLEGAL FRAME TYPE %d\n", __func__, h2n->type);
1318 		h2n->type = LWS_H2_FRAME_TYPE_COUNT; /* ie, IGNORE */
1319 		break;
1320 	}
1321 	if (h2n->length == 0)
1322 		h2n->frame_state = 0;
1323 
1324 	return 0;
1325 }
1326 
1327 static const char * const method_names[] = {
1328 	"GET", "POST",
1329 #if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
1330 	"OPTIONS", "PUT", "PATCH", "DELETE",
1331 #endif
1332 	"CONNECT", "HEAD"
1333 };
1334 static unsigned char method_index[] = {
1335 	WSI_TOKEN_GET_URI,
1336 	WSI_TOKEN_POST_URI,
1337 #if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
1338 	WSI_TOKEN_OPTIONS_URI,
1339 	WSI_TOKEN_PUT_URI,
1340 	WSI_TOKEN_PATCH_URI,
1341 	WSI_TOKEN_DELETE_URI,
1342 #endif
1343 	WSI_TOKEN_CONNECT,
1344 	WSI_TOKEN_HEAD_URI,
1345 };
1346 
1347 /*
1348  * The last byte of the whole frame has been handled.
1349  * Perform actions for frame completion.
1350  *
1351  * This is the crunch time for parsing that may have occured on a network
1352  * wsi with a pending partial send... we may call lws_http_action() to send
1353  * a response, conflicting with the partial.
1354  *
1355  * So in that case we change the wsi state and do the lws_http_action() in the
1356  * WRITABLE handler as a priority.
1357  */
1358 static int
lws_h2_parse_end_of_frame(struct lws * wsi)1359 lws_h2_parse_end_of_frame(struct lws *wsi)
1360 {
1361 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
1362 	struct lws *eff_wsi = wsi;
1363 	const char *p;
1364 	int n;
1365 
1366 	h2n->frame_state = 0;
1367 	h2n->count = 0;
1368 
1369 	if (h2n->sid)
1370 		h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
1371 
1372 	if (h2n->sid > h2n->highest_sid)
1373 		h2n->highest_sid = h2n->sid;
1374 
1375 	if (h2n->collected_priority && (h2n->dep & ~(1u << 31)) == h2n->sid) {
1376 		lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "depends on own sid");
1377 		return 0;
1378 	}
1379 
1380 	switch (h2n->type) {
1381 
1382 	case LWS_H2_FRAME_TYPE_SETTINGS:
1383 
1384 #if defined(LWS_WITH_CLIENT)
1385 		if (wsi->client_h2_alpn && !wsi->client_mux_migrated &&
1386 		    !(h2n->flags & LWS_H2_FLAG_SETTINGS_ACK)) {
1387 			struct lws_h2_protocol_send *pps;
1388 
1389 			/* migrate original client ask on to substream 1 */
1390 #if defined(LWS_WITH_FILE_OPS)
1391 			wsi->http.fop_fd = NULL;
1392 #endif
1393 			lwsl_info("%s: migrating\n", __func__);
1394 			wsi->client_mux_migrated = 1;
1395 			/*
1396 			 * we need to treat the headers from the upgrade as the
1397 			 * first job.  So these need to get shifted to sid 1.
1398 			 */
1399 			h2n->swsi = lws_wsi_server_new(wsi->vhost, wsi, 1);
1400 			if (!h2n->swsi)
1401 				return 1;
1402 			h2n->sid = 1;
1403 
1404 			assert(lws_wsi_mux_from_id(wsi, 1) == h2n->swsi);
1405 
1406 			lws_role_transition(wsi, LWSIFR_CLIENT,
1407 					    LRS_H2_WAITING_TO_SEND_HEADERS,
1408 					    &role_ops_h2);
1409 
1410 			lws_role_transition(h2n->swsi, LWSIFR_CLIENT,
1411 					    LRS_H2_WAITING_TO_SEND_HEADERS,
1412 					    &role_ops_h2);
1413 
1414 			/* pass on the initial headers to SID 1 */
1415 			h2n->swsi->http.ah = wsi->http.ah;
1416 			h2n->swsi->client_mux_substream = 1;
1417 			h2n->swsi->client_h2_alpn = 1;
1418 #if defined(LWS_WITH_CLIENT)
1419 			h2n->swsi->flags = wsi->flags;
1420 #endif
1421 
1422 			h2n->swsi->protocol = wsi->protocol;
1423 			if (h2n->swsi->user_space &&
1424 			    !h2n->swsi->user_space_externally_allocated)
1425 				lws_free(h2n->swsi->user_space);
1426 			h2n->swsi->user_space = wsi->user_space;
1427 			h2n->swsi->user_space_externally_allocated =
1428 					wsi->user_space_externally_allocated;
1429 			h2n->swsi->opaque_user_data = wsi->opaque_user_data;
1430 			wsi->opaque_user_data = NULL;
1431 			h2n->swsi->txc.manual_initial_tx_credit =
1432 					wsi->txc.manual_initial_tx_credit;
1433 
1434 			wsi->user_space = NULL;
1435 
1436 			if (h2n->swsi->http.ah)
1437 				h2n->swsi->http.ah->wsi = h2n->swsi;
1438 			wsi->http.ah = NULL;
1439 
1440 			lwsl_info("%s: MIGRATING nwsi %p: swsi %p\n", __func__,
1441 				  wsi, h2n->swsi);
1442 			h2n->swsi->txc.tx_cr =
1443 				h2n->peer_set.s[H2SET_INITIAL_WINDOW_SIZE];
1444 			lwsl_info("%s: initial tx credit on conn %p: %d\n",
1445 				  __func__, h2n->swsi, (int)h2n->swsi->txc.tx_cr);
1446 			h2n->swsi->h2.initialized = 1;
1447 
1448 			/* set our initial window size */
1449 			if (!wsi->h2.initialized) {
1450 				wsi->txc.tx_cr =
1451 				     h2n->peer_set.s[H2SET_INITIAL_WINDOW_SIZE];
1452 
1453 				lwsl_info("%s: initial tx credit for us to "
1454 					  "write on master %p: %d\n", __func__,
1455 					  wsi, (int)wsi->txc.tx_cr);
1456 				wsi->h2.initialized = 1;
1457 			}
1458 
1459 			lws_callback_on_writable(h2n->swsi);
1460 
1461 			if (!wsi->h2_acked_settings ||
1462 			    !(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM)
1463 			) {
1464 				pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS);
1465 				if (!pps)
1466 					return 1;
1467 				lws_pps_schedule(wsi, pps);
1468 				lwsl_info("%s: SETTINGS ack PPS\n", __func__);
1469 				wsi->h2_acked_settings = 1;
1470 			}
1471 
1472 			/* also attach any queued guys */
1473 
1474 			lws_wsi_mux_apply_queue(wsi);
1475 		}
1476 #endif
1477 		break;
1478 
1479 	case LWS_H2_FRAME_TYPE_CONTINUATION:
1480 	case LWS_H2_FRAME_TYPE_HEADERS:
1481 
1482 		if (!h2n->swsi)
1483 			break;
1484 
1485 		/* service the http request itself */
1486 
1487 		if (h2n->last_action_dyntable_resize) {
1488 			lws_h2_goaway(wsi, H2_ERR_COMPRESSION_ERROR,
1489 				"dyntable resize last in headers");
1490 			break;
1491 		}
1492 
1493 		if (!h2n->swsi->h2.END_HEADERS) {
1494 			/* we are not finished yet */
1495 			lwsl_info("witholding http action for continuation\n");
1496 			h2n->cont_exp_sid = h2n->sid;
1497 			h2n->cont_exp = 1;
1498 			break;
1499 		}
1500 
1501 		/* confirm the hpack stream state is reasonable for finishing */
1502 
1503 		if (h2n->hpack != HPKS_TYPE) {
1504 			/* hpack incomplete */
1505 			lwsl_info("hpack incomplete %d (type %d, len %u)\n",
1506 				  h2n->hpack, h2n->type,
1507 				  (unsigned int)h2n->hpack_len);
1508 			lws_h2_goaway(wsi, H2_ERR_COMPRESSION_ERROR,
1509 				      "hpack incomplete");
1510 			break;
1511 		}
1512 
1513 		/* this is the last part of HEADERS */
1514 		switch (h2n->swsi->h2.h2_state) {
1515 		case LWS_H2_STATE_IDLE:
1516 			lws_h2_state(h2n->swsi, LWS_H2_STATE_OPEN);
1517 			break;
1518 		case LWS_H2_STATE_RESERVED_REMOTE:
1519 			lws_h2_state(h2n->swsi, LWS_H2_STATE_HALF_CLOSED_LOCAL);
1520 			break;
1521 		}
1522 
1523 		lwsl_info("http req, wsi=%p, h2n->swsi=%p\n", wsi, h2n->swsi);
1524 		h2n->swsi->hdr_parsing_completed = 1;
1525 
1526 #if defined(LWS_WITH_CLIENT)
1527 		if (h2n->swsi->client_mux_substream &&
1528 		    lws_client_interpret_server_handshake(h2n->swsi)) {
1529 			lwsl_info("%s: cli int serv hs closed it\n", __func__);
1530 			break;
1531 		}
1532 #endif
1533 
1534 		if (lws_hdr_extant(h2n->swsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
1535 			h2n->swsi->http.rx_content_length  = atoll(
1536 				lws_hdr_simple_ptr(h2n->swsi,
1537 				      WSI_TOKEN_HTTP_CONTENT_LENGTH));
1538 			h2n->swsi->http.rx_content_remain =
1539 					h2n->swsi->http.rx_content_length;
1540 			lwsl_info("setting rx_content_length %lld\n",
1541 				  (long long)h2n->swsi->http.rx_content_length);
1542 		}
1543 
1544 		{
1545 			int n = 0, len;
1546 			char buf[256];
1547 			const unsigned char *c;
1548 
1549 			do {
1550 				c = lws_token_to_string(n);
1551 				if (!c) {
1552 					n++;
1553 					continue;
1554 				}
1555 
1556 				len = lws_hdr_total_length(h2n->swsi, n);
1557 				if (!len || len > (int)sizeof(buf) - 1) {
1558 					n++;
1559 					continue;
1560 				}
1561 
1562 				if (lws_hdr_copy(h2n->swsi, buf, sizeof buf,
1563 						 n) < 0) {
1564 					lwsl_info("    %s !oversize!\n",
1565 						  (char *)c);
1566 				} else {
1567 					buf[sizeof(buf) - 1] = '\0';
1568 
1569 					lwsl_info("    %s = %s\n",
1570 						  (char *)c, buf);
1571 				}
1572 				n++;
1573 			} while (c);
1574 		}
1575 
1576 		if (h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE ||
1577 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED) {
1578 			lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED,
1579 				      "Banning service on CLOSED_REMOTE");
1580 			break;
1581 		}
1582 
1583 		switch (h2n->swsi->h2.h2_state) {
1584 		case LWS_H2_STATE_IDLE:
1585 			lws_h2_state(h2n->swsi, LWS_H2_STATE_OPEN);
1586 			break;
1587 		case LWS_H2_STATE_OPEN:
1588 			if (h2n->swsi->h2.END_STREAM)
1589 				lws_h2_state(h2n->swsi,
1590 					     LWS_H2_STATE_HALF_CLOSED_REMOTE);
1591 			break;
1592 		case LWS_H2_STATE_HALF_CLOSED_LOCAL:
1593 			if (h2n->swsi->h2.END_STREAM)
1594 				lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED);
1595 			break;
1596 		}
1597 
1598 #if defined(LWS_WITH_CLIENT)
1599 		if (h2n->swsi->client_mux_substream) {
1600 			lwsl_info("%s: wsi %p: headers: client path (h2 state %s)\n",
1601 				  __func__, wsi, h2_state_names[h2n->swsi->h2.h2_state]);
1602 			break;
1603 		}
1604 #endif
1605 
1606 		if (!lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_COLON_PATH) ||
1607 		    !lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_COLON_METHOD) ||
1608 		    !lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_COLON_SCHEME) ||
1609 		     lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_COLON_STATUS) ||
1610 		     lws_hdr_extant(h2n->swsi, WSI_TOKEN_CONNECTION)) {
1611 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1612 				      "Pseudoheader checks");
1613 			break;
1614 		}
1615 
1616 		if (lws_hdr_extant(h2n->swsi, WSI_TOKEN_TE)) {
1617 			n = lws_hdr_total_length(h2n->swsi, WSI_TOKEN_TE);
1618 
1619 			if (n != 8 ||
1620 			    strncmp(lws_hdr_simple_ptr(h2n->swsi, WSI_TOKEN_TE),
1621 				  "trailers", n)) {
1622 				lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1623 					      "Illegal transfer-encoding");
1624 				break;
1625 			}
1626 		}
1627 
1628 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
1629 		lws_http_compression_validate(h2n->swsi);
1630 #endif
1631 
1632 #if defined(LWS_WITH_SERVER_STATUS)
1633 		wsi->vhost->conn_stats.h2_trans++;
1634 #endif
1635 		p = lws_hdr_simple_ptr(h2n->swsi, WSI_TOKEN_HTTP_COLON_METHOD);
1636 		/*
1637 		 * duplicate :path into the individual method uri header
1638 		 * index, so that it looks the same as h1 in the ah
1639 		 */
1640 		for (n = 0; n < (int)LWS_ARRAY_SIZE(method_names); n++)
1641 			if (!strcasecmp(p, method_names[n])) {
1642 				h2n->swsi->http.ah->frag_index[method_index[n]] =
1643 						h2n->swsi->http.ah->frag_index[
1644 				                     WSI_TOKEN_HTTP_COLON_PATH];
1645 				break;
1646 			}
1647 
1648 		lwsl_debug("%s: setting DEF_ACT from 0x%x\n", __func__,
1649 			   (unsigned int)h2n->swsi->wsistate);
1650 		lwsi_set_state(h2n->swsi, LRS_DEFERRING_ACTION);
1651 		lws_callback_on_writable(h2n->swsi);
1652 		break;
1653 
1654 	case LWS_H2_FRAME_TYPE_DATA:
1655 		lwsl_info("%s: DATA flags 0x%x\n", __func__, h2n->flags);
1656 		if (!h2n->swsi)
1657 			break;
1658 
1659 		if (lws_hdr_total_length(h2n->swsi,
1660 					 WSI_TOKEN_HTTP_CONTENT_LENGTH) &&
1661 		    h2n->swsi->h2.END_STREAM &&
1662 		    h2n->swsi->http.rx_content_length &&
1663 		    h2n->swsi->http.rx_content_remain) {
1664 			lws_h2_rst_stream(h2n->swsi, H2_ERR_PROTOCOL_ERROR,
1665 					  "Not enough rx content");
1666 			break;
1667 		}
1668 
1669 		if (h2n->swsi->h2.END_STREAM &&
1670 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_OPEN)
1671 			lws_h2_state(h2n->swsi,
1672 				     LWS_H2_STATE_HALF_CLOSED_REMOTE);
1673 
1674 		if (h2n->swsi->h2.END_STREAM &&
1675 		    h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_LOCAL)
1676 			lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED);
1677 
1678 #if defined(LWS_WITH_CLIENT)
1679 		/*
1680 		 * client... remote END_STREAM implies we weren't going to
1681 		 * send anything else anyway.
1682 		 */
1683 
1684 		if (h2n->swsi->client_mux_substream &&
1685 		    (h2n->flags & LWS_H2_FLAG_END_STREAM)) {
1686 			lwsl_info("%s: %p: DATA: end stream\n",
1687 				  __func__, h2n->swsi);
1688 
1689 			if (h2n->swsi->h2.h2_state == LWS_H2_STATE_OPEN) {
1690 				lws_h2_state(h2n->swsi,
1691 					     LWS_H2_STATE_HALF_CLOSED_REMOTE);
1692 		//		lws_h2_rst_stream(h2n->swsi, H2_ERR_NO_ERROR,
1693 		//				  "client done");
1694 
1695 		//		if (lws_http_transaction_completed_client(h2n->swsi))
1696 		//			lwsl_debug("tx completed returned close\n");
1697 			}
1698 
1699 			//if (h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_LOCAL)
1700 			{
1701 				lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED);
1702 
1703 				lws_h2_rst_stream(h2n->swsi, H2_ERR_NO_ERROR,
1704 						  "client done");
1705 
1706 				if (lws_http_transaction_completed_client(h2n->swsi))
1707 					lwsl_debug("tx completed returned close\n");
1708 			}
1709 		}
1710 #endif
1711 		break;
1712 
1713 	case LWS_H2_FRAME_TYPE_PING:
1714 		if (h2n->flags & LWS_H2_FLAG_SETTINGS_ACK)
1715 			lws_validity_confirmed(wsi);
1716 		else {
1717 			/* they're sending us a ping request */
1718 			struct lws_h2_protocol_send *pps =
1719 					lws_h2_new_pps(LWS_H2_PPS_PONG);
1720 			if (!pps)
1721 				return 1;
1722 
1723 			lwsl_info("rx ping, preparing pong\n");
1724 
1725 			memcpy(pps->u.ping.ping_payload, h2n->ping_payload, 8);
1726 			lws_pps_schedule(wsi, pps);
1727 		}
1728 
1729 		break;
1730 
1731 	case LWS_H2_FRAME_TYPE_WINDOW_UPDATE:
1732 		/*
1733 		 * We only have an unsigned 31-bit (positive) increment possible
1734 		 */
1735 		h2n->hpack_e_dep &= ~(1u << 31);
1736 		lwsl_info("WINDOW_UPDATE: sid %u %u (0x%x)\n",
1737 			  (unsigned int)h2n->sid,
1738 			  (unsigned int)h2n->hpack_e_dep,
1739 			  (unsigned int)h2n->hpack_e_dep);
1740 
1741 		if (h2n->sid)
1742 			eff_wsi = h2n->swsi;
1743 
1744 		if (!eff_wsi) {
1745 			if (h2n->sid > h2n->highest_sid_opened)
1746 				lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1747 					      "alien sid");
1748 			break; /* ignore */
1749 		}
1750 
1751 		if (eff_wsi->vhost->options &
1752 		        LWS_SERVER_OPTION_H2_JUST_FIX_WINDOW_UPDATE_OVERFLOW &&
1753 		    (uint64_t)eff_wsi->txc.tx_cr + (uint64_t)h2n->hpack_e_dep >
1754 		    (uint64_t)0x7fffffff)
1755 			h2n->hpack_e_dep = 0x7fffffff - eff_wsi->txc.tx_cr;
1756 
1757 		if ((uint64_t)eff_wsi->txc.tx_cr + (uint64_t)h2n->hpack_e_dep >
1758 		    (uint64_t)0x7fffffff) {
1759 			if (h2n->sid)
1760 				lws_h2_rst_stream(h2n->swsi,
1761 						  H2_ERR_FLOW_CONTROL_ERROR,
1762 						  "Flow control exceeded max");
1763 			else
1764 				lws_h2_goaway(wsi, H2_ERR_FLOW_CONTROL_ERROR,
1765 					      "Flow control exceeded max");
1766 			break;
1767 		}
1768 
1769 		if (!h2n->hpack_e_dep) {
1770 			lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1771 				      "Zero length window update");
1772 			break;
1773 		}
1774 		n = eff_wsi->txc.tx_cr;
1775 		eff_wsi->txc.tx_cr += h2n->hpack_e_dep;
1776 
1777 		lws_wsi_txc_report_manual_txcr_in(eff_wsi,
1778 						  (int32_t)h2n->hpack_e_dep);
1779 
1780 		lws_wsi_txc_describe(&eff_wsi->txc, "WINDOW_UPDATE in",
1781 				     eff_wsi->mux.my_sid);
1782 
1783 		if (n <= 0 && eff_wsi->txc.tx_cr <= 0)
1784 			/* it helps, but won't change sendability for anyone */
1785 			break;
1786 
1787 		/*
1788 		 * It may have changed sendability (depends on SID 0 tx credit
1789 		 * too)... for us and any children waiting on us... reassess
1790 		 * blockage for all children first
1791 		 */
1792 		lws_start_foreach_ll(struct lws *, w, wsi->mux.child_list) {
1793 			lws_callback_on_writable(w);
1794 		} lws_end_foreach_ll(w, mux.sibling_list);
1795 
1796 		if (eff_wsi->txc.skint &&
1797 		    !lws_wsi_txc_check_skint(&eff_wsi->txc,
1798 					     lws_h2_tx_cr_get(eff_wsi)))
1799 			/*
1800 			 * This one became un-skint, schedule a writeable
1801 			 * callback
1802 			 */
1803 			lws_callback_on_writable(eff_wsi);
1804 
1805 		break;
1806 
1807 	case LWS_H2_FRAME_TYPE_GOAWAY:
1808 		lwsl_notice("GOAWAY: last sid %u, error 0x%08X, string '%s'\n",
1809 			  (unsigned int)h2n->goaway_last_sid,
1810 			  (unsigned int)h2n->goaway_err, h2n->goaway_str);
1811 
1812 		return 1;
1813 
1814 	case LWS_H2_FRAME_TYPE_RST_STREAM:
1815 		lwsl_info("LWS_H2_FRAME_TYPE_RST_STREAM: sid %u: reason 0x%x\n",
1816 			  (unsigned int)h2n->sid,
1817 			  (unsigned int)h2n->hpack_e_dep);
1818 		break;
1819 
1820 	case LWS_H2_FRAME_TYPE_COUNT: /* IGNORING FRAME */
1821 		break;
1822 	}
1823 
1824 	return 0;
1825 }
1826 
1827 /*
1828  * This may want to send something on the network wsi, which may be in the
1829  * middle of a partial send.  PPS sends are OK because they are queued to
1830  * go through the WRITABLE handler already.
1831  *
1832  * The read parser for the network wsi has no choice but to parse its stream
1833  * anyway, because otherwise it will not be able to get tx credit window
1834  * messages.
1835  *
1836  * Therefore if we will send non-PPS, ie, lws_http_action() for a stream
1837  * wsi, we must change its state and handle it as a priority in the
1838  * POLLOUT handler instead of writing it here.
1839  *
1840  * About closing... for the main network wsi, it should return nonzero to
1841  * close it all.  If it needs to close an swsi, it can do it here.
1842  */
1843 int
lws_h2_parser(struct lws * wsi,unsigned char * in,lws_filepos_t inlen,lws_filepos_t * inused)1844 lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen,
1845 	      lws_filepos_t *inused)
1846 {
1847 	struct lws_h2_netconn *h2n = wsi->h2.h2n;
1848 	struct lws_h2_protocol_send *pps;
1849 	unsigned char c, *oldin = in;
1850 	int n, m;
1851 
1852 	if (!h2n)
1853 		goto fail;
1854 
1855 	while (inlen--) {
1856 
1857 		c = *in++;
1858 
1859 		// lwsl_notice("%s: 0x%x\n", __func__, c);
1860 
1861 		switch (lwsi_state(wsi)) {
1862 		case LRS_H2_AWAIT_PREFACE:
1863 			if (preface[h2n->count++] != c)
1864 				goto fail;
1865 
1866 			if (preface[h2n->count])
1867 				break;
1868 
1869 			lwsl_info("http2: %p: established\n", wsi);
1870 			lwsi_set_state(wsi, LRS_H2_AWAIT_SETTINGS);
1871 			lws_validity_confirmed(wsi);
1872 			h2n->count = 0;
1873 			wsi->txc.tx_cr = 65535;
1874 
1875 			/*
1876 			 * we must send a settings frame -- empty one is OK...
1877 			 * that must be the first thing sent by server
1878 			 * and the peer must send a SETTINGS with ACK flag...
1879 			 */
1880 			pps = lws_h2_new_pps(LWS_H2_PPS_MY_SETTINGS);
1881 			if (!pps)
1882 				goto fail;
1883 			lws_pps_schedule(wsi, pps);
1884 			break;
1885 
1886 		case LRS_H2_WAITING_TO_SEND_HEADERS:
1887 		case LRS_ESTABLISHED:
1888 		case LRS_H2_AWAIT_SETTINGS:
1889 			if (h2n->frame_state != LWS_H2_FRAME_HEADER_LENGTH)
1890 				goto try_frame_start;
1891 
1892 			/*
1893 			 * post-header, preamble / payload / padding part
1894 			 */
1895 			h2n->count++;
1896 
1897 			if (h2n->flags & LWS_H2_FLAG_PADDED &&
1898 			    !h2n->pad_length) {
1899 				/*
1900 				 * Get the padding count... actual padding is
1901 				 * at the end of the frame.
1902 				 */
1903 				h2n->padding = c;
1904 				h2n->pad_length = 1;
1905 				h2n->preamble++;
1906 
1907 				if (h2n->padding > h2n->length - 1)
1908 					lws_h2_goaway(wsi,
1909 						      H2_ERR_PROTOCOL_ERROR,
1910 						      "execssive padding");
1911 				break; /* we consumed this */
1912 			}
1913 
1914 			if (h2n->flags & LWS_H2_FLAG_PRIORITY &&
1915 			    !h2n->collected_priority) {
1916 				/* going to be 5 preamble bytes */
1917 
1918 				lwsl_debug("PRIORITY FLAG:  0x%x\n", c);
1919 
1920 				if (h2n->preamble++ - h2n->pad_length < 4) {
1921 					h2n->dep = ((h2n->dep) << 8) | c;
1922 					break; /* we consumed this */
1923 				}
1924 				h2n->weight_temp = c;
1925 				h2n->collected_priority = 1;
1926 				lwsl_debug("PRI FL: dep 0x%x, weight 0x%02X\n",
1927 					   (unsigned int)h2n->dep,
1928 					   h2n->weight_temp);
1929 				break; /* we consumed this */
1930 			}
1931 			if (h2n->padding && h2n->count >
1932 			    (h2n->length - h2n->padding)) {
1933 				if (c) {
1934 					lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
1935 						      "nonzero padding");
1936 					break;
1937 				}
1938 				goto frame_end;
1939 			}
1940 
1941 			/* applies to wsi->h2.swsi which may be wsi */
1942 			switch(h2n->type) {
1943 
1944 			case LWS_H2_FRAME_TYPE_SETTINGS:
1945 				n = (h2n->count - 1 - h2n->preamble) %
1946 				     LWS_H2_SETTINGS_LEN;
1947 				h2n->one_setting[n] = c;
1948 				if (n != LWS_H2_SETTINGS_LEN - 1)
1949 					break;
1950 				lws_h2_settings(wsi, &h2n->peer_set,
1951 						h2n->one_setting,
1952 						LWS_H2_SETTINGS_LEN);
1953 				break;
1954 
1955 			case LWS_H2_FRAME_TYPE_CONTINUATION:
1956 			case LWS_H2_FRAME_TYPE_HEADERS:
1957 				if (!h2n->swsi)
1958 					break;
1959 				if (lws_hpack_interpret(h2n->swsi, c)) {
1960 					lwsl_info("%s: hpack failed\n",
1961 						  __func__);
1962 					goto fail;
1963 				}
1964 				break;
1965 
1966 			case LWS_H2_FRAME_TYPE_GOAWAY:
1967 				switch (h2n->inside++) {
1968 				case 0:
1969 				case 1:
1970 				case 2:
1971 				case 3:
1972 					h2n->goaway_last_sid <<= 8;
1973 					h2n->goaway_last_sid |= c;
1974 					h2n->goaway_str[0] = '\0';
1975 					break;
1976 
1977 				case 4:
1978 				case 5:
1979 				case 6:
1980 				case 7:
1981 					h2n->goaway_err <<= 8;
1982 					h2n->goaway_err |= c;
1983 					break;
1984 
1985 				default:
1986 					if (h2n->inside - 9 <
1987 					    sizeof(h2n->goaway_str) - 1)
1988 						h2n->goaway_str[
1989 						           h2n->inside - 9] = c;
1990 					h2n->goaway_str[
1991 					    sizeof(h2n->goaway_str) - 1] = '\0';
1992 					break;
1993 				}
1994 				break;
1995 
1996 			case LWS_H2_FRAME_TYPE_DATA:
1997 
1998 				lwsl_info("%s: LWS_H2_FRAME_TYPE_DATA: fl 0x%x\n",
1999 					  __func__, h2n->flags);
2000 
2001 				/*
2002 				 * let the network wsi live a bit longer if
2003 				 * subs are active... our frame may take a long
2004 				 * time to chew through
2005 				 */
2006 				if (!wsi->immortal_substream_count)
2007 					lws_set_timeout(wsi,
2008 					PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE,
2009 						wsi->vhost->keepalive_timeout ?
2010 					    wsi->vhost->keepalive_timeout : 31);
2011 
2012 				if (!h2n->swsi)
2013 					break;
2014 
2015 				if (lws_buflist_next_segment_len(
2016 						&h2n->swsi->buflist, NULL))
2017 					lwsl_info("%s: substream has pending\n",
2018 						  __func__);
2019 
2020 				if (lwsi_role_http(h2n->swsi) &&
2021 				    lwsi_state(h2n->swsi) == LRS_ESTABLISHED) {
2022 					lwsi_set_state(h2n->swsi, LRS_BODY);
2023 					lwsl_info("%s: swsi %p to LRS_BODY\n",
2024 							__func__, h2n->swsi);
2025 				}
2026 
2027 				if (lws_hdr_total_length(h2n->swsi,
2028 					     WSI_TOKEN_HTTP_CONTENT_LENGTH) &&
2029 				    h2n->swsi->http.rx_content_length &&
2030 				    h2n->swsi->http.rx_content_remain <
2031 						    inlen + 1 && /* last */
2032 				    h2n->inside < h2n->length) {
2033 					/* unread data in frame */
2034 					lws_h2_goaway(wsi,
2035 						      H2_ERR_PROTOCOL_ERROR,
2036 					    "More rx than content_length told");
2037 					break;
2038 				}
2039 
2040 				/*
2041 				 * We operate on a frame.  The RX we have at
2042 				 * hand may exceed the current frame.
2043 				 */
2044 
2045 				n = (int)inlen + 1;
2046 				if (n > (int)(h2n->length - h2n->count + 1)) {
2047 					n = h2n->length - h2n->count + 1;
2048 					lwsl_debug("---- restricting len to %d "
2049 						   "vs %ld\n", n, (long)inlen + 1);
2050 				}
2051 #if defined(LWS_WITH_CLIENT)
2052 				if (h2n->swsi->client_mux_substream) {
2053 					if (!h2n->swsi->protocol) {
2054 						lwsl_err("%s: swsi %p doesn't have protocol\n",
2055 							 __func__, h2n->swsi);
2056 						m = 1;
2057 					} else {
2058 						h2n->swsi->txc.peer_tx_cr_est -= n;
2059 						wsi->txc.peer_tx_cr_est -= n;
2060 						lws_wsi_txc_describe(&h2n->swsi->txc,
2061 							__func__,
2062 							h2n->swsi->mux.my_sid);
2063 					m = user_callback_handle_rxflow(
2064 						h2n->swsi->protocol->callback,
2065 						h2n->swsi,
2066 					  LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
2067 						h2n->swsi->user_space,
2068 						in - 1, n);
2069 					}
2070 
2071 					in += n - 1;
2072 					h2n->inside += n;
2073 					h2n->count += n - 1;
2074 					inlen -= n - 1;
2075 
2076 					if (m) {
2077 						lwsl_info("RECEIVE_CLIENT_HTTP "
2078 							  "closed it\n");
2079 						goto close_swsi_and_return;
2080 					}
2081 
2082 					break;
2083 				}
2084 #endif
2085 
2086 				if (lwsi_state(h2n->swsi) == LRS_DEFERRING_ACTION) {
2087 					m = lws_buflist_append_segment(
2088 						&h2n->swsi->buflist, in - 1, n);
2089 					if (m < 0)
2090 						return -1;
2091 					if (m) {
2092 						struct lws_context_per_thread *pt;
2093 
2094 						pt = &wsi->context->pt[(int)wsi->tsi];
2095 						lwsl_debug("%s: added %p to rxflow list\n",
2096 							   __func__, wsi);
2097 						lws_dll2_add_head(
2098 							&h2n->swsi->dll_buflist,
2099 							&pt->dll_buflist_owner);
2100 					}
2101 					in += n - 1;
2102 					h2n->inside += n;
2103 					h2n->count += n - 1;
2104 					inlen -= n - 1;
2105 
2106 					lwsl_debug("%s: deferred %d\n", __func__, n);
2107 					goto do_windows;
2108 				}
2109 
2110 				h2n->swsi->outer_will_close = 1;
2111 				/*
2112 				 * choose the length for this go so that we end at
2113 				 * the frame boundary, in the case there is already
2114 				 * more waiting leave it for next time around
2115 				 */
2116 
2117 				n = lws_read_h1(h2n->swsi, in - 1, n);
2118 				// lwsl_notice("%s: lws_read_h1 %d\n", __func__, n);
2119 				h2n->swsi->outer_will_close = 0;
2120 				/*
2121 				 * can return 0 in POST body with
2122 				 * content len exhausted somehow.
2123 				 */
2124 				if (n < 0 ||
2125 				    (!n && !lws_buflist_next_segment_len(
2126 						    &wsi->buflist, NULL))) {
2127 					lwsl_info("%s: lws_read_h1 told %d %u / %u\n",
2128 						__func__, n,
2129 						(unsigned int)h2n->count,
2130 						(unsigned int)h2n->length);
2131 					in += h2n->length - h2n->count;
2132 					h2n->inside = h2n->length;
2133 					h2n->count = h2n->length - 1;
2134 
2135 					//if (n < 0)
2136 					//	goto already_closed_swsi;
2137 					goto close_swsi_and_return;
2138 				}
2139 
2140 				inlen -= n - 1;
2141 				in += n - 1;
2142 				h2n->inside += n;
2143 				h2n->count += n - 1;
2144 				h2n->swsi->txc.peer_tx_cr_est -= n;
2145 				wsi->txc.peer_tx_cr_est -= n;
2146 
2147 do_windows:
2148 
2149 #if defined(LWS_WITH_CLIENT)
2150 				if (!(h2n->swsi->flags & LCCSCF_H2_MANUAL_RXFLOW))
2151 #endif
2152 				{
2153 					/*
2154 					 * The default behaviour is we just keep
2155 					 * cranking the other side's tx credit
2156 					 * back up, for simple bulk transfer as
2157 					 * fast as we can take it
2158 					 */
2159 
2160 					m = n; //(2 * h2n->length) + 65536;
2161 
2162 					/* update both the stream and nwsi */
2163 
2164 					lws_h2_update_peer_txcredit_thresh(h2n->swsi,
2165 								    h2n->sid, m, m);
2166 				}
2167 #if defined(LWS_WITH_CLIENT)
2168 				else {
2169 					/*
2170 					 * If he's handling it himself, only
2171 					 * repair the nwsi credit but allow the
2172 					 * stream credit to run down until the
2173 					 * user code deals with it
2174 					 */
2175 					lws_h2_update_peer_txcredit(wsi, 0, n);
2176 					h2n->swsi->txc.manual = 1;
2177 				}
2178 #endif
2179 				break;
2180 
2181 			case LWS_H2_FRAME_TYPE_PRIORITY:
2182 				if (h2n->count <= 4) {
2183 					h2n->dep <<= 8;
2184 					h2n->dep |= c;
2185 					break;
2186 				}
2187 				h2n->weight_temp = c;
2188 				lwsl_info("PRIORITY: dep 0x%x, weight 0x%02X\n",
2189 					  (unsigned int)h2n->dep, h2n->weight_temp);
2190 
2191 				if ((h2n->dep & ~(1u << 31)) == h2n->sid) {
2192 					lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
2193 						      "cant depend on own sid");
2194 					break;
2195 				}
2196 				break;
2197 
2198 			case LWS_H2_FRAME_TYPE_RST_STREAM:
2199 				h2n->hpack_e_dep <<= 8;
2200 				h2n->hpack_e_dep |= c;
2201 				break;
2202 
2203 			case LWS_H2_FRAME_TYPE_PUSH_PROMISE:
2204 				break;
2205 
2206 			case LWS_H2_FRAME_TYPE_PING:
2207 				if (h2n->flags & LWS_H2_FLAG_SETTINGS_ACK) { // ack
2208 				} else { /* they're sending us a ping request */
2209 					if (h2n->count > 8)
2210 						return 1;
2211 					h2n->ping_payload[h2n->count - 1] = c;
2212 				}
2213 				break;
2214 
2215 			case LWS_H2_FRAME_TYPE_WINDOW_UPDATE:
2216 				h2n->hpack_e_dep <<= 8;
2217 				h2n->hpack_e_dep |= c;
2218 				break;
2219 
2220 			case LWS_H2_FRAME_TYPE_COUNT: /* IGNORING FRAME */
2221 				break;
2222 
2223 			default:
2224 				lwsl_notice("%s: unhandled frame type %d\n",
2225 					    __func__, h2n->type);
2226 
2227 				goto fail;
2228 			}
2229 
2230 frame_end:
2231 			if (h2n->count > h2n->length) {
2232 				lwsl_notice("%s: count > length %u %u\n",
2233 					    __func__, (unsigned int)h2n->count,
2234 					    (unsigned int)h2n->length);
2235 				goto fail;
2236 			}
2237 			if (h2n->count != h2n->length)
2238 				break;
2239 
2240 			/*
2241 			 * end of frame just happened
2242 			 */
2243 			if (lws_h2_parse_end_of_frame(wsi))
2244 				goto fail;
2245 
2246 			break;
2247 
2248 try_frame_start:
2249 			if (h2n->frame_state <= 8) {
2250 
2251 				switch (h2n->frame_state++) {
2252 				case 0:
2253 					h2n->pad_length = 0;
2254 					h2n->collected_priority = 0;
2255 					h2n->padding = 0;
2256 					h2n->preamble = 0;
2257 					h2n->length = c;
2258 					h2n->inside = 0;
2259 					break;
2260 				case 1:
2261 				case 2:
2262 					h2n->length <<= 8;
2263 					h2n->length |= c;
2264 					break;
2265 				case 3:
2266 					h2n->type = c;
2267 					break;
2268 				case 4:
2269 					h2n->flags = c;
2270 					break;
2271 
2272 				case 5:
2273 				case 6:
2274 				case 7:
2275 				case 8:
2276 					h2n->sid <<= 8;
2277 					h2n->sid |= c;
2278 					break;
2279 				}
2280 			}
2281 
2282 			if (h2n->frame_state == LWS_H2_FRAME_HEADER_LENGTH)
2283 				if (lws_h2_parse_frame_header(wsi))
2284 					goto fail;
2285 			break;
2286 
2287 		default:
2288 			break;
2289 		}
2290 	}
2291 
2292 	*inused = in - oldin;
2293 
2294 	return 0;
2295 
2296 close_swsi_and_return:
2297 
2298 	lws_close_free_wsi(h2n->swsi, 0, "close_swsi_and_return");
2299 	h2n->swsi = NULL;
2300 	h2n->frame_state = 0;
2301 	h2n->count = 0;
2302 
2303 // already_closed_swsi:
2304 	*inused = in - oldin;
2305 
2306 	return 2;
2307 
2308 fail:
2309 	*inused = in - oldin;
2310 
2311 	return 1;
2312 }
2313 
2314 #if defined(LWS_WITH_CLIENT)
2315 int
lws_h2_client_handshake(struct lws * wsi)2316 lws_h2_client_handshake(struct lws *wsi)
2317 {
2318 	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
2319 	uint8_t *buf, *start, *p, *p1, *end;
2320 	char *meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD),
2321 	     *uri = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI);
2322 	struct lws *nwsi = lws_get_network_wsi(wsi);
2323 	int n, m;
2324 	/*
2325 	 * The identifier of a newly established stream MUST be numerically
2326 	 * greater than all streams that the initiating endpoint has opened or
2327 	 * reserved.  This governs streams that are opened using a HEADERS frame
2328 	 * and streams that are reserved using PUSH_PROMISE.  An endpoint that
2329 	 * receives an unexpected stream identifier MUST respond with a
2330 	 * connection error (Section 5.4.1) of type PROTOCOL_ERROR.
2331 	 */
2332 	int sid = nwsi->h2.h2n->highest_sid_opened + 2;
2333 
2334 	lwsl_debug("%s\n", __func__);
2335 
2336 	/*
2337 	 * We MUST allocate our sid here at the point we're about to send the
2338 	 * stream open.  It's because we don't know the order in which multiple
2339 	 * open streams will send their headers... in h2, sending the headers
2340 	 * is the point the stream is opened.  The peer requires that we only
2341 	 * open streams in ascending sid order
2342 	 */
2343 
2344 	wsi->mux.my_sid = nwsi->h2.h2n->highest_sid_opened = sid;
2345 	lwsl_info("%s: wsi %p: assigning SID %d at header send\n", __func__, wsi, sid);
2346 
2347 	lwsl_info("%s: CLIENT_WAITING_TO_SEND_HEADERS: pollout (sid %d)\n",
2348 			__func__, wsi->mux.my_sid);
2349 
2350 	p = start = buf = pt->serv_buf + LWS_PRE;
2351 	end = start + (wsi->context->pt_serv_buf_size / 2) - LWS_PRE - 1;
2352 
2353 	/* it's time for us to send our client stream headers */
2354 
2355 	if (!meth)
2356 		meth = "GET";
2357 
2358 	if (lws_add_http_header_by_token(wsi,
2359 				WSI_TOKEN_HTTP_COLON_METHOD,
2360 				(unsigned char *)meth,
2361 				(int)strlen(meth), &p, end))
2362 		goto fail_length;
2363 
2364 	if (lws_add_http_header_by_token(wsi,
2365 				WSI_TOKEN_HTTP_COLON_SCHEME,
2366 				(unsigned char *)"https", 5,
2367 				&p, end))
2368 		goto fail_length;
2369 
2370 	if (lws_add_http_header_by_token(wsi,
2371 				WSI_TOKEN_HTTP_COLON_PATH,
2372 				(unsigned char *)uri,
2373 				lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI),
2374 				&p, end))
2375 		goto fail_length;
2376 
2377 	if (lws_add_http_header_by_token(wsi,
2378 				WSI_TOKEN_HTTP_COLON_AUTHORITY,
2379 				(unsigned char *)lws_hdr_simple_ptr(wsi,
2380 						_WSI_TOKEN_CLIENT_ORIGIN),
2381 			lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_ORIGIN),
2382 				&p, end))
2383 		goto fail_length;
2384 
2385 	if (!wsi->client_h2_alpn &&
2386 	    lws_add_http_header_by_token(wsi, WSI_TOKEN_HOST,
2387 				(unsigned char *)lws_hdr_simple_ptr(wsi,
2388 						_WSI_TOKEN_CLIENT_HOST),
2389 			lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_HOST),
2390 				&p, end))
2391 		goto fail_length;
2392 
2393 	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_USER_AGENT,
2394 				(unsigned char *)"lwsss", 5,
2395 				&p, end))
2396 		goto fail_length;
2397 
2398 	if (wsi->flags & LCCSCF_HTTP_MULTIPART_MIME) {
2399 		p1 = lws_http_multipart_headers(wsi, p);
2400 		if (!p1)
2401 			goto fail_length;
2402 		p = p1;
2403 	}
2404 
2405 	if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED) {
2406 		if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
2407 			   (unsigned char *)"application/x-www-form-urlencoded",
2408 			   33, &p, end))
2409 			goto fail_length;
2410 		lws_client_http_body_pending(wsi, 1);
2411 	}
2412 
2413 	/* give userland a chance to append, eg, cookies */
2414 
2415 	if (wsi->protocol->callback(wsi,
2416 				LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
2417 				wsi->user_space, &p, (end - p) - 12))
2418 		goto fail_length;
2419 
2420 	if (lws_finalize_http_header(wsi, &p, end))
2421 		goto fail_length;
2422 
2423 #if defined(LWS_WITH_DETAILED_LATENCY)
2424 	wsi->detlat.earliest_write_req_pre_write = lws_now_usecs();
2425 #endif
2426 
2427 	m = LWS_WRITE_HTTP_HEADERS;
2428 #if defined(LWS_WITH_CLIENT)
2429 	/* below is not needed in spec, indeed it destroys the long poll
2430 	 * feature, but required by nghttp2 */
2431 	if ((wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM) &&
2432 	    !(wsi->client_http_body_pending))
2433 		m |= LWS_WRITE_H2_STREAM_END;
2434 #endif
2435 
2436 	// lwsl_hexdump_notice(start, p - start);
2437 
2438 	n = lws_write(wsi, start, p - start, m);
2439 
2440 	if (n != (p - start)) {
2441 		lwsl_err("_write returned %d from %ld\n", n,
2442 			 (long)(p - start));
2443 		return -1;
2444 	}
2445 
2446 	/*
2447 	 * Normally let's charge up the peer tx credit a bit.  But if
2448 	 * MANUAL_REFLOW is set, just set it to the initial credit given in
2449 	 * the client create info
2450 	 */
2451 
2452 	n = 4 * 65536;
2453 	if (wsi->flags & LCCSCF_H2_MANUAL_RXFLOW) {
2454 		n = wsi->txc.manual_initial_tx_credit;
2455 		wsi->txc.manual = 1;
2456 	}
2457 
2458 	if (lws_h2_update_peer_txcredit(wsi, wsi->mux.my_sid, n))
2459 		return 1;
2460 
2461 	lws_h2_state(wsi, LWS_H2_STATE_OPEN);
2462 	lwsi_set_state(wsi, LRS_ESTABLISHED);
2463 
2464 	if (wsi->flags & LCCSCF_HTTP_MULTIPART_MIME)
2465 		lws_callback_on_writable(wsi);
2466 
2467 	return 0;
2468 
2469 fail_length:
2470 	lwsl_err("Client hdrs too long: incr context info.pt_serv_buf_size\n");
2471 
2472 	return -1;
2473 }
2474 #endif
2475 
2476 #if defined(LWS_ROLE_WS)
2477 int
lws_h2_ws_handshake(struct lws * wsi)2478 lws_h2_ws_handshake(struct lws *wsi)
2479 {
2480 	uint8_t buf[LWS_PRE + 2048], *p = buf + LWS_PRE, *start = p,
2481 		*end = &buf[sizeof(buf) - 1];
2482 	const struct lws_http_mount *hit;
2483 	const char * uri_ptr;
2484 	int n, m;
2485 
2486 	if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
2487 		return -1;
2488 
2489 	if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) > 64)
2490 		return -1;
2491 
2492 	if (wsi->proxied_ws_parent && wsi->child_list) {
2493 		if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL)) {
2494 			if (lws_add_http_header_by_token(wsi, WSI_TOKEN_PROTOCOL,
2495 				(uint8_t *)lws_hdr_simple_ptr(wsi,
2496 							   WSI_TOKEN_PROTOCOL),
2497 				(int)strlen(lws_hdr_simple_ptr(wsi,
2498 							   WSI_TOKEN_PROTOCOL)),
2499 						 &p, end))
2500 			return -1;
2501 		}
2502 	} else {
2503 
2504 		/* we can only return the protocol header if:
2505 		 *  - one came in, and ... */
2506 		if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) &&
2507 		    /*  - it is not an empty string */
2508 		    wsi->protocol->name && wsi->protocol->name[0]) {
2509 			if (lws_add_http_header_by_token(wsi, WSI_TOKEN_PROTOCOL,
2510 				(unsigned char *)wsi->protocol->name,
2511 				(int)strlen(wsi->protocol->name), &p, end))
2512 			return -1;
2513 		}
2514 	}
2515 
2516 	if (lws_finalize_http_header(wsi, &p, end))
2517 		return -1;
2518 
2519 	m = lws_ptr_diff(p, start);
2520 	// lwsl_hexdump_notice(start, m);
2521 	n = lws_write(wsi, start, m, LWS_WRITE_HTTP_HEADERS);
2522 	if (n != m) {
2523 		lwsl_err("_write returned %d from %d\n", n, m);
2524 
2525 		return -1;
2526 	}
2527 
2528 	/*
2529 	 * alright clean up, set our state to generic ws established, the
2530 	 * mode / state of the nwsi will get the h2 processing done.
2531 	 */
2532 
2533 	lwsi_set_state(wsi, LRS_ESTABLISHED);
2534 	wsi->lws_rx_parse_state = 0; // ==LWS_RXPS_NEW;
2535 
2536 	uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH);
2537 	n = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
2538 	hit = lws_find_mount(wsi, uri_ptr, n);
2539 
2540 	if (hit && hit->cgienv &&
2541 	    wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_PMO, wsi->user_space,
2542 				    (void *)hit->cgienv, 0))
2543 		return 1;
2544 
2545 	lws_validity_confirmed(wsi);
2546 
2547 	return 0;
2548 }
2549 #endif
2550 
2551 int
lws_read_h2(struct lws * wsi,unsigned char * buf,lws_filepos_t len)2552 lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
2553 {
2554 	unsigned char *oldbuf = buf;
2555 	lws_filepos_t body_chunk_len;
2556 
2557 	// lwsl_notice("%s: h2 path: wsistate 0x%x len %d\n", __func__,
2558 	//		wsi->wsistate, (int)len);
2559 
2560 	/*
2561 	 * wsi here is always the network connection wsi, not a stream
2562 	 * wsi.  Once we unpicked the framing we will find the right
2563 	 * swsi and make it the target of the frame.
2564 	 *
2565 	 * If it's ws over h2, the nwsi will get us here to do the h2
2566 	 * processing, and that will call us back with the swsi +
2567 	 * ESTABLISHED state for the inner payload, handled in a later
2568 	 * case.
2569 	 */
2570 	while (len) {
2571 		int m;
2572 
2573 		/*
2574 		 * we were accepting input but now we stopped doing so
2575 		 */
2576 		if (lws_is_flowcontrolled(wsi)) {
2577 			lws_rxflow_cache(wsi, buf, 0, (int)len);
2578 			buf += len;
2579 			break;
2580 		}
2581 
2582 		/*
2583 		 * lws_h2_parser() may send something; when it gets the
2584 		 * whole frame, it will want to perform some action
2585 		 * involving a reply.  But we may be in a partial send
2586 		 * situation on the network wsi...
2587 		 *
2588 		 * Even though we may be in a partial send and unable to
2589 		 * send anything new, we still have to parse the network
2590 		 * wsi in order to gain tx credit to send, which is
2591 		 * potentially necessary to clear the old partial send.
2592 		 *
2593 		 * ALL network wsi-specific frames are sent by PPS
2594 		 * already, these are sent as a priority on the writable
2595 		 * handler, and so respect partial sends.  The only
2596 		 * problem is when a stream wsi wants to send an, eg,
2597 		 * reply headers frame in response to the parsing
2598 		 * we will do now... the *stream wsi* must stall in a
2599 		 * different state until it is able to do so from a
2600 		 * priority on the WRITABLE callback, same way that
2601 		 * file transfers operate.
2602 		 */
2603 
2604 		m = lws_h2_parser(wsi, buf, len, &body_chunk_len);
2605 		if (m && m != 2) {
2606 			lwsl_debug("%s: http2_parser bail: %d\n", __func__, m);
2607 			lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
2608 					   "lws_read_h2 bail");
2609 
2610 			return -1;
2611 		}
2612 		if (m == 2) {
2613 			/* swsi has been closed */
2614 			buf += body_chunk_len;
2615 			break;
2616 		}
2617 
2618 		buf += body_chunk_len;
2619 		len -= body_chunk_len;
2620 	}
2621 
2622 	return lws_ptr_diff(buf, oldbuf);
2623 }
2624 
2625 int
lws_h2_client_stream_long_poll_rxonly(struct lws * wsi)2626 lws_h2_client_stream_long_poll_rxonly(struct lws *wsi)
2627 {
2628 
2629 	if (!wsi->mux_substream)
2630 		return 1;
2631 
2632 	/*
2633 	 * Elect to send an empty DATA with END_STREAM, to force the stream
2634 	 * into HALF_CLOSED LOCAL
2635 	 */
2636 	wsi->h2.long_poll = 1;
2637 	wsi->h2.send_END_STREAM = 1;
2638 
2639 	// lws_header_table_detach(wsi, 0);
2640 
2641 	lws_callback_on_writable(wsi);
2642 
2643 	return 0;
2644 }
2645