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