varnish-cache/bin/varnishd/http2/cache_http2_proto.c
1
/*-
2
 * Copyright (c) 2016 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 *
28
 */
29
30
#include "config.h"
31
32
#include "cache/cache_varnishd.h"
33
34
#include <stdio.h>
35
#include <stdlib.h>
36
37
#include "cache/cache_transport.h"
38
#include "cache/cache_filter.h"
39
#include "http2/cache_http2.h"
40
41
#include "vend.h"
42
#include "vtcp.h"
43
#include "vtim.h"
44
45
#define H2EC1(U,v,d) const struct h2_error_s H2CE_##U[1] = {{#U,d,v,0,1}};
46
#define H2EC2(U,v,d) const struct h2_error_s H2SE_##U[1] = {{#U,d,v,1,0}};
47
#define H2EC3(U,v,d) H2EC1(U,v,d) H2EC2(U,v,d)
48
#define H2_ERROR(NAME, val, sc, desc) H2EC##sc(NAME, val, desc)
49
#include "tbl/h2_error.h"
50
#undef H2EC1
51
#undef H2EC2
52
#undef H2EC3
53
54
static const struct h2_error_s H2NN_ERROR[1] = {{
55
        "UNKNOWN_ERROR",
56
        "Unknown error number",
57
        0xffffffff,
58
        1,
59
        1
60
}};
61
62
enum h2frame {
63
#define H2_FRAME(l,u,t,f,...)   H2F_##u = t,
64
#include "tbl/h2_frames.h"
65
};
66
67
static const char *
68 211
h2_framename(enum h2frame h2f)
69
{
70
71 211
        switch (h2f) {
72
#define H2_FRAME(l,u,t,f,...)   case H2F_##u: return #u;
73
#include "tbl/h2_frames.h"
74
        default:
75 1
                return (NULL);
76
        }
77
}
78
79
#define H2_FRAME_FLAGS(l,u,v)   const uint8_t H2FF_##u = v;
80
#include "tbl/h2_frames.h"
81
82
/**********************************************************************
83
 */
84
85
static const h2_error stream_errors[] = {
86
#define H2EC1(U,v,d)
87
#define H2EC2(U,v,d) [v] = H2SE_##U,
88
#define H2EC3(U,v,d) H2EC1(U,v,d) H2EC2(U,v,d)
89
#define H2_ERROR(NAME, val, sc, desc) H2EC##sc(NAME, val, desc)
90
#include "tbl/h2_error.h"
91
#undef H2EC1
92
#undef H2EC2
93
#undef H2EC3
94
};
95
96
#define NSTREAMERRORS (sizeof(stream_errors)/sizeof(stream_errors[0]))
97
98
static h2_error
99 1
h2_streamerror(uint32_t u)
100
{
101 1
        if (u < NSTREAMERRORS && stream_errors[u] != NULL)
102 0
                return (stream_errors[u]);
103
        else
104 1
                return (H2NN_ERROR);
105
}
106
107
/**********************************************************************
108
 */
109
110
static const h2_error conn_errors[] = {
111
#define H2EC1(U,v,d) [v] = H2CE_##U,
112
#define H2EC2(U,v,d)
113
#define H2EC3(U,v,d) H2EC1(U,v,d) H2EC2(U,v,d)
114
#define H2_ERROR(NAME, val, sc, desc) H2EC##sc(NAME, val, desc)
115
#include "tbl/h2_error.h"
116
#undef H2EC1
117
#undef H2EC2
118
#undef H2EC3
119
};
120
121
#define NCONNERRORS (sizeof(conn_errors)/sizeof(conn_errors[0]))
122
123
static h2_error
124 3
h2_connectionerror(uint32_t u)
125
{
126 3
        if (u < NCONNERRORS && conn_errors[u] != NULL)
127 2
                return (conn_errors[u]);
128
        else
129 1
                return (H2NN_ERROR);
130
}
131
132
/**********************************************************************
133
 */
134
135
struct h2_req *
136 117
h2_new_req(const struct worker *wrk, struct h2_sess *h2,
137
    unsigned stream, struct req *req)
138
{
139
        struct h2_req *r2;
140
141 117
        ASSERT_RXTHR(h2);
142 117
        if (req == NULL)
143 114
                req = Req_New(wrk, h2->sess);
144 117
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
145
146 117
        r2 = WS_Alloc(req->ws, sizeof *r2);
147 117
        AN(r2);
148 117
        INIT_OBJ(r2, H2_REQ_MAGIC);
149 117
        r2->state = H2_S_IDLE;
150 117
        r2->h2sess = h2;
151 117
        r2->stream = stream;
152 117
        r2->req = req;
153 117
        r2->r_window = h2->local_settings.initial_window_size;
154 117
        r2->t_window = h2->remote_settings.initial_window_size;
155 117
        req->transport_priv = r2;
156 117
        Lck_Lock(&h2->sess->mtx);
157 117
        VTAILQ_INSERT_TAIL(&h2->streams, r2, list);
158 117
        Lck_Unlock(&h2->sess->mtx);
159 117
        h2->refcnt++;
160 117
        return (r2);
161
}
162
163
void
164 115
h2_del_req(struct worker *wrk, const struct h2_req *r2)
165
{
166
        struct h2_sess *h2;
167
        struct sess *sp;
168
        struct req *req;
169
        int r;
170
171 115
        CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
172 115
        AZ(r2->scheduled);
173 115
        h2 = r2->h2sess;
174 115
        CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
175 115
        ASSERT_RXTHR(h2);
176 115
        sp = h2->sess;
177 115
        Lck_Lock(&sp->mtx);
178 115
        assert(h2->refcnt > 0);
179 115
        r = --h2->refcnt;
180
        /* XXX: PRIORITY reshuffle */
181 115
        VTAILQ_REMOVE(&h2->streams, r2, list);
182 115
        Lck_Unlock(&sp->mtx);
183 115
        AZ(r2->req->ws->r);
184 115
        Req_Cleanup(sp, wrk, r2->req);
185 115
        Req_Release(r2->req);
186 115
        if (r)
187 174
                return;
188
        /* All streams gone, including stream #0, clean up */
189 56
        VHT_Fini(h2->dectbl);
190 56
        req = h2->srq;
191 56
        AZ(req->ws->r);
192 56
        Req_Cleanup(sp, wrk, req);
193 56
        Req_Release(req);
194 56
        SES_Delete(sp, SC_RX_JUNK, NAN);
195
}
196
197
void
198 46
h2_kill_req(struct worker *wrk, const struct h2_sess *h2,
199
    struct h2_req *r2, h2_error h2e)
200
{
201
202 46
        ASSERT_RXTHR(h2);
203 46
        AN(h2e);
204 46
        Lck_Lock(&h2->sess->mtx);
205 46
        VSLb(h2->vsl, SLT_Debug, "KILL st=%u state=%d", r2->stream, r2->state);
206 46
        if (r2->error == NULL)
207 1
                r2->error = h2e;
208 46
        if (r2->scheduled) {
209 5
                if (r2->cond != NULL)
210 2
                        AZ(pthread_cond_signal(r2->cond));
211 5
                r2 = NULL;
212
        } else {
213 41
                if (r2->state == H2_S_OPEN) {
214 5
                        (void)h2h_decode_fini(h2, r2->decode);
215 5
                        FREE_OBJ(r2->decode);
216
                }
217
        }
218 46
        Lck_Unlock(&h2->sess->mtx);
219 46
        if (r2 != NULL)
220 41
                h2_del_req(wrk, r2);
221 46
}
222
223
/**********************************************************************/
224
225
static void
226 211
h2_vsl_frame(const struct h2_sess *h2, const void *ptr, size_t len)
227
{
228
        const uint8_t *b;
229
        struct vsb *vsb;
230
        const char *p;
231
        unsigned u;
232
233 211
        AN(ptr);
234 211
        assert(len >= 9);
235 211
        b = ptr;
236
237 211
        vsb = VSB_new_auto();
238 211
        AN(vsb);
239 211
        p = h2_framename((enum h2frame)b[3]);
240 211
        if (p != NULL)
241 210
                VSB_cat(vsb, p);
242
        else
243 1
                VSB_quote(vsb, b + 3, 1, VSB_QUOTE_HEX);
244
245 211
        u = vbe32dec(b) >> 8;
246 211
        VSB_printf(vsb, "[%u] ", u);
247 211
        VSB_quote(vsb, b + 4, 1, VSB_QUOTE_HEX);
248 211
        VSB_putc(vsb, ' ');
249 211
        VSB_quote(vsb, b + 5, 4, VSB_QUOTE_HEX);
250 211
        if (u > 0) {
251 104
                VSB_putc(vsb, ' ');
252 104
                VSB_quote(vsb, b + 9, len - 9, VSB_QUOTE_HEX);
253
        }
254 211
        AZ(VSB_finish(vsb));
255 211
        Lck_Lock(&h2->sess->mtx);
256 211
        VSLb_bin(h2->vsl, SLT_H2RxHdr, 9, b);
257 211
        if (len > 9)
258 104
                VSLb_bin(h2->vsl, SLT_H2RxBody, len - 9, b + 9);
259
260 211
        VSLb(h2->vsl, SLT_Debug, "H2RXF %s", VSB_data(vsb));
261 211
        Lck_Unlock(&h2->sess->mtx);
262 211
        VSB_destroy(&vsb);
263 211
}
264
265
266
/**********************************************************************
267
 */
268
269
static h2_error v_matchproto_(h2_frame_f)
270 5
h2_rx_ping(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
271
{
272
273 5
        ASSERT_RXTHR(h2);
274
        (void)r2;
275 5
        if (h2->rxf_len != 8)                           // rfc7540,l,2364,2366
276 1
                return (H2CE_FRAME_SIZE_ERROR);
277 4
        AZ(h2->rxf_stream);                             // rfc7540,l,2359,2362
278 4
        if (h2->rxf_flags != 0)                         // We never send pings
279 1
                return (H2SE_PROTOCOL_ERROR);
280 3
        H2_Send_Get(wrk, h2, r2);
281 3
        H2_Send_Frame(wrk, h2,
282 3
            H2_F_PING, H2FF_PING_ACK, 8, 0, h2->rxf_data);
283 3
        H2_Send_Rel(h2, r2);
284 3
        return (0);
285
}
286
287
/**********************************************************************
288
 */
289
290
static h2_error v_matchproto_(h2_frame_f)
291 1
h2_rx_push_promise(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
292
{
293
294
        (void)wrk;
295 1
        ASSERT_RXTHR(h2);
296
        // rfc7540,l,2262,2267
297
        (void)r2;
298 1
        return (H2CE_PROTOCOL_ERROR);
299
}
300
301
/**********************************************************************
302
 */
303
304
static h2_error v_matchproto_(h2_frame_f)
305 4
h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
306
{
307
308
        (void)wrk;
309 4
        ASSERT_RXTHR(h2);
310
311 4
        if (h2->rxf_len != 4)                   // rfc7540,l,2003,2004
312 1
                return (H2CE_FRAME_SIZE_ERROR);
313 3
        if (r2 == NULL)
314 2
                return (0);
315 1
        h2_kill_req(wrk, h2, r2, h2_streamerror(vbe32dec(h2->rxf_data)));
316 1
        return (0);
317
}
318
319
/**********************************************************************
320
 */
321
322
static h2_error v_matchproto_(h2_frame_f)
323 3
h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
324
{
325
326
        (void)wrk;
327 3
        ASSERT_RXTHR(h2);
328
        (void)r2;
329 3
        h2->goaway_last_stream = vbe32dec(h2->rxf_data);
330 3
        h2->error = h2_connectionerror(vbe32dec(h2->rxf_data + 4));
331 3
        Lck_Lock(&h2->sess->mtx);
332 3
        VSLb(h2->vsl, SLT_Debug, "GOAWAY %s", h2->error->name);
333 3
        Lck_Unlock(&h2->sess->mtx);
334 3
        return (h2->error);
335
}
336
337
/**********************************************************************
338
 */
339
340
static h2_error v_matchproto_(h2_frame_f)
341 7
h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
342
{
343
        uint32_t wu;
344
345
        (void)wrk;
346 7
        ASSERT_RXTHR(h2);
347 7
        if (h2->rxf_len != 4)
348 1
                return (H2CE_FRAME_SIZE_ERROR);
349 6
        wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
350 6
        if (wu == 0)
351 1
                return (H2SE_PROTOCOL_ERROR);
352 5
        if (r2 == NULL)
353 1
                return (0);
354 4
        Lck_Lock(&h2->sess->mtx);
355 4
        r2->t_window += wu;
356 4
        if (r2 == h2->req0)
357 2
                AZ(pthread_cond_broadcast(h2->cond));
358 2
        else if (r2->cond != NULL)
359 0
                AZ(pthread_cond_signal(r2->cond));
360 4
        Lck_Unlock(&h2->sess->mtx);
361 4
        if (r2->t_window >= (1LLU << 31))
362 2
                return (H2SE_FLOW_CONTROL_ERROR);
363 2
        return (0);
364
}
365
366
/**********************************************************************
367
 * Incoming PRIORITY, possibly an ACK of one we sent.
368
 */
369
370
static h2_error v_matchproto_(h2_frame_f)
371 11
h2_rx_priority(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
372
{
373
374
        (void)wrk;
375 11
        ASSERT_RXTHR(h2);
376 11
        xxxassert(r2->stream & 1);
377 11
        return (0);
378
}
379
380
/**********************************************************************
381
 * Incoming SETTINGS, possibly an ACK of one we sent.
382
 */
383
384
#define H2_SETTING(U,l, ...)                                    \
385
static void v_matchproto_(h2_setsetting_f)                      \
386
h2_setting_##l(struct h2_settings* s, uint32_t v)               \
387
{                                                               \
388
        s -> l = v;                                             \
389
}
390
#include <tbl/h2_settings.h>
391
392
#define H2_SETTING(U, l, ...)                                   \
393
const struct h2_setting_s H2_SET_##U[1] = {{                    \
394
        #l,                                                     \
395
        h2_setting_##l,                                         \
396
        __VA_ARGS__                                             \
397
}};
398
#include <tbl/h2_settings.h>
399
400
static const struct h2_setting_s * const h2_setting_tbl[] = {
401
#define H2_SETTING(U,l,v, ...) [v] = H2_SET_##U,
402
#include <tbl/h2_settings.h>
403
};
404
405
#define H2_SETTING_TBL_LEN (sizeof(h2_setting_tbl)/sizeof(h2_setting_tbl[0]))
406
407
h2_error
408 9
h2_set_setting(struct h2_sess *h2, const uint8_t *d)
409
{
410
        const struct h2_setting_s *s;
411
        uint16_t x;
412
        uint32_t y;
413
414 9
        x = vbe16dec(d);
415 9
        y = vbe32dec(d + 2);
416 9
        if (x >= H2_SETTING_TBL_LEN || h2_setting_tbl[x] == NULL) {
417
                // rfc7540,l,2181,2182
418 1
                Lck_Lock(&h2->sess->mtx);
419 1
                VSLb(h2->vsl, SLT_Debug,
420
                    "H2SETTING unknown setting 0x%04x=%08x (ignored)", x, y);
421 1
                Lck_Unlock(&h2->sess->mtx);
422 1
                return (0);
423
        }
424 8
        s = h2_setting_tbl[x];
425 8
        AN(s);
426 8
        if (y < s->minval || y > s->maxval) {
427 2
                Lck_Lock(&h2->sess->mtx);
428 2
                VSLb(h2->vsl, SLT_Debug, "H2SETTING invalid %s=0x%08x",
429
                    s->name, y);
430 2
                Lck_Unlock(&h2->sess->mtx);
431 2
                AN(s->range_error);
432 2
                if (!DO_DEBUG(DBG_H2_NOCHECK))
433 1
                        return (s->range_error);
434
        }
435 7
        Lck_Lock(&h2->sess->mtx);
436 7
        VSLb(h2->vsl, SLT_Debug, "H2SETTING %s=0x%08x", s->name, y);
437 7
        Lck_Unlock(&h2->sess->mtx);
438 7
        AN(s->setfunc);
439 7
        s->setfunc(&h2->remote_settings, y);
440 7
        return (0);
441
}
442
443
static h2_error v_matchproto_(h2_frame_f)
444 111
h2_rx_settings(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
445
{
446
        const uint8_t *p;
447
        unsigned l;
448 111
        h2_error retval = 0;
449
450 111
        AN(wrk);
451 111
        ASSERT_RXTHR(h2);
452 111
        AN(r2);
453 111
        AZ(h2->rxf_stream);
454 111
        if (h2->rxf_flags == H2FF_SETTINGS_ACK) {
455 54
                if (h2->rxf_len > 0)                    // rfc7540,l,2047,2049
456 1
                        return (H2CE_FRAME_SIZE_ERROR);
457 53
                return (0);
458
        } else {
459 57
                if (h2->rxf_len % 6)                    // rfc7540,l,2062,2064
460 1
                        return (H2CE_PROTOCOL_ERROR);
461 56
                p = h2->rxf_data;
462 58
                for (l = h2->rxf_len; l >= 6; l -= 6, p += 6) {
463 3
                        retval = h2_set_setting(h2, p);
464 3
                        if (retval)
465 1
                                return (retval);
466
                }
467 55
                H2_Send_Get(wrk, h2, r2);
468 55
                H2_Send_Frame(wrk, h2,
469
                    H2_F_SETTINGS, H2FF_SETTINGS_ACK, 0, 0, NULL);
470 55
                H2_Send_Rel(h2, r2);
471
        }
472 55
        return (0);
473
}
474
475
/**********************************************************************
476
 * Incoming HEADERS, this is where the partys at...
477
 */
478
479
void v_matchproto_(task_func_t)
480 39
h2_do_req(struct worker *wrk, void *priv)
481
{
482
        struct req *req;
483
        struct h2_req *r2;
484
485 39
        CAST_OBJ_NOTNULL(req, priv, REQ_MAGIC);
486 39
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
487 39
        THR_SetRequest(req);
488
489 39
        req->http->conds = 1;
490 39
        if (CNT_Request(wrk, req) != REQ_FSM_DISEMBARK) {
491 35
                AZ(req->ws->r);
492 35
                r2->scheduled = 0;
493 35
                r2->state = H2_S_CLOSED;
494 35
                if (r2->h2sess->error)
495 4
                        AZ(pthread_cond_signal(r2->h2sess->cond));
496
        }
497 38
        THR_SetRequest(NULL);
498 38
}
499
500
static h2_error
501 37
h2_end_headers(struct worker *wrk, struct h2_sess *h2,
502
    struct req *req, struct h2_req *r2)
503
{
504
        h2_error h2e;
505
        const char *b;
506
507 37
        ASSERT_RXTHR(h2);
508 37
        assert(r2->state == H2_S_OPEN);
509 37
        h2e = h2h_decode_fini(h2, r2->decode);
510 37
        FREE_OBJ(r2->decode);
511 37
        r2->state = H2_S_CLOS_REM;
512 37
        h2->new_req = NULL;
513 37
        if (h2e != NULL) {
514 1
                Lck_Lock(&h2->sess->mtx);
515 1
                VSLb(h2->vsl, SLT_Debug, "HPACK/FINI %s", h2e->name);
516 1
                Lck_Unlock(&h2->sess->mtx);
517 1
                AZ(r2->req->ws->r);
518 1
                h2_del_req(wrk, r2);
519 1
                return (h2e);
520
        }
521 36
        VSLb_ts_req(req, "Req", req->t_req);
522
523
        // XXX: Smarter to do this already at HPACK time into tail end of
524
        // XXX: WS, then copy back once all headers received.
525
        // XXX: Have I mentioned H/2 Is hodge-podge ?
526 36
        http_CollectHdrSep(req->http, H_Cookie, "; ");  // rfc7540,l,3114,3120
527
528 36
        if (req->req_body_status == REQ_BODY_INIT) {
529 8
                if (!http_GetHdr(req->http, H_Content_Length, &b))
530 6
                        req->req_body_status = REQ_BODY_WITHOUT_LEN;
531
                else
532 2
                        req->req_body_status = REQ_BODY_WITH_LEN;
533
        } else {
534 28
                assert (req->req_body_status == REQ_BODY_NONE);
535 28
                if (http_GetContentLength(req->http) > 0)
536 1
                        return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840
537
        }
538
539 35
        req->req_step = R_STP_TRANSPORT;
540 35
        req->task.func = h2_do_req;
541 35
        req->task.priv = req;
542 35
        r2->scheduled = 1;
543 35
        if (Pool_Task(wrk->pool, &req->task, TASK_QUEUE_STR) != 0) {
544 1
                r2->scheduled = 0;
545 1
                return (H2SE_REFUSED_STREAM); //rfc7540,l,3326,3329
546
        }
547 34
        return (0);
548
}
549
550
static h2_error v_matchproto_(h2_frame_f)
551 46
h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
552
{
553
        struct req *req;
554
        h2_error h2e;
555
        const uint8_t *p;
556
        size_t l;
557
558 46
        ASSERT_RXTHR(h2);
559 46
        AN(r2);
560 46
        if (r2->state != H2_S_IDLE)
561 1
                return (H2CE_PROTOCOL_ERROR);   // XXX spec ?
562 45
        r2->state = H2_S_OPEN;
563
564 45
        req = r2->req;
565 45
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
566
567 45
        req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);
568 45
        VSLb(req->vsl, SLT_Begin, "req %u rxreq", VXID(req->sp->vxid));
569 45
        VSL(SLT_Link, req->sp->vxid, "req %u rxreq", VXID(req->vsl->wid));
570
571 45
        h2->new_req = req;
572 45
        req->sp = h2->sess;
573 45
        req->transport = &H2_transport;
574
575 45
        req->t_first = VTIM_real();
576 45
        req->t_req = VTIM_real();
577 45
        req->t_prev = req->t_first;
578 45
        VSLb_ts_req(req, "Start", req->t_first);
579 45
        VCL_Refresh(&wrk->vcl);
580 45
        req->vcl = wrk->vcl;
581 45
        wrk->vcl = NULL;
582 45
        req->acct.req_hdrbytes += h2->rxf_len;
583
584 45
        HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
585 45
        http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0");
586
587 45
        ALLOC_OBJ(r2->decode, H2H_DECODE_MAGIC);
588 45
        AN(r2->decode);
589 45
        h2h_decode_init(h2, r2->decode);
590
591 45
        p = h2->rxf_data;
592 45
        l = h2->rxf_len;
593 45
        if (h2->rxf_flags & H2FF_HEADERS_PADDED) {
594 4
                if (*p + 1 > l)
595 2
                        return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1884,1887
596 2
                l -= 1 + *p;
597 2
                p += 1;
598
        }
599 43
        if (h2->rxf_flags & H2FF_HEADERS_PRIORITY) {
600 2
                if (l < 5)
601 1
                        return (H2CE_PROTOCOL_ERROR);
602 1
                l -= 5;
603 1
                p += 5;
604
        }
605 42
        h2e = h2h_decode_bytes(h2, r2->decode, p, l);
606 42
        if (h2e != NULL) {
607 2
                Lck_Lock(&h2->sess->mtx);
608 2
                VSLb(h2->vsl, SLT_Debug, "HPACK(hdr) %s", h2e->name);
609 2
                Lck_Unlock(&h2->sess->mtx);
610 2
                (void)h2h_decode_fini(h2, r2->decode);
611 2
                FREE_OBJ(r2->decode);
612 2
                AZ(r2->req->ws->r);
613 2
                h2_del_req(wrk, r2);
614 2
                return (h2e);
615
        }
616
617 40
        if (h2->rxf_flags & H2FF_HEADERS_END_STREAM)
618 32
                req->req_body_status = REQ_BODY_NONE;
619
620 40
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
621 34
                return (h2_end_headers(wrk, h2, req, r2));
622 6
        return (0);
623
}
624
625
/**********************************************************************/
626
627
static h2_error v_matchproto_(h2_frame_f)
628 7
h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
629
{
630
        struct req *req;
631
        h2_error h2e;
632
633 7
        ASSERT_RXTHR(h2);
634 7
        if (r2 == NULL || r2->state != H2_S_OPEN)
635 2
                return (H2CE_PROTOCOL_ERROR);   // XXX spec ?
636 5
        req = r2->req;
637 5
        h2e = h2h_decode_bytes(h2, r2->decode, h2->rxf_data, h2->rxf_len);
638 5
        r2->req->acct.req_hdrbytes += h2->rxf_len;
639 5
        if (h2e != NULL) {
640 1
                Lck_Lock(&h2->sess->mtx);
641 1
                VSLb(h2->vsl, SLT_Debug, "HPACK(cont) %s", h2e->name);
642 1
                Lck_Unlock(&h2->sess->mtx);
643 1
                (void)h2h_decode_fini(h2, r2->decode);
644 1
                FREE_OBJ(r2->decode);
645 1
                AZ(r2->req->ws->r);
646 1
                h2_del_req(wrk, r2);
647 1
                return (h2e);
648
        }
649 4
        if (h2->rxf_flags & H2FF_HEADERS_END_HEADERS)
650 3
                return (h2_end_headers(wrk, h2, req, r2));
651 1
        return (0);
652
}
653
654
/**********************************************************************/
655
656
static h2_error v_matchproto_(h2_frame_f)
657 7
h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
658
{
659 7
        int w1 = 0, w2 = 0;
660
        char buf[4];
661
        unsigned wi;
662
663
        (void)wrk;
664 7
        ASSERT_RXTHR(h2);
665 7
        if (r2 == NULL)
666 1
                return (0);
667 6
        Lck_Lock(&h2->sess->mtx);
668 6
        AZ(h2->mailcall);
669 6
        h2->mailcall = r2;
670 6
        h2->req0->r_window -= h2->rxf_len;
671 6
        r2->r_window -= h2->rxf_len;
672
        // req_bodybytes accounted in CNT code.
673 6
        if (r2->cond)
674 2
                AZ(pthread_cond_signal(r2->cond));
675 18
        while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0)
676 6
                AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0));
677 6
        wi = cache_param->h2_rx_window_increment;
678 6
        if (h2->req0->r_window < cache_param->h2_rx_window_low_water) {
679 6
                h2->req0->r_window += wi;
680 6
                w1 = 1;
681
        }
682 6
        if (r2->r_window < cache_param->h2_rx_window_low_water) {
683 6
                r2->r_window += wi;
684 6
                w2 = 1;
685
        }
686 6
        Lck_Unlock(&h2->sess->mtx);
687
688 6
        if (w1 || w2) {
689 6
                vbe32enc(buf, wi);
690 6
                H2_Send_Get(wrk, h2, h2->req0);
691 6
                if (w1)
692 6
                        H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
693
                            4, 0, buf);
694 6
                if (w2)
695 6
                        H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
696
                            4, r2->stream, buf);
697 6
                H2_Send_Rel(h2, h2->req0);
698
        }
699 6
        return (0);
700
}
701
702
static enum vfp_status v_matchproto_(vfp_pull_f)
703 10
h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp)
704
{
705
        struct h2_req *r2;
706
        struct h2_sess *h2;
707
        unsigned l;
708 10
        enum vfp_status retval = VFP_OK;
709
710 10
        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
711 10
        CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
712 10
        CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC);
713 10
        h2 = r2->h2sess;
714
715 10
        AN(ptr);
716 10
        AN(lp);
717 10
        l = *lp;
718 10
        *lp = 0;
719
720 10
        Lck_Lock(&h2->sess->mtx);
721 10
        r2->cond = &vc->wrk->cond;
722 24
        while (h2->mailcall != r2 && h2->error == 0 && r2->error == 0)
723 4
                AZ(Lck_CondWait(r2->cond, &h2->sess->mtx, 0));
724 10
        r2->cond = NULL;
725 10
        if (h2->error || r2->error) {
726 4
                retval = VFP_ERROR;
727
        } else {
728 6
                assert(h2->mailcall == r2);
729 6
                if (l > h2->rxf_len)
730 6
                        l = h2->rxf_len;
731 6
                if (l > 0) {
732 6
                        memcpy(ptr, h2->rxf_data, l);
733 6
                        h2->rxf_data += l;
734 6
                        h2->rxf_len -= l;
735
                }
736 6
                *lp = l;
737 6
                if (h2->rxf_len == 0) {
738 6
                        if (h2->rxf_flags & H2FF_DATA_END_STREAM)
739 4
                                retval = VFP_END;
740
                }
741 6
                h2->mailcall = NULL;
742 6
                AZ(pthread_cond_signal(h2->cond));
743
        }
744 10
        Lck_Unlock(&h2->sess->mtx);
745 10
        return (retval);
746
}
747
748
static const struct vfp h2_body = {
749
        .name = "H2_BODY",
750
        .pull = h2_vfp_body,
751
};
752
753
void v_matchproto_(vtr_req_body_t)
754 8
h2_req_body(struct req *req)
755
{
756
        struct h2_req *r2;
757
        struct vfp_entry *vfe;
758
759 8
        CHECK_OBJ(req, REQ_MAGIC);
760 8
        CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
761 8
        vfe = VFP_Push(req->vfc, &h2_body);
762 8
        AN(vfe);
763 8
        vfe->priv1 = r2;
764 8
}
765
766
/**********************************************************************/
767
768
void v_matchproto_(vtr_req_fail_f)
769 1
h2_req_fail(struct req *req, enum sess_close reason)
770
{
771 1
        assert(reason > 0);
772 1
        assert(req->sp->fd != 0);
773 1
        VSLb(req->vsl, SLT_Debug, "H2FAILREQ");
774 1
}
775
776
/**********************************************************************/
777
778
static enum htc_status_e v_matchproto_(htc_complete_f)
779 450
h2_frame_complete(struct http_conn *htc)
780
{
781
        int l;
782
        unsigned u;
783
784 450
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
785 450
        l = htc->rxbuf_e - htc->rxbuf_b;
786 450
        if (l < 9)
787 231
                return (HTC_S_MORE);
788 219
        u = vbe32dec(htc->rxbuf_b) >> 8;
789 219
        if (l < u + 9)  // XXX: Only for !DATA frames
790 8
                return (HTC_S_MORE);
791 211
        return (HTC_S_COMPLETE);
792
}
793
794
/**********************************************************************/
795
796
static h2_error
797 210
h2_procframe(struct worker *wrk, struct h2_sess *h2,
798
    h2_frame h2f)
799
{
800 210
        struct h2_req *r2 = NULL, *r22;
801
        h2_error h2e;
802
        char b[4];
803
804 210
        ASSERT_RXTHR(h2);
805 210
        if (h2->rxf_stream == 0 && h2f->act_szero != 0)
806 1
                return (h2f->act_szero);
807
808 209
        if (h2->rxf_stream != 0 && h2f->act_snonzero != 0)
809 1
                return (h2f->act_snonzero);
810
811 208
        if (h2->rxf_stream > h2->highest_stream && h2f->act_sidle != 0)
812 2
                return (h2f->act_sidle);
813
814 206
        if (h2->rxf_stream != 0 && !(h2->rxf_stream & 1)) {
815
                // rfc7540,l,1140,1145
816
                // rfc7540,l,1153,1158
817
                /* No even streams, we don't do PUSH_PROMISE */
818 1
                Lck_Lock(&h2->sess->mtx);
819 1
                VSLb(h2->vsl, SLT_Debug, "H2: illegal stream (=%u)",
820
                    h2->rxf_stream);
821 1
                Lck_Unlock(&h2->sess->mtx);
822 1
                return (H2CE_PROTOCOL_ERROR);
823
        }
824
825 326
        VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
826 263
                if (r2->state == H2_S_CLOSED && !r2->scheduled)
827 13
                        h2_del_req(wrk, r2);
828 250
                else if (r2->stream == h2->rxf_stream)
829 142
                        break;
830
        }
831
832 205
        if (r2 == NULL && h2f->act_sidle == 0) {
833 58
                if (h2->rxf_stream <= h2->highest_stream)
834 1
                        return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1153,1158
835 57
                h2->highest_stream = h2->rxf_stream;
836 57
                r2 = h2_new_req(wrk, h2, h2->rxf_stream, NULL);
837 57
                AN(r2);
838
        }
839
840 204
        if (h2->new_req != NULL &&
841 7
            !(r2 && h2->new_req == r2->req && h2f == H2_F_CONTINUATION))
842 2
                return (H2CE_PROTOCOL_ERROR);   // rfc7540,l,1859,1863
843
844 202
        h2e = h2f->rxfunc(wrk, h2, r2);
845 202
        if (h2e == 0)
846 176
                return (0);
847 26
        if (h2->rxf_stream == 0 || h2e->connection)
848 22
                return (h2e);   // Connection errors one level up
849
850 4
        Lck_Lock(&h2->sess->mtx);
851 4
        VSLb(h2->vsl, SLT_Debug, "H2: stream %u: %s", h2->rxf_stream, h2e->txt);
852 4
        Lck_Unlock(&h2->sess->mtx);
853 4
        vbe32enc(b, h2e->val);
854
855 4
        H2_Send_Get(wrk, h2, h2->req0);
856 4
        (void)H2_Send_Frame(wrk, h2, H2_F_RST_STREAM,
857
            0, sizeof b, h2->rxf_stream, b);
858 4
        H2_Send_Rel(h2, h2->req0);
859
860 4
        return (0);
861
}
862
863
/***********************************************************************
864
 * Called in loop from h2_new_session()
865
 */
866
867
#define H2_FRAME(l,U,...) const struct h2_frame_s H2_F_##U[1] = \
868
    {{ #U, h2_rx_##l, __VA_ARGS__ }};
869
#include "tbl/h2_frames.h"
870
871
static const h2_frame h2flist[] = {
872
#define H2_FRAME(l,U,t,...) [t] = H2_F_##U,
873
#include "tbl/h2_frames.h"
874
};
875
876
#define H2FMAX (sizeof(h2flist) / sizeof(h2flist[0]))
877
878
int
879 235
h2_rxframe(struct worker *wrk, struct h2_sess *h2)
880
{
881
        enum htc_status_e hs;
882
        h2_frame h2f;
883
        h2_error h2e;
884
        int again;
885
        struct h2_req *r2, *r22;
886
        char b[8];
887
888 235
        ASSERT_RXTHR(h2);
889 235
        (void)VTCP_blocking(*h2->htc->rfd);
890
        while (1) {
891 235
                h2->sess->t_idle = VTIM_real();
892 235
                hs = HTC_RxStuff(h2->htc, h2_frame_complete,
893
                    NULL, NULL, NAN,
894 235
                    h2->sess->t_idle + cache_param->timeout_idle,
895
                    16384 + 9);         // rfc7540,l,4228,4228
896 234
                if (hs == HTC_S_COMPLETE)
897 211
                        break;
898 23
                else if (hs == HTC_S_TIMEOUT) {
899 0
                        again = 0;
900 0
                        VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
901 0
                                switch (r2->state) {
902
                                case H2_S_CLOSED:
903 0
                                        if (!r2->scheduled)
904 0
                                                h2_del_req(wrk, r2);
905 0
                                        break;
906
                                case H2_S_OPEN:
907
                                case H2_S_CLOS_REM:
908
                                case H2_S_CLOS_LOC:
909 0
                                        again = 1;
910 0
                                        break;
911
                                default:
912 0
                                        break;
913
                                }
914
                        }
915 0
                        if (again)
916 0
                                continue;
917
                }
918 23
                Lck_Lock(&h2->sess->mtx);
919 23
                VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
920 23
                h2->error = H2CE_NO_ERROR;
921 23
                Lck_Unlock(&h2->sess->mtx);
922 23
                return (0);
923 0
        }
924
925 211
        h2->rxf_len =  vbe32dec(h2->htc->rxbuf_b) >> 8;
926 211
        h2->rxf_type =  h2->htc->rxbuf_b[3];
927 211
        h2->rxf_flags = h2->htc->rxbuf_b[4];
928 211
        h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5);
929 211
        h2->rxf_stream &= ~(1LU<<31);                   // rfc7540,l,690,692
930 211
        h2->rxf_data = (void*)(h2->htc->rxbuf_b + 9);
931
        /* XXX: later full DATA will not be rx'ed yet. */
932 211
        HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
933
934 211
        h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
935 211
        h2->srq->acct.req_hdrbytes += 9;
936
937 211
        if (h2->rxf_type >= H2FMAX) {
938
                // rfc7540,l,679,681
939
                // XXX: later, drain rest of frame
940 1
                h2->bogosity++;
941 1
                Lck_Lock(&h2->sess->mtx);
942 1
                VSLb(h2->vsl, SLT_Debug,
943
                    "H2: Unknown frame type 0x%02x (ignored)",
944 1
                    (uint8_t)h2->rxf_type);
945 1
                Lck_Unlock(&h2->sess->mtx);
946 1
                h2->srq->acct.req_bodybytes += h2->rxf_len;
947 1
                return (1);
948
        }
949 210
        h2f = h2flist[h2->rxf_type];
950
951 210
        AN(h2f->name);
952 210
        AN(h2f->rxfunc);
953 210
        if (h2f->overhead)
954 148
                h2->srq->acct.req_bodybytes += h2->rxf_len;
955
956 210
        if (h2->rxf_flags & ~h2f->flags) {
957
                // rfc7540,l,687,688
958 2
                h2->bogosity++;
959 2
                Lck_Lock(&h2->sess->mtx);
960 6
                VSLb(h2->vsl, SLT_Debug,
961
                    "H2: Unknown flags 0x%02x on %s (ignored)",
962 4
                    (uint8_t)h2->rxf_flags & ~h2f->flags, h2f->name);
963 2
                Lck_Unlock(&h2->sess->mtx);
964 2
                h2->rxf_flags &= h2f->flags;
965
        }
966
967 210
        h2e = h2_procframe(wrk, h2, h2f);
968 210
        if (h2->error == 0 && h2e) {
969 27
                h2->error = h2e;
970 27
                vbe32enc(b, h2->highest_stream);
971 27
                vbe32enc(b + 4, h2e->val);
972 27
                H2_Send_Get(wrk, h2, h2->req0);
973 27
                (void)H2_Send_Frame(wrk, h2, H2_F_GOAWAY, 0, 8, 0, b);
974 27
                H2_Send_Rel(h2, h2->req0);
975
        }
976 210
        return (h2e ? 0 : 1);
977
}