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 4105
h2_framename(enum h2frame h2f)
78
{
79
80 4105
        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 4105
}
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 75
h2_streamerror(uint32_t u)
110
{
111 75
        if (u < NSTREAMERRORS && stream_errors[u] != NULL)
112 65
                return (stream_errors[u]);
113
        else
114 10
                return (H2NN_ERROR);
115 75
}
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 15
h2_connectionerror(uint32_t u)
136
{
137 15
        if (u < NCONNERRORS && conn_errors[u] != NULL)
138 10
                return (conn_errors[u]);
139
        else
140 5
                return (H2NN_ERROR);
141 15
}
142
143
/**********************************************************************/
144
145
struct h2_req *
146 1535
h2_new_req(struct h2_sess *h2, unsigned stream, struct req *req)
147
{
148
        struct h2_req *r2;
149
150 1535
        ASSERT_RXTHR(h2);
151 1535
        if (req == NULL)
152 1510
                req = Req_New(h2->sess);
153 1535
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
154
155 1535
        r2 = WS_Alloc(req->ws, sizeof *r2);
156 1535
        AN(r2);
157 1535
        INIT_OBJ(r2, H2_REQ_MAGIC);
158 1535
        r2->state = H2_S_IDLE;
159 1535
        r2->h2sess = h2;
160 1535
        r2->stream = stream;
161 1535
        r2->req = req;
162 1535
        if (stream)
163 825
                r2->counted = 1;
164 1535
        r2->r_window = h2->local_settings.initial_window_size;
165 1535
        r2->t_window = h2->remote_settings.initial_window_size;
166 1535
        req->transport_priv = r2;
167 1535
        Lck_Lock(&h2->sess->mtx);
168 1535
        if (stream)
169 825
                h2->open_streams++;
170 1535
        VTAILQ_INSERT_TAIL(&h2->streams, r2, list);
171 1535
        Lck_Unlock(&h2->sess->mtx);
172 1535
        h2->refcnt++;
173 1535
        return (r2);
174
}
175
176
void
177 1493
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 1493
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
184 1493
        AZ(r2->scheduled);
185 1493
        h2 = r2->h2sess;
186 1493
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
187 1493
        ASSERT_RXTHR(h2);
188 1493
        sp = h2->sess;
189 1493
        Lck_Lock(&sp->mtx);
190 1493
        assert(h2->refcnt > 0);
191 1493
        --h2->refcnt;
192
        /* XXX: PRIORITY reshuffle */
193 1493
        VTAILQ_REMOVE(&h2->streams, r2, list);
194 1493
        Lck_Unlock(&sp->mtx);
195
196 1493
        assert(!WS_IsReserved(r2->req->ws));
197 1493
        AZ(r2->req->ws->r);
198
199 1493
        CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
200 1493
        if (r2->rxbuf) {
201 20
                stvbuf = r2->rxbuf->stvbuf;
202 20
                r2->rxbuf = NULL;
203 20
                STV_FreeBuf(wrk, &stvbuf);
204 20
                AZ(stvbuf);
205 20
        }
206
207 1493
        Req_Cleanup(sp, wrk, r2->req);
208 1493
        if (FEATURE(FEATURE_BUSY_STATS_RATE))
209 0
                WRK_AddStat(wrk);
210 1493
        Req_Release(r2->req);
211 1493
}
212
213
void
214 725
h2_kill_req(struct worker *wrk, struct h2_sess *h2,
215
    struct h2_req *r2, h2_error h2e)
216
{
217
218 725
        ASSERT_RXTHR(h2);
219 725
        AN(h2e);
220 725
        Lck_Lock(&h2->sess->mtx);
221 1450
        VSLb(h2->vsl, SLT_Debug, "KILL st=%u state=%d sched=%d",
222 725
            r2->stream, r2->state, r2->scheduled);
223 725
        if (r2->counted) {
224 223
                assert(h2->open_streams > 0);
225 223
                h2->open_streams--;
226 223
                r2->counted = 0;
227 223
        }
228 725
        if (r2->error == NULL)
229 75
                r2->error = h2e;
230 725
        if (r2->scheduled) {
231 286
                if (r2->cond != NULL)
232 30
                        PTOK(pthread_cond_signal(r2->cond));
233 286
                r2 = NULL;
234 286
                Lck_Unlock(&h2->sess->mtx);
235 286
        } else {
236 439
                Lck_Unlock(&h2->sess->mtx);
237 439
                if (r2->state == H2_S_OPEN && h2->new_req == r2->req)
238 20
                        (void)h2h_decode_hdr_fini(h2);
239
        }
240 725
        if (r2 != NULL)
241 439
                h2_del_req(wrk, r2);
242 725
}
243
244
/**********************************************************************/
245
246
static void
247 4180
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 4180
        if (VSL_tag_is_masked(SLT_H2RxHdr) &&
255 75
            VSL_tag_is_masked(SLT_H2RxBody))
256 75
                return;
257
258 4105
        AN(ptr);
259 4105
        assert(len >= 9);
260 4105
        b = ptr;
261
262 4105
        vsb = VSB_new_auto();
263 4105
        AN(vsb);
264 4105
        p = h2_framename((enum h2frame)b[3]);
265 4105
        if (p != NULL)
266 4100
                VSB_cat(vsb, p);
267
        else
268 5
                VSB_quote(vsb, b + 3, 1, VSB_QUOTE_HEX);
269
270 4105
        u = vbe32dec(b) >> 8;
271 4105
        VSB_printf(vsb, "[%u] ", u);
272 4105
        VSB_quote(vsb, b + 4, 1, VSB_QUOTE_HEX);
273 4105
        VSB_putc(vsb, ' ');
274 4105
        VSB_quote(vsb, b + 5, 4, VSB_QUOTE_HEX);
275 4105
        if (u > 0) {
276 2775
                VSB_putc(vsb, ' ');
277 2775
                VSB_quote(vsb, b + 9, len - 9, VSB_QUOTE_HEX);
278 2775
        }
279 4105
        AZ(VSB_finish(vsb));
280 4105
        Lck_Lock(&h2->sess->mtx);
281 4105
        VSLb_bin(h2->vsl, SLT_H2RxHdr, 9, b);
282 4105
        if (len > 9)
283 2775
                VSLb_bin(h2->vsl, SLT_H2RxBody, len - 9, b + 9);
284
285 4105
        VSLb(h2->vsl, SLT_Debug, "H2RXF %s", VSB_data(vsb));
286 4105
        Lck_Unlock(&h2->sess->mtx);
287 4105
        VSB_destroy(&vsb);
288 4180
}
289
290
291
/**********************************************************************
292
 */
293
294
static h2_error v_matchproto_(h2_rxframe_f)
295 30
h2_rx_ping(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
296
{
297
298 30
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
299 30
        ASSERT_RXTHR(h2);
300 30
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
301 30
        assert(r2 == h2->req0);
302
303 30
        if (h2->rxf_len != 8) {                         // rfc7540,l,2364,2366
304 5
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx ping with (len != 8)");
305 5
                return (H2CE_FRAME_SIZE_ERROR);
306
        }
307 25
        AZ(h2->rxf_stream);                             // rfc7540,l,2359,2362
308 25
        if (h2->rxf_flags != 0) {                       // We never send pings
309 5
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx ping ack");
310 5
                return (H2SE_PROTOCOL_ERROR);
311
        }
312 20
        H2_Send_Get(wrk, h2, r2);
313 40
        H2_Send_Frame(wrk, h2,
314 20
            H2_F_PING, H2FF_PING_ACK, 8, 0, h2->rxf_data);
315 20
        H2_Send_Rel(h2, r2);
316 20
        return (0);
317 30
}
318
319
/**********************************************************************
320
 */
321
322
static h2_error v_matchproto_(h2_rxframe_f)
323 10
h2_rx_push_promise(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
324
{
325
326 10
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
327 10
        ASSERT_RXTHR(h2);
328 10
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
329
        // rfc7540,l,2262,2267
330 10
        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx push promise");
331 10
        return (H2CE_PROTOCOL_ERROR);
332
}
333
334
/**********************************************************************
335
 */
336
337
static h2_error
338 75
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 75
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
344 75
        ASSERT_RXTHR(h2);
345 75
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
346
347 75
        if (h2->rapid_reset_limit == 0)
348 0
                return (0);
349
350 75
        now = VTIM_real();
351 75
        CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
352 75
        AN(r2->req->t_first);
353 75
        if (now - r2->req->t_first > h2->rapid_reset)
354 0
                return (0);
355
356 75
        d = now - h2->last_rst;
357 150
        h2->rst_budget += h2->rapid_reset_limit * d /
358 75
            h2->rapid_reset_period;
359 75
        h2->rst_budget = vmin_t(double, h2->rst_budget,
360
            h2->rapid_reset_limit);
361 75
        h2->last_rst = now;
362
363 75
        if (h2->rst_budget < 1.0) {
364 10
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: Hit RST limit. Closing session.");
365 10
                return (H2CE_RAPID_RESET);
366
        }
367 65
        h2->rst_budget -= 1.0;
368 65
        return (0);
369 75
}
370
371
static h2_error v_matchproto_(h2_rxframe_f)
372 95
h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
373
{
374
        h2_error h2e;
375
376 95
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
377 95
        ASSERT_RXTHR(h2);
378 95
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
379
380 95
        if (h2->rxf_len != 4) {                 // rfc7540,l,2003,2004
381 5
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx rst with (len != 4)");
382 5
                return (H2CE_FRAME_SIZE_ERROR);
383
        }
384 90
        if (r2 == NULL)
385 15
                return (0);
386 75
        h2e = h2_rapid_reset(wrk, h2, r2);
387 75
        h2_kill_req(wrk, h2, r2, h2_streamerror(vbe32dec(h2->rxf_data)));
388 75
        return (h2e);
389 95
}
390
391
/**********************************************************************
392
 */
393
394
static h2_error v_matchproto_(h2_rxframe_f)
395 15
h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
396
{
397
398 15
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
399 15
        ASSERT_RXTHR(h2);
400 15
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
401 15
        assert(r2 == h2->req0);
402
403 15
        h2->goaway = 1;
404 15
        h2->goaway_last_stream = vbe32dec(h2->rxf_data);
405 15
        h2->error = h2_connectionerror(vbe32dec(h2->rxf_data + 4));
406 15
        H2S_Lock_VSLb(h2, SLT_Debug, "GOAWAY %s", h2->error->name);
407 15
        return (h2->error);
408
}
409
410
static void
411 670
h2_tx_goaway(struct worker *wrk, struct h2_sess *h2, h2_error h2e)
412
{
413
        char b[8];
414
415 670
        ASSERT_RXTHR(h2);
416 670
        AN(h2e);
417
418 670
        if (h2->goaway || !h2e->send_goaway)
419 0
                return;
420
421 670
        h2->goaway = 1;
422 670
        vbe32enc(b, h2->highest_stream);
423 670
        vbe32enc(b + 4, h2e->val);
424 670
        H2_Send_Get(wrk, h2, h2->req0);
425 670
        H2_Send_Frame(wrk, h2, H2_F_GOAWAY, 0, 8, 0, b);
426 670
        H2_Send_Rel(h2, h2->req0);
427 670
}
428
429
/**********************************************************************
430
 */
431
432
static h2_error v_matchproto_(h2_rxframe_f)
433 110
h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
434
{
435
        uint32_t wu;
436
437 110
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
438 110
        ASSERT_RXTHR(h2);
439 110
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
440
441 110
        if (h2->rxf_len != 4) {
442 5
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx winup with (len != 4)");
443 5
                return (H2CE_FRAME_SIZE_ERROR);
444
        }
445 105
        wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
446 105
        if (wu == 0)
447 5
                return (H2SE_PROTOCOL_ERROR);
448 100
        if (r2 == NULL)
449 5
                return (0);
450 95
        Lck_Lock(&h2->sess->mtx);
451 95
        r2->t_window += wu;
452 95
        if (r2 == h2->req0)
453 40
                PTOK(pthread_cond_broadcast(h2->winupd_cond));
454 55
        else if (r2->cond != NULL)
455 40
                PTOK(pthread_cond_signal(r2->cond));
456 95
        Lck_Unlock(&h2->sess->mtx);
457 95
        if (r2->t_window >= (1LL << 31))
458 10
                return (H2SE_FLOW_CONTROL_ERROR);
459 85
        return (0);
460 110
}
461
462
/**********************************************************************
463
 * Incoming PRIORITY, possibly an ACK of one we sent.
464
 */
465
466
static h2_error v_matchproto_(h2_rxframe_f)
467 45
h2_rx_priority(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
468
{
469
470 45
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
471 45
        ASSERT_RXTHR(h2);
472 45
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
473 45
        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 45
h2_win_adjust(const struct h2_sess *h2, uint32_t oldval, uint32_t newval)
505
{
506
        struct h2_req *r2;
507
508 45
        Lck_AssertHeld(&h2->sess->mtx);
509
        // rfc7540,l,2668,2674
510 90
        VTAILQ_FOREACH(r2, &h2->streams, list) {
511 45
                CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
512 45
                if (r2 == h2->req0)
513 45
                        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 45
}
529
530
h2_error
531 90
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 90
        x = vbe16dec(d);
538 90
        y = vbe32dec(d + 2);
539 90
        if (x >= H2_SETTING_TBL_LEN || h2_setting_tbl[x] == NULL) {
540
                // rfc7540,l,2181,2182
541 10
                H2S_Lock_VSLb(h2, SLT_Debug,
542 5
                    "H2SETTING unknown setting 0x%04x=%08x (ignored)", x, y);
543 5
                return (0);
544
        }
545 85
        s = h2_setting_tbl[x];
546 85
        AN(s);
547 85
        if (y < s->minval || y > s->maxval) {
548 30
                H2S_Lock_VSLb(h2, SLT_Debug, "H2SETTING invalid %s=0x%08x",
549 15
                    s->name, y);
550 15
                AN(s->range_error);
551 15
                if (!DO_DEBUG(DBG_H2_NOCHECK))
552 5
                        return (s->range_error);
553 10
        }
554 80
        Lck_Lock(&h2->sess->mtx);
555 80
        if (s == H2_SET_INITIAL_WINDOW_SIZE)
556 45
                h2_win_adjust(h2, h2->remote_settings.initial_window_size, y);
557 80
        VSLb(h2->vsl, SLT_Debug, "H2SETTING %s=0x%08x", s->name, y);
558 80
        Lck_Unlock(&h2->sess->mtx);
559 80
        AN(s->setfunc);
560 80
        s->setfunc(&h2->remote_settings, y);
561 80
        return (0);
562 90
}
563
564
static h2_error v_matchproto_(h2_rxframe_f)
565 1360
h2_rx_settings(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
566
{
567
        const uint8_t *p;
568
        unsigned l;
569 1360
        h2_error retval = 0;
570
571 1360
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
572 1360
        ASSERT_RXTHR(h2);
573 1360
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
574 1360
        assert(r2 == h2->req0);
575 1360
        AZ(h2->rxf_stream);
576
577 1360
        if (h2->rxf_flags == H2FF_SETTINGS_ACK) {
578 670
                if (h2->rxf_len > 0) {                  // rfc7540,l,2047,2049
579 5
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx settings ack with "
580
                            "(len > 0)");
581 5
                        return (H2CE_FRAME_SIZE_ERROR);
582
                }
583 665
                return (0);
584
        } else {
585 690
                if (h2->rxf_len % 6) {                  // rfc7540,l,2062,2064
586 5
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx settings with "
587
                            "((len %% 6) != 0)");
588 5
                        return (H2CE_PROTOCOL_ERROR);
589
                }
590 685
                p = h2->rxf_data;
591 720
                for (l = h2->rxf_len; l >= 6; l -= 6, p += 6) {
592 40
                        retval = h2_set_setting(h2, p);
593 40
                        if (retval)
594 5
                                return (retval);
595 35
                }
596 680
                H2_Send_Get(wrk, h2, r2);
597 680
                H2_Send_Frame(wrk, h2,
598
                    H2_F_SETTINGS, H2FF_SETTINGS_ACK, 0, 0, NULL);
599 680
                H2_Send_Rel(h2, r2);
600
        }
601 680
        return (0);
602 1360
}
603
604
/**********************************************************************
605
 * Incoming HEADERS, this is where the party's at...
606
 */
607
608
void v_matchproto_(task_func_t)
609 625
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 625
        CAST_OBJ_NOTNULL(req, priv, REQ_MAGIC);
616 625
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
617 625
        THR_SetRequest(req);
618 625
        CNT_Embark(wrk, req);
619
620 625
        if (CNT_Request(req) != REQ_FSM_DISEMBARK) {
621 560
                wrk->stats->client_req++;
622 560
                assert(!WS_IsReserved(req->ws));
623 560
                AZ(req->top->vcl0);
624 560
                h2 = r2->h2sess;
625 560
                CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
626 560
                Lck_Lock(&h2->sess->mtx);
627 560
                r2->scheduled = 0;
628 560
                r2->state = H2_S_CLOSED;
629 560
                r2->h2sess->do_sweep = 1;
630 560
                Lck_Unlock(&h2->sess->mtx);
631 560
        }
632 625
        THR_SetRequest(NULL);
633 625
}
634
635
static h2_error
636 610
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 610
        ASSERT_RXTHR(h2);
643 610
        assert(r2->state == H2_S_OPEN);
644 610
        h2e = h2h_decode_hdr_fini(h2);
645 610
        h2->new_req = NULL;
646 610
        if (h2e != NULL) {
647 25
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK/FINI %s", h2e->name);
648 25
                assert(!WS_IsReserved(r2->req->ws));
649 25
                h2_del_req(wrk, r2);
650 25
                return (h2e);
651
        }
652 585
        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 585
        http_CollectHdrSep(req->http, H_Cookie, "; ");  // rfc7540,l,3114,3120
658
659 585
        cl = http_GetContentLength(req->http);
660 585
        assert(cl >= -2);
661 585
        if (cl == -2) {
662 0
                H2S_Lock_VSLb(h2, SLT_Debug, "Non-parseable Content-Length");
663 0
                return (H2SE_PROTOCOL_ERROR);
664
        }
665
666 585
        if (req->req_body_status == NULL) {
667 175
                if (cl == -1)
668 90
                        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 85
                        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 175
                req->htc->content_length = cl;
680 175
        } else {
681
                /* A HEADER frame contained END_STREAM */
682 410
                assert (req->req_body_status == BS_NONE);
683 410
                r2->state = H2_S_CLOS_REM;
684 410
                if (cl > 0) {
685 5
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx header with END_STREAM "
686
                            "and content-length > 0");
687 5
                        return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840
688
                }
689
        }
690
691 580
        if (req->http->hd[HTTP_HDR_METHOD].b == NULL) {
692 5
                H2S_Lock_VSLb(h2, SLT_Debug, "Missing :method");
693 5
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
694
        }
695
696 575
        if (req->http->hd[HTTP_HDR_URL].b == NULL) {
697 5
                H2S_Lock_VSLb(h2, SLT_Debug, "Missing :path");
698 5
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3087,3090
699
        }
700
701 570
        AN(req->http->hd[HTTP_HDR_PROTO].b);
702
703 580
        if (*req->http->hd[HTTP_HDR_URL].b == '*' &&
704 20
            (Tlen(req->http->hd[HTTP_HDR_METHOD]) != 7 ||
705 10
            strncmp(req->http->hd[HTTP_HDR_METHOD].b, "OPTIONS", 7))) {
706 15
                H2S_Lock_VSLb(h2, SLT_BogoHeader, "Illegal :path pseudo-header");
707 15
                return (H2SE_PROTOCOL_ERROR); //rfc7540,l,3068,3071
708
        }
709
710 555
        assert(req->req_step == R_STP_TRANSPORT);
711 555
        VCL_TaskEnter(req->privs);
712 555
        VCL_TaskEnter(req->top->privs);
713 555
        req->task->func = h2_do_req;
714 555
        req->task->priv = req;
715 555
        r2->scheduled = 1;
716 555
        if (Pool_Task(wrk->pool, req->task, TASK_QUEUE_STR) != 0) {
717 5
                r2->scheduled = 0;
718 5
                r2->state = H2_S_CLOSED;
719 5
                return (H2SE_REFUSED_STREAM); //rfc7540,l,3326,3329
720
        }
721 550
        return (0);
722 610
}
723
724
static h2_error v_matchproto_(h2_rxframe_f)
725 815
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 815
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
733 815
        ASSERT_RXTHR(h2);
734
735 815
        if (r2 == NULL) {
736 810
                if (h2->rxf_stream <= h2->highest_stream) {
737 5
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: new stream ID < highest stream");
738 5
                        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 1610
                if (h2->open_streams >=
745 805
                    (int)h2->local_settings.max_concurrent_streams) {
746 10
                        H2S_Lock_VSLb(h2, SLT_Debug,
747
                             "H2: stream %u: Hit maximum number of "
748 5
                             "concurrent streams", h2->rxf_stream);
749 5
                        return (H2SE_REFUSED_STREAM);   // rfc7540,l,1200,1205
750
                }
751 800
                h2->highest_stream = h2->rxf_stream;
752 800
                r2 = h2_new_req(h2, h2->rxf_stream, NULL);
753 800
        }
754 805
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
755
756 805
        if (r2->state != H2_S_IDLE) {
757 5
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers on non-idle stream");
758 5
                return (H2CE_PROTOCOL_ERROR);   // XXX spec ?
759
        }
760 800
        r2->state = H2_S_OPEN;
761
762 800
        req = r2->req;
763 800
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
764
765 800
        req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);
766 800
        VSLb(req->vsl, SLT_Begin, "req %ju rxreq", VXID(req->sp->vxid));
767 800
        VSL(SLT_Link, req->sp->vxid, "req %ju rxreq", VXID(req->vsl->wid));
768
769 800
        h2->new_req = req;
770 800
        req->sp = h2->sess;
771 800
        req->transport = &HTTP2_transport;
772
773 800
        req->t_first = VTIM_real();
774 800
        req->t_req = VTIM_real();
775 800
        req->t_prev = req->t_first;
776 800
        VSLb_ts_req(req, "Start", req->t_first);
777 800
        req->acct.req_hdrbytes += h2->rxf_len;
778
779 800
        HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
780 800
        http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0");
781
782 800
        h2h_decode_hdr_init(h2);
783
784 800
        p = h2->rxf_data;
785 800
        l = h2->rxf_len;
786 800
        if (h2->rxf_flags & H2FF_HEADERS_PADDED) {
787 35
                if (*p + 1 > l) {
788 10
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers with pad length > frame len");
789 10
                        return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1884,1887
790
                }
791 25
                l -= 1 + *p;
792 25
                p += 1;
793 25
        }
794 790
        if (h2->rxf_flags & H2FF_HEADERS_PRIORITY) {
795 15
                if (l < 5) {
796 5
                        H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx headers with incorrect "
797
                            "priority data");
798 5
                        return (H2CE_PROTOCOL_ERROR);
799
                }
800 10
                l -= 5;
801 10
                p += 5;
802 10
        }
803 785
        h2e = h2h_decode_bytes(h2, p, l);
804 785
        if (h2e != NULL) {
805 160
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK(hdr) %s", h2e->name);
806 160
                (void)h2h_decode_hdr_fini(h2);
807 160
                assert(!WS_IsReserved(r2->req->ws));
808 160
                h2_del_req(wrk, r2);
809 160
                return (h2e);
810
        }
811
812 625
        if (h2->rxf_flags & H2FF_HEADERS_END_STREAM)
813 450
                req->req_body_status = BS_NONE;
814
815 625
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
816 595
                return (h2_end_headers(wrk, h2, req, r2));
817 30
        return (0);
818 815
}
819
820
/**********************************************************************/
821
822
static h2_error v_matchproto_(h2_rxframe_f)
823 95
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 95
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
829 95
        ASSERT_RXTHR(h2);
830 95
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
831
832 95
        if (r2 == NULL || r2->state != H2_S_OPEN || r2->req != h2->new_req) {
833 20
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: rx unexpected CONT frame"
834 10
                    " on stream %d", h2->rxf_stream);
835 10
                return (H2CE_PROTOCOL_ERROR);   // XXX spec ?
836
        }
837 85
        req = r2->req;
838 85
        h2e = h2h_decode_bytes(h2, h2->rxf_data, h2->rxf_len);
839 85
        r2->req->acct.req_hdrbytes += h2->rxf_len;
840 85
        if (h2e != NULL) {
841 10
                H2S_Lock_VSLb(h2, SLT_Debug, "HPACK(cont) %s", h2e->name);
842 10
                (void)h2h_decode_hdr_fini(h2);
843 10
                assert(!WS_IsReserved(r2->req->ws));
844 10
                h2_del_req(wrk, r2);
845 10
                return (h2e);
846
        }
847 75
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
848 15
                return (h2_end_headers(wrk, h2, req, r2));
849 60
        return (0);
850 95
}
851
852
/**********************************************************************/
853
854
static h2_error v_matchproto_(h2_rxframe_f)
855 1570
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 1570
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
868 1570
        ASSERT_RXTHR(h2);
869 1570
        CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);
870
871 1570
        if (r2 == NULL)
872 5
                return (0);
873
874 1565
        if (r2->state >= H2_S_CLOS_REM) {
875 10
                r2->error = H2SE_STREAM_CLOSED;
876 10
                return (H2SE_STREAM_CLOSED); // rfc7540,l,1766,1769
877
        }
878
879 1555
        Lck_Lock(&h2->sess->mtx);
880 1555
        CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
881
882 1555
        if (h2->error != NULL || r2->error != NULL) {
883 5
                if (r2->cond)
884 0
                        PTOK(pthread_cond_signal(r2->cond));
885 5
                Lck_Unlock(&h2->sess->mtx);
886 5
                return (h2->error != NULL ? h2->error : r2->error);
887
        }
888
889
        /* Check padding if present */
890 1550
        src = h2->rxf_data;
891 1550
        len = h2->rxf_len;
892 1550
        if (h2->rxf_flags & H2FF_DATA_PADDED) {
893 1330
                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 1330
                len -= 1 + *src;
904 1330
                src += 1;
905 1330
        }
906
907
        /* Check against the Content-Length header if given */
908 1550
        if (r2->req->htc->content_length >= 0) {
909 1505
                if (r2->rxbuf)
910 140
                        l = r2->rxbuf->head;
911
                else
912 1365
                        l = 0;
913 1505
                l += len;
914 1575
                if (l > r2->req->htc->content_length ||
915 1490
                    ((h2->rxf_flags & H2FF_DATA_END_STREAM) &&
916 70
                     l != r2->req->htc->content_length)) {
917 30
                        VSLb(h2->vsl, SLT_Debug,
918
                            "H2: stream %u: Received data and Content-Length"
919 15
                            " mismatch", h2->rxf_stream);
920 15
                        r2->error = H2SE_PROTOCOL_ERROR;
921 15
                        if (r2->cond)
922 5
                                PTOK(pthread_cond_signal(r2->cond));
923 15
                        Lck_Unlock(&h2->sess->mtx);
924 15
                        return (H2SE_PROTOCOL_ERROR);
925
                }
926 1490
        }
927
928
        /* Check and charge connection window. The entire frame including
929
         * padding (h2->rxf_len) counts towards the window. */
930 1535
        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 1535
        h2->req0->r_window -= h2->rxf_len;
941 1535
        if (h2->req0->r_window < cache_param->h2_rx_window_low_water) {
942 215
                h2->req0->r_window += cache_param->h2_rx_window_increment;
943 215
                vbe32enc(buf, cache_param->h2_rx_window_increment);
944 215
                Lck_Unlock(&h2->sess->mtx);
945 215
                H2_Send_Get(wrk, h2, h2->req0);
946 215
                H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0, 4, 0, buf);
947 215
                H2_Send_Rel(h2, h2->req0);
948 215
                Lck_Lock(&h2->sess->mtx);
949 215
        }
950
951
        /* Check stream window. The entire frame including padding
952
         * (h2->rxf_len) counts towards the window. */
953 1535
        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 1535
        if (len == 0) {
966 1295
                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 1295
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
975 1295
                if (r2->r_window == 0 &&
976 5
                    (r2->rxbuf == NULL || r2->rxbuf->tail == r2->rxbuf->head)) {
977 5
                        if (r2->rxbuf)
978 0
                                l = r2->rxbuf->size;
979
                        else
980 5
                                l = h2->local_settings.initial_window_size;
981 5
                        r2->r_window += l;
982 5
                        Lck_Unlock(&h2->sess->mtx);
983 5
                        vbe32enc(buf, l);
984 5
                        H2_Send_Get(wrk, h2, h2->req0);
985 10
                        H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0, 4,
986 5
                            r2->stream, buf);
987 5
                        H2_Send_Rel(h2, h2->req0);
988 5
                        Lck_Lock(&h2->sess->mtx);
989 5
                }
990
991 1295
                if (h2->rxf_flags & H2FF_DATA_END_STREAM)
992 15
                        r2->state = H2_S_CLOS_REM;
993 1295
                if (r2->cond)
994 1257
                        PTOK(pthread_cond_signal(r2->cond));
995 1295
                Lck_Unlock(&h2->sess->mtx);
996 1295
                return (0);
997
        }
998
999
        /* Make the buffer on demand */
1000 240
        if (r2->rxbuf == NULL) {
1001
                unsigned bufsize;
1002
                size_t bstest;
1003
                struct stv_buffer *stvbuf;
1004
                struct h2_rxbuf *rxbuf;
1005
1006 110
                Lck_Unlock(&h2->sess->mtx);
1007
1008 110
                bufsize = h2->local_settings.initial_window_size;
1009 110
                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 110
                assert(bufsize > 0);
1017 110
                if ((h2->rxf_flags & H2FF_DATA_END_STREAM) &&
1018 65
                    bufsize > len)
1019
                        /* Cap the buffer size when we know this is the
1020
                         * single data frame. */
1021 65
                        bufsize = len;
1022 110
                CHECK_OBJ_NOTNULL(stv_h2_rxbuf, STEVEDORE_MAGIC);
1023 220
                stvbuf = STV_AllocBuf(wrk, stv_h2_rxbuf,
1024 110
                    bufsize + sizeof *rxbuf);
1025 110
                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 110
                rxbuf = STV_GetBufPtr(stvbuf, &bstest);
1038 110
                AN(rxbuf);
1039 110
                assert(bstest >= bufsize + sizeof *rxbuf);
1040 110
                assert(PAOK(rxbuf));
1041 110
                INIT_OBJ(rxbuf, H2_RXBUF_MAGIC);
1042 110
                rxbuf->size = bufsize;
1043 110
                rxbuf->stvbuf = stvbuf;
1044
1045 110
                r2->rxbuf = rxbuf;
1046
1047 110
                Lck_Lock(&h2->sess->mtx);
1048 110
        }
1049
1050 240
        CHECK_OBJ_NOTNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1051 240
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1052 240
        l = r2->rxbuf->head - r2->rxbuf->tail;
1053 240
        assert(l <= r2->rxbuf->size);
1054 240
        l = r2->rxbuf->size - l;
1055 240
        assert(len <= l); /* Stream window handling ensures this */
1056
1057 240
        Lck_Unlock(&h2->sess->mtx);
1058
1059 240
        l = len;
1060 240
        head = r2->rxbuf->head;
1061 240
        do {
1062 265
                l2 = l;
1063 265
                if ((head % r2->rxbuf->size) + l2 > r2->rxbuf->size)
1064 25
                        l2 = r2->rxbuf->size - (head % r2->rxbuf->size);
1065 265
                assert(l2 > 0);
1066 265
                memcpy(&r2->rxbuf->data[head % r2->rxbuf->size], src, l2);
1067 265
                src += l2;
1068 265
                head += l2;
1069 265
                l -= l2;
1070 265
        } while (l > 0);
1071
1072 240
        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 240
        r2->r_window -= h2->rxf_len;
1080 240
        r2->rxbuf->head += len;
1081 240
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1082 240
        if (h2->rxf_flags & H2FF_DATA_END_STREAM)
1083 90
                r2->state = H2_S_CLOS_REM;
1084 240
        if (r2->cond)
1085 134
                PTOK(pthread_cond_signal(r2->cond));
1086 240
        Lck_Unlock(&h2->sess->mtx);
1087
1088 240
        return (0);
1089 1570
}
1090
1091
static enum vfp_status v_matchproto_(vfp_pull_f)
1092 250
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 250
        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
1104 250
        CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
1105 250
        CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
1106 250
        h2 = r2->h2sess;
1107
1108 250
        AN(ptr);
1109 250
        AN(lp);
1110 250
        assert(*lp >= 0);
1111
1112 250
        Lck_Lock(&h2->sess->mtx);
1113
1114 250
        r2->cond = &vc->wrk->cond;
1115 1671
        while (1) {
1116 1671
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1117 1671
                if (r2->rxbuf) {
1118 340
                        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1119 340
                        l = r2->rxbuf->head - r2->rxbuf->tail;
1120 340
                } else
1121 1331
                        l = 0;
1122
1123 1671
                if (h2->error != NULL || r2->error != NULL)
1124 30
                        retval = VFP_ERROR;
1125 1641
                else if (r2->state >= H2_S_CLOS_REM && l <= *lp)
1126 100
                        retval = VFP_END;
1127
                else {
1128 1541
                        if (l > *lp)
1129 0
                                l = *lp;
1130 1541
                        retval = VFP_OK;
1131
                }
1132
1133 1671
                if (retval != VFP_OK || l > 0)
1134 250
                        break;
1135
1136 2842
                i = Lck_CondWaitTimeout(r2->cond, &h2->sess->mtx,
1137 1421
                    SESS_TMO(h2->sess, timeout_idle));
1138 1421
                if (i == ETIMEDOUT) {
1139 0
                        retval = VFP_ERROR;
1140 0
                        break;
1141
                }
1142
        }
1143 250
        r2->cond = NULL;
1144
1145 250
        Lck_Unlock(&h2->sess->mtx);
1146
1147 250
        if (l == 0 || retval == VFP_ERROR) {
1148 45
                *lp = 0;
1149 45
                return (retval);
1150
        }
1151
1152 205
        *lp = l;
1153 205
        dst = ptr;
1154 205
        tail = r2->rxbuf->tail;
1155 205
        do {
1156 230
                l2 = l;
1157 230
                if ((tail % r2->rxbuf->size) + l2 > r2->rxbuf->size)
1158 25
                        l2 = r2->rxbuf->size - (tail % r2->rxbuf->size);
1159 230
                assert(l2 > 0);
1160 230
                memcpy(dst, &r2->rxbuf->data[tail % r2->rxbuf->size], l2);
1161 230
                dst += l2;
1162 230
                tail += l2;
1163 230
                l -= l2;
1164 230
        } while (l > 0);
1165
1166 205
        Lck_Lock(&h2->sess->mtx);
1167
1168 205
        CHECK_OBJ_NOTNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1169 205
        r2->rxbuf->tail = tail;
1170 205
        assert(r2->rxbuf->tail <= r2->rxbuf->head);
1171
1172 205
        if (r2->r_window < cache_param->h2_rx_window_low_water &&
1173 145
            r2->state < H2_S_CLOS_REM) {
1174
                /* l is free buffer space */
1175
                /* l2 is calculated window increment */
1176 95
                l = r2->rxbuf->size - (r2->rxbuf->head - r2->rxbuf->tail);
1177 95
                assert(r2->r_window <= l);
1178 95
                l2 = cache_param->h2_rx_window_increment;
1179 95
                if (r2->r_window + l2 > l)
1180 95
                        l2 = l - r2->r_window;
1181 95
                r2->r_window += l2;
1182 95
        } else
1183 110
                l2 = 0;
1184
1185 205
        Lck_Unlock(&h2->sess->mtx);
1186
1187 205
        if (l2 > 0) {
1188 95
                vbe32enc(buf, l2);
1189 95
                H2_Send_Get(vc->wrk, h2, r2);
1190 190
                H2_Send_Frame(vc->wrk, h2, H2_F_WINDOW_UPDATE, 0, 4,
1191 95
                    r2->stream, buf);
1192 95
                H2_Send_Rel(h2, r2);
1193 95
        }
1194
1195 205
        return (retval);
1196 250
}
1197
1198
static void
1199 130
h2_vfp_body_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
1200
{
1201
        struct h2_req *r2;
1202
        struct h2_sess *h2;
1203 130
        struct stv_buffer *stvbuf = NULL;
1204
1205 130
        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
1206 130
        CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
1207 130
        CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
1208 130
        CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
1209 130
        h2 = r2->h2sess;
1210
1211 130
        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 130
        if (r2->state >= H2_S_CLOS_REM && r2->rxbuf != NULL) {
1223 90
                Lck_Lock(&h2->sess->mtx);
1224 90
                CHECK_OBJ_ORNULL(r2->rxbuf, H2_RXBUF_MAGIC);
1225 90
                if (r2->rxbuf != NULL) {
1226 90
                        stvbuf = r2->rxbuf->stvbuf;
1227 90
                        r2->rxbuf = NULL;
1228 90
                }
1229 90
                Lck_Unlock(&h2->sess->mtx);
1230 90
                if (stvbuf != NULL) {
1231 90
                        STV_FreeBuf(vc->wrk, &stvbuf);
1232 90
                        AZ(stvbuf);
1233 90
                }
1234 90
        }
1235 130
}
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 175
h2_req_body(struct req *req)
1245
{
1246
        struct h2_req *r2;
1247
        struct vfp_entry *vfe;
1248
1249 175
        CHECK_OBJ(req, REQ_MAGIC);
1250 175
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
1251 175
        vfe = VFP_Push(req->vfc, &h2_body);
1252 175
        AN(vfe);
1253 175
        vfe->priv1 = r2;
1254 175
}
1255
1256
/**********************************************************************/
1257
1258
void v_matchproto_(vtr_req_fail_f)
1259 5
h2_req_fail(struct req *req, stream_close_t reason)
1260
{
1261 5
        assert(reason != SC_NULL);
1262 5
        assert(req->sp->fd != 0);
1263 5
        VSLb(req->vsl, SLT_Debug, "H2FAILREQ");
1264 5
}
1265
1266
/**********************************************************************/
1267
1268
static enum htc_status_e v_matchproto_(htc_complete_f)
1269 8163
h2_frame_complete(struct http_conn *htc)
1270
{
1271
        struct h2_sess *h2;
1272
1273 8163
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
1274 8163
        CAST_OBJ_NOTNULL(h2, htc->priv, H2_SESS_MAGIC);
1275 8163
        if (htc->rxbuf_b + 9 > htc->rxbuf_e ||
1276 4286
            htc->rxbuf_b + 9 + (vbe32dec(htc->rxbuf_b) >> 8) > htc->rxbuf_e)
1277 3983
                return (HTC_S_MORE);
1278 4180
        return (HTC_S_COMPLETE);
1279 8163
}
1280
1281
/**********************************************************************/
1282
1283
static h2_error
1284 4175
h2_procframe(struct worker *wrk, struct h2_sess *h2, h2_frame h2f)
1285
{
1286
        struct h2_req *r2;
1287
        h2_error h2e;
1288
1289 4175
        ASSERT_RXTHR(h2);
1290 4175
        if (h2->rxf_stream == 0 && h2f->act_szero != 0) {
1291 10
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on stream 0",
1292 5
                    h2f->name);
1293 5
                return (h2f->act_szero);
1294
        }
1295
1296 4170
        if (h2->rxf_stream != 0 && h2f->act_snonzero != 0) {
1297 10
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on stream %d",
1298 5
                    h2f->name, h2->rxf_stream);
1299 5
                return (h2f->act_snonzero);
1300
        }
1301
1302 4165
        if (h2->rxf_stream > h2->highest_stream && h2f->act_sidle != 0) {
1303 20
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: unexpected %s frame on idle stream "
1304 10
                    "%d", h2f->name, h2->rxf_stream);
1305 10
                return (h2f->act_sidle);
1306
        }
1307
1308 4155
        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 10
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: illegal stream (=%u)",
1313 5
                    h2->rxf_stream);
1314 5
                return (H2CE_PROTOCOL_ERROR);
1315
        }
1316
1317 7180
        VTAILQ_FOREACH(r2, &h2->streams, list)
1318 6285
                if (r2->stream == h2->rxf_stream)
1319 3255
                        break;
1320
1321 4150
        if (h2->new_req != NULL && h2f != H2_F_CONTINUATION) {
1322 10
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: expected continuation but "
1323 5
                    " received %s on stream %d", h2f->name, h2->rxf_stream);
1324 5
                return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1859,1863
1325
        }
1326
1327 4145
        h2e = h2f->rxfunc(wrk, h2, r2);
1328 4145
        if (h2e == NULL)
1329 3760
                return (NULL);
1330 385
        if (h2->rxf_stream == 0 || h2e->connection)
1331 135
                return (h2e);   // Connection errors one level up
1332
1333 250
        H2_Send_Get(wrk, h2, h2->req0);
1334 250
        H2_Send_RST(wrk, h2, h2->req0, h2->rxf_stream, h2e);
1335 250
        H2_Send_Rel(h2, h2->req0);
1336 250
        return (NULL);
1337 4175
}
1338
1339
h2_error
1340 381
h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now)
1341
{
1342 381
        h2_error h2e = NULL;
1343
1344 381
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
1345 381
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
1346 381
        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 381
        if (isnan(now))
1352 5
                AN(r2->t_winupd);
1353
1354 381
        if (h2->error != NULL && h2->error->connection &&
1355 0
            !h2->error->send_goaway)
1356 0
                return (h2->error);
1357
1358 381
        if (r2->t_winupd == 0 && r2->t_send == 0)
1359 240
                return (NULL);
1360
1361 141
        if (isnan(now) || (r2->t_winupd != 0 &&
1362 117
            now - r2->t_winupd > cache_param->h2_window_timeout)) {
1363 20
                VSLb(h2->vsl, SLT_Debug,
1364 10
                     "H2: stream %u: Hit h2_window_timeout", r2->stream);
1365 10
                h2e = H2SE_BROKE_WINDOW;
1366 10
        }
1367
1368 272
        if (h2e == NULL && r2->t_send != 0 &&
1369 131
            now - r2->t_send > SESS_TMO(h2->sess, send_timeout)) {
1370 10
                VSLb(h2->vsl, SLT_Debug,
1371 5
                     "H2: stream %u: Hit send_timeout", r2->stream);
1372 5
                h2e = H2SE_CANCEL;
1373 5
        }
1374
1375 141
        return (h2e);
1376 381
}
1377
1378
static h2_error
1379 313
h2_stream_tmo_unlocked(struct h2_sess *h2, const struct h2_req *r2)
1380
{
1381
        h2_error h2e;
1382
1383 313
        Lck_Lock(&h2->sess->mtx);
1384 313
        h2e = h2_stream_tmo(h2, r2, h2->sess->t_idle);
1385 313
        Lck_Unlock(&h2->sess->mtx);
1386
1387 313
        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 560
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 560
        ASSERT_RXTHR(h2);
1402
1403 560
        h2e = h2->error;
1404 560
        now = VTIM_real();
1405 560
        if (h2e == NULL && h2->open_streams == 0 &&
1406 351
            h2->sess->t_idle + cache_param->timeout_idle < now)
1407 15
                h2e = H2CE_NO_ERROR;
1408
1409 562
        h2->do_sweep = 0;
1410 1612
        VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
1411 1050
                if (r2 == h2->req0) {
1412 561
                        assert (r2->state == H2_S_IDLE);
1413 561
                        continue;
1414
                }
1415 489
                switch (r2->state) {
1416
                case H2_S_CLOSED:
1417 176
                        AZ(r2->scheduled);
1418 176
                        h2_del_req(wrk, r2);
1419 176
                        break;
1420
                case H2_S_CLOS_REM:
1421 273
                        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 313
                        tmo = h2_stream_tmo_unlocked(h2, r2);
1433 313
                        if (h2e == NULL)
1434 313
                                h2e = tmo;
1435 313
                        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 489
        }
1446 562
        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 5147
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 5147
        ASSERT_RXTHR(h2);
1474
1475 5147
        if (h2->goaway && h2->open_streams == 0)
1476 0
                return (0);
1477
1478 5147
        VTCP_blocking(*h2->htc->rfd);
1479 10294
        hs = HTC_RxStuff(h2->htc, h2_frame_complete, NULL, NULL, NAN,
1480 5147
            VTIM_real() + 0.5, NAN, h2->local_settings.max_frame_size + 9);
1481
1482 5147
        h2e = NULL;
1483 5147
        switch (hs) {
1484
        case HTC_S_COMPLETE:
1485 4180
                h2->sess->t_idle = VTIM_real();
1486 4180
                if (h2->do_sweep)
1487 98
                        h2e = h2_sweep(wrk, h2);
1488 4180
                break;
1489
        case HTC_S_TIMEOUT:
1490 462
                h2e = h2_sweep(wrk, h2);
1491 462
                break;
1492
        default:
1493 505
                h2e = H2CE_ENHANCE_YOUR_CALM;
1494 505
        }
1495
1496 5147
        if (h2e != NULL && h2e->connection) {
1497 519
                HTC_Status(hs, &s, &r);
1498 519
                H2S_Lock_VSLb(h2, SLT_SessError, "H2: HTC %s (%s)", s, r);
1499 519
                h2->error = h2e;
1500 519
                h2_tx_goaway(wrk, h2, h2e);
1501 519
                return (0);
1502
        }
1503
1504 4628
        if (hs != HTC_S_COMPLETE)
1505 448
                return (1);
1506
1507 4180
        h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8;
1508 4180
        h2->rxf_type = h2->htc->rxbuf_b[3];
1509 4180
        h2->rxf_flags = h2->htc->rxbuf_b[4];
1510 4180
        h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5);
1511 4180
        h2->rxf_stream &= ~(1LU<<31);                   // rfc7540,l,690,692
1512 4180
        h2->rxf_data = (void*)(h2->htc->rxbuf_b + 9);
1513
        /* XXX: later full DATA will not be rx'ed yet. */
1514 4180
        HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
1515
1516 4180
        h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
1517 4180
        h2->srq->acct.req_hdrbytes += 9;
1518
1519 4180
        if (h2->rxf_type >= H2FMAX) {
1520
                // rfc7540,l,679,681
1521
                // XXX: later, drain rest of frame
1522 5
                h2->bogosity++;
1523 10
                H2S_Lock_VSLb(h2, SLT_Debug,
1524
                    "H2: Unknown frame type 0x%02x (ignored)",
1525 5
                    (uint8_t)h2->rxf_type);
1526 5
                h2->srq->acct.req_bodybytes += h2->rxf_len;
1527 5
                return (1);
1528
        }
1529 4175
        h2f = h2flist[h2->rxf_type];
1530
1531 4175
        AN(h2f->name);
1532 4175
        AN(h2f->rxfunc);
1533 4175
        if (h2f->overhead)
1534 1685
                h2->srq->acct.req_bodybytes += h2->rxf_len;
1535
1536 4175
        if (h2->rxf_flags & ~h2f->flags) {
1537
                // rfc7540,l,687,688
1538 10
                h2->bogosity++;
1539 20
                H2S_Lock_VSLb(h2, SLT_Debug,
1540
                    "H2: Unknown flags 0x%02x on %s (ignored)",
1541 10
                    (uint8_t)h2->rxf_flags & ~h2f->flags, h2f->name);
1542 10
                h2->rxf_flags &= h2f->flags;
1543 10
        }
1544
1545 4175
        h2e = h2_procframe(wrk, h2, h2f);
1546 4175
        if (h2->error == NULL && h2e != NULL) {
1547 150
                h2->error = h2e;
1548 150
                h2_tx_goaway(wrk, h2, h2e);
1549 150
        }
1550
1551 4175
        return (h2->error != NULL ? 0 : 1);
1552 5147
}