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