varnish-cache/bin/varnishd/http2/cache_http2_proto.c
0
/*-
1
 * Copyright (c) 2016-2019 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 */
30
31
#include "config.h"
32
33
#include "cache/cache_varnishd.h"
34
35
#include <stdio.h>
36
#include <stdlib.h>
37
38
#include "cache/cache_transport.h"
39
#include "cache/cache_filter.h"
40
#include "http2/cache_http2.h"
41
#include "cache/cache_objhead.h"
42
#include "storage/storage.h"
43
44
#include "vend.h"
45
#include "vtcp.h"
46
#include "vtim.h"
47
48
#define H2_CUSTOM_ERRORS
49
#define H2EC1(U,v,g,r,d)        \
50
        const struct h2_error_s H2CE_##U[1] = {{"H2CE_" #U,d,v,0,1,g,r}};
51
#define H2EC2(U,v,g,r,d)        \
52
        const struct h2_error_s H2SE_##U[1] = {{"H2SE_" #U,d,v,1,0,g,r}};
53
#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
54
#define H2_ERROR(NAME, val, sc, goaway, reason, desc)   \
55
        H2EC##sc(NAME, val, goaway, reason, desc)
56
#include "tbl/h2_error.h"
57
#undef H2EC1
58
#undef H2EC2
59
#undef H2EC3
60
61
static const struct h2_error_s H2NN_ERROR[1] = {{
62
        "UNKNOWN_ERROR",
63
        "Unknown error number",
64
        0xffffffff,
65
        1,
66
        1,
67
        0,
68
        SC_RX_JUNK
69
}};
70
71
enum h2frame {
72
#define H2_FRAME(l,u,t,f,...)   H2F_##u = t,
73
#include "tbl/h2_frames.h"
74
};
75
76
static const char *
77 18333
h2_framename(enum h2frame h2f)
78
{
79
80 18333
        switch (h2f) {
81
#define H2_FRAME(l,u,t,f,...)   case H2F_##u: return (#u);
82
#include "tbl/h2_frames.h"
83
        default:
84
                return (NULL);
85
        }
86 18333
}
87
88
#define H2_FRAME_FLAGS(l,u,v)   const uint8_t H2FF_##u = v;
89
#include "tbl/h2_frames.h"
90
91
/**********************************************************************
92
 */
93
94
static const h2_error stream_errors[] = {
95
#define H2EC1(U,v,g,r,d)
96
#define H2EC2(U,v,g,r,d) [v] = H2SE_##U,
97
#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
98
#define H2_ERROR(NAME, val, sc, goaway, reason, desc)   \
99
        H2EC##sc(NAME, val, goaway, reason, desc)
100
#include "tbl/h2_error.h"
101
#undef H2EC1
102
#undef H2EC2
103
#undef H2EC3
104
};
105
106
#define NSTREAMERRORS vcountof(stream_errors)
107
108
static h2_error
109 315
h2_streamerror(uint32_t u)
110
{
111 315
        if (u < NSTREAMERRORS && stream_errors[u] != NULL)
112 273
                return (stream_errors[u]);
113
        else
114 42
                return (H2NN_ERROR);
115 315
}
116
117
/**********************************************************************
118
 */
119
120
static const h2_error conn_errors[] = {
121
#define H2EC1(U,v,g,r,d) [v] = H2CE_##U,
122
#define H2EC2(U,v,g,r,d)
123
#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
124
#define H2_ERROR(NAME, val, sc, goaway, reason, desc)   \
125
        H2EC##sc(NAME, val, goaway, reason, desc)
126
#include "tbl/h2_error.h"
127
#undef H2EC1
128
#undef H2EC2
129
#undef H2EC3
130
};
131
132
#define NCONNERRORS vcountof(conn_errors)
133
134
static h2_error
135 63
h2_connectionerror(uint32_t u)
136
{
137 63
        if (u < NCONNERRORS && conn_errors[u] != NULL)
138 42
                return (conn_errors[u]);
139
        else
140 21
                return (H2NN_ERROR);
141 63
}
142
143
/**********************************************************************/
144
145
struct h2_req *
146 7245
h2_new_req(struct h2_sess *h2, unsigned stream, struct req *req)
147
{
148
        struct h2_req *r2;
149
150 7245
        ASSERT_RXTHR(h2);
151 7245
        if (req == NULL)
152 7140
                req = Req_New(h2->sess, NULL);
153 7245
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
154
155 7245
        r2 = WS_Alloc(req->ws, sizeof *r2);
156 7245
        AN(r2);
157 7245
        INIT_OBJ(r2, H2_REQ_MAGIC);
158 7245
        r2->state = H2_S_IDLE;
159 7245
        r2->h2sess = h2;
160 7245
        r2->stream = stream;
161 7245
        r2->req = req;
162 7245
        if (stream)
163 4011
                r2->counted = 1;
164 7245
        r2->r_window = h2->local_settings.initial_window_size;
165 7245
        r2->t_window = h2->remote_settings.initial_window_size;
166 7245
        req->transport_priv = r2;
167 7245
        Lck_Lock(&h2->sess->mtx);
168 7245
        if (stream)
169 4011
                h2->open_streams++;
170 7245
        VTAILQ_INSERT_TAIL(&h2->streams, r2, list);
171 7245
        Lck_Unlock(&h2->sess->mtx);
172 7245
        h2->refcnt++;
173 7245
        return (r2);
174
}
175
176
void
177 7199
h2_del_req(struct worker *wrk, struct h2_req *r2)
178
{
179
        struct h2_sess *h2;
180
        struct sess *sp;
181
        struct stv_buffer *stvbuf;
182
183 7199
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
184 7199
        AZ(r2->scheduled);
185 7199
        h2 = r2->h2sess;
186 7199
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
187 7199
        ASSERT_RXTHR(h2);
188 7199
        sp = h2->sess;
189 7199
        Lck_Lock(&sp->mtx);
190 7199
        assert(h2->refcnt > 0);
191 7199
        --h2->refcnt;
192
        /* XXX: PRIORITY reshuffle */
193 7199
        VTAILQ_REMOVE(&h2->streams, r2, list);
194 7199
        if (r2->req == h2->new_req)
195 819
                h2->new_req = NULL;
196 7199
        Lck_Unlock(&sp->mtx);
197
198 7199
        assert(!WS_IsReserved(r2->req->ws));
199 7199
        AZ(r2->req->ws->r);
200
201 7199
        CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
202 7199
        if (r2->rxbuf) {
203 84
                stvbuf = r2->rxbuf->stvbuf;
204 84
                r2->rxbuf = NULL;
205 84
                STV_FreeBuf(wrk, &stvbuf);
206 84
                AZ(stvbuf);
207 84
        }
208
209 7199
        Req_Cleanup(sp, wrk, r2->req);
210 7199
        if (FEATURE(FEATURE_BUSY_STATS_RATE))
211 0
                WRK_AddStat(wrk);
212 7199
        Req_Release(r2->req);
213 7199
}
214
215
void
216 3673
h2_kill_req(struct worker *wrk, struct h2_sess *h2,
217
    struct h2_req *r2, h2_error h2e)
218
{
219
220 3673
        ASSERT_RXTHR(h2);
221 3673
        AN(h2e);
222 3673
        Lck_Lock(&h2->sess->mtx);
223 7346
        VSLb(h2->vsl, SLT_Debug, "KILL st=%u state=%d sched=%d",
224 3673
            r2->stream, r2->state, r2->scheduled);
225 3673
        if (r2->counted) {
226 1063
                assert(h2->open_streams > 0);
227 1063
                h2->open_streams--;
228 1063
                r2->counted = 0;
229 1063
        }
230 3673
        if (r2->error == NULL)
231 315
                r2->error = h2e;
232 3673
        if (r2->scheduled) {
233 1309
                if (r2->cond != NULL)
234 128
                        PTOK(pthread_cond_signal(r2->cond));
235 1309
                r2 = NULL;
236 1309
                Lck_Unlock(&h2->sess->mtx);
237 1309
        } else {
238 2364
                Lck_Unlock(&h2->sess->mtx);
239 2364
                if (r2->state == H2_S_OPEN && h2->new_req == r2->req)
240 105
                        (void)h2h_decode_hdr_fini(h2);
241
        }
242 3673
        if (r2 != NULL)
243 2364
                h2_del_req(wrk, r2);
244 3673
}
245
246
/**********************************************************************/
247
248
static void
249 18648
h2_vsl_frame(const struct h2_sess *h2, const void *ptr, size_t len)
250
{
251
        const uint8_t *b;
252
        struct vsb *vsb;
253
        const char *p;
254
        unsigned u;
255
256 18648
        if (VSL_tag_is_masked(SLT_H2RxHdr) &&
257 315
            VSL_tag_is_masked(SLT_H2RxBody))
258 315
                return;
259
260 18333
        AN(ptr);
261 18333
        assert(len >= 9);
262 18333
        b = ptr;
263
264 18333
        vsb = VSB_new_auto();
265 18333
        AN(vsb);
266 18333
        p = h2_framename((enum h2frame)b[3]);
267 18333
        if (p != NULL)
268 18312
                VSB_cat(vsb, p);
269
        else
270 21
                VSB_quote(vsb, b + 3, 1, VSB_QUOTE_HEX);
271
272 18333
        u = vbe32dec(b) >> 8;
273 18333
        VSB_printf(vsb, "[%u] ", u);
274 18333
        VSB_quote(vsb, b + 4, 1, VSB_QUOTE_HEX);
275 18333
        VSB_putc(vsb, ' ');
276 18333
        VSB_quote(vsb, b + 5, 4, VSB_QUOTE_HEX);
277 18333
        if (u > 0) {
278 12285
                VSB_putc(vsb, ' ');
279 12285
                VSB_quote(vsb, b + 9, len - 9, VSB_QUOTE_HEX);
280 12285
        }
281 18333
        AZ(VSB_finish(vsb));
282 18333
        Lck_Lock(&h2->sess->mtx);
283 18333
        VSLb_bin(h2->vsl, SLT_H2RxHdr, 9, b);
284 18333
        if (len > 9)
285 12285
                VSLb_bin(h2->vsl, SLT_H2RxBody, len - 9, b + 9);
286
287 18333
        VSLb(h2->vsl, SLT_Debug, "H2RXF %s", VSB_data(vsb));
288 18333
        Lck_Unlock(&h2->sess->mtx);
289 18333
        VSB_destroy(&vsb);
290 18648
}
291
292
293
/**********************************************************************
294
 */
295
296
static h2_error v_matchproto_(h2_rxframe_f)
297 126
h2_rx_ping(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
298
{
299
300 126
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
301 126
        ASSERT_RXTHR(h2);
302 126
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
303 126
        assert(r2 == h2->req0);
304
305 126
        if (h2->rxf_len != 8) {                         // rfc7540,l,2364,2366
306 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx ping with (len != 8)");
307 21
                return (H2CE_FRAME_SIZE_ERROR);
308
        }
309 105
        AZ(h2->rxf_stream);                             // rfc7540,l,2359,2362
310 105
        if (h2->rxf_flags != 0) {                       // We never send pings
311 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx ping ack");
312 21
                return (H2SE_PROTOCOL_ERROR);
313
        }
314 84
        H2_Send_Get(wrk, h2, r2);
315 168
        H2_Send_Frame(wrk, h2,
316 84
            H2_F_PING, H2FF_PING_ACK, 8, 0, h2->rxf_data);
317 84
        H2_Send_Rel(h2, r2);
318 84
        return (0);
319 126
}
320
321
/**********************************************************************
322
 */
323
324
static h2_error v_matchproto_(h2_rxframe_f)
325 42
h2_rx_push_promise(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
326
{
327
328 42
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
329 42
        ASSERT_RXTHR(h2);
330 42
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
331
332
        // rfc7540,l,2262,2267
333 42
        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx push promise");
334 42
        return (H2CE_PROTOCOL_ERROR);
335
}
336
337
/**********************************************************************
338
 */
339
340
int
341 1579
h2_rapid_reset_check(struct worker *wrk, struct h2_sess *h2,
342
    const struct h2_req *r2)
343
{
344
        vtim_real now;
345
346 1579
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
347 1579
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
348 1579
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
349
350 1579
        if (h2->rapid_reset_limit == 0)
351 0
                return (0);
352
353 1579
        now = VTIM_real();
354 1579
        CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
355 1579
        AN(r2->req->t_first);
356 1579
        if (now - r2->req->t_first > h2->rapid_reset)
357 130
                return (0);
358
359 1449
        return (1);
360 1579
}
361
362
h2_error
363 1449
h2_rapid_reset_charge(struct worker *wrk, struct h2_sess *h2,
364
    const struct h2_req *r2)
365
{
366
        vtim_real now;
367
        vtim_dur d;
368 1449
        h2_error h2e = NULL;
369
370 1449
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
371 1449
        AN(H2_SEND_HELD(h2, r2));
372 1449
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
373
374 1449
        now = VTIM_real();
375
376 1449
        d = now - h2->last_rst;
377 2898
        h2->rst_budget += h2->rapid_reset_limit * d /
378 1449
            h2->rapid_reset_period;
379 1449
        h2->rst_budget = vmin_t(double, h2->rst_budget,
380
            h2->rapid_reset_limit);
381 1449
        h2->last_rst = now;
382
383 1449
        h2->rst_budget -= 1.0;
384
385 1449
        if (h2->rst_budget < 0) {
386 63
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: Hit RST limit. Closing session.");
387 63
                h2e = H2CE_RAPID_RESET;
388 63
                H2_Send_GOAWAY(wrk, h2, r2, h2e);
389 63
        }
390
391 1449
        return (h2e);
392
}
393
394
static h2_error v_matchproto_(h2_rxframe_f)
395 399
h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
396
{
397 399
        h2_error h2e = NULL;
398
399 399
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
400 399
        ASSERT_RXTHR(h2);
401 399
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
402
403 399
        if (h2->rxf_len != 4) {                 // rfc7540,l,2003,2004
404 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx rst with (len != 4)");
405 21
                return (H2CE_FRAME_SIZE_ERROR);
406
        }
407 378
        if (r2 == NULL)
408 63
                return (0);
409 315
        if (h2_rapid_reset_check(wrk, h2, r2)) {
410 315
                H2_Send_Get(wrk, h2, h2->req0);
411 315
                h2e = h2_rapid_reset_charge(wrk, h2, h2->req0);
412 315
                H2_Send_Rel(h2, h2->req0);
413 315
        }
414 315
        h2_kill_req(wrk, h2, r2, h2_streamerror(vbe32dec(h2->rxf_data)));
415 315
        return (h2e);
416 399
}
417
418
/**********************************************************************
419
 */
420
421
static h2_error v_matchproto_(h2_rxframe_f)
422 63
h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
423
{
424
425 63
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
426 63
        ASSERT_RXTHR(h2);
427 63
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
428 63
        assert(r2 == h2->req0);
429
430 63
        h2->goaway = 1;
431 63
        h2->goaway_last_stream = vbe32dec(h2->rxf_data);
432 63
        h2->error = h2_connectionerror(vbe32dec(h2->rxf_data + 4));
433 63
        H2S_Lock_VSLb(h2, SLT_Debug, "GOAWAY %s", h2->error->name);
434 63
        return (h2->error);
435
}
436
437
static void
438 3045
h2_tx_goaway(struct worker *wrk, struct h2_sess *h2, h2_error h2e)
439
{
440 3045
        ASSERT_RXTHR(h2);
441 3045
        AN(h2e);
442
443 3045
        if (h2->goaway || !h2e->send_goaway)
444 42
                return;
445
446 3003
        H2_Send_Get(wrk, h2, h2->req0);
447 3003
        H2_Send_GOAWAY(wrk, h2, h2->req0, h2e);
448 3003
        H2_Send_Rel(h2, h2->req0);
449 3045
}
450
451
/**********************************************************************
452
 */
453
454
static h2_error v_matchproto_(h2_rxframe_f)
455 546
h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
456
{
457
        uint32_t wu;
458
459 546
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
460 546
        ASSERT_RXTHR(h2);
461 546
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
462
463 546
        if (h2->rxf_len != 4) {
464 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx winup with (len != 4)");
465 21
                return (H2CE_FRAME_SIZE_ERROR);
466
        }
467 525
        wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
468 525
        if (wu == 0)
469 105
                return (H2SE_PROTOCOL_ERROR);
470 420
        if (r2 == NULL)
471 21
                return (0);
472 399
        Lck_Lock(&h2->sess->mtx);
473 399
        r2->t_window += wu;
474 399
        if (r2 == h2->req0)
475 168
                PTOK(pthread_cond_broadcast(h2->winupd_cond));
476 231
        else if (r2->cond != NULL)
477 168
                PTOK(pthread_cond_signal(r2->cond));
478 399
        Lck_Unlock(&h2->sess->mtx);
479 399
        if (r2->t_window >= (1LL << 31))
480 42
                return (H2SE_FLOW_CONTROL_ERROR);
481 357
        return (0);
482 546
}
483
484
/**********************************************************************
485
 * Incoming PRIORITY, possibly an ACK of one we sent.
486
 *
487
 * deprecated, rfc9113,l,1103,1104
488
 */
489
490
static h2_error v_matchproto_(h2_rxframe_f)
491 189
h2_rx_priority(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
492
{
493
494 189
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
495 189
        ASSERT_RXTHR(h2);
496 189
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
497 189
        return (0);
498
}
499
500
/**********************************************************************
501
 * Incoming SETTINGS, possibly an ACK of one we sent.
502
 */
503
504
#define H2_SETTING(U,l, ...)                                    \
505
static void v_matchproto_(h2_setsetting_f)                      \
506
h2_setting_##l(struct h2_settings* s, uint32_t v)               \
507
{                                                               \
508
        s -> l = v;                                             \
509
}
510
#include <tbl/h2_settings.h>
511
512
#define H2_SETTING(U, l, ...)                                   \
513
const struct h2_setting_s H2_SET_##U[1] = {{                    \
514
        #l,                                                     \
515
        h2_setting_##l,                                         \
516
        __VA_ARGS__                                             \
517
}};
518
#include <tbl/h2_settings.h>
519
520
static const struct h2_setting_s * const h2_setting_tbl[] = {
521
#define H2_SETTING(U,l,v, ...) [v] = H2_SET_##U,
522
#include <tbl/h2_settings.h>
523
};
524
525
#define H2_SETTING_TBL_LEN vcountof(h2_setting_tbl)
526
527
static void
528 189
h2_win_adjust(const struct h2_sess *h2, uint32_t oldval, uint32_t newval)
529
{
530
        struct h2_req *r2;
531
532 189
        Lck_AssertHeld(&h2->sess->mtx);
533
        // rfc7540,l,2668,2674
534 378
        VTAILQ_FOREACH(r2, &h2->streams, list) {
535 189
                CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
536 189
                if (r2 == h2->req0)
537 189
                        continue; // rfc7540,l,2699,2699
538 0
                switch (r2->state) {
539
                case H2_S_IDLE:
540
                case H2_S_OPEN:
541
                case H2_S_CLOS_REM:
542
                        /*
543
                         * We allow a window to go negative, as per
544
                         * rfc7540,l,2676,2680
545
                         */
546 0
                        r2->t_window += (int64_t)newval - oldval;
547 0
                        break;
548
                default:
549 0
                        break;
550
                }
551 0
        }
552 189
}
553
554
h2_error
555 378
h2_set_setting(struct h2_sess *h2, const uint8_t *d)
556
{
557
        const struct h2_setting_s *s;
558
        uint16_t x;
559
        uint32_t y;
560
561 378
        x = vbe16dec(d);
562 378
        y = vbe32dec(d + 2);
563 378
        if (x >= H2_SETTING_TBL_LEN || h2_setting_tbl[x] == NULL) {
564
                // rfc7540,l,2181,2182
565 42
                H2S_Lock_VSLb(h2, SLT_Debug,
566 21
                    "H2SETTING unknown setting 0x%04x=%08x (ignored)", x, y);
567 21
                return (0);
568
        }
569 357
        s = h2_setting_tbl[x];
570 357
        AN(s);
571 357
        if (y < s->minval || y > s->maxval) {
572 126
                H2S_Lock_VSLb(h2, SLT_Debug, "H2SETTING invalid %s=0x%08x",
573 63
                    s->name, y);
574 63
                AN(s->range_error);
575 63
                if (!DO_DEBUG(DBG_H2_NOCHECK))
576 21
                        return (s->range_error);
577 42
        }
578 336
        Lck_Lock(&h2->sess->mtx);
579 336
        if (s == H2_SET_INITIAL_WINDOW_SIZE)
580 189
                h2_win_adjust(h2, h2->remote_settings.initial_window_size, y);
581 336
        VSLb(h2->vsl, SLT_Debug, "H2SETTING %s=0x%08x", s->name, y);
582 336
        Lck_Unlock(&h2->sess->mtx);
583 336
        AN(s->setfunc);
584 336
        s->setfunc(&h2->remote_settings, y);
585 336
        return (0);
586 378
}
587
588
static h2_error v_matchproto_(h2_rxframe_f)
589 6174
h2_rx_settings(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
590
{
591
        const uint8_t *p;
592
        unsigned l;
593 6174
        h2_error retval = 0;
594
595 6174
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
596 6174
        ASSERT_RXTHR(h2);
597 6174
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
598 6174
        assert(r2 == h2->req0);
599 6174
        AZ(h2->rxf_stream);
600
601 6174
        if (h2->rxf_flags == H2FF_SETTINGS_ACK) {
602 3045
                if (h2->rxf_len > 0) {                  // rfc7540,l,2047,2049
603 21
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx settings ack with "
604
                            "(len > 0)");
605 21
                        return (H2CE_FRAME_SIZE_ERROR);
606
                }
607 3024
                return (0);
608
        } else {
609 3129
                if (h2->rxf_len % 6) {                  // rfc7540,l,2062,2064
610 21
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx settings with "
611
                            "((len %% 6) != 0)");
612 21
                        return (H2CE_PROTOCOL_ERROR);
613
                }
614 3108
                p = h2->rxf_data;
615 3255
                for (l = h2->rxf_len; l >= 6; l -= 6, p += 6) {
616 168
                        retval = h2_set_setting(h2, p);
617 168
                        if (retval)
618 21
                                return (retval);
619 147
                }
620 3087
                H2_Send_Get(wrk, h2, r2);
621 3087
                H2_Send_Frame(wrk, h2,
622
                    H2_F_SETTINGS, H2FF_SETTINGS_ACK, 0, 0, NULL);
623 3087
                H2_Send_Rel(h2, r2);
624
        }
625 3087
        return (0);
626 6174
}
627
628
/**********************************************************************
629
 * Incoming HEADERS, this is where the party's at...
630
 */
631
632
void v_matchproto_(task_func_t)
633 3148
h2_do_req(struct worker *wrk, void *priv)
634
{
635
        struct req *req;
636
        struct h2_req *r2;
637
        struct h2_sess *h2;
638
639 3148
        CAST_OBJ_NOTNULL(req, priv, REQ_MAGIC);
640 3148
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
641 3148
        THR_SetRequest(req);
642 3148
        CNT_Embark(wrk, req);
643
644 3148
        if (CNT_Request(req) != REQ_FSM_DISEMBARK) {
645 2876
                wrk->stats->client_req++;
646 2876
                assert(!WS_IsReserved(req->ws));
647 2876
                AZ(req->top->vcl0);
648 2876
                h2 = r2->h2sess;
649 2876
                CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
650 2876
                Lck_Lock(&h2->sess->mtx);
651 2876
                r2->scheduled = 0;
652 2876
                r2->state = H2_S_CLOSED;
653 2876
                r2->h2sess->do_sweep = 1;
654 2876
                Lck_Unlock(&h2->sess->mtx);
655 2876
        }
656 3148
        THR_SetRequest(NULL);
657 3148
}
658
659
static h2_error
660 3087
h2_end_headers(struct worker *wrk, struct h2_sess *h2,
661
    struct req *req, struct h2_req *r2)
662
{
663
        h2_error h2e;
664
        ssize_t cl;
665
666 3087
        ASSERT_RXTHR(h2);
667 3087
        assert(r2->state == H2_S_OPEN);
668 3087
        h2e = h2h_decode_hdr_fini(h2);
669 3087
        h2->new_req = NULL;
670 3087
        if (h2e != NULL) {
671 105
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK/FINI %s", h2e->name);
672 105
                assert(!WS_IsReserved(r2->req->ws));
673 105
                h2_del_req(wrk, r2);
674 105
                return (h2e);
675
        }
676 2982
        req->t_req = VTIM_real();
677 2982
        VSLb_ts_req(req, "Req", req->t_req);
678
679
        // XXX: Smarter to do this already at HPACK time into tail end of
680
        // XXX: WS, then copy back once all headers received.
681
        // XXX: Have I mentioned H/2 Is hodge-podge ?
682 2982
        http_CollectHdrSep(req->http, H_Cookie, "; ");  // rfc7540,l,3114,3120
683
684 2982
        cl = http_GetContentLength(req->http);
685 2982
        assert(cl >= -2);
686 2982
        if (cl == -2) {
687 0
                H2S_Lock_VSLb(h2, SLT_Debug, "Non-parseable Content-Length");
688 0
                return (H2SE_PROTOCOL_ERROR);
689
        }
690
691 2982
        if (req->req_body_status == NULL) {
692 756
                if (cl == -1)
693 399
                        req->req_body_status = BS_EOF;
694
                else {
695
                        /* Note: If cl==0 here, we still need to have
696
                         * req_body_status==BS_LENGTH, so that there will
697
                         * be a wait for the stream to reach H2_S_CLOS_REM
698
                         * while dealing with the request body. */
699 357
                        req->req_body_status = BS_LENGTH;
700
                }
701
                /* Set req->htc->content_length because this is used as
702
                 * the hint in vrb_pull() for how large the storage
703
                 * buffers need to be */
704 756
                req->htc->content_length = cl;
705 756
        } else {
706
                /* A HEADER frame contained END_STREAM */
707 2226
                assert (req->req_body_status == BS_NONE);
708 2226
                r2->state = H2_S_CLOS_REM;
709 2226
                if (cl > 0) {
710 21
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx header with END_STREAM "
711
                            "and content-length > 0");
712 21
                        return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840
713
                }
714
        }
715
716 2961
        if (req->http->hd[HTTP_HDR_METHOD].b == NULL) {
717 21
                H2S_Lock_VSLb(h2, SLT_Debug, "Missing :method");
718 21
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
719
        }
720
721 2940
        if (req->http->hd[HTTP_HDR_URL].b == NULL) {
722 21
                H2S_Lock_VSLb(h2, SLT_Debug, "Missing :path");
723 21
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
724
        }
725
726 2919
        AN(req->http->hd[HTTP_HDR_PROTO].b);
727
728 2961
        if (*req->http->hd[HTTP_HDR_URL].b == '*' &&
729 84
            (Tlen(req->http->hd[HTTP_HDR_METHOD]) != 7 ||
730 42
            strncmp(req->http->hd[HTTP_HDR_METHOD].b, "OPTIONS", 7))) {
731 63
                H2S_Lock_VSLb(h2, SLT_BogoHeader, "Illegal :path pseudo-header");
732 63
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3068,3071
733
        }
734
735 2856
        assert(req->req_step == R_STP_TRANSPORT);
736 2856
        VCL_TaskEnter(req->privs);
737 2856
        VCL_TaskEnter(req->top->privs);
738 2856
        req->task->func = h2_do_req;
739 2856
        req->task->priv = req;
740 2856
        r2->scheduled = 1;
741 2856
        if (Pool_Task(wrk->pool, req->task, TASK_QUEUE_STR) != 0) {
742 21
                r2->scheduled = 0;
743 21
                r2->state = H2_S_CLOSED;
744 21
                return (H2SE_REFUSED_STREAM); //rfc7540,l,3326,3329
745
        }
746 2835
        return (0);
747 3087
}
748
749
static h2_error v_matchproto_(h2_rxframe_f)
750 3969
h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
751
{
752
        struct req *req;
753
        h2_error h2e;
754
        const uint8_t *p;
755
        size_t l;
756
757 3969
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
758 3969
        ASSERT_RXTHR(h2);
759
760 3969
        if (r2 != NULL) {
761 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers on non-idle stream");
762 21
                return (H2CE_PROTOCOL_ERROR);   // rfc9113,l,887,891
763
        }
764
765 3948
        if (h2->rxf_stream <= h2->highest_stream) {
766 21
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: new stream ID < highest stream");
767 21
                return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1153,1158
768
        }
769
        /* NB: we don't need to guard the read of h2->open_streams
770
         * because headers are handled sequentially so it cannot
771
         * increase under our feet.
772
         */
773 7854
        if (h2->open_streams >=
774 3927
            (int)h2->local_settings.max_concurrent_streams) {
775 42
                H2S_Lock_VSLb(h2, SLT_Debug,
776
                    "H2: stream %u: Hit maximum number of "
777 21
                    "concurrent streams", h2->rxf_stream);
778 21
                return (H2SE_REFUSED_STREAM);   // rfc7540,l,1200,1205
779
        }
780 3906
        h2->highest_stream = h2->rxf_stream;
781 3906
        r2 = h2_new_req(h2, h2->rxf_stream, NULL);
782 3906
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
783 3906
        assert(r2->state == H2_S_IDLE);
784 3906
        r2->state = H2_S_OPEN;
785
786 3906
        req = r2->req;
787 3906
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
788
789 3906
        req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);
790 3906
        VSLb(req->vsl, SLT_Begin, "req %ju rxreq", VXID(req->sp->vxid));
791 3906
        VSL(SLT_Link, req->sp->vxid, "req %ju rxreq", VXID(req->vsl->wid));
792
793 3906
        h2->new_req = req;
794 3906
        req->sp = h2->sess;
795 3906
        req->transport = &HTTP2_transport;
796
797 3906
        req->t_first = h2->t1;
798 3906
        req->t_prev = req->t_first;
799 3906
        VSLb_ts_req(req, "Start", req->t_first);
800 3906
        req->acct.req_hdrbytes += h2->rxf_len;
801
802 3906
        HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
803 3906
        http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0");
804
805 3906
        h2h_decode_hdr_init(h2);
806
807 3906
        p = h2->rxf_data;
808 3906
        l = h2->rxf_len;
809 3906
        if (h2->rxf_flags & H2FF_HEADERS_PADDED) {
810 147
                if (*p + 1 > l) {
811 42
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers with pad length > frame len");
812 42
                        return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1884,1887
813
                }
814 105
                l -= 1 + *p;
815 105
                p += 1;
816 105
        }
817 3864
        if (h2->rxf_flags & H2FF_HEADERS_PRIORITY) {
818 63
                if (l < 5) {
819 21
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers with incorrect "
820
                            "priority data");
821 21
                        return (H2CE_PROTOCOL_ERROR);
822
                }
823 42
                l -= 5;
824 42
                p += 5;
825 42
        }
826 3843
        h2e = h2h_decode_bytes(h2, p, l);
827 3843
        if (h2e != NULL) {
828 672
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK(hdr) %s", h2e->name);
829 672
                (void)h2h_decode_hdr_fini(h2);
830 672
                assert(!WS_IsReserved(r2->req->ws));
831 672
                h2_del_req(wrk, r2);
832 672
                return (h2e);
833
        }
834
835 3171
        if (h2->rxf_flags & H2FF_HEADERS_END_STREAM)
836 2415
                req->req_body_status = BS_NONE;
837
838 3171
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
839 3024
                return (h2_end_headers(wrk, h2, req, r2));
840 147
        return (0);
841 3969
}
842
843
/**********************************************************************/
844
845
static h2_error v_matchproto_(h2_rxframe_f)
846 399
h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
847
{
848
        struct req *req;
849
        h2_error h2e;
850
851 399
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
852 399
        ASSERT_RXTHR(h2);
853 399
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
854
855 399
        if (r2 == NULL || r2->state != H2_S_OPEN || r2->req != h2->new_req) {
856 84
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx unexpected CONT frame"
857 42
                    " on stream %d", h2->rxf_stream);
858 42
                return (H2CE_PROTOCOL_ERROR);   // XXX spec ?
859
        }
860 357
        req = r2->req;
861 357
        h2e = h2h_decode_bytes(h2, h2->rxf_data, h2->rxf_len);
862 357
        r2->req->acct.req_hdrbytes += h2->rxf_len;
863 357
        if (h2e != NULL) {
864 42
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK(cont) %s", h2e->name);
865 42
                (void)h2h_decode_hdr_fini(h2);
866 42
                assert(!WS_IsReserved(r2->req->ws));
867 42
                h2_del_req(wrk, r2);
868 42
                return (h2e);
869
        }
870 315
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
871 63
                return (h2_end_headers(wrk, h2, req, r2));
872 252
        return (0);
873 399
}
874
875
/**********************************************************************/
876
877
static h2_error v_matchproto_(h2_rxframe_f)
878 6594
h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
879
{
880
        char buf[4];
881
        ssize_t l;
882
        uint64_t l2, head;
883
        const uint8_t *src;
884
        unsigned len;
885
886
        /* XXX: Shouldn't error handling, setting of r2->error and
887
         * r2->cond signalling be handled more generally at the end of
888
         * procframe()??? */
889
890 6594
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
891 6594
        ASSERT_RXTHR(h2);
892 6594
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
893
894 6594
        if (r2 == NULL)
895 21
                return (0);
896
897 6573
        if (r2->state >= H2_S_CLOS_REM) {
898 42
                r2->error = H2SE_STREAM_CLOSED;
899 42
                return (H2SE_STREAM_CLOSED); // rfc7540,l,1766,1769
900
        }
901
902 6531
        Lck_Lock(&h2->sess->mtx);
903 6531
        CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
904
905 6531
        if (h2->error != NULL || r2->error != NULL) {
906 21
                if (r2->cond)
907 0
                        PTOK(pthread_cond_signal(r2->cond));
908 21
                Lck_Unlock(&h2->sess->mtx);
909 21
                return (h2->error != NULL ? h2->error : r2->error);
910
        }
911
912
        /* Check padding if present */
913 6510
        src = h2->rxf_data;
914 6510
        len = h2->rxf_len;
915 6510
        if (h2->rxf_flags & H2FF_DATA_PADDED) {
916 5586
                if (*src >= len) {
917 0
                        VSLb(h2->vsl, SLT_SessError,
918
                            "H2: stream %u: Padding larger than frame length",
919 0
                            h2->rxf_stream);
920 0
                        r2->error = H2CE_PROTOCOL_ERROR;
921 0
                        if (r2->cond)
922 0
                                PTOK(pthread_cond_signal(r2->cond));
923 0
                        Lck_Unlock(&h2->sess->mtx);
924 0
                        return (H2CE_PROTOCOL_ERROR);
925
                }
926 5586
                len -= 1 + *src;
927 5586
                src += 1;
928 5586
        }
929
930
        /* Check against the Content-Length header if given */
931 6510
        if (r2->req->htc->content_length >= 0) {
932 6321
                if (r2->rxbuf)
933 588
                        l = r2->rxbuf->head;
934
                else
935 5733
                        l = 0;
936 6321
                l += len;
937 6615
                if (l > r2->req->htc->content_length ||
938 6258
                    ((h2->rxf_flags & H2FF_DATA_END_STREAM) &&
939 294
                     l != r2->req->htc->content_length)) {
940 126
                        VSLb(h2->vsl, SLT_Debug,
941
                            "H2: stream %u: Received data and Content-Length"
942 63
                            " mismatch", h2->rxf_stream);
943 63
                        r2->error = H2SE_PROTOCOL_ERROR;
944 63
                        if (r2->cond)
945 21
                                PTOK(pthread_cond_signal(r2->cond));
946 63
                        Lck_Unlock(&h2->sess->mtx);
947 63
                        return (H2SE_PROTOCOL_ERROR);
948
                }
949 6258
        }
950
951
        /* Check and charge connection window. The entire frame including
952
         * padding (h2->rxf_len) counts towards the window. */
953 6447
        if (h2->rxf_len > h2->req0->r_window) {
954 0
                VSLb(h2->vsl, SLT_SessError,
955
                    "H2: stream %u: Exceeded connection receive window",
956 0
                    h2->rxf_stream);
957 0
                r2->error = H2CE_FLOW_CONTROL_ERROR;
958 0
                if (r2->cond)
959 0
                        PTOK(pthread_cond_signal(r2->cond));
960 0
                Lck_Unlock(&h2->sess->mtx);
961 0
                return (H2CE_FLOW_CONTROL_ERROR);
962
        }
963 6447
        h2->req0->r_window -= h2->rxf_len;
964 6447
        if (h2->req0->r_window < cache_param->h2_rx_window_low_water) {
965 903
                h2->req0->r_window += cache_param->h2_rx_window_increment;
966 903
                vbe32enc(buf, cache_param->h2_rx_window_increment);
967 903
                Lck_Unlock(&h2->sess->mtx);
968 903
                H2_Send_Get(wrk, h2, h2->req0);
969 903
                H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0, 4, 0, buf);
970 903
                H2_Send_Rel(h2, h2->req0);
971 903
                Lck_Lock(&h2->sess->mtx);
972 903
        }
973
974
        /* Check stream window. The entire frame including padding
975
         * (h2->rxf_len) counts towards the window. */
976 6447
        if (h2->rxf_len > r2->r_window) {
977 0
                VSLb(h2->vsl, SLT_Debug,
978
                    "H2: stream %u: Exceeded stream receive window",
979 0
                    h2->rxf_stream);
980 0
                r2->error = H2SE_FLOW_CONTROL_ERROR;
981 0
                if (r2->cond)
982 0
                        PTOK(pthread_cond_signal(r2->cond));
983 0
                Lck_Unlock(&h2->sess->mtx);
984 0
                return (H2SE_FLOW_CONTROL_ERROR);
985
        }
986
987
        /* Handle zero size frame before starting to allocate buffers */
988 6447
        if (len == 0) {
989 5439
                r2->r_window -= h2->rxf_len;
990
991
                /* Handle the specific corner case where the entire window
992
                 * has been exhausted using nothing but padding
993
                 * bytes. Since no bytes have been buffered, no bytes
994
                 * would be consumed by the request thread and no stream
995
                 * window updates sent. Unpaint ourselves from this corner
996
                 * by sending a stream window update here. */
997 5439
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
998 5439
                if (r2->r_window == 0 &&
999 21
                    (r2->rxbuf == NULL || r2->rxbuf->tail == r2->rxbuf->head)) {
1000 21
                        if (r2->rxbuf)
1001 0
                                l = r2->rxbuf->size;
1002
                        else
1003 21
                                l = h2->local_settings.initial_window_size;
1004 21
                        r2->r_window += l;
1005 21
                        Lck_Unlock(&h2->sess->mtx);
1006 21
                        vbe32enc(buf, l);
1007 21
                        H2_Send_Get(wrk, h2, h2->req0);
1008 42
                        H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0, 4,
1009 21
                            r2->stream, buf);
1010 21
                        H2_Send_Rel(h2, h2->req0);
1011 21
                        Lck_Lock(&h2->sess->mtx);
1012 21
                }
1013
1014 5439
                if (h2->rxf_flags & H2FF_DATA_END_STREAM)
1015 63
                        r2->state = H2_S_CLOS_REM;
1016 5439
                if (r2->cond)
1017 5276
                        PTOK(pthread_cond_signal(r2->cond));
1018 5439
                Lck_Unlock(&h2->sess->mtx);
1019 5439
                return (0);
1020
        }
1021
1022
        /* Make the buffer on demand */
1023 1008
        if (r2->rxbuf == NULL) {
1024
                unsigned bufsize;
1025
                size_t bstest;
1026
                struct stv_buffer *stvbuf;
1027
                struct h2_rxbuf *rxbuf;
1028
1029 462
                Lck_Unlock(&h2->sess->mtx);
1030
1031 462
                bufsize = h2->local_settings.initial_window_size;
1032 462
                if (bufsize < r2->r_window) {
1033
                        /* This will not happen because we do not have any
1034
                         * mechanism to change the initial window size on
1035
                         * a running session. But if we gain that ability,
1036
                         * this future proofs it. */
1037 0
                        bufsize = r2->r_window;
1038 0
                }
1039 462
                assert(bufsize > 0);
1040 462
                if ((h2->rxf_flags & H2FF_DATA_END_STREAM) &&
1041 273
                    bufsize > len)
1042
                        /* Cap the buffer size when we know this is the
1043
                         * single data frame. */
1044 273
                        bufsize = len;
1045 462
                CHECK_OBJ_NOTNULL(stv_h2_rxbuf, STEVEDORE_MAGIC);
1046 924
                stvbuf = STV_AllocBuf(wrk, stv_h2_rxbuf,
1047 462
                    bufsize + sizeof *rxbuf);
1048 462
                if (stvbuf == NULL) {
1049 0
                        Lck_Lock(&h2->sess->mtx);
1050 0
                        VSLb(h2->vsl, SLT_Debug,
1051
                            "H2: stream %u: Failed to allocate request body"
1052
                            " buffer",
1053 0
                            h2->rxf_stream);
1054 0
                        r2->error = H2SE_INTERNAL_ERROR;
1055 0
                        if (r2->cond)
1056 0
                                PTOK(pthread_cond_signal(r2->cond));
1057 0
                        Lck_Unlock(&h2->sess->mtx);
1058 0
                        return (H2SE_INTERNAL_ERROR);
1059
                }
1060 462
                rxbuf = STV_GetBufPtr(stvbuf, &bstest);
1061 462
                AN(rxbuf);
1062 462
                assert(bstest >= bufsize + sizeof *rxbuf);
1063 462
                assert(PAOK(rxbuf));
1064 462
                INIT_OBJ(rxbuf, H2_RXBUF_MAGIC);
1065 462
                rxbuf->size = bufsize;
1066 462
                rxbuf->stvbuf = stvbuf;
1067
1068 462
                r2->rxbuf = rxbuf;
1069
1070 462
                Lck_Lock(&h2->sess->mtx);
1071 462
        }
1072
1073 1008
        CHECK_OBJ_NOTNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1074 1008
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1075 1008
        l = r2->rxbuf->head - r2->rxbuf->tail;
1076 1008
        assert(l <= r2->rxbuf->size);
1077 1008
        l = r2->rxbuf->size - l;
1078 1008
        assert(len <= l); /* Stream window handling ensures this */
1079
1080 1008
        Lck_Unlock(&h2->sess->mtx);
1081
1082 1008
        l = len;
1083 1008
        head = r2->rxbuf->head;
1084 1008
        do {
1085 1113
                l2 = l;
1086 1113
                if ((head % r2->rxbuf->size) + l2 > r2->rxbuf->size)
1087 105
                        l2 = r2->rxbuf->size - (head % r2->rxbuf->size);
1088 1113
                assert(l2 > 0);
1089 1113
                memcpy(&r2->rxbuf->data[head % r2->rxbuf->size], src, l2);
1090 1113
                src += l2;
1091 1113
                head += l2;
1092 1113
                l -= l2;
1093 1113
        } while (l > 0);
1094
1095 1008
        Lck_Lock(&h2->sess->mtx);
1096
1097
        /* Charge stream window. The entire frame including padding
1098
         * (h2->rxf_len) counts towards the window. The used padding
1099
         * bytes will be included in the next connection window update
1100
         * sent when the buffer bytes are consumed because that is
1101
         * calculated against the available buffer space. */
1102 1008
        r2->r_window -= h2->rxf_len;
1103 1008
        r2->rxbuf->head += len;
1104 1008
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1105 1008
        if (h2->rxf_flags & H2FF_DATA_END_STREAM)
1106 378
                r2->state = H2_S_CLOS_REM;
1107 1008
        if (r2->cond)
1108 564
                PTOK(pthread_cond_signal(r2->cond));
1109 1008
        Lck_Unlock(&h2->sess->mtx);
1110
1111 1008
        return (0);
1112 6594
}
1113
1114
static enum vfp_status v_matchproto_(vfp_pull_f)
1115 1049
h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp)
1116
{
1117
        struct h2_req *r2;
1118
        struct h2_sess *h2;
1119
        enum vfp_status retval;
1120
        ssize_t l, l2;
1121
        uint64_t tail;
1122
        uint8_t *dst;
1123
        char buf[4];
1124
        int i;
1125
1126 1049
        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
1127 1049
        CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
1128 1049
        CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
1129 1049
        h2 = r2->h2sess;
1130
1131 1049
        AN(ptr);
1132 1049
        AN(lp);
1133 1049
        assert(*lp >= 0);
1134
1135 1049
        Lck_Lock(&h2->sess->mtx);
1136
1137 1049
        r2->cond = &vc->wrk->cond;
1138 7007
        while (1) {
1139 7007
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1140 7007
                if (r2->rxbuf) {
1141 1427
                        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1142 1427
                        l = r2->rxbuf->head - r2->rxbuf->tail;
1143 1427
                } else
1144 5580
                        l = 0;
1145
1146 7007
                if (h2->error != NULL || r2->error != NULL)
1147 131
                        retval = VFP_ERROR;
1148 6876
                else if (r2->state >= H2_S_CLOS_REM && l <= *lp)
1149 415
                        retval = VFP_END;
1150
                else {
1151 6461
                        if (l > *lp)
1152 0
                                l = *lp;
1153 6461
                        retval = VFP_OK;
1154
                }
1155
1156 7007
                if (retval != VFP_OK || l > 0)
1157 1049
                        break;
1158
1159 11916
                i = Lck_CondWaitTimeout(r2->cond, &h2->sess->mtx,
1160 5958
                    SESS_TMO(h2->sess, timeout_idle));
1161 5958
                if (i == ETIMEDOUT) {
1162 0
                        retval = VFP_ERROR;
1163 0
                        break;
1164
                }
1165
        }
1166 1049
        r2->cond = NULL;
1167
1168 1049
        Lck_Unlock(&h2->sess->mtx);
1169
1170 1049
        if (l == 0 || retval == VFP_ERROR) {
1171 188
                *lp = 0;
1172 188
                return (retval);
1173
        }
1174
1175 861
        *lp = l;
1176 861
        dst = ptr;
1177 861
        tail = r2->rxbuf->tail;
1178 861
        do {
1179 966
                l2 = l;
1180 966
                if ((tail % r2->rxbuf->size) + l2 > r2->rxbuf->size)
1181 105
                        l2 = r2->rxbuf->size - (tail % r2->rxbuf->size);
1182 966
                assert(l2 > 0);
1183 966
                memcpy(dst, &r2->rxbuf->data[tail % r2->rxbuf->size], l2);
1184 966
                dst += l2;
1185 966
                tail += l2;
1186 966
                l -= l2;
1187 966
        } while (l > 0);
1188
1189 861
        Lck_Lock(&h2->sess->mtx);
1190
1191 861
        CHECK_OBJ_NOTNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1192 861
        r2->rxbuf->tail = tail;
1193 861
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1194
1195 861
        if (r2->r_window < cache_param->h2_rx_window_low_water &&
1196 609
            r2->state < H2_S_CLOS_REM) {
1197
                /* l is free buffer space */
1198
                /* l2 is calculated window increment */
1199 399
                l = r2->rxbuf->size - (r2->rxbuf->head - r2->rxbuf->tail);
1200 399
                assert(r2->r_window <= l);
1201 399
                l2 = cache_param->h2_rx_window_increment;
1202 399
                if (r2->r_window + l2 > l)
1203 399
                        l2 = l - r2->r_window;
1204 399
                r2->r_window += l2;
1205 399
        } else
1206 462
                l2 = 0;
1207
1208 861
        Lck_Unlock(&h2->sess->mtx);
1209
1210 861
        if (l2 > 0) {
1211 399
                vbe32enc(buf, l2);
1212 399
                H2_Send_Get(vc->wrk, h2, r2);
1213 798
                H2_Send_Frame(vc->wrk, h2, H2_F_WINDOW_UPDATE, 0, 4,
1214 399
                    r2->stream, buf);
1215 399
                H2_Send_Rel(h2, r2);
1216 399
        }
1217
1218 861
        return (retval);
1219 1049
}
1220
1221
static void
1222 546
h2_vfp_body_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
1223
{
1224
        struct h2_req *r2;
1225
        struct h2_sess *h2;
1226 546
        struct stv_buffer *stvbuf = NULL;
1227
1228 546
        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
1229 546
        CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
1230 546
        CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
1231 546
        CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
1232 546
        h2 = r2->h2sess;
1233
1234 546
        if (vc->failed) {
1235 0
                CHECK_OBJ_NOTNULL(r2->req->wrk, WORKER_MAGIC);
1236 0
                H2_Send_Get(r2->req->wrk, h2, r2);
1237 0
                H2_Send_RST(r2->req->wrk, h2, r2, r2->stream,
1238
                    H2SE_REFUSED_STREAM);
1239 0
                H2_Send_Rel(h2, r2);
1240 0
                Lck_Lock(&h2->sess->mtx);
1241 0
                r2->error = H2SE_REFUSED_STREAM;
1242 0
                Lck_Unlock(&h2->sess->mtx);
1243 0
        }
1244
1245 546
        if (r2->state >= H2_S_CLOS_REM && r2->rxbuf != NULL) {
1246 378
                Lck_Lock(&h2->sess->mtx);
1247 378
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1248 378
                if (r2->rxbuf != NULL) {
1249 378
                        stvbuf = r2->rxbuf->stvbuf;
1250 378
                        r2->rxbuf = NULL;
1251 378
                }
1252 378
                Lck_Unlock(&h2->sess->mtx);
1253 378
                if (stvbuf != NULL) {
1254 378
                        STV_FreeBuf(vc->wrk, &stvbuf);
1255 378
                        AZ(stvbuf);
1256 378
                }
1257 378
        }
1258 546
}
1259
1260
static const struct vfp h2_body = {
1261
        .name = "H2_BODY",
1262
        .pull = h2_vfp_body,
1263
        .fini = h2_vfp_body_fini
1264
};
1265
1266
void v_matchproto_(vtr_req_body_t)
1267 756
h2_req_body(struct req *req)
1268
{
1269
        struct h2_req *r2;
1270
        struct vfp_entry *vfe;
1271
1272 756
        CHECK_OBJ(req, REQ_MAGIC);
1273 756
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
1274 756
        vfe = VFP_Push(req->vfc, &h2_body);
1275 756
        AN(vfe);
1276 756
        vfe->priv1 = r2;
1277 756
}
1278
1279
/**********************************************************************/
1280
1281
void v_matchproto_(vtr_req_fail_f)
1282 21
h2_req_fail(struct req *req, stream_close_t reason)
1283
{
1284 21
        assert(reason != SC_NULL);
1285 21
        assert(req->sp->fd != 0);
1286 21
        VSLb(req->vsl, SLT_Debug, "H2FAILREQ");
1287 21
}
1288
1289
/**********************************************************************/
1290
1291
static enum htc_status_e v_matchproto_(htc_complete_f)
1292 36683
h2_frame_complete(struct http_conn *htc)
1293
{
1294
        struct h2_sess *h2;
1295
1296 36683
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
1297 36683
        CAST_OBJ_NOTNULL(h2, htc->priv, H2_SESS_MAGIC);
1298 36683
        if (htc->rxbuf_b + 9 > htc->rxbuf_e ||
1299 19142
            htc->rxbuf_b + 9 + (vbe32dec(htc->rxbuf_b) >> 8) > htc->rxbuf_e)
1300 18035
                return (HTC_S_MORE);
1301 18648
        return (HTC_S_COMPLETE);
1302 36683
}
1303
1304
/**********************************************************************/
1305
1306
static h2_error
1307 18627
h2_procframe(struct worker *wrk, struct h2_sess *h2, h2_frame h2f)
1308
{
1309
        struct h2_req *r2;
1310
        h2_error h2e;
1311
1312 18627
        ASSERT_RXTHR(h2);
1313 18627
        if (h2->rxf_stream == 0 && h2f->act_szero != 0) {
1314 42
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on stream 0",
1315 21
                    h2f->name);
1316 21
                return (h2f->act_szero);
1317
        }
1318
1319 18606
        if (h2->rxf_stream != 0 && h2f->act_snonzero != 0) {
1320 42
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on stream %d",
1321 21
                    h2f->name, h2->rxf_stream);
1322 21
                return (h2f->act_snonzero);
1323
        }
1324
1325 18585
        if (h2->rxf_stream > h2->highest_stream && h2f->act_sidle != 0) {
1326 84
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on idle stream "
1327 42
                    "%d", h2f->name, h2->rxf_stream);
1328 42
                return (h2f->act_sidle);
1329
        }
1330
1331 18543
        if (h2->rxf_stream != 0 && !(h2->rxf_stream & 1)) {
1332
                // rfc7540,l,1140,1145
1333
                // rfc7540,l,1153,1158
1334
                /* No even streams, we don't do PUSH_PROMISE */
1335 42
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: illegal stream (=%u)",
1336 21
                    h2->rxf_stream);
1337 21
                return (H2CE_PROTOCOL_ERROR);
1338
        }
1339
1340 32133
        VTAILQ_FOREACH(r2, &h2->streams, list)
1341 27828
                if (r2->stream == h2->rxf_stream)
1342 14217
                        break;
1343
1344 18522
        if (h2->new_req != NULL && h2f != H2_F_CONTINUATION) {
1345 42
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: expected continuation but "
1346 21
                    " received %s on stream %d", h2f->name, h2->rxf_stream);
1347 21
                return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1859,1863
1348
        }
1349
1350 18501
        h2e = h2f->rxfunc(wrk, h2, r2);
1351 18501
        if (h2e == NULL)
1352 16800
                return (NULL);
1353 1701
        if (h2->rxf_stream == 0 || h2e->connection)
1354 567
                return (h2e);   // Connection errors one level up
1355
1356 1134
        H2_Send_Get(wrk, h2, h2->req0);
1357 1134
        H2_Send_RST(wrk, h2, h2->req0, h2->rxf_stream, h2e);
1358 1134
        H2_Send_Rel(h2, h2->req0);
1359 1134
        return (NULL);
1360 18627
}
1361
1362
h2_error
1363 1620
h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now)
1364
{
1365 1620
        h2_error h2e = NULL;
1366
1367 1620
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
1368 1620
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
1369 1620
        Lck_AssertHeld(&h2->sess->mtx);
1370
1371
        /* NB: when now is NAN, it means that h2_window_timeout was hit
1372
         * on a lock condwait operation.
1373
         */
1374 1620
        if (isnan(now))
1375 21
                AN(r2->t_winupd);
1376
1377 1620
        if (h2->error != NULL && h2->error->connection &&
1378 0
            !h2->error->send_goaway)
1379 0
                return (h2->error);
1380
1381 1620
        if (r2->t_winupd == 0 && r2->t_send == 0)
1382 995
                return (NULL);
1383
1384 625
        if (isnan(now) || (r2->t_winupd != 0 &&
1385 522
            now - r2->t_winupd > cache_param->h2_window_timeout)) {
1386 84
                VSLb(h2->vsl, SLT_Debug,
1387 42
                     "H2: stream %u: Hit h2_window_timeout", r2->stream);
1388 42
                h2e = H2SE_BROKE_WINDOW;
1389 42
        }
1390
1391 1208
        if (h2e == NULL && r2->t_send != 0 &&
1392 583
            now - r2->t_send > SESS_TMO(h2->sess, send_timeout)) {
1393 42
                VSLb(h2->vsl, SLT_Debug,
1394 21
                     "H2: stream %u: Hit send_timeout", r2->stream);
1395 21
                h2e = H2SE_CANCEL;
1396 21
        }
1397
1398 625
        return (h2e);
1399 1620
}
1400
1401
static h2_error
1402 1319
h2_stream_tmo_unlocked(struct h2_sess *h2, const struct h2_req *r2)
1403
{
1404
        h2_error h2e;
1405
1406 1319
        Lck_Lock(&h2->sess->mtx);
1407 1319
        h2e = h2_stream_tmo(h2, r2, h2->sess->t_idle);
1408 1319
        Lck_Unlock(&h2->sess->mtx);
1409
1410 1319
        return (h2e);
1411
}
1412
1413
/*
1414
 * This is the janitorial task of cleaning up any closed & refused
1415
 * streams, and checking if the session is timed out.
1416
 */
1417
static h2_error
1418 2374
h2_sweep(struct worker *wrk, struct h2_sess *h2)
1419
{
1420
        struct h2_req *r2, *r22;
1421
        h2_error h2e, tmo;
1422
        vtim_real now;
1423
1424 2374
        ASSERT_RXTHR(h2);
1425
1426 2374
        h2e = h2->error;
1427 2374
        now = VTIM_real();
1428 2374
        if (h2e == NULL && h2->open_streams == 0 &&
1429 1485
            h2->sess->t_idle + cache_param->timeout_idle < now)
1430 63
                h2e = H2CE_NO_ERROR;
1431
1432 2376
        h2->do_sweep = 0;
1433 6835
        VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
1434 4459
                if (r2 == h2->req0) {
1435 2375
                        assert (r2->state == H2_S_IDLE);
1436 2375
                        continue;
1437
                }
1438 2084
                switch (r2->state) {
1439
                case H2_S_CLOSED:
1440 765
                        AZ(r2->scheduled);
1441 765
                        h2_del_req(wrk, r2);
1442 765
                        break;
1443
                case H2_S_CLOS_REM:
1444 1146
                        if (!r2->scheduled) {
1445 0
                                H2_Send_Get(wrk, h2, h2->req0);
1446 0
                                H2_Send_RST(wrk, h2, h2->req0, r2->stream,
1447
                                    H2SE_REFUSED_STREAM);
1448 0
                                H2_Send_Rel(h2, h2->req0);
1449 0
                                h2_del_req(wrk, r2);
1450 0
                                continue;
1451
                        }
1452
                        /* FALLTHROUGH */
1453
                case H2_S_CLOS_LOC:
1454
                case H2_S_OPEN:
1455 1319
                        tmo = h2_stream_tmo_unlocked(h2, r2);
1456 1319
                        if (h2e == NULL)
1457 1319
                                h2e = tmo;
1458 1319
                        break;
1459 0
                case H2_S_IDLE:
1460
                        /* Current code make this unreachable: h2_new_req is
1461
                         * only called inside h2_rx_headers, which immediately
1462
                         * sets the new stream state to H2_S_OPEN */
1463
                        /* FALLTHROUGH */
1464
                default:
1465 0
                        WRONG("Wrong h2 stream state");
1466 0
                        break;
1467
                }
1468 2084
        }
1469 2376
        return (h2e);
1470
}
1471
1472
/*
1473
 * if we have received end_headers, the new request is started
1474
 * if we have not received end_stream, DATA frames are expected later
1475
 *
1476
 * neither of these make much sense to output here
1477
 *
1478
 * goaway currently is always 0, see #4285
1479
 */
1480
static void
1481 2352
h2_htc_debug(enum htc_status_e hs, struct h2_sess *h2)
1482
{
1483
        const char *s, *r;
1484
1485 2352
        if (LIKELY(VSL_tag_is_masked(SLT_Debug)))
1486 0
                return;
1487
1488 2352
        HTC_Status(hs, &s, &r);
1489 4704
        H2S_Lock_VSLb(h2, SLT_Debug, "H2: HTC %s (%s) frame=%s goaway=%d",
1490 2352
            s, r, h2->htc->rxbuf_b == h2->htc->rxbuf_e ? "complete" : "partial",
1491 2352
            h2->goaway);
1492 2352
}
1493
1494
/***********************************************************************
1495
 * Called in loop from h2_new_session()
1496
 */
1497
1498
#define H2_FRAME(l,U,...) const struct h2_frame_s H2_F_##U[1] = \
1499
    {{ #U, h2_rx_##l, __VA_ARGS__ }};
1500
#include "tbl/h2_frames.h"
1501
1502
static const h2_frame h2flist[] = {
1503
#define H2_FRAME(l,U,t,...) [t] = H2_F_##U,
1504
#include "tbl/h2_frames.h"
1505
};
1506
1507
#define H2FMAX vcountof(h2flist)
1508
1509
int
1510 22938
h2_rxframe(struct worker *wrk, struct h2_sess *h2)
1511
{
1512
        enum htc_status_e hs;
1513
        h2_frame h2f;
1514
        h2_error h2e;
1515
        const char *s, *r;
1516
1517 22938
        ASSERT_RXTHR(h2);
1518
1519 22938
        if (h2->goaway && h2->open_streams == 0) {
1520
                // h2 WS must always be released before returning
1521 0
                WS_ReleaseP(h2->ws, h2->htc->rxbuf_b);
1522 0
                return (0);
1523
        }
1524
1525 22938
        h2->t1 = NAN;
1526 22938
        VTCP_blocking(*h2->htc->rfd);
1527 45876
        hs = HTC_RxStuff(h2->htc, h2_frame_complete, &h2->t1, NULL, NAN,
1528 22938
            VTIM_real() + 0.5, NAN, h2->local_settings.max_frame_size + 9);
1529
1530 22938
        h2e = NULL;
1531 22938
        switch (hs) {
1532
        case HTC_S_EOF:
1533 2352
                h2_htc_debug(hs, h2);
1534 2352
                h2e = H2CE_NO_ERROR;
1535 2352
                break;
1536
        case HTC_S_COMPLETE:
1537 18648
                h2->sess->t_idle = VTIM_real();
1538 18648
                if (h2->do_sweep)
1539 436
                        h2e = h2_sweep(wrk, h2);
1540 18648
                break;
1541
        case HTC_S_TIMEOUT:
1542
                //// #4279
1543
                // h2_htc_debug(hs, h2);
1544 1938
                h2e = h2_sweep(wrk, h2);
1545 1938
                break;
1546
        default:
1547 0
                HTC_Status(hs, &s, &r);
1548 0
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: HTC %s (%s)", s, r);
1549 0
                h2e = H2CE_ENHANCE_YOUR_CALM;
1550 0
        }
1551
1552 22938
        if (h2e != NULL && h2e->connection) {
1553 2412
                h2->error = h2e;
1554 2412
                h2_tx_goaway(wrk, h2, h2e);
1555 2412
                return (0);
1556
        }
1557
1558 20526
        if (hs != HTC_S_COMPLETE)
1559 1876
                return (1);
1560
1561 18648
        h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8;
1562 18648
        h2->rxf_type = h2->htc->rxbuf_b[3];
1563 18648
        h2->rxf_flags = h2->htc->rxbuf_b[4];
1564 18648
        h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5);
1565 18648
        h2->rxf_stream &= ~(1LU<<31);                   // rfc7540,l,690,692
1566 18648
        h2->rxf_data = (void*)(h2->htc->rxbuf_b + 9);
1567
        /* XXX: later full DATA will not be rx'ed yet. */
1568 18648
        HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
1569
1570 18648
        h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
1571 18648
        h2->srq->acct.req_hdrbytes += 9;
1572
1573 18648
        if (h2->rxf_type >= H2FMAX) {
1574
                // rfc7540,l,679,681
1575
                // XXX: later, drain rest of frame
1576 21
                h2->bogosity++;
1577 42
                H2S_Lock_VSLb(h2, SLT_Debug,
1578
                    "H2: Unknown frame type 0x%02x (ignored)",
1579 21
                    (uint8_t)h2->rxf_type);
1580 21
                h2->srq->acct.req_bodybytes += h2->rxf_len;
1581 21
                return (1);
1582
        }
1583 18627
        h2f = h2flist[h2->rxf_type];
1584
1585 18627
        AN(h2f->name);
1586 18627
        AN(h2f->rxfunc);
1587 18627
        if (h2f->overhead)
1588 7623
                h2->srq->acct.req_bodybytes += h2->rxf_len;
1589
1590 18627
        if (h2->rxf_flags & ~h2f->flags) {
1591
                // rfc7540,l,687,688
1592 42
                h2->bogosity++;
1593 84
                H2S_Lock_VSLb(h2, SLT_Debug,
1594
                    "H2: Unknown flags 0x%02x on %s (ignored)",
1595 42
                    (uint8_t)h2->rxf_flags & ~h2f->flags, h2f->name);
1596 42
                h2->rxf_flags &= h2f->flags;
1597 42
        }
1598
1599 18627
        h2e = h2_procframe(wrk, h2, h2f);
1600 18627
        if (h2->error == NULL && h2e != NULL) {
1601 630
                h2->error = h2e;
1602 630
                h2_tx_goaway(wrk, h2, h2e);
1603 630
        }
1604
1605 18627
        return (h2->error != NULL ? 0 : 1);
1606 22936
}