1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include <private-lib-core.h>
26 
27 /*
28  * These are the standardized defaults.
29  * Override what actually goes in the vhost settings in platform or user code.
30  * Leave these alone because they are used to determine "what is different
31  * from the protocol defaults".
32  */
33 const struct http2_settings lws_h2_defaults = { {
34 	1,
35 	/* H2SET_HEADER_TABLE_SIZE */			4096,
36 	/* *** This controls how many entries in the dynamic table ***
37 	 * Allows the sender to inform the remote endpoint of the maximum
38 	 * size of the header compression table used to decode header
39 	 * blocks, in octets.  The encoder can select any size equal to or
40 	 * less than this value by using signaling specific to the header
41 	 * compression format inside a header block (see [COMPRESSION]).
42 	 * The initial value is 4,096 octets.
43 	 */
44 	/* H2SET_ENABLE_PUSH */				   1,
45 	/* H2SET_MAX_CONCURRENT_STREAMS */	  0x7fffffff,
46 	/* H2SET_INITIAL_WINDOW_SIZE */		       65535,
47 	/* H2SET_MAX_FRAME_SIZE */		       16384,
48 	/* H2SET_MAX_HEADER_LIST_SIZE */	  0x7fffffff,
49 	/*< This advisory setting informs a peer of the maximum size of
50 	 * header list that the sender is prepared to accept, in octets.
51 	 * The value is based on the uncompressed size of header fields,
52 	 * including the length of the name and value in octets plus an
53 	 * overhead of 32 octets for each header field.
54 	 */
55 	/* H2SET_RESERVED7 */				   0,
56 	/* H2SET_ENABLE_CONNECT_PROTOCOL */		   0,
57 }};
58 
59 /* these are the "lws defaults"... they can be overridden in plat */
60 
61 const struct http2_settings lws_h2_stock_settings = { {
62 	1,
63 	/* H2SET_HEADER_TABLE_SIZE */			65536, /* ffox */
64 	/* *** This controls how many entries in the dynamic table ***
65 	 * Allows the sender to inform the remote endpoint of the maximum
66 	 * size of the header compression table used to decode header
67 	 * blocks, in octets.  The encoder can select any size equal to or
68 	 * less than this value by using signaling specific to the header
69 	 * compression format inside a header block (see [COMPRESSION]).
70 	 * The initial value is 4,096 octets.
71 	 *
72 	 * Can't pass h2spec with less than 4096 here...
73 	 */
74 	/* H2SET_ENABLE_PUSH */				   0,
75 	/* H2SET_MAX_CONCURRENT_STREAMS */		  24,
76 	/* H2SET_INITIAL_WINDOW_SIZE */		           0,
77 	/*< This is managed by explicit WINDOW_UPDATE.  Because otherwise no
78 	 * way to precisely control it when we do want to.
79 	 */
80 	/* H2SET_MAX_FRAME_SIZE */		       16384,
81 	/* H2SET_MAX_HEADER_LIST_SIZE */	        4096,
82 	/*< This advisory setting informs a peer of the maximum size of
83 	 * header list that the sender is prepared to accept, in octets.
84 	 * The value is based on the uncompressed size of header fields,
85 	 * including the length of the name and value in octets plus an
86 	 * overhead of 32 octets for each header field.
87 	 */
88 	/* H2SET_RESERVED7 */				   0,
89 	/* H2SET_ENABLE_CONNECT_PROTOCOL */		   1,
90 }};
91 
92 /*
93  * The wsi at this level is normally the network wsi... we can get called on
94  * another path via lws_service_do_ripe_rxflow() on mux children too tho...
95  */
96 
97 static int
rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi, struct lws_pollfd *pollfd)98 rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi,
99 		       struct lws_pollfd *pollfd)
100 {
101 	struct lws_tokens ebuf;
102 	unsigned int pending = 0;
103 	char buffered = 0;
104 	struct lws *wsi1;
105 	int n, m;
106 
107 #ifdef LWS_WITH_CGI
108 	if (wsi->http.cgi && (pollfd->revents & LWS_POLLOUT)) {
109 		if (lws_handle_POLLOUT_event(wsi, pollfd))
110 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
111 
112 		return LWS_HPI_RET_HANDLED;
113 	}
114 #endif
115 
116 	 lwsl_info("%s: %s wsistate 0x%x, events %d, revents %d, pollout %d\n", __func__,
117 		   wsi->lc.gutag, (unsigned int)wsi->wsistate,
118 		   pollfd->events, pollfd->revents,
119 		   pollfd->revents & LWS_POLLOUT);
120 
121 	 /* !!! */
122 	 if (wsi->wsistate == 0x10000013) {
123 		 wsi->bugcatcher++;
124 		 if (wsi->bugcatcher == 250) {
125 			 lwsl_err("%s: BUGCATCHER\n", __func__);
126 			 return LWS_HPI_RET_PLEASE_CLOSE_ME;
127 		 }
128 	 } else
129 		 wsi->bugcatcher = 0;
130 
131 	/*
132 	 * something went wrong with parsing the handshake, and
133 	 * we ended up back in the event loop without completing it
134 	 */
135 	if (lwsi_state(wsi) == LRS_PRE_WS_SERVING_ACCEPT) {
136 		wsi->socket_is_permanently_unusable = 1;
137 		return LWS_HPI_RET_PLEASE_CLOSE_ME;
138 	}
139 
140 	if (lwsi_state(wsi) == LRS_WAITING_CONNECT) {
141 #if defined(LWS_WITH_CLIENT)
142 		if ((pollfd->revents & LWS_POLLOUT) &&
143 		    lws_handle_POLLOUT_event(wsi, pollfd)) {
144 			lwsl_debug("POLLOUT event closed it\n");
145 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
146 		}
147 
148 		n = lws_http_client_socket_service(wsi, pollfd);
149 		if (n)
150 			return LWS_HPI_RET_WSI_ALREADY_DIED;
151 #endif
152 		return LWS_HPI_RET_HANDLED;
153 	}
154 
155 	/* 1: something requested a callback when it was OK to write */
156 
157 	if ((pollfd->revents & LWS_POLLOUT) &&
158 	    lwsi_state_can_handle_POLLOUT(wsi) &&
159 	    lws_handle_POLLOUT_event(wsi, pollfd)) {
160 		if (lwsi_state(wsi) == LRS_RETURNED_CLOSE)
161 			lwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE);
162 		/* the write failed... it's had it */
163 		wsi->socket_is_permanently_unusable = 1;
164 
165 		return LWS_HPI_RET_PLEASE_CLOSE_ME;
166 	}
167 
168 	if (lwsi_state(wsi) == LRS_RETURNED_CLOSE ||
169 	    lwsi_state(wsi) == LRS_WAITING_TO_SEND_CLOSE ||
170 	    lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) {
171 		/*
172 		 * we stopped caring about anything except control
173 		 * packets.  Force flow control off, defeat tx
174 		 * draining.
175 		 */
176 		lws_rx_flow_control(wsi, 1);
177 #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
178 		if (wsi->ws)
179 			wsi->ws->tx_draining_ext = 0;
180 #endif
181 	}
182 
183 	if (wsi->mux_substream || wsi->upgraded_to_http2) {
184 		wsi1 = lws_get_network_wsi(wsi);
185 		if (wsi1 && lws_has_buffered_out(wsi1)) {
186 
187 			lwsl_info("%s: has buffered out\n", __func__);
188 			/*
189 			 * We cannot deal with any kind of new RX
190 			 * because we are dealing with a partial send
191 			 * (new RX may trigger new http_action() that
192 			 * expect to be able to send)
193 			 */
194 			return LWS_HPI_RET_HANDLED;
195 		}
196 	}
197 
198 read:
199 	/* 3: network wsi buflist needs to be drained */
200 
201 	// lws_buflist_describe(&wsi->buflist, wsi, __func__);
202 
203 	ebuf.len = (int)lws_buflist_next_segment_len(&wsi->buflist,
204 						&ebuf.token);
205 	if (ebuf.len) {
206 		lwsl_info("draining buflist (len %d)\n", ebuf.len);
207 		buffered = 1;
208 		goto drain;
209 	} else {
210 
211 		if (wsi->mux_substream) {
212 			lwsl_warn("%s: uh... %s mux child with nothing to drain\n", __func__, lws_wsi_tag(wsi));
213 			// assert(0);
214 			lws_dll2_remove(&wsi->dll_buflist);
215 			return LWS_HPI_RET_HANDLED;
216 		}
217 	}
218 
219 	if (!lws_ssl_pending(wsi) &&
220 	    !(pollfd->revents & pollfd->events & LWS_POLLIN))
221 		return LWS_HPI_RET_HANDLED;
222 
223 	/* We have something to read... */
224 
225 	if (!(lwsi_role_client(wsi) &&
226 	      (lwsi_state(wsi) != LRS_ESTABLISHED &&
227 	       // lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2 &&
228 	       lwsi_state(wsi) != LRS_H2_WAITING_TO_SEND_HEADERS))) {
229 
230 		ebuf.token = pt->serv_buf;
231 		ebuf.len = lws_ssl_capable_read(wsi,
232 					ebuf.token,
233 					wsi->a.context->pt_serv_buf_size);
234 		switch (ebuf.len) {
235 		case 0:
236 			lwsl_info("%s: zero length read\n", __func__);
237 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
238 		case LWS_SSL_CAPABLE_MORE_SERVICE:
239 			lwsl_info("SSL Capable more service\n");
240 			return LWS_HPI_RET_HANDLED;
241 		case LWS_SSL_CAPABLE_ERROR:
242 			lwsl_info("%s: LWS_SSL_CAPABLE_ERROR\n", __func__);
243 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
244 		}
245 
246 		// lwsl_notice("%s: Actual RX %d\n", __func__, ebuf.len);
247 		// if (ebuf.len > 0)
248 		//	lwsl_hexdump_notice(ebuf.token, ebuf.len);
249 	} else
250 		lwsl_info("%s: skipped read\n", __func__);
251 
252 	if (ebuf.len < 0)
253 		return LWS_HPI_RET_PLEASE_CLOSE_ME;
254 
255 drain:
256 #if defined(LWS_WITH_CLIENT)
257 	if (lwsi_role_http(wsi) && lwsi_role_client(wsi) &&
258 	    wsi->hdr_parsing_completed && !wsi->told_user_closed) {
259 
260 		/*
261 		 * In SSL mode we get POLLIN notification about
262 		 * encrypted data in.
263 		 *
264 		 * But that is not necessarily related to decrypted
265 		 * data out becoming available; in may need to perform
266 		 * other in or out before that happens.
267 		 *
268 		 * simply mark ourselves as having readable data
269 		 * and turn off our POLLIN
270 		 */
271 		wsi->client_rx_avail = 1;
272 		if (lws_change_pollfd(wsi, LWS_POLLIN, 0))
273 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
274 
275 		/* let user code know, he'll usually ask for writeable
276 		 * callback and drain / re-enable it there
277 		 */
278 		if (user_callback_handle_rxflow(
279 				wsi->a.protocol->callback,
280 				wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP,
281 				wsi->user_space, NULL, 0)) {
282 			lwsl_info("RECEIVE_CLIENT_HTTP closed it\n");
283 			return LWS_HPI_RET_PLEASE_CLOSE_ME;
284 		}
285 
286 		return LWS_HPI_RET_HANDLED;
287 	}
288 #endif
289 
290 	/* service incoming data */
291 
292 	if (ebuf.len) {
293 		n = 0;
294 		if (lwsi_role_h2(wsi) && lwsi_state(wsi) != LRS_BODY &&
295 		    lwsi_state(wsi) != LRS_DISCARD_BODY)
296 			n = lws_read_h2(wsi, ebuf.token, (unsigned int)ebuf.len);
297 		else
298 			n = lws_read_h1(wsi, ebuf.token, (unsigned int)ebuf.len);
299 
300 		if (n < 0) {
301 			/* we closed wsi */
302 			return LWS_HPI_RET_WSI_ALREADY_DIED;
303 		}
304 
305 		if (n && buffered) {
306 			// lwsl_notice("%s: h2 use %d\n", __func__, n);
307 			m = (int)lws_buflist_use_segment(&wsi->buflist, (size_t)n);
308 			lwsl_info("%s: draining rxflow: used %d, next %d\n",
309 				    __func__, n, m);
310 			if (!m) {
311 				lwsl_notice("%s: removed %s from dll_buflist\n",
312 					    __func__, lws_wsi_tag(wsi));
313 				lws_dll2_remove(&wsi->dll_buflist);
314 			}
315 		} else
316 			if (n && n < ebuf.len && ebuf.len > 0) {
317 				// lwsl_notice("%s: h2 append seg %d\n", __func__, ebuf.len - n);
318 				m = lws_buflist_append_segment(&wsi->buflist,
319 						ebuf.token + n,
320 						(unsigned int)(ebuf.len - n));
321 				if (m < 0)
322 					return LWS_HPI_RET_PLEASE_CLOSE_ME;
323 				if (m) {
324 					lwsl_debug("%s: added %s to rxflow list\n",
325 						   __func__, lws_wsi_tag(wsi));
326 					if (lws_dll2_is_detached(&wsi->dll_buflist))
327 						lws_dll2_add_head(&wsi->dll_buflist,
328 							 &pt->dll_buflist_owner);
329 				}
330 			}
331 	}
332 
333 	// lws_buflist_describe(&wsi->buflist, wsi, __func__);
334 
335 #if 0
336 
337 	/*
338 	 * This seems to be too aggressive... we don't want the ah stuck
339 	 * there but eg, WINDOW_UPDATE may come and detach it if we leave
340 	 * it like that... it will get detached at stream close
341 	 */
342 
343 	if (wsi->http.ah
344 #if defined(LWS_WITH_CLIENT)
345 			&& !wsi->client_h2_alpn
346 #endif
347 			) {
348 		lwsl_err("xxx\n");
349 
350 		lws_header_table_detach(wsi, 0);
351 	}
352 #endif
353 
354 	pending = (unsigned int)lws_ssl_pending(wsi);
355 	if (pending) {
356 		// lwsl_info("going around\n");
357 		goto read;
358 	}
359 
360 	return LWS_HPI_RET_HANDLED;
361 }
362 
rops_handle_POLLOUT_h2(struct lws *wsi)363 int rops_handle_POLLOUT_h2(struct lws *wsi)
364 {
365 	// lwsl_notice("%s\n", __func__);
366 
367 	if (lwsi_state(wsi) == LRS_ISSUE_HTTP_BODY)
368 		return LWS_HP_RET_USER_SERVICE;
369 
370 	/*
371 	 * Priority 1: H2 protocol packets
372 	 */
373 	if ((wsi->upgraded_to_http2
374 #if defined(LWS_WITH_CLIENT)
375 			|| wsi->client_h2_alpn
376 #endif
377 			) && wsi->h2.h2n->pps) {
378 		lwsl_info("servicing pps\n");
379 		/*
380 		 * this is called on the network connection, but may close
381 		 * substreams... that may affect callers
382 		 */
383 		if (lws_h2_do_pps_send(wsi)) {
384 			wsi->socket_is_permanently_unusable = 1;
385 			return LWS_HP_RET_BAIL_DIE;
386 		}
387 		if (wsi->h2.h2n->pps)
388 			return LWS_HP_RET_BAIL_OK;
389 
390 		/* we can resume whatever we were doing */
391 		lws_rx_flow_control(wsi, LWS_RXFLOW_REASON_APPLIES_ENABLE |
392 					 LWS_RXFLOW_REASON_H2_PPS_PENDING);
393 
394 		return LWS_HP_RET_BAIL_OK; /* leave POLLOUT active */
395 	}
396 
397 	/* Priority 2: if we are closing, not allowed to send more data frags
398 	 *	       which means user callback or tx ext flush banned now
399 	 */
400 	if (lwsi_state(wsi) == LRS_RETURNED_CLOSE)
401 		return LWS_HP_RET_USER_SERVICE;
402 
403 	return LWS_HP_RET_USER_SERVICE;
404 }
405 
406 static int
rops_write_role_protocol_h2(struct lws *wsi, unsigned char *buf, size_t len, enum lws_write_protocol *wp)407 rops_write_role_protocol_h2(struct lws *wsi, unsigned char *buf, size_t len,
408 			    enum lws_write_protocol *wp)
409 {
410 	unsigned char flags = 0, base = (*wp) & 0x1f;
411 	size_t olen = len;
412 	int n;
413 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
414 	unsigned char mtubuf[4096 + LWS_PRE];
415 #endif
416 
417 	/* if not in a state to send stuff, then just send nothing */
418 
419 	if (!lwsi_role_ws(wsi) && !wsi->mux_stream_immortal &&
420 	    base != LWS_WRITE_HTTP &&
421 	    base != LWS_WRITE_HTTP_FINAL &&
422 	    base != LWS_WRITE_HTTP_HEADERS_CONTINUATION &&
423 	    base != LWS_WRITE_HTTP_HEADERS && lwsi_state(wsi) != LRS_BODY &&
424 	    ((lwsi_state(wsi) != LRS_RETURNED_CLOSE &&
425 	      lwsi_state(wsi) != LRS_WAITING_TO_SEND_CLOSE &&
426 	      lwsi_state(wsi) != LRS_ESTABLISHED &&
427 	      lwsi_state(wsi) != LRS_AWAITING_CLOSE_ACK)
428 #if defined(LWS_ROLE_WS)
429 	   || base != LWS_WRITE_CLOSE
430 #endif
431 	)) {
432 		//assert(0);
433 		lwsl_notice("%s: binning wsistate 0x%x %d: %s\n", __func__,
434 				(unsigned int)wsi->wsistate, *wp, wsi->a.protocol ?
435 					wsi->a.protocol->name : "no protocol");
436 
437 		return 0;
438 	}
439 
440 	/* compression transform... */
441 
442 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
443 	if (wsi->http.lcs) {
444 		unsigned char *out = mtubuf + LWS_PRE;
445 		size_t o = sizeof(mtubuf) - LWS_PRE;
446 
447 		n = lws_http_compression_transform(wsi, buf, len, wp, &out, &o);
448 		if (n)
449 			return n;
450 
451 		lwsl_info("%s: %s: transformed %d bytes to %d "
452 			   "(wp 0x%x, more %d)\n", __func__,
453 			   lws_wsi_tag(wsi), (int)len, (int)o, (int)*wp,
454 			   wsi->http.comp_ctx.may_have_more);
455 
456 		buf = out;
457 		len = o;
458 		base = (*wp) & 0x1f;
459 
460 		if (!len)
461 			return (int)olen;
462 	}
463 #endif
464 
465 	/*
466 	 * ws-over-h2 also ends up here after the ws framing applied
467 	 */
468 
469 	n = LWS_H2_FRAME_TYPE_DATA;
470 	if (base == LWS_WRITE_HTTP_HEADERS) {
471 		n = LWS_H2_FRAME_TYPE_HEADERS;
472 		if (!((*wp) & LWS_WRITE_NO_FIN))
473 			flags = LWS_H2_FLAG_END_HEADERS;
474 		if (wsi->h2.send_END_STREAM ||
475 		    ((*wp) & LWS_WRITE_H2_STREAM_END)) {
476 			flags |= LWS_H2_FLAG_END_STREAM;
477 			wsi->h2.send_END_STREAM = 1;
478 		}
479 	}
480 
481 	if (base == LWS_WRITE_HTTP_HEADERS_CONTINUATION) {
482 		n = LWS_H2_FRAME_TYPE_CONTINUATION;
483 		if (!((*wp) & LWS_WRITE_NO_FIN))
484 			flags = LWS_H2_FLAG_END_HEADERS;
485 		if (wsi->h2.send_END_STREAM ||
486 		    ((*wp) & LWS_WRITE_H2_STREAM_END)) {
487 			flags |= LWS_H2_FLAG_END_STREAM;
488 			wsi->h2.send_END_STREAM = 1;
489 		}
490 	}
491 
492 	if ((base == LWS_WRITE_HTTP ||
493 	     base == LWS_WRITE_HTTP_FINAL) &&
494 	     wsi->http.tx_content_length) {
495 		wsi->http.tx_content_remain -= len;
496 		lwsl_info("%s: %s: tx_content_rem = %llu\n", __func__,
497 			  lws_wsi_tag(wsi),
498 			  (unsigned long long)wsi->http.tx_content_remain);
499 		if (!wsi->http.tx_content_remain) {
500 			lwsl_info("%s: selecting final write mode\n", __func__);
501 			base = *wp = LWS_WRITE_HTTP_FINAL;
502 		}
503 	}
504 
505 	if (base == LWS_WRITE_HTTP_FINAL || ((*wp) & LWS_WRITE_H2_STREAM_END)) {
506 		flags |= LWS_H2_FLAG_END_STREAM;
507 		lwsl_info("%s: %s: setting END_STREAM, 0x%x\n", __func__,
508 				lws_wsi_tag(wsi), flags);
509 		wsi->h2.send_END_STREAM = 1;
510 	}
511 
512 	n = lws_h2_frame_write(wsi, n, flags, wsi->mux.my_sid, (unsigned int)len, buf);
513 	if (n < 0)
514 		return n;
515 
516 	/* hide it may have been compressed... */
517 
518 	return (int)olen;
519 }
520 
521 #if defined(LWS_WITH_SERVER)
522 static int
rops_check_upgrades_h2(struct lws *wsi)523 rops_check_upgrades_h2(struct lws *wsi)
524 {
525 #if defined(LWS_ROLE_WS)
526 	char *p;
527 
528 	/*
529 	 * with H2 there's also a way to upgrade a stream to something
530 	 * else... :method is CONNECT and :protocol says the name of
531 	 * the new protocol we want to carry.  We have to have sent a
532 	 * SETTINGS saying that we support it though.
533 	 */
534 	p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
535 	if (!wsi->a.vhost->h2.set.s[H2SET_ENABLE_CONNECT_PROTOCOL] ||
536 	    !wsi->mux_substream || !p || strcmp(p, "CONNECT"))
537 		return LWS_UPG_RET_CONTINUE;
538 
539 	p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_COLON_PROTOCOL);
540 	if (!p || strcmp(p, "websocket"))
541 		return LWS_UPG_RET_CONTINUE;
542 
543 	lwsl_info("Upgrade h2 to ws\n");
544 	lws_mux_mark_immortal(wsi);
545 	wsi->h2_stream_carries_ws = 1;
546 
547 	lws_metrics_tag_wsi_add(wsi, "upg", "ws_over_h2");
548 
549 	if (lws_process_ws_upgrade(wsi))
550 		return LWS_UPG_RET_BAIL;
551 
552 	lwsl_info("Upgraded h2 to ws OK\n");
553 
554 	return LWS_UPG_RET_DONE;
555 #else
556 	return LWS_UPG_RET_CONTINUE;
557 #endif
558 }
559 #endif
560 
561 static int
rops_init_vhost_h2(struct lws_vhost *vh, const struct lws_context_creation_info *info)562 rops_init_vhost_h2(struct lws_vhost *vh,
563 		   const struct lws_context_creation_info *info)
564 {
565 	vh->h2.set = vh->context->set;
566 	if (info->http2_settings[0]) {
567 		int n;
568 
569 		for (n = 1; n < LWS_H2_SETTINGS_LEN; n++)
570 			vh->h2.set.s[n] = info->http2_settings[n];
571 	}
572 
573 	return 0;
574 }
575 
576 int
rops_pt_init_destroy_h2(struct lws_context *context, const struct lws_context_creation_info *info, struct lws_context_per_thread *pt, int destroy)577 rops_pt_init_destroy_h2(struct lws_context *context,
578 		    const struct lws_context_creation_info *info,
579 		    struct lws_context_per_thread *pt, int destroy)
580 {
581 	/* if not already set by plat, use lws default SETTINGS */
582 	if (!context->set.s[0])
583 		context->set = lws_h2_stock_settings;
584 
585 	/*
586 	 * We only want to do this once... we will do it if we are built
587 	 * otherwise h1 ops will do it (or nobody if no http at all)
588 	 */
589 #if !defined(LWS_ROLE_H2) && defined(LWS_WITH_SERVER)
590 	if (!destroy) {
591 
592 		pt->sul_ah_lifecheck.cb = lws_sul_http_ah_lifecheck;
593 
594 		__lws_sul_insert_us(&pt->pt_sul_owner[LWSSULLI_MISS_IF_SUSPENDED],
595 				 &pt->sul_ah_lifecheck, 30 * LWS_US_PER_SEC);
596 	} else
597 		lws_dll2_remove(&pt->sul_ah_lifecheck.list);
598 #endif
599 
600 	return 0;
601 }
602 
603 
604 static int
rops_tx_credit_h2(struct lws *wsi, char peer_to_us, int add)605 rops_tx_credit_h2(struct lws *wsi, char peer_to_us, int add)
606 {
607 	struct lws *nwsi = lws_get_network_wsi(wsi);
608 	int n;
609 
610 	if (add) {
611 		if (peer_to_us == LWSTXCR_PEER_TO_US) {
612 			/*
613 			 * We want to tell the peer they can write an additional
614 			 * "add" bytes to us
615 			 */
616 			return lws_h2_update_peer_txcredit(wsi, (unsigned int)-1, add);
617 		}
618 
619 		/*
620 		 * We're being told we can write an additional "add" bytes
621 		 * to the peer
622 		 */
623 
624 		wsi->txc.tx_cr += add;
625 		nwsi->txc.tx_cr += add;
626 
627 		return 0;
628 	}
629 
630 	if (peer_to_us == LWSTXCR_US_TO_PEER)
631 		return lws_h2_tx_cr_get(wsi);
632 
633 	n = wsi->txc.peer_tx_cr_est;
634 	if (n > nwsi->txc.peer_tx_cr_est)
635 		n = nwsi->txc.peer_tx_cr_est;
636 
637 	return n;
638 }
639 
640 static int
rops_destroy_role_h2(struct lws *wsi)641 rops_destroy_role_h2(struct lws *wsi)
642 {
643 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
644 	struct allocated_headers *ah;
645 
646 	/* we may not have an ah, but may be on the waiting list... */
647 	lwsl_info("%s: %s: ah det due to close\n", __func__, lws_wsi_tag(wsi));
648 	__lws_header_table_detach(wsi, 0);
649 
650 	ah = pt->http.ah_list;
651 
652 	while (ah) {
653 		if (ah->in_use && ah->wsi == wsi) {
654 			lwsl_err("%s: ah leak: %s\n", __func__, lws_wsi_tag(wsi));
655 			ah->in_use = 0;
656 			ah->wsi = NULL;
657 			pt->http.ah_count_in_use--;
658 			break;
659 		}
660 		ah = ah->next;
661 	}
662 
663 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
664 	lws_http_compression_destroy(wsi);
665 #endif
666 
667 	if (wsi->upgraded_to_http2 || wsi->mux_substream) {
668 		lws_hpack_destroy_dynamic_header(wsi);
669 
670 		if (wsi->h2.h2n)
671 			lws_free_set_NULL(wsi->h2.h2n);
672 	}
673 
674 	return 0;
675 }
676 
677 static int
rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)678 rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)
679 {
680 
681 #if defined(LWS_WITH_HTTP_PROXY)
682 	if (wsi->http.proxy_clientside) {
683 
684 		wsi->http.proxy_clientside = 0;
685 
686 		if (user_callback_handle_rxflow(wsi->a.protocol->callback,
687 						wsi,
688 					    LWS_CALLBACK_COMPLETED_CLIENT_HTTP,
689 						wsi->user_space, NULL, 0))
690 			wsi->http.proxy_clientside = 0;
691 	}
692 #endif
693 
694 	if (wsi->mux_substream && wsi->h2_stream_carries_ws)
695 		lws_h2_rst_stream(wsi, 0, "none");
696 /*	else
697 		if (wsi->mux_substream)
698 			lws_h2_rst_stream(wsi, H2_ERR_STREAM_CLOSED, "swsi got closed");
699 */
700 
701 	lwsl_info(" %s, his parent %s: siblings:\n", lws_wsi_tag(wsi), lws_wsi_tag(wsi->mux.parent_wsi));
702 	lws_wsi_mux_dump_children(wsi);
703 
704 	if (wsi->upgraded_to_http2 || wsi->mux_substream
705 #if defined(LWS_WITH_CLIENT)
706 			|| wsi->client_mux_substream
707 #endif
708 	) {
709 		lwsl_info("closing %s: parent %s\n", lws_wsi_tag(wsi),
710 				lws_wsi_tag(wsi->mux.parent_wsi));
711 
712 		if (wsi->mux.child_list && lwsl_visible(LLL_INFO)) {
713 			lwsl_info(" parent %s: closing children: list:\n", lws_wsi_tag(wsi));
714 			lws_wsi_mux_dump_children(wsi);
715 		}
716 		lws_wsi_mux_close_children(wsi, (int)reason);
717 	}
718 
719 	if (wsi->upgraded_to_http2) {
720 		/* remove pps */
721 		struct lws_h2_protocol_send *w = wsi->h2.h2n->pps, *w1;
722 
723 		while (w) {
724 			w1 = w->next;
725 			free(w);
726 			w = w1;
727 		}
728 		wsi->h2.h2n->pps = NULL;
729 	}
730 
731 	if ((
732 #if defined(LWS_WITH_CLIENT)
733 			wsi->client_mux_substream ||
734 #endif
735 			wsi->mux_substream) &&
736 	     wsi->mux.parent_wsi) {
737 		lws_wsi_mux_sibling_disconnect(wsi);
738 		if (wsi->h2.pending_status_body)
739 			lws_free_set_NULL(wsi->h2.pending_status_body);
740 	}
741 
742 	return 0;
743 }
744 
745 static int
rops_callback_on_writable_h2(struct lws *wsi)746 rops_callback_on_writable_h2(struct lws *wsi)
747 {
748 #if defined(LWS_WITH_CLIENT)
749 	struct lws *network_wsi;
750 #endif
751 	int already;
752 
753 //	if (!lwsi_role_h2(wsi) && !lwsi_role_h2_ENCAPSULATION(wsi))
754 //		return 0;
755 
756 	if (wsi->mux.requested_POLLOUT
757 #if defined(LWS_WITH_CLIENT)
758 			&& !wsi->client_h2_alpn
759 #endif
760 	) {
761 		lwsl_debug("already pending writable\n");
762 		// return 1;
763 	}
764 
765 	/* is this for DATA or for control messages? */
766 
767 	if (wsi->upgraded_to_http2 && !wsi->h2.h2n->pps &&
768 	    lws_wsi_txc_check_skint(&wsi->txc, lws_h2_tx_cr_get(wsi))) {
769 		/*
770 		 * refuse his efforts to get WRITABLE if we have no credit and
771 		 * no non-DATA pps to send
772 		 */
773 		lwsl_err("%s: skint\n", __func__);
774 		return 0;
775 	}
776 
777 #if defined(LWS_WITH_CLIENT)
778 	network_wsi = lws_get_network_wsi(wsi);
779 #endif
780 	already = lws_wsi_mux_mark_parents_needing_writeable(wsi);
781 
782 	/* for network action, act only on the network wsi */
783 
784 	if (already
785 #if defined(LWS_WITH_CLIENT)
786 			&& !network_wsi->client_h2_alpn
787 			&& !network_wsi->client_mux_substream
788 #endif
789 			)
790 		return 1;
791 
792 	return 0;
793 }
794 
795 #if defined(LWS_WITH_SERVER)
796 static int
lws_h2_bind_for_post_before_action(struct lws *wsi)797 lws_h2_bind_for_post_before_action(struct lws *wsi)
798 {
799 	const struct lws_http_mount *hit;
800 	int uri_len = 0, methidx;
801 	char *uri_ptr = NULL;
802 	uint8_t *buffered;
803 	const char *p;
804 	size_t blen;
805 
806 	p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
807 	if (!p || strcmp(p, "POST"))
808 		return 0;
809 
810 
811 	if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH) ||
812 	    !lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH))
813 		/*
814 		 * There must be a path.  Actually this is checked at
815 		 * http2.c along with the other required header
816 		 * presence before we can get here.
817 		 *
818 		 * But Coverity insists to see us check it.
819 		 */
820 		return 1;
821 
822 	hit = lws_find_mount(wsi,
823 		  lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH),
824 		  lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH));
825 
826 	lwsl_debug("%s: %s: hit %p: %s\n", __func__,
827 		    lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH),
828 		    hit, hit ? hit->origin : "null");
829 	if (hit) {
830 		const struct lws_protocols *pp;
831 		const char *name = hit->origin;
832 
833 		if (hit->origin_protocol == LWSMPRO_CGI ||
834 		    hit->origin_protocol == LWSMPRO_HTTP ||
835 		    hit->origin_protocol == LWSMPRO_HTTPS)
836 			return 0;
837 
838 		if (hit->protocol)
839 			name = hit->protocol;
840 		else
841 			if (hit->origin_protocol == LWSMPRO_FILE)
842 				return 0;
843 
844 		pp = lws_vhost_name_to_protocol(wsi->a.vhost, name);
845 		if (!pp) {
846 			lwsl_info("Unable to find protocol '%s'\n", name);
847 			return 1;
848 		}
849 
850 		if (lws_bind_protocol(wsi, pp, __func__))
851 			return 1;
852 	}
853 
854 	methidx = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
855 
856 	if (methidx >= 0)
857 		if (wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP,
858 					      wsi->user_space,
859 					      hit ? uri_ptr +
860 						  hit->mountpoint_len : uri_ptr,
861 					      (size_t)(hit ? uri_len -
862 							  hit->mountpoint_len :
863 							  uri_len)))
864 			return 1;
865 
866 #if defined(LWS_WITH_ACCESS_LOG)
867 	lws_prepare_access_log_info(wsi, uri_ptr, uri_len, methidx);
868 #endif
869 
870 	lwsl_info("%s: setting LRS_BODY from 0x%x (%s)\n", __func__,
871 		    (int)wsi->wsistate, wsi->a.protocol->name);
872 
873 	lwsi_set_state(wsi, LRS_BODY);
874 
875 	if (wsi->http.content_length_explicitly_zero)
876 		return 0;
877 
878 	/*
879 	 * Dump any stashed body
880 	 */
881 
882 	while (((!wsi->http.content_length_given) ||
883 		  wsi->http.rx_content_length) &&
884 	       (blen = lws_buflist_next_segment_len(&wsi->buflist, &buffered))) {
885 
886 		if ((size_t)wsi->http.rx_content_length < blen)
887 			blen = (size_t)wsi->http.rx_content_length;
888 
889 		if (wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP_BODY,
890 				wsi->user_space, buffered, blen))
891 			return 1;
892 		lws_buflist_use_segment(&wsi->buflist, blen);
893 
894 		wsi->http.rx_content_length -= blen;
895 	}
896 
897 	if (!wsi->buflist)
898 		/* Take us off the pt's "wsi holding input buflist" list */
899 		lws_dll2_remove(&wsi->dll_buflist);
900 
901 	if (wsi->http.content_length_given && wsi->http.rx_content_length)
902 		/* still a-ways to go */
903 		return 0;
904 
905 	if (!wsi->http.content_length_given && !wsi->h2.END_STREAM)
906 		return 0;
907 
908 	if (wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP_BODY_COMPLETION,
909 				      wsi->user_space, NULL, 0))
910 		return 1;
911 
912 	return 0;
913 }
914 #endif
915 
916 /*
917  * we are the 'network wsi' for potentially many muxed child wsi with
918  * no network connection of their own, who have to use us for all their
919  * network actions.  So we use a round-robin scheme to share out the
920  * POLLOUT notifications to our children.
921  *
922  * But because any child could exhaust the socket's ability to take
923  * writes, we can only let one child get notified each time.
924  *
925  * In addition children may be closed / deleted / added between POLLOUT
926  * notifications, so we can't hold pointers
927  */
928 
929 static int
rops_perform_user_POLLOUT_h2(struct lws *wsi)930 rops_perform_user_POLLOUT_h2(struct lws *wsi)
931 {
932 	struct lws **wsi2;
933 #if defined(LWS_ROLE_WS)
934 	int write_type = LWS_WRITE_PONG;
935 #endif
936 	int n;
937 
938 	wsi = lws_get_network_wsi(wsi);
939 
940 	wsi->mux.requested_POLLOUT = 0;
941 //	if (!wsi->h2.initialized) {
942 //		lwsl_info("pollout on uninitialized http2 conn\n");
943 //		return 0;
944 //	}
945 
946 	lws_wsi_mux_dump_waiting_children(wsi);
947 
948 	wsi2 = &wsi->mux.child_list;
949 	if (!*wsi2)
950 		return 0;
951 
952 	do {
953 		struct lws *w, **wa;
954 
955 		wa = &(*wsi2)->mux.sibling_list;
956 		if (!(*wsi2)->mux.requested_POLLOUT)
957 			goto next_child;
958 
959 		/*
960 		 * we're going to do writable callback for this child.
961 		 * move him to be the last child
962 		 */
963 
964 		lwsl_debug("servicing child %s\n", lws_wsi_tag(*wsi2));
965 
966 		w = lws_wsi_mux_move_child_to_tail(wsi2);
967 
968 		if (!w) {
969 			wa = &wsi->mux.child_list;
970 			goto next_child;
971 		}
972 
973 		lwsl_info("%s: child %s, sid %d, (wsistate 0x%x)\n",
974 			  __func__, lws_wsi_tag(w), w->mux.my_sid,
975 			  (unsigned int)w->wsistate);
976 
977 		/* priority 1: post compression-transform buffered output */
978 
979 		if (lws_has_buffered_out(w)) {
980 			lwsl_debug("%s: completing partial\n", __func__);
981 			if (lws_issue_raw(w, NULL, 0) < 0) {
982 				lwsl_info("%s signalling to close\n", __func__);
983 				lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
984 						   "h2 end stream 1");
985 				wa = &wsi->mux.child_list;
986 				goto next_child;
987 			}
988 			lws_callback_on_writable(w);
989 			wa = &wsi->mux.child_list;
990 			goto next_child;
991 		}
992 
993 		/* priority 2: pre compression-transform buffered output */
994 
995 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
996 		if (w->http.comp_ctx.buflist_comp ||
997 		    w->http.comp_ctx.may_have_more) {
998 			enum lws_write_protocol wp = LWS_WRITE_HTTP;
999 
1000 			lwsl_info("%s: completing comp partial"
1001 				   "(buflist_comp %p, may %d)\n",
1002 				   __func__, w->http.comp_ctx.buflist_comp,
1003 				    w->http.comp_ctx.may_have_more);
1004 
1005 			if (rops_write_role_protocol_h2(w, NULL, 0, &wp) < 0) {
1006 				lwsl_info("%s signalling to close\n", __func__);
1007 				lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1008 						   "comp write fail");
1009 			}
1010 			lws_callback_on_writable(w);
1011 			wa = &wsi->mux.child_list;
1012 			goto next_child;
1013 		}
1014 #endif
1015 
1016 		/* priority 3: if no buffered out and waiting for that... */
1017 
1018 		if (lwsi_state(w) == LRS_FLUSHING_BEFORE_CLOSE) {
1019 			w->socket_is_permanently_unusable = 1;
1020 			lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1021 					   "h2 end stream 1");
1022 			wa = &wsi->mux.child_list;
1023 			goto next_child;
1024 		}
1025 
1026 		/* if we arrived here, even by looping, we checked choked */
1027 		w->could_have_pending = 0;
1028 		wsi->could_have_pending = 0;
1029 
1030 		if (w->h2.pending_status_body) {
1031 			w->h2.send_END_STREAM = 1;
1032 			n = lws_write(w, (uint8_t *)w->h2.pending_status_body +
1033 					 LWS_PRE,
1034 				         strlen(w->h2.pending_status_body +
1035 					        LWS_PRE), LWS_WRITE_HTTP_FINAL);
1036 			lws_free_set_NULL(w->h2.pending_status_body);
1037 			lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1038 					   "h2 end stream 1");
1039 			wa = &wsi->mux.child_list;
1040 			goto next_child;
1041 		}
1042 
1043 #if defined(LWS_WITH_CLIENT)
1044 		if (lwsi_state(w) == LRS_H2_WAITING_TO_SEND_HEADERS) {
1045 			if (lws_h2_client_handshake(w))
1046 				return -1;
1047 
1048 			goto next_child;
1049 		}
1050 #endif
1051 
1052 #if defined(LWS_WITH_SERVER)
1053 		if (lwsi_state(w) == LRS_DEFERRING_ACTION) {
1054 
1055 			/*
1056 			 * we had to defer the http_action to the POLLOUT
1057 			 * handler, because we know it will send something and
1058 			 * only in the POLLOUT handler do we know for sure
1059 			 * that there is no partial pending on the network wsi.
1060 			 */
1061 
1062 			lwsi_set_state(w, LRS_ESTABLISHED);
1063 
1064 			if (w->buflist) {
1065 				struct lws_context_per_thread *pt;
1066 
1067 				pt = &w->a.context->pt[(int)w->tsi];
1068 				lwsl_debug("%s: added %s to rxflow list\n",
1069 					   __func__, lws_wsi_tag(w));
1070 				lws_dll2_add_head(
1071 					&w->dll_buflist,
1072 					&pt->dll_buflist_owner);
1073 			}
1074 
1075 			if (lws_h2_bind_for_post_before_action(w))
1076 				return -1;
1077 
1078 			/*
1079 			 * Well, we could be getting a POST from the client, it
1080 			 * may not have any content-length.  In that case, we
1081 			 * will be in LRS_BODY state, we can't actually start
1082 			 * the action until we had the body and the stream is
1083 			 * half-closed, indicating that we can reply
1084 			 */
1085 
1086 			if (lwsi_state(w) == LRS_BODY &&
1087 			    w->h2.h2_state != LWS_H2_STATE_HALF_CLOSED_REMOTE)
1088 				goto next_child;
1089 
1090 			lwsl_info("  h2 action start...\n");
1091 			n = lws_http_action(w);
1092 			if (n < 0)
1093 				lwsl_info ("   h2 action result %d\n", n);
1094 			else
1095 			lwsl_info("  h2 action result %d "
1096 				  "(wsi->http.rx_content_remain %lld)\n",
1097 				  n, w->http.rx_content_remain);
1098 
1099 			/*
1100 			 * Commonly we only managed to start a larger transfer
1101 			 * that will complete asynchronously under its own wsi
1102 			 * states.  In those cases we will hear about
1103 			 * END_STREAM going out in the POLLOUT handler.
1104 			 */
1105 			if (n >= 0 && !w->h2.pending_status_body &&
1106 			    (n || w->h2.send_END_STREAM)) {
1107 				lwsl_info("closing stream after h2 action\n");
1108 				lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1109 						   "h2 end stream");
1110 				wa = &wsi->mux.child_list;
1111 			}
1112 
1113 			if (n < 0)
1114 				wa = &wsi->mux.child_list;
1115 
1116 			goto next_child;
1117 		}
1118 
1119 #if defined(LWS_WITH_FILE_OPS)
1120 
1121 		if (lwsi_state(w) == LRS_ISSUING_FILE) {
1122 
1123 			if (lws_wsi_txc_check_skint(&w->txc,
1124 						    lws_h2_tx_cr_get(w))) {
1125 				wa = &wsi->mux.child_list;
1126 				goto next_child;
1127 			}
1128 
1129 			((volatile struct lws *)w)->leave_pollout_active = 0;
1130 
1131 			/* >0 == completion, <0 == error
1132 			 *
1133 			 * We'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION
1134 			 * callback when it's done.  That's the case even if we
1135 			 * just completed the send, so wait for that.
1136 			 */
1137 			n = lws_serve_http_file_fragment(w);
1138 			lwsl_debug("lws_serve_http_file_fragment says %d\n", n);
1139 
1140 			/*
1141 			 * We will often hear about out having sent the final
1142 			 * DATA here... if so close the actual wsi
1143 			 */
1144 			if (n < 0 || w->h2.send_END_STREAM) {
1145 				lwsl_debug("Closing POLLOUT child %s\n",
1146 						lws_wsi_tag(w));
1147 				lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1148 						   "h2 end stream file");
1149 				wa = &wsi->mux.child_list;
1150 				goto next_child;
1151 			}
1152 			if (n > 0)
1153 				if (lws_http_transaction_completed(w))
1154 					return -1;
1155 			if (!n) {
1156 				lws_callback_on_writable(w);
1157 				(w)->mux.requested_POLLOUT = 1;
1158 			}
1159 
1160 			goto next_child;
1161 		}
1162 #endif
1163 #endif
1164 
1165 #if defined(LWS_ROLE_WS)
1166 
1167 		/* Notify peer that we decided to close */
1168 
1169 		if (lwsi_role_ws(w) &&
1170 		    lwsi_state(w) == LRS_WAITING_TO_SEND_CLOSE) {
1171 			lwsl_debug("sending close packet\n");
1172 			w->waiting_to_send_close_frame = 0;
1173 			n = lws_write(w, &w->ws->ping_payload_buf[LWS_PRE],
1174 				      w->ws->close_in_ping_buffer_len,
1175 				      LWS_WRITE_CLOSE);
1176 			if (n >= 0) {
1177 				lwsi_set_state(w, LRS_AWAITING_CLOSE_ACK);
1178 				lws_set_timeout(w, PENDING_TIMEOUT_CLOSE_ACK, 5);
1179 				lwsl_debug("sent close frame, awaiting ack\n");
1180 			}
1181 
1182 			goto next_child;
1183 		}
1184 
1185 		/*
1186 		 * Acknowledge receipt of peer's notification he closed,
1187 		 * then logically close ourself
1188 		 */
1189 
1190 		if ((lwsi_role_ws(w) && w->ws->pong_pending_flag) ||
1191 		    (lwsi_state(w) == LRS_RETURNED_CLOSE &&
1192 		     w->ws->payload_is_close)) {
1193 
1194 			if (w->ws->payload_is_close)
1195 				write_type = LWS_WRITE_CLOSE |
1196 					     LWS_WRITE_H2_STREAM_END;
1197 
1198 			n = lws_write(w, &w->ws->pong_payload_buf[LWS_PRE],
1199 				      w->ws->pong_payload_len, (enum lws_write_protocol)write_type);
1200 			if (n < 0)
1201 				return -1;
1202 
1203 			/* well he is sent, mark him done */
1204 			w->ws->pong_pending_flag = 0;
1205 			if (w->ws->payload_is_close) {
1206 				/* oh... a close frame... then we are done */
1207 				lwsl_debug("Ack'd peer's close packet\n");
1208 				w->ws->payload_is_close = 0;
1209 				lwsi_set_state(w, LRS_RETURNED_CLOSE);
1210 				lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1211 						   "returned close packet");
1212 				wa = &wsi->mux.child_list;
1213 				goto next_child;
1214 			}
1215 
1216 			lws_callback_on_writable(w);
1217 			(w)->mux.requested_POLLOUT = 1;
1218 
1219 			/* otherwise for PING, leave POLLOUT active both ways */
1220 			goto next_child;
1221 		}
1222 #endif
1223 
1224 		/*
1225 		 * set client wsi to immortal long-poll mode; send END_STREAM
1226 		 * flag on headers to indicate to a server, that allows
1227 		 * it, that you want them to leave the stream in a long poll
1228 		 * ro immortal state.  We have to send headers so the client
1229 		 * understands the http connection is ongoing.
1230 		 */
1231 
1232 		if (w->h2.send_END_STREAM && w->h2.long_poll) {
1233 			uint8_t buf[LWS_PRE + 1];
1234 			enum lws_write_protocol wp = 0;
1235 
1236 			if (!rops_write_role_protocol_h2(w, buf + LWS_PRE, 0,
1237 							 &wp)) {
1238 				lwsl_info("%s: %s: entering ro long poll\n",
1239 					  __func__, lws_wsi_tag(w));
1240 				lws_mux_mark_immortal(w);
1241 			} else
1242 				lwsl_err("%s: %s: failed to set long poll\n",
1243 						__func__, lws_wsi_tag(w));
1244 			goto next_child;
1245 		}
1246 
1247 		if (lws_callback_as_writeable(w)) {
1248 			lwsl_info("Closing POLLOUT child (end stream %d)\n",
1249 				  w->h2.send_END_STREAM);
1250 			lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
1251 					   "h2 pollout handle");
1252 			wa = &wsi->mux.child_list;
1253 		} else
1254 			 if (w->h2.send_END_STREAM)
1255 				lws_h2_state(w, LWS_H2_STATE_HALF_CLOSED_LOCAL);
1256 
1257 next_child:
1258 		wsi2 = wa;
1259 	} while (wsi2 && *wsi2 && !lws_send_pipe_choked(wsi));
1260 
1261 	// lws_wsi_mux_dump_waiting_children(wsi);
1262 
1263 	if (lws_wsi_mux_action_pending_writeable_reqs(wsi))
1264 		return -1;
1265 
1266 	return 0;
1267 }
1268 
1269 static struct lws *
rops_encapsulation_parent_h2(struct lws *wsi)1270 rops_encapsulation_parent_h2(struct lws *wsi)
1271 {
1272 	if (wsi->mux.parent_wsi)
1273 		return wsi->mux.parent_wsi;
1274 
1275 	return NULL;
1276 }
1277 
1278 static int
rops_alpn_negotiated_h2(struct lws *wsi, const char *alpn)1279 rops_alpn_negotiated_h2(struct lws *wsi, const char *alpn)
1280 {
1281 	struct allocated_headers *ah;
1282 
1283 	lwsl_debug("%s: client %d\n", __func__, lwsi_role_client(wsi));
1284 #if defined(LWS_WITH_CLIENT)
1285 	if (lwsi_role_client(wsi)) {
1286 		lwsl_info("%s: upgraded to H2\n", __func__);
1287 		wsi->client_h2_alpn = 1;
1288 	}
1289 #endif
1290 
1291 	wsi->upgraded_to_http2 = 1;
1292 
1293 	/* adopt the header info */
1294 
1295 	ah = wsi->http.ah;
1296 
1297 	lws_role_transition(wsi, lwsi_role_client(wsi) ? LWSIFR_CLIENT : LWSIFR_SERVER, LRS_H2_AWAIT_PREFACE,
1298 			    &role_ops_h2);
1299 
1300 	/* http2 union member has http union struct at start */
1301 	wsi->http.ah = ah;
1302 
1303 	if (!wsi->h2.h2n)
1304 		wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), "h2n");
1305 	if (!wsi->h2.h2n)
1306 		return 1;
1307 
1308 	lws_h2_init(wsi);
1309 
1310 	/* HTTP2 union */
1311 
1312 	if (lws_hpack_dynamic_size(wsi,
1313 			   (int)wsi->h2.h2n->our_set.s[H2SET_HEADER_TABLE_SIZE]))
1314 		return 1;
1315 	wsi->txc.tx_cr = 65535;
1316 
1317 	lwsl_info("%s: %s: configured for h2\n", __func__, lws_wsi_tag(wsi));
1318 
1319 	return 0;
1320 }
1321 
1322 static int
rops_issue_keepalive_h2(struct lws *wsi, int isvalid)1323 rops_issue_keepalive_h2(struct lws *wsi, int isvalid)
1324 {
1325 	struct lws *nwsi = lws_get_network_wsi(wsi);
1326 	struct lws_h2_protocol_send *pps;
1327 	uint64_t us = (uint64_t)lws_now_usecs();
1328 
1329 	if (isvalid) {
1330 		_lws_validity_confirmed_role(nwsi);
1331 
1332 		return 0;
1333 	}
1334 
1335 	/*
1336 	 * We can only send these frames on the network connection itself...
1337 	 * we shouldn't be tracking validity on anything else
1338 	 */
1339 
1340 	assert(wsi == nwsi);
1341 
1342 	pps = lws_h2_new_pps(LWS_H2_PPS_PING);
1343 	if (!pps)
1344 		return 1;
1345 
1346 	/*
1347 	 * The peer is defined to copy us back the unchanged payload in another
1348 	 * PING frame this time with ACK set.  So by sending that out with the
1349 	 * current time, it's an interesting opportunity to learn the effective
1350 	 * RTT on the link when the PONG comes in, plus or minus the time to
1351 	 * schedule the PPS.
1352 	 */
1353 
1354 	memcpy(pps->u.ping.ping_payload, &us, 8);
1355 	lws_pps_schedule(nwsi, pps);
1356 
1357 	return 0;
1358 }
1359 
1360 static const lws_rops_t rops_table_h2[] = {
1361 #if defined(LWS_WITH_SERVER)
1362 	/*  1 */ { .check_upgrades	  = rops_check_upgrades_h2 },
1363 #else
1364 	/*  1 */ { .check_upgrades	  = NULL },
1365 #endif
1366 	/*  2 */ { .pt_init_destroy	  = rops_pt_init_destroy_h2 },
1367 	/*  3 */ { .init_vhost		  = rops_init_vhost_h2 },
1368 	/*  4 */ { .handle_POLLIN	  = rops_handle_POLLIN_h2 },
1369 	/*  5 */ { .handle_POLLOUT	  = rops_handle_POLLOUT_h2 },
1370 	/*  6 */ { .perform_user_POLLOUT  = rops_perform_user_POLLOUT_h2 },
1371 	/*  7 */ { .callback_on_writable  = rops_callback_on_writable_h2 },
1372 	/*  8 */ { .tx_credit		  = rops_tx_credit_h2 },
1373 	/*  9 */ { .write_role_protocol	  = rops_write_role_protocol_h2 },
1374 	/* 10 */ { .encapsulation_parent  = rops_encapsulation_parent_h2 },
1375 	/* 11 */ { .alpn_negotiated	  = rops_alpn_negotiated_h2 },
1376 	/* 12 */ { .close_kill_connection = rops_close_kill_connection_h2 },
1377 	/* 13 */ { .destroy_role	  = rops_destroy_role_h2 },
1378 	/* 14 */ { .issue_keepalive	  = rops_issue_keepalive_h2 },
1379 };
1380 
1381 
1382 const struct lws_role_ops role_ops_h2 = {
1383 	/* role name */			"h2",
1384 	/* alpn id */			"h2",
1385 
1386 	/* rops_table */		rops_table_h2,
1387 	/* rops_idx */			{
1388 	  /* LWS_ROPS_check_upgrades */
1389 #if defined(LWS_WITH_SERVER)
1390 	  /* LWS_ROPS_pt_init_destroy */		0x12,
1391 #else
1392 	  /* LWS_ROPS_pt_init_destroy */		0x02,
1393 #endif
1394 	  /* LWS_ROPS_init_vhost */
1395 	  /* LWS_ROPS_destroy_vhost */			0x30,
1396 	  /* LWS_ROPS_service_flag_pending */
1397 	  /* LWS_ROPS_handle_POLLIN */			0x04,
1398 	  /* LWS_ROPS_handle_POLLOUT */
1399 	  /* LWS_ROPS_perform_user_POLLOUT */		0x56,
1400 	  /* LWS_ROPS_callback_on_writable */
1401 	  /* LWS_ROPS_tx_credit */			0x78,
1402 	  /* LWS_ROPS_write_role_protocol */
1403 	  /* LWS_ROPS_encapsulation_parent */		0x9a,
1404 	  /* LWS_ROPS_alpn_negotiated */
1405 	  /* LWS_ROPS_close_via_role_protocol */	0xb0,
1406 	  /* LWS_ROPS_close_role */
1407 	  /* LWS_ROPS_close_kill_connection */		0x0c,
1408 	  /* LWS_ROPS_destroy_role */
1409 	  /* LWS_ROPS_adoption_bind */			0xd0,
1410 	  /* LWS_ROPS_client_bind */
1411 	  /* LWS_ROPS_issue_keepalive */		0x0e,
1412 					},
1413 	/* adoption_cb clnt, srv */	{ LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED,
1414 					  LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED },
1415 	/* rx cb clnt, srv */		{ LWS_CALLBACK_RECEIVE_CLIENT_HTTP,
1416 					  0 /* may be POST, etc */ },
1417 	/* writeable cb clnt, srv */	{ LWS_CALLBACK_CLIENT_HTTP_WRITEABLE,
1418 					  LWS_CALLBACK_HTTP_WRITEABLE },
1419 	/* close cb clnt, srv */	{ LWS_CALLBACK_CLOSED_CLIENT_HTTP,
1420 					  LWS_CALLBACK_CLOSED_HTTP },
1421 	/* protocol_bind cb c, srv */	{ LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL,
1422 					  LWS_CALLBACK_HTTP_BIND_PROTOCOL },
1423 	/* protocol_unbind cb c, srv */	{ LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL,
1424 					  LWS_CALLBACK_HTTP_DROP_PROTOCOL },
1425 	/* file_handle */		0,
1426 };
1427