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