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