1 /*-
2  * Copyright (c) 2016-2019 Varnish Software AS
3  * All rights reserved.
4  *
5  * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 
32 #include "config.h"
33 
34 #include "cache/cache_varnishd.h"
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 
39 #include "cache/cache_transport.h"
40 #include "cache/cache_filter.h"
41 #include "http2/cache_http2.h"
42 #include "cache/cache_objhead.h"
43 
44 #include "vend.h"
45 #include "vtcp.h"
46 #include "vtim.h"
47 
48 #define H2EC1(U,v,r,d) const struct h2_error_s H2CE_##U[1] = {{#U,d,v,0,1,r}};
49 #define H2EC2(U,v,r,d) const struct h2_error_s H2SE_##U[1] = {{#U,d,v,1,0,r}};
50 #define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
51 #define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
52 #include "tbl/h2_error.h"
53 #undef H2EC1
54 #undef H2EC2
55 #undef H2EC3
56 
57 static const struct h2_error_s H2NN_ERROR[1] = {{
58 	"UNKNOWN_ERROR",
59 	"Unknown error number",
60 	0xffffffff,
61 	1,
62 	1,
63 	SC_RX_JUNK
64 }};
65 
66 enum h2frame {
67 #define H2_FRAME(l,u,t,f,...)	H2F_##u = t,
68 #include "tbl/h2_frames.h"
69 };
70 
71 static const char *
h2_framename(enum h2frame h2f)72 h2_framename(enum h2frame h2f)
73 {
74 
75 	switch (h2f) {
76 #define H2_FRAME(l,u,t,f,...)	case H2F_##u: return #u;
77 #include "tbl/h2_frames.h"
78 	default:
79 		return (NULL);
80 	}
81 }
82 
83 #define H2_FRAME_FLAGS(l,u,v)	const uint8_t H2FF_##u = v;
84 #include "tbl/h2_frames.h"
85 
86 /**********************************************************************
87  */
88 
89 static const h2_error stream_errors[] = {
90 #define H2EC1(U,v,r,d)
91 #define H2EC2(U,v,r,d) [v] = H2SE_##U,
92 #define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
93 #define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
94 #include "tbl/h2_error.h"
95 #undef H2EC1
96 #undef H2EC2
97 #undef H2EC3
98 };
99 
100 #define NSTREAMERRORS (sizeof(stream_errors)/sizeof(stream_errors[0]))
101 
102 static h2_error
h2_streamerror(uint32_t u)103 h2_streamerror(uint32_t u)
104 {
105 	if (u < NSTREAMERRORS && stream_errors[u] != NULL)
106 		return (stream_errors[u]);
107 	else
108 		return (H2NN_ERROR);
109 }
110 
111 /**********************************************************************
112  */
113 
114 static const h2_error conn_errors[] = {
115 #define H2EC1(U,v,r,d) [v] = H2CE_##U,
116 #define H2EC2(U,v,r,d)
117 #define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
118 #define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
119 #include "tbl/h2_error.h"
120 #undef H2EC1
121 #undef H2EC2
122 #undef H2EC3
123 };
124 
125 #define NCONNERRORS (sizeof(conn_errors)/sizeof(conn_errors[0]))
126 
127 static h2_error
h2_connectionerror(uint32_t u)128 h2_connectionerror(uint32_t u)
129 {
130 	if (u < NCONNERRORS && conn_errors[u] != NULL)
131 		return (conn_errors[u]);
132 	else
133 		return (H2NN_ERROR);
134 }
135 
136 /**********************************************************************/
137 
138 struct h2_req *
h2_new_req(const struct worker * wrk,struct h2_sess * h2,unsigned stream,struct req * req)139 h2_new_req(const struct worker *wrk, struct h2_sess *h2,
140     unsigned stream, struct req *req)
141 {
142 	struct h2_req *r2;
143 
144 	ASSERT_RXTHR(h2);
145 	if (req == NULL)
146 		req = Req_New(wrk, h2->sess);
147 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
148 
149 	r2 = WS_Alloc(req->ws, sizeof *r2);
150 	AN(r2);
151 	INIT_OBJ(r2, H2_REQ_MAGIC);
152 	r2->state = H2_S_IDLE;
153 	r2->h2sess = h2;
154 	r2->stream = stream;
155 	r2->req = req;
156 	if (stream)
157 		r2->counted = 1;
158 	r2->r_window = h2->local_settings.initial_window_size;
159 	r2->t_window = h2->remote_settings.initial_window_size;
160 	req->transport_priv = r2;
161 	Lck_Lock(&h2->sess->mtx);
162 	if (stream)
163 		h2->open_streams++;
164 	VTAILQ_INSERT_TAIL(&h2->streams, r2, list);
165 	Lck_Unlock(&h2->sess->mtx);
166 	h2->refcnt++;
167 	return (r2);
168 }
169 
170 void
h2_del_req(struct worker * wrk,const struct h2_req * r2)171 h2_del_req(struct worker *wrk, const struct h2_req *r2)
172 {
173 	struct h2_sess *h2;
174 	struct sess *sp;
175 
176 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
177 	AZ(r2->scheduled);
178 	h2 = r2->h2sess;
179 	CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
180 	ASSERT_RXTHR(h2);
181 	sp = h2->sess;
182 	Lck_Lock(&sp->mtx);
183 	assert(h2->refcnt > 0);
184 	--h2->refcnt;
185 	/* XXX: PRIORITY reshuffle */
186 	VTAILQ_REMOVE(&h2->streams, r2, list);
187 	Lck_Unlock(&sp->mtx);
188 	assert(!WS_IsReserved(r2->req->ws));
189 	Req_Cleanup(sp, wrk, r2->req);
190 	Req_Release(r2->req);
191 }
192 
193 void
h2_kill_req(struct worker * wrk,struct h2_sess * h2,struct h2_req * r2,h2_error h2e)194 h2_kill_req(struct worker *wrk, struct h2_sess *h2,
195     struct h2_req *r2, h2_error h2e)
196 {
197 
198 	ASSERT_RXTHR(h2);
199 	AN(h2e);
200 	Lck_Lock(&h2->sess->mtx);
201 	VSLb(h2->vsl, SLT_Debug, "KILL st=%u state=%d sched=%d",
202 	    r2->stream, r2->state, r2->scheduled);
203 	if (r2->counted) {
204 		assert(h2->open_streams > 0);
205 		h2->open_streams--;
206 		r2->counted = 0;
207 	}
208 	if (r2->error == NULL)
209 		r2->error = h2e;
210 	if (r2->scheduled) {
211 		if (r2->cond != NULL)
212 			AZ(pthread_cond_signal(r2->cond));
213 		r2 = NULL;
214 	} else {
215 		if (r2->state == H2_S_OPEN && h2->new_req == r2->req)
216 			(void)h2h_decode_fini(h2);
217 	}
218 	Lck_Unlock(&h2->sess->mtx);
219 	if (r2 != NULL)
220 		h2_del_req(wrk, r2);
221 }
222 
223 /**********************************************************************/
224 
225 static void
h2_vsl_frame(const struct h2_sess * h2,const void * ptr,size_t len)226 h2_vsl_frame(const struct h2_sess *h2, const void *ptr, size_t len)
227 {
228 	const uint8_t *b;
229 	struct vsb *vsb;
230 	const char *p;
231 	unsigned u;
232 
233 	AN(ptr);
234 	assert(len >= 9);
235 	b = ptr;
236 
237 	vsb = VSB_new_auto();
238 	AN(vsb);
239 	p = h2_framename((enum h2frame)b[3]);
240 	if (p != NULL)
241 		VSB_cat(vsb, p);
242 	else
243 		VSB_quote(vsb, b + 3, 1, VSB_QUOTE_HEX);
244 
245 	u = vbe32dec(b) >> 8;
246 	VSB_printf(vsb, "[%u] ", u);
247 	VSB_quote(vsb, b + 4, 1, VSB_QUOTE_HEX);
248 	VSB_putc(vsb, ' ');
249 	VSB_quote(vsb, b + 5, 4, VSB_QUOTE_HEX);
250 	if (u > 0) {
251 		VSB_putc(vsb, ' ');
252 		VSB_quote(vsb, b + 9, len - 9, VSB_QUOTE_HEX);
253 	}
254 	AZ(VSB_finish(vsb));
255 	Lck_Lock(&h2->sess->mtx);
256 	VSLb_bin(h2->vsl, SLT_H2RxHdr, 9, b);
257 	if (len > 9)
258 		VSLb_bin(h2->vsl, SLT_H2RxBody, len - 9, b + 9);
259 
260 	VSLb(h2->vsl, SLT_Debug, "H2RXF %s", VSB_data(vsb));
261 	Lck_Unlock(&h2->sess->mtx);
262 	VSB_destroy(&vsb);
263 }
264 
265 
266 /**********************************************************************
267  */
268 
v_matchproto_(h2_rxframe_f)269 static h2_error v_matchproto_(h2_rxframe_f)
270 h2_rx_ping(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
271 {
272 
273 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
274 	ASSERT_RXTHR(h2);
275 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
276 	assert(r2 == h2->req0);
277 
278 	if (h2->rxf_len != 8)				// rfc7540,l,2364,2366
279 		return (H2CE_FRAME_SIZE_ERROR);
280 	AZ(h2->rxf_stream);				// rfc7540,l,2359,2362
281 	if (h2->rxf_flags != 0)				// We never send pings
282 		return (H2SE_PROTOCOL_ERROR);
283 	H2_Send_Get(wrk, h2, r2);
284 	H2_Send_Frame(wrk, h2,
285 	    H2_F_PING, H2FF_PING_ACK, 8, 0, h2->rxf_data);
286 	H2_Send_Rel(h2, r2);
287 	return (0);
288 }
289 
290 /**********************************************************************
291  */
292 
v_matchproto_(h2_rxframe_f)293 static h2_error v_matchproto_(h2_rxframe_f)
294 h2_rx_push_promise(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
295 {
296 
297 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
298 	ASSERT_RXTHR(h2);
299 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
300 	// rfc7540,l,2262,2267
301 	return (H2CE_PROTOCOL_ERROR);
302 }
303 
304 /**********************************************************************
305  */
306 
v_matchproto_(h2_rxframe_f)307 static h2_error v_matchproto_(h2_rxframe_f)
308 h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
309 {
310 
311 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
312 	ASSERT_RXTHR(h2);
313 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
314 
315 	if (h2->rxf_len != 4)			// rfc7540,l,2003,2004
316 		return (H2CE_FRAME_SIZE_ERROR);
317 	if (r2 == NULL)
318 		return (0);
319 	h2_kill_req(wrk, h2, r2, h2_streamerror(vbe32dec(h2->rxf_data)));
320 	return (0);
321 }
322 
323 /**********************************************************************
324  */
325 
v_matchproto_(h2_rxframe_f)326 static h2_error v_matchproto_(h2_rxframe_f)
327 h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
328 {
329 
330 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
331 	ASSERT_RXTHR(h2);
332 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
333 	assert(r2 == h2->req0);
334 
335 	h2->goaway_last_stream = vbe32dec(h2->rxf_data);
336 	h2->error = h2_connectionerror(vbe32dec(h2->rxf_data + 4));
337 	Lck_Lock(&h2->sess->mtx);
338 	VSLb(h2->vsl, SLT_Debug, "GOAWAY %s", h2->error->name);
339 	Lck_Unlock(&h2->sess->mtx);
340 	return (h2->error);
341 }
342 
343 /**********************************************************************
344  */
345 
v_matchproto_(h2_rxframe_f)346 static h2_error v_matchproto_(h2_rxframe_f)
347 h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
348 {
349 	uint32_t wu;
350 
351 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
352 	ASSERT_RXTHR(h2);
353 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
354 
355 	if (h2->rxf_len != 4)
356 		return (H2CE_FRAME_SIZE_ERROR);
357 	wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
358 	if (wu == 0)
359 		return (H2SE_PROTOCOL_ERROR);
360 	if (r2 == NULL)
361 		return (0);
362 	Lck_Lock(&h2->sess->mtx);
363 	r2->t_window += wu;
364 	if (r2 == h2->req0)
365 		AZ(pthread_cond_broadcast(h2->winupd_cond));
366 	else if (r2->cond != NULL)
367 		AZ(pthread_cond_signal(r2->cond));
368 	Lck_Unlock(&h2->sess->mtx);
369 	if (r2->t_window >= (1LL << 31))
370 		return (H2SE_FLOW_CONTROL_ERROR);
371 	return (0);
372 }
373 
374 /**********************************************************************
375  * Incoming PRIORITY, possibly an ACK of one we sent.
376  */
377 
v_matchproto_(h2_rxframe_f)378 static h2_error v_matchproto_(h2_rxframe_f)
379 h2_rx_priority(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
380 {
381 
382 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
383 	ASSERT_RXTHR(h2);
384 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
385 	return (0);
386 }
387 
388 /**********************************************************************
389  * Incoming SETTINGS, possibly an ACK of one we sent.
390  */
391 
392 #define H2_SETTING(U,l, ...)					\
393 static void v_matchproto_(h2_setsetting_f)			\
394 h2_setting_##l(struct h2_settings* s, uint32_t v)		\
395 {								\
396 	s -> l = v;						\
397 }
398 #include <tbl/h2_settings.h>
399 
400 #define H2_SETTING(U, l, ...)					\
401 const struct h2_setting_s H2_SET_##U[1] = {{			\
402 	#l,							\
403 	h2_setting_##l,						\
404 	__VA_ARGS__						\
405 }};
406 #include <tbl/h2_settings.h>
407 
408 static const struct h2_setting_s * const h2_setting_tbl[] = {
409 #define H2_SETTING(U,l,v, ...) [v] = H2_SET_##U,
410 #include <tbl/h2_settings.h>
411 };
412 
413 #define H2_SETTING_TBL_LEN (sizeof(h2_setting_tbl)/sizeof(h2_setting_tbl[0]))
414 
415 static void
h2_win_adjust(const struct h2_sess * h2,uint32_t oldval,uint32_t newval)416 h2_win_adjust(const struct h2_sess *h2, uint32_t oldval, uint32_t newval)
417 {
418 	struct h2_req *r2;
419 
420 	Lck_AssertHeld(&h2->sess->mtx);
421 	// rfc7540,l,2668,2674
422 	VTAILQ_FOREACH(r2, &h2->streams, list) {
423 		CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
424 		if (r2 == h2->req0)
425 			continue; // rfc7540,l,2699,2699
426 		switch (r2->state) {
427 		case H2_S_IDLE:
428 		case H2_S_OPEN:
429 		case H2_S_CLOS_REM:
430 			/*
431 			 * We allow a window to go negative, as per
432 			 * rfc7540,l,2676,2680
433 			 */
434 			r2->t_window += (int64_t)newval - oldval;
435 			break;
436 		default:
437 			break;
438 		}
439 	}
440 }
441 
442 h2_error
h2_set_setting(struct h2_sess * h2,const uint8_t * d)443 h2_set_setting(struct h2_sess *h2, const uint8_t *d)
444 {
445 	const struct h2_setting_s *s;
446 	uint16_t x;
447 	uint32_t y;
448 
449 	x = vbe16dec(d);
450 	y = vbe32dec(d + 2);
451 	if (x >= H2_SETTING_TBL_LEN || h2_setting_tbl[x] == NULL) {
452 		// rfc7540,l,2181,2182
453 		Lck_Lock(&h2->sess->mtx);
454 		VSLb(h2->vsl, SLT_Debug,
455 		    "H2SETTING unknown setting 0x%04x=%08x (ignored)", x, y);
456 		Lck_Unlock(&h2->sess->mtx);
457 		return (0);
458 	}
459 	s = h2_setting_tbl[x];
460 	AN(s);
461 	if (y < s->minval || y > s->maxval) {
462 		Lck_Lock(&h2->sess->mtx);
463 		VSLb(h2->vsl, SLT_Debug, "H2SETTING invalid %s=0x%08x",
464 		    s->name, y);
465 		Lck_Unlock(&h2->sess->mtx);
466 		AN(s->range_error);
467 		if (!DO_DEBUG(DBG_H2_NOCHECK))
468 			return (s->range_error);
469 	}
470 	Lck_Lock(&h2->sess->mtx);
471 	if (s == H2_SET_INITIAL_WINDOW_SIZE)
472 		h2_win_adjust(h2, h2->remote_settings.initial_window_size, y);
473 	VSLb(h2->vsl, SLT_Debug, "H2SETTING %s=0x%08x", s->name, y);
474 	Lck_Unlock(&h2->sess->mtx);
475 	AN(s->setfunc);
476 	s->setfunc(&h2->remote_settings, y);
477 	return (0);
478 }
479 
v_matchproto_(h2_rxframe_f)480 static h2_error v_matchproto_(h2_rxframe_f)
481 h2_rx_settings(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
482 {
483 	const uint8_t *p;
484 	unsigned l;
485 	h2_error retval = 0;
486 
487 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
488 	ASSERT_RXTHR(h2);
489 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
490 	assert(r2 == h2->req0);
491 	AZ(h2->rxf_stream);
492 
493 	if (h2->rxf_flags == H2FF_SETTINGS_ACK) {
494 		if (h2->rxf_len > 0)			// rfc7540,l,2047,2049
495 			return (H2CE_FRAME_SIZE_ERROR);
496 		return (0);
497 	} else {
498 		if (h2->rxf_len % 6)			// rfc7540,l,2062,2064
499 			return (H2CE_PROTOCOL_ERROR);
500 		p = h2->rxf_data;
501 		for (l = h2->rxf_len; l >= 6; l -= 6, p += 6) {
502 			retval = h2_set_setting(h2, p);
503 			if (retval)
504 				return (retval);
505 		}
506 		H2_Send_Get(wrk, h2, r2);
507 		H2_Send_Frame(wrk, h2,
508 		    H2_F_SETTINGS, H2FF_SETTINGS_ACK, 0, 0, NULL);
509 		H2_Send_Rel(h2, r2);
510 	}
511 	return (0);
512 }
513 
514 /**********************************************************************
515  * Incoming HEADERS, this is where the partys at...
516  */
517 
v_matchproto_(task_func_t)518 void v_matchproto_(task_func_t)
519 h2_do_req(struct worker *wrk, void *priv)
520 {
521 	struct req *req;
522 	struct h2_req *r2;
523 	struct h2_sess *h2;
524 
525 	CAST_OBJ_NOTNULL(req, priv, REQ_MAGIC);
526 	CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
527 	THR_SetRequest(req);
528 	CNT_Embark(wrk, req);
529 
530 	wrk->stats->client_req++;
531 	if (CNT_Request(req) != REQ_FSM_DISEMBARK) {
532 		assert(!WS_IsReserved(req->ws));
533 		AZ(req->top->vcl0);
534 		h2 = r2->h2sess;
535 		CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
536 		Lck_Lock(&h2->sess->mtx);
537 		r2->scheduled = 0;
538 		r2->state = H2_S_CLOSED;
539 		r2->h2sess->do_sweep = 1;
540 		if (h2->mailcall == r2) {
541 			h2->mailcall = NULL;
542 			AZ(pthread_cond_signal(h2->cond));
543 		}
544 		Lck_Unlock(&h2->sess->mtx);
545 	}
546 	THR_SetRequest(NULL);
547 }
548 
549 static h2_error
h2_end_headers(struct worker * wrk,struct h2_sess * h2,struct req * req,struct h2_req * r2)550 h2_end_headers(struct worker *wrk, struct h2_sess *h2,
551     struct req *req, struct h2_req *r2)
552 {
553 	h2_error h2e;
554 	ssize_t cl;
555 
556 	ASSERT_RXTHR(h2);
557 	assert(r2->state == H2_S_OPEN);
558 	h2e = h2h_decode_fini(h2);
559 	h2->new_req = NULL;
560 	if (h2e != NULL) {
561 		Lck_Lock(&h2->sess->mtx);
562 		VSLb(h2->vsl, SLT_Debug, "HPACK/FINI %s", h2e->name);
563 		Lck_Unlock(&h2->sess->mtx);
564 		assert(!WS_IsReserved(r2->req->ws));
565 		h2_del_req(wrk, r2);
566 		return (h2e);
567 	}
568 	VSLb_ts_req(req, "Req", req->t_req);
569 
570 	// XXX: Smarter to do this already at HPACK time into tail end of
571 	// XXX: WS, then copy back once all headers received.
572 	// XXX: Have I mentioned H/2 Is hodge-podge ?
573 	http_CollectHdrSep(req->http, H_Cookie, "; ");	// rfc7540,l,3114,3120
574 
575 	cl = http_GetContentLength(req->http);
576 	assert(cl >= -2);
577 	if (cl == -2) {
578 		VSLb(h2->vsl, SLT_Debug, "Non-parseable Content-Length");
579 		return (H2SE_PROTOCOL_ERROR);
580 	}
581 
582 	if (req->req_body_status == NULL) {
583 		if (cl == -1)
584 			req->req_body_status = BS_EOF;
585 		else
586 			req->req_body_status = BS_LENGTH;
587 		req->htc->content_length = cl;
588 	} else {
589 		/* A HEADER frame contained END_STREAM */
590 		assert (req->req_body_status == BS_NONE);
591 		r2->state = H2_S_CLOS_REM;
592 		if (cl > 0)
593 			return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840
594 	}
595 
596 	if (req->http->hd[HTTP_HDR_METHOD].b == NULL) {
597 		VSLb(h2->vsl, SLT_Debug, "Missing :method");
598 		return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
599 	}
600 	if (req->http->hd[HTTP_HDR_URL].b == NULL) {
601 		VSLb(h2->vsl, SLT_Debug, "Missing :path");
602 		return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
603 	}
604 	AN(req->http->hd[HTTP_HDR_PROTO].b);
605 
606 	assert(req->req_step == R_STP_TRANSPORT);
607 	VCL_TaskEnter(req->privs);
608 	VCL_TaskEnter(req->top->privs);
609 	req->task->func = h2_do_req;
610 	req->task->priv = req;
611 	r2->scheduled = 1;
612 	if (Pool_Task(wrk->pool, req->task, TASK_QUEUE_STR) != 0) {
613 		r2->scheduled = 0;
614 		r2->state = H2_S_CLOSED;
615 		return (H2SE_REFUSED_STREAM); //rfc7540,l,3326,3329
616 	}
617 	return (0);
618 }
619 
v_matchproto_(h2_rxframe_f)620 static h2_error v_matchproto_(h2_rxframe_f)
621 h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
622 {
623 	struct req *req;
624 	h2_error h2e;
625 	const uint8_t *p;
626 	size_t l;
627 
628 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
629 	ASSERT_RXTHR(h2);
630 
631 	if (r2 == NULL) {
632 		if (h2->rxf_stream <= h2->highest_stream)
633 			return (H2CE_PROTOCOL_ERROR);	// rfc7540,l,1153,1158
634 		/* NB: we don't need to guard the read of h2->open_streams
635 		 * because headers are handled sequentially so it cannot
636 		 * increase under our feet.
637 		 */
638 		if (h2->open_streams >=
639 		    h2->local_settings.max_concurrent_streams) {
640 			VSLb(h2->vsl, SLT_Debug,
641 			     "H2: stream %u: Hit maximum number of "
642 			     "concurrent streams", h2->rxf_stream);
643 			return (H2SE_REFUSED_STREAM);	// rfc7540,l,1200,1205
644 		}
645 		h2->highest_stream = h2->rxf_stream;
646 		r2 = h2_new_req(wrk, h2, h2->rxf_stream, NULL);
647 	}
648 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
649 
650 	if (r2->state != H2_S_IDLE)
651 		return (H2CE_PROTOCOL_ERROR);	// XXX spec ?
652 	r2->state = H2_S_OPEN;
653 
654 	req = r2->req;
655 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
656 
657 	req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);
658 	VSLb(req->vsl, SLT_Begin, "req %u rxreq", VXID(req->sp->vxid));
659 	VSL(SLT_Link, req->sp->vxid, "req %u rxreq", VXID(req->vsl->wid));
660 
661 	h2->new_req = req;
662 	req->sp = h2->sess;
663 	req->transport = &H2_transport;
664 
665 	req->t_first = VTIM_real();
666 	req->t_req = VTIM_real();
667 	req->t_prev = req->t_first;
668 	VSLb_ts_req(req, "Start", req->t_first);
669 	req->acct.req_hdrbytes += h2->rxf_len;
670 
671 	HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
672 	http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0");
673 
674 	h2h_decode_init(h2);
675 
676 	p = h2->rxf_data;
677 	l = h2->rxf_len;
678 	if (h2->rxf_flags & H2FF_HEADERS_PADDED) {
679 		if (*p + 1 > l)
680 			return (H2CE_PROTOCOL_ERROR);	// rfc7540,l,1884,1887
681 		l -= 1 + *p;
682 		p += 1;
683 	}
684 	if (h2->rxf_flags & H2FF_HEADERS_PRIORITY) {
685 		if (l < 5)
686 			return (H2CE_PROTOCOL_ERROR);
687 		l -= 5;
688 		p += 5;
689 	}
690 	h2e = h2h_decode_bytes(h2, p, l);
691 	if (h2e != NULL) {
692 		Lck_Lock(&h2->sess->mtx);
693 		VSLb(h2->vsl, SLT_Debug, "HPACK(hdr) %s", h2e->name);
694 		Lck_Unlock(&h2->sess->mtx);
695 		(void)h2h_decode_fini(h2);
696 		assert(!WS_IsReserved(r2->req->ws));
697 		h2_del_req(wrk, r2);
698 		return (h2e);
699 	}
700 
701 	if (h2->rxf_flags & H2FF_HEADERS_END_STREAM)
702 		req->req_body_status = BS_NONE;
703 
704 	if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
705 		return (h2_end_headers(wrk, h2, req, r2));
706 	return (0);
707 }
708 
709 /**********************************************************************/
710 
v_matchproto_(h2_rxframe_f)711 static h2_error v_matchproto_(h2_rxframe_f)
712 h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
713 {
714 	struct req *req;
715 	h2_error h2e;
716 
717 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
718 	ASSERT_RXTHR(h2);
719 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
720 
721 	if (r2 == NULL || r2->state != H2_S_OPEN || r2->req != h2->new_req)
722 		return (H2CE_PROTOCOL_ERROR);	// XXX spec ?
723 	req = r2->req;
724 	h2e = h2h_decode_bytes(h2, h2->rxf_data, h2->rxf_len);
725 	r2->req->acct.req_hdrbytes += h2->rxf_len;
726 	if (h2e != NULL) {
727 		Lck_Lock(&h2->sess->mtx);
728 		VSLb(h2->vsl, SLT_Debug, "HPACK(cont) %s", h2e->name);
729 		Lck_Unlock(&h2->sess->mtx);
730 		(void)h2h_decode_fini(h2);
731 		assert(!WS_IsReserved(r2->req->ws));
732 		h2_del_req(wrk, r2);
733 		return (h2e);
734 	}
735 	if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
736 		return (h2_end_headers(wrk, h2, req, r2));
737 	return (0);
738 }
739 
740 /**********************************************************************/
741 
v_matchproto_(h2_rxframe_f)742 static h2_error v_matchproto_(h2_rxframe_f)
743 h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
744 {
745 	int w1 = 0, w2 = 0;
746 	char buf[4];
747 	unsigned wi;
748 	ssize_t cl;
749 
750 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
751 	ASSERT_RXTHR(h2);
752 	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
753 
754 	if (r2 == NULL || !r2->scheduled)
755 		return (0);
756 	if (r2->state >= H2_S_CLOS_REM) {
757 		r2->error = H2SE_STREAM_CLOSED;
758 		return (H2SE_STREAM_CLOSED); // rfc7540,l,1766,1769
759 	}
760 	Lck_Lock(&h2->sess->mtx);
761 	while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0)
762 		AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0));
763 	if (h2->error || r2->error) {
764 		Lck_Unlock(&h2->sess->mtx);
765 		return (h2->error ? h2->error : r2->error);
766 	}
767 
768 	r2->reqbody_bytes += h2->rxf_len;
769 	if (h2->rxf_flags & H2FF_DATA_END_STREAM)
770 		r2->state = H2_S_CLOS_REM;
771 	cl = r2->req->htc->content_length;
772 	if (cl >= 0 && (r2->reqbody_bytes > cl ||
773 	      (r2->state >= H2_S_CLOS_REM && r2->reqbody_bytes != cl))) {
774 		VSLb(h2->vsl, SLT_Debug,
775 		    "H2: stream %u: Received data and Content-Length"
776 		    " mismatch", h2->rxf_stream);
777 		r2->error = H2SE_PROTOCOL_ERROR; // rfc7540,l,3150,3163
778 		if (r2->cond)
779 			AZ(pthread_cond_signal(r2->cond));
780 		Lck_Unlock(&h2->sess->mtx);
781 		return (H2SE_PROTOCOL_ERROR);
782 	}
783 
784 	AZ(h2->mailcall);
785 	h2->mailcall = r2;
786 	h2->req0->r_window -= h2->rxf_len;
787 	r2->r_window -= h2->rxf_len;
788 	// req_bodybytes accounted in CNT code.
789 	if (r2->cond)
790 		AZ(pthread_cond_signal(r2->cond));
791 	while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0)
792 		AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0));
793 	wi = cache_param->h2_rx_window_increment;
794 	if (h2->req0->r_window < cache_param->h2_rx_window_low_water) {
795 		h2->req0->r_window += wi;
796 		w1 = 1;
797 	}
798 	if (r2->r_window < cache_param->h2_rx_window_low_water) {
799 		r2->r_window += wi;
800 		w2 = 1;
801 	}
802 
803 
804 	Lck_Unlock(&h2->sess->mtx);
805 
806 	if (w1 || w2) {
807 		vbe32enc(buf, wi);
808 		H2_Send_Get(wrk, h2, h2->req0);
809 		if (w1)
810 			H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
811 			    4, 0, buf);
812 		if (w2)
813 			H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
814 			    4, r2->stream, buf);
815 		H2_Send_Rel(h2, h2->req0);
816 	}
817 	return (0);
818 }
819 
v_matchproto_(vfp_pull_f)820 static enum vfp_status v_matchproto_(vfp_pull_f)
821 h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp)
822 {
823 	struct h2_req *r2;
824 	struct h2_sess *h2;
825 	unsigned l;
826 	enum vfp_status retval;
827 
828 	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
829 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
830 	CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
831 	h2 = r2->h2sess;
832 
833 	AN(ptr);
834 	AN(lp);
835 	l = *lp;
836 	*lp = 0;
837 
838 	Lck_Lock(&h2->sess->mtx);
839 	r2->cond = &vc->wrk->cond;
840 	while (h2->mailcall != r2 && h2->error == 0 && r2->error == 0)
841 		AZ(Lck_CondWait(r2->cond, &h2->sess->mtx, 0));
842 	r2->cond = NULL;
843 	if (h2->error || r2->error) {
844 		retval = VFP_ERROR;
845 	} else {
846 		assert(h2->mailcall == r2);
847 		if (l > h2->rxf_len)
848 			l = h2->rxf_len;
849 		if (l > 0) {
850 			memcpy(ptr, h2->rxf_data, l);
851 			h2->rxf_data += l;
852 			h2->rxf_len -= l;
853 		}
854 		*lp = l;
855 		if (h2->rxf_len > 0) {
856 			/* We ran out of storage: Have VFP call us
857 			 * again with a fresh buffer */
858 			Lck_Unlock(&h2->sess->mtx);
859 			return (VFP_OK);
860 		}
861 		if (h2->rxf_len == 0 && r2->state >= H2_S_CLOS_REM)
862 			retval = VFP_END;
863 		else
864 			retval = VFP_OK;
865 		h2->mailcall = NULL;
866 		AZ(pthread_cond_signal(h2->cond));
867 	}
868 	Lck_Unlock(&h2->sess->mtx);
869 	return (retval);
870 }
871 
872 static void
h2_vfp_body_fini(struct vfp_ctx * vc,struct vfp_entry * vfe)873 h2_vfp_body_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
874 {
875 	struct h2_req *r2;
876 	struct h2_sess *h2;
877 
878 	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
879 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
880 	CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
881 	CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
882 	h2 = r2->h2sess;
883 
884 	if (vc->failed) {
885 		CHECK_OBJ_NOTNULL(r2->req->wrk, WORKER_MAGIC);
886 		H2_Send_Get(r2->req->wrk, h2, r2);
887 		H2_Send_RST(r2->req->wrk, h2, r2, r2->stream,
888 		    H2SE_REFUSED_STREAM);
889 		H2_Send_Rel(h2, r2);
890 		Lck_Lock(&h2->sess->mtx);
891 		r2->error = H2SE_REFUSED_STREAM;
892 		if (h2->mailcall == r2) {
893 			h2->mailcall = NULL;
894 			AZ(pthread_cond_signal(h2->cond));
895 		}
896 		Lck_Unlock(&h2->sess->mtx);
897 	}
898 }
899 
900 static const struct vfp h2_body = {
901 	.name = "H2_BODY",
902 	.pull = h2_vfp_body,
903 	.fini = h2_vfp_body_fini
904 };
905 
v_matchproto_(vtr_req_body_t)906 void v_matchproto_(vtr_req_body_t)
907 h2_req_body(struct req *req)
908 {
909 	struct h2_req *r2;
910 	struct vfp_entry *vfe;
911 
912 	CHECK_OBJ(req, REQ_MAGIC);
913 	CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
914 	vfe = VFP_Push(req->vfc, &h2_body);
915 	AN(vfe);
916 	vfe->priv1 = r2;
917 }
918 
919 /**********************************************************************/
920 
v_matchproto_(vtr_req_fail_f)921 void v_matchproto_(vtr_req_fail_f)
922 h2_req_fail(struct req *req, enum sess_close reason)
923 {
924 	assert(reason > 0);
925 	assert(req->sp->fd != 0);
926 	VSLb(req->vsl, SLT_Debug, "H2FAILREQ");
927 }
928 
929 /**********************************************************************/
930 
v_matchproto_(htc_complete_f)931 static enum htc_status_e v_matchproto_(htc_complete_f)
932 h2_frame_complete(struct http_conn *htc)
933 {
934 	struct h2_sess *h2;
935 
936 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
937 	CAST_OBJ_NOTNULL(h2, htc->priv, H2_SESS_MAGIC);
938 	if (htc->rxbuf_b + 9 > htc->rxbuf_e ||
939 	    htc->rxbuf_b + 9 + (vbe32dec(htc->rxbuf_b) >> 8) > htc->rxbuf_e)
940 		return (HTC_S_MORE);
941 	return (HTC_S_COMPLETE);
942 }
943 
944 /**********************************************************************/
945 
946 static h2_error
h2_procframe(struct worker * wrk,struct h2_sess * h2,h2_frame h2f)947 h2_procframe(struct worker *wrk, struct h2_sess *h2, h2_frame h2f)
948 {
949 	struct h2_req *r2;
950 	h2_error h2e;
951 
952 	ASSERT_RXTHR(h2);
953 	if (h2->rxf_stream == 0 && h2f->act_szero != 0)
954 		return (h2f->act_szero);
955 
956 	if (h2->rxf_stream != 0 && h2f->act_snonzero != 0)
957 		return (h2f->act_snonzero);
958 
959 	if (h2->rxf_stream > h2->highest_stream && h2f->act_sidle != 0)
960 		return (h2f->act_sidle);
961 
962 	if (h2->rxf_stream != 0 && !(h2->rxf_stream & 1)) {
963 		// rfc7540,l,1140,1145
964 		// rfc7540,l,1153,1158
965 		/* No even streams, we don't do PUSH_PROMISE */
966 		Lck_Lock(&h2->sess->mtx);
967 		VSLb(h2->vsl, SLT_Debug, "H2: illegal stream (=%u)",
968 		    h2->rxf_stream);
969 		Lck_Unlock(&h2->sess->mtx);
970 		return (H2CE_PROTOCOL_ERROR);
971 	}
972 
973 	VTAILQ_FOREACH(r2, &h2->streams, list)
974 		if (r2->stream == h2->rxf_stream)
975 			break;
976 
977 	if (h2->new_req != NULL &&
978 	    !(r2 && h2->new_req == r2->req && h2f == H2_F_CONTINUATION))
979 		return (H2CE_PROTOCOL_ERROR);	// rfc7540,l,1859,1863
980 
981 	h2e = h2f->rxfunc(wrk, h2, r2);
982 	if (h2e == 0)
983 		return (0);
984 	if (h2->rxf_stream == 0 || h2e->connection)
985 		return (h2e);	// Connection errors one level up
986 
987 	H2_Send_Get(wrk, h2, h2->req0);
988 	H2_Send_RST(wrk, h2, h2->req0, h2->rxf_stream, h2e);
989 	H2_Send_Rel(h2, h2->req0);
990 	return (0);
991 }
992 
993 int
h2_stream_tmo(struct h2_sess * h2,const struct h2_req * r2,vtim_real now)994 h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now)
995 {
996 	int r = 0;
997 
998 	CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
999 	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
1000 	Lck_AssertHeld(&h2->sess->mtx);
1001 
1002 	/* NB: when now is NAN, it means that idle_send_timeout was hit
1003 	 * on a lock condwait operation.
1004 	 */
1005 	if (isnan(now))
1006 		AN(r2->t_winupd);
1007 
1008 	if (r2->t_winupd == 0 && r2->t_send == 0)
1009 		return (0);
1010 
1011 	if (isnan(now) || (r2->t_winupd != 0 &&
1012 	    now - r2->t_winupd > SESS_TMO(h2->sess, idle_send_timeout))) {
1013 		VSLb(h2->vsl, SLT_Debug,
1014 		     "H2: stream %u: Hit idle_send_timeout waiting for"
1015 		     " WINDOW_UPDATE", r2->stream);
1016 		r = 1;
1017 	}
1018 
1019 	if (r == 0 && r2->t_send != 0 &&
1020 	    now - r2->t_send > SESS_TMO(h2->sess, send_timeout)) {
1021 		VSLb(h2->vsl, SLT_Debug,
1022 		     "H2: stream %u: Hit send_timeout", r2->stream);
1023 		r = 1;
1024 	}
1025 
1026 	return (r);
1027 }
1028 
1029 static int
h2_stream_tmo_unlocked(struct h2_sess * h2,const struct h2_req * r2)1030 h2_stream_tmo_unlocked(struct h2_sess *h2, const struct h2_req *r2)
1031 {
1032 	int r;
1033 
1034 	Lck_Lock(&h2->sess->mtx);
1035 	r = h2_stream_tmo(h2, r2, h2->sess->t_idle);
1036 	Lck_Unlock(&h2->sess->mtx);
1037 
1038 	return (r);
1039 }
1040 
1041 /*
1042  * This is the janitorial task of cleaning up any closed & refused
1043  * streams, and checking if the session is timed out.
1044  */
1045 static int
h2_sweep(struct worker * wrk,struct h2_sess * h2)1046 h2_sweep(struct worker *wrk, struct h2_sess *h2)
1047 {
1048 	int tmo = 0;
1049 	struct h2_req *r2, *r22;
1050 
1051 	ASSERT_RXTHR(h2);
1052 
1053 	h2->do_sweep = 0;
1054 	VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
1055 		if (r2 == h2->req0) {
1056 			assert (r2->state == H2_S_IDLE);
1057 			continue;
1058 		}
1059 		switch (r2->state) {
1060 		case H2_S_CLOSED:
1061 			if (!r2->scheduled)
1062 				h2_del_req(wrk, r2);
1063 			break;
1064 		case H2_S_CLOS_REM:
1065 			if (!r2->scheduled) {
1066 				H2_Send_Get(wrk, h2, h2->req0);
1067 				H2_Send_RST(wrk, h2, h2->req0, r2->stream,
1068 				    H2SE_REFUSED_STREAM);
1069 				H2_Send_Rel(h2, h2->req0);
1070 				h2_del_req(wrk, r2);
1071 				continue;
1072 			}
1073 			/* FALLTHROUGH */
1074 		case H2_S_CLOS_LOC:
1075 		case H2_S_OPEN:
1076 			if (h2_stream_tmo_unlocked(h2, r2)) {
1077 				tmo = 1;
1078 				continue;
1079 			}
1080 			break;
1081 		case H2_S_IDLE:
1082 			/* Current code make this unreachable: h2_new_req is
1083 			 * only called inside h2_rx_headers, which immediately
1084 			 * sets the new stream state to H2_S_OPEN */
1085 			/* FALLTHROUGH */
1086 		default:
1087 			WRONG("Wrong h2 stream state");
1088 			break;
1089 		}
1090 	}
1091 	if (tmo)
1092 		return (0);
1093 	return (h2->refcnt > 1);
1094 }
1095 
1096 
1097 /***********************************************************************
1098  * Called in loop from h2_new_session()
1099  */
1100 
1101 #define H2_FRAME(l,U,...) const struct h2_frame_s H2_F_##U[1] = \
1102     {{ #U, h2_rx_##l, __VA_ARGS__ }};
1103 #include "tbl/h2_frames.h"
1104 
1105 static const h2_frame h2flist[] = {
1106 #define H2_FRAME(l,U,t,...) [t] = H2_F_##U,
1107 #include "tbl/h2_frames.h"
1108 };
1109 
1110 #define H2FMAX (sizeof(h2flist) / sizeof(h2flist[0]))
1111 
1112 int
h2_rxframe(struct worker * wrk,struct h2_sess * h2)1113 h2_rxframe(struct worker *wrk, struct h2_sess *h2)
1114 {
1115 	enum htc_status_e hs;
1116 	h2_frame h2f;
1117 	h2_error h2e;
1118 	char b[8];
1119 
1120 	ASSERT_RXTHR(h2);
1121 	VTCP_blocking(*h2->htc->rfd);
1122 	h2->sess->t_idle = VTIM_real();
1123 	hs = HTC_RxStuff(h2->htc, h2_frame_complete,
1124 	    NULL, NULL, NAN,
1125 	    h2->sess->t_idle + SESS_TMO(h2->sess, timeout_idle),
1126 	    NAN, h2->local_settings.max_frame_size + 9);
1127 	switch (hs) {
1128 	case HTC_S_COMPLETE:
1129 		break;
1130 	case HTC_S_TIMEOUT:
1131 		if (h2_sweep(wrk, h2))
1132 			return (1);
1133 
1134 		/* FALLTHROUGH */
1135 	default:
1136 		/* XXX: HTC_S_OVERFLOW / FRAME_SIZE_ERROR handling */
1137 		Lck_Lock(&h2->sess->mtx);
1138 		VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
1139 		h2->error = H2CE_NO_ERROR;
1140 		Lck_Unlock(&h2->sess->mtx);
1141 		return (0);
1142 	}
1143 
1144 	if (h2->do_sweep)
1145 		(void)h2_sweep(wrk, h2);
1146 
1147 	h2->rxf_len =  vbe32dec(h2->htc->rxbuf_b) >> 8;
1148 	h2->rxf_type =  h2->htc->rxbuf_b[3];
1149 	h2->rxf_flags = h2->htc->rxbuf_b[4];
1150 	h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5);
1151 	h2->rxf_stream &= ~(1LU<<31);			// rfc7540,l,690,692
1152 	h2->rxf_data = (void*)(h2->htc->rxbuf_b + 9);
1153 	/* XXX: later full DATA will not be rx'ed yet. */
1154 	HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
1155 
1156 	h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
1157 	h2->srq->acct.req_hdrbytes += 9;
1158 
1159 	if (h2->rxf_type >= H2FMAX) {
1160 		// rfc7540,l,679,681
1161 		// XXX: later, drain rest of frame
1162 		h2->bogosity++;
1163 		Lck_Lock(&h2->sess->mtx);
1164 		VSLb(h2->vsl, SLT_Debug,
1165 		    "H2: Unknown frame type 0x%02x (ignored)",
1166 		    (uint8_t)h2->rxf_type);
1167 		Lck_Unlock(&h2->sess->mtx);
1168 		h2->srq->acct.req_bodybytes += h2->rxf_len;
1169 		return (1);
1170 	}
1171 	h2f = h2flist[h2->rxf_type];
1172 
1173 	AN(h2f->name);
1174 	AN(h2f->rxfunc);
1175 	if (h2f->overhead)
1176 		h2->srq->acct.req_bodybytes += h2->rxf_len;
1177 
1178 	if (h2->rxf_flags & ~h2f->flags) {
1179 		// rfc7540,l,687,688
1180 		h2->bogosity++;
1181 		Lck_Lock(&h2->sess->mtx);
1182 		VSLb(h2->vsl, SLT_Debug,
1183 		    "H2: Unknown flags 0x%02x on %s (ignored)",
1184 		    (uint8_t)h2->rxf_flags & ~h2f->flags, h2f->name);
1185 		Lck_Unlock(&h2->sess->mtx);
1186 		h2->rxf_flags &= h2f->flags;
1187 	}
1188 
1189 	h2e = h2_procframe(wrk, h2, h2f);
1190 	if (h2->error == 0 && h2e) {
1191 		h2->error = h2e;
1192 		vbe32enc(b, h2->highest_stream);
1193 		vbe32enc(b + 4, h2e->val);
1194 		H2_Send_Get(wrk, h2, h2->req0);
1195 		H2_Send_Frame(wrk, h2, H2_F_GOAWAY, 0, 8, 0, b);
1196 		H2_Send_Rel(h2, h2->req0);
1197 	}
1198 	return (h2->error ? 0 : 1);
1199 }
1200