Coverage Report

Created: 2025-08-26 06:35

/src/h2o/lib/http2/connection.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2014-2016 DeNA Co., Ltd., Kazuho Oku, Fastly, Inc.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
#include <inttypes.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include "h2o.h"
26
#include "h2o/hpack.h"
27
#include "h2o/http1.h"
28
#include "h2o/http2.h"
29
#include "h2o/http2_internal.h"
30
#include "h2o/absprio.h"
31
#include "../probes_.h"
32
33
static const h2o_iovec_t CONNECTION_PREFACE = {H2O_STRLIT("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")};
34
35
h2o_buffer_prototype_t h2o_http2_wbuf_buffer_prototype = {{H2O_HTTP2_DEFAULT_OUTBUF_SIZE}};
36
37
static void update_stream_input_window(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, size_t bytes);
38
static void proceed_request(h2o_req_t *req, const char *errstr);
39
static void initiate_graceful_shutdown(h2o_conn_t *_conn);
40
static void close_connection_now(h2o_http2_conn_t *conn);
41
static int close_connection(h2o_http2_conn_t *conn);
42
static ssize_t expect_default(h2o_http2_conn_t *conn, const uint8_t *src, size_t len, const char **err_desc);
43
static void do_emit_writereq(h2o_http2_conn_t *conn);
44
static void on_read(h2o_socket_t *sock, const char *err);
45
static void push_path(h2o_req_t *src_req, const char *abspath, size_t abspath_len, int is_critical);
46
static int foreach_request(h2o_conn_t *_conn, int (*cb)(h2o_req_t *req, void *cbdata), void *cbdata);
47
static void stream_send_error(h2o_http2_conn_t *conn, uint32_t stream_id, int errnum);
48
49
static int is_idle_stream_id(h2o_http2_conn_t *conn, uint32_t stream_id)
50
5.20k
{
51
5.20k
    return (h2o_http2_stream_is_push(stream_id) ? conn->push_stream_ids.max_open : conn->pull_stream_ids.max_open) < stream_id;
52
5.20k
}
53
54
static void enqueue_goaway(h2o_http2_conn_t *conn, int errnum, h2o_iovec_t additional_data)
55
6.43k
{
56
6.43k
    if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING) {
57
        /* http2 spec allows sending GOAWAY more than once (for one reason since errors may arise after sending the first one) */
58
6.43k
        h2o_http2_encode_goaway_frame(&conn->_write.buf, conn->pull_stream_ids.max_open, errnum, additional_data);
59
6.43k
        h2o_http2_conn_request_write(conn);
60
6.43k
        conn->state = H2O_HTTP2_CONN_STATE_HALF_CLOSED;
61
6.43k
    }
62
6.43k
}
63
64
static void enqueue_server_preface(h2o_http2_conn_t *conn)
65
11.9k
{
66
    /* Send settings and initial window update */
67
11.9k
    h2o_http2_settings_kvpair_t settings[] = {
68
11.9k
        {H2O_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, conn->super.ctx->globalconf->http2.max_streams},
69
11.9k
        {H2O_HTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL, 1}};
70
11.9k
    h2o_http2_encode_settings_frame(&conn->_write.buf, settings, PTLS_ELEMENTSOF(settings));
71
11.9k
    h2o_http2_encode_window_update_frame(
72
11.9k
        &conn->_write.buf, 0, H2O_HTTP2_SETTINGS_HOST_CONNECTION_WINDOW_SIZE - H2O_HTTP2_SETTINGS_HOST_STREAM_INITIAL_WINDOW_SIZE);
73
11.9k
}
74
75
static void graceful_shutdown_close_straggler(h2o_timer_t *entry)
76
0
{
77
0
    h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, _graceful_shutdown_timeout, entry);
78
    /* We've sent two GOAWAY frames, close the remaining connections */
79
0
    close_connection(conn);
80
0
}
81
82
static void graceful_shutdown_resend_goaway(h2o_timer_t *entry)
83
0
{
84
0
    h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, _graceful_shutdown_timeout, entry);
85
86
0
    if (conn->state < H2O_HTTP2_CONN_STATE_HALF_CLOSED) {
87
0
        enqueue_goaway(conn, H2O_HTTP2_ERROR_NONE, (h2o_iovec_t){NULL});
88
89
        /* After waiting a second, we still have an active connection. If configured, wait one
90
         * final timeout before closing the connection */
91
0
        if (conn->super.ctx->globalconf->http2.graceful_shutdown_timeout > 0) {
92
0
            conn->_graceful_shutdown_timeout.cb = graceful_shutdown_close_straggler;
93
0
            h2o_timer_link(conn->super.ctx->loop, conn->super.ctx->globalconf->http2.graceful_shutdown_timeout,
94
0
                           &conn->_graceful_shutdown_timeout);
95
0
        }
96
0
    }
97
0
}
98
99
static void close_idle_connection(h2o_conn_t *_conn)
100
0
{
101
0
    initiate_graceful_shutdown(_conn);
102
0
}
103
104
static void initiate_graceful_shutdown(h2o_conn_t *_conn)
105
0
{
106
0
    h2o_conn_set_state(_conn, H2O_CONN_STATE_SHUTDOWN);
107
108
    /* draft-16 6.8
109
     * A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last stream
110
     * identifier set to 231-1 and a NO_ERROR code. This signals to the client that a shutdown is imminent and that no further
111
     * requests can be initiated. After waiting at least one round trip time, the server can send another GOAWAY frame with an
112
     * updated last stream identifier. This ensures that a connection can be cleanly shut down without losing requests.
113
     */
114
115
0
    h2o_http2_conn_t *conn = (void *)_conn;
116
0
    assert(conn->_graceful_shutdown_timeout.cb == NULL);
117
0
    conn->_graceful_shutdown_timeout.cb = graceful_shutdown_resend_goaway;
118
119
0
    if (conn->state < H2O_HTTP2_CONN_STATE_HALF_CLOSED) {
120
0
        h2o_http2_encode_goaway_frame(&conn->_write.buf, INT32_MAX, H2O_HTTP2_ERROR_NONE,
121
0
                                      (h2o_iovec_t){H2O_STRLIT("graceful shutdown")});
122
0
        h2o_http2_conn_request_write(conn);
123
0
    }
124
125
0
    h2o_timer_link(conn->super.ctx->loop, 1000, &conn->_graceful_shutdown_timeout);
126
0
}
127
128
static void on_idle_timeout(h2o_timer_t *entry)
129
0
{
130
0
    h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, _timeout_entry, entry);
131
0
    conn->super.ctx->http2.events.idle_timeouts++;
132
133
0
    if (conn->_write.buf_in_flight != NULL) {
134
0
        close_connection_now(conn);
135
0
    } else {
136
0
        enqueue_goaway(conn, H2O_HTTP2_ERROR_NONE, h2o_iovec_init(H2O_STRLIT("idle timeout")));
137
0
        close_connection(conn);
138
0
    }
139
0
}
140
141
static void update_idle_timeout(h2o_http2_conn_t *conn)
142
74.6k
{
143
    /* do nothing touch anything if write is in progress */
144
74.6k
    if (conn->_write.buf_in_flight != NULL) {
145
16
        assert(h2o_timer_is_linked(&conn->_timeout_entry));
146
16
        return;
147
16
    }
148
149
74.6k
    h2o_timer_unlink(&conn->_timeout_entry);
150
151
    /* always set idle timeout if TLS handshake is in progress */
152
74.6k
    if (conn->sock->ssl != NULL && h2o_socket_ssl_is_early_data(conn->sock))
153
0
        goto SetTimeout;
154
155
    /* no need to set timeout if pending requests exist */
156
74.6k
    if (conn->num_streams.blocked_by_server != 0)
157
6.36k
        return;
158
159
68.2k
SetTimeout:
160
68.2k
    conn->_timeout_entry.cb = on_idle_timeout;
161
68.2k
    h2o_timer_link(conn->super.ctx->loop, conn->super.ctx->globalconf->http2.idle_timeout, &conn->_timeout_entry);
162
68.2k
}
163
164
static int can_run_requests(h2o_http2_conn_t *conn)
165
6.62k
{
166
6.62k
    return conn->num_streams.pull.half_closed + conn->num_streams.push.half_closed <
167
6.62k
           conn->super.ctx->globalconf->http2.max_concurrent_requests_per_connection;
168
6.62k
}
169
170
static void process_request(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
171
5.92k
{
172
5.92k
    if (stream->req.proceed_req != NULL) {
173
470
        assert(
174
470
            !(stream->req_body.state == H2O_HTTP2_REQ_BODY_NONE || stream->req_body.state == H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED));
175
470
        conn->num_streams._req_streaming_in_progress++;
176
470
        conn->super.ctx->http2.events.streaming_requests++;
177
470
        stream->req_body.streamed = 1;
178
470
        if (stream->req.is_tunnel_req)
179
19
            conn->num_streams.tunnel++;
180
470
        update_stream_input_window(conn, stream,
181
470
                                   conn->super.ctx->globalconf->http2.active_stream_window_size -
182
470
                                       H2O_HTTP2_SETTINGS_HOST_STREAM_INITIAL_WINDOW_SIZE);
183
5.45k
    } else {
184
5.45k
        if (stream->state < H2O_HTTP2_STREAM_STATE_SEND_HEADERS) {
185
5.45k
            h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_REQ_PENDING);
186
5.45k
            h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_SEND_HEADERS);
187
5.45k
        }
188
5.45k
    }
189
190
5.92k
    if (!h2o_http2_stream_is_push(stream->stream_id) && conn->pull_stream_ids.max_processed < stream->stream_id)
191
5.79k
        conn->pull_stream_ids.max_processed = stream->stream_id;
192
193
5.92k
    h2o_process_request(&stream->req);
194
5.92k
}
195
196
static void run_pending_requests(h2o_http2_conn_t *conn)
197
31.5k
{
198
31.5k
    if (h2o_timer_is_linked(&conn->dos_mitigation.process_delay))
199
3.19k
        return;
200
201
28.3k
    h2o_linklist_t *link, *lnext;
202
28.3k
    int ran_one_request;
203
204
28.3k
    do {
205
28.3k
        ran_one_request = 0;
206
207
34.9k
        for (link = conn->_pending_reqs.next; link != &conn->_pending_reqs && can_run_requests(conn); link = lnext) {
208
            /* fetch and detach a pending stream */
209
6.62k
            h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _link, link);
210
211
6.62k
            lnext = link->next;
212
213
            /* handle no more than specified number of streaming requests at a time */
214
6.62k
            if (stream->req.proceed_req != NULL &&
215
6.62k
                conn->num_streams._req_streaming_in_progress - conn->num_streams.tunnel >=
216
1.16k
                    conn->super.ctx->globalconf->http2.max_concurrent_streaming_requests_per_connection)
217
716
                continue;
218
219
            /* handle it */
220
5.90k
            h2o_linklist_unlink(&stream->_link);
221
5.90k
            ran_one_request = 1;
222
5.90k
            process_request(conn, stream);
223
5.90k
        }
224
225
28.3k
    } while (ran_one_request && !h2o_linklist_is_empty(&conn->_pending_reqs));
226
28.3k
}
227
228
static int reset_stream_if_disregarded(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
229
8.35k
{
230
8.35k
    if (!h2o_http2_stream_is_push(stream->stream_id) && stream->stream_id > conn->pull_stream_ids.max_open) {
231
        /* this stream is opened after sending GOAWAY, so ignore it */
232
0
        h2o_http2_stream_reset(conn, stream);
233
0
        return 1;
234
0
    }
235
8.35k
    return 0;
236
8.35k
}
237
238
static void execute_or_enqueue_request_core(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
239
5.96k
{
240
    /* TODO schedule the pending reqs using the scheduler */
241
5.96k
    h2o_linklist_insert(&conn->_pending_reqs, &stream->_link);
242
243
5.96k
    run_pending_requests(conn);
244
5.96k
    update_idle_timeout(conn);
245
5.96k
}
246
247
static void execute_or_enqueue_request(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
248
5.45k
{
249
5.45k
    assert(stream->state == H2O_HTTP2_STREAM_STATE_RECV_HEADERS || stream->state == H2O_HTTP2_STREAM_STATE_REQ_PENDING);
250
251
5.45k
    if (reset_stream_if_disregarded(conn, stream))
252
0
        return;
253
254
5.45k
    h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_REQ_PENDING);
255
5.45k
    if (!stream->blocked_by_server)
256
5.28k
        h2o_http2_stream_set_blocked_by_server(conn, stream, 1);
257
5.45k
    execute_or_enqueue_request_core(conn, stream);
258
5.45k
}
259
260
void h2o_http2_conn_register_stream(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
261
44.7k
{
262
44.7k
    khiter_t iter;
263
44.7k
    int r;
264
265
44.7k
    iter = kh_put(h2o_http2_stream_t, conn->streams, stream->stream_id, &r);
266
44.7k
    assert(iter != kh_end(conn->streams));
267
44.7k
    kh_val(conn->streams, iter) = stream;
268
44.7k
}
269
270
void h2o_http2_conn_preserve_stream_scheduler(h2o_http2_conn_t *conn, h2o_http2_stream_t *src)
271
44.7k
{
272
44.7k
    assert(h2o_http2_scheduler_is_open(&src->_scheduler));
273
274
44.7k
    h2o_http2_stream_t **dst = conn->_recently_closed_streams.streams + conn->_recently_closed_streams.next_slot;
275
44.7k
    if (++conn->_recently_closed_streams.next_slot == HTTP2_CLOSED_STREAM_PRIORITIES)
276
2.40k
        conn->_recently_closed_streams.next_slot = 0;
277
278
44.7k
    if (*dst != NULL) {
279
18.3k
        assert(h2o_http2_scheduler_is_open(&(*dst)->_scheduler));
280
18.3k
        h2o_http2_scheduler_close(&(*dst)->_scheduler);
281
26.4k
    } else {
282
26.4k
        *dst = h2o_mem_alloc(offsetof(h2o_http2_stream_t, _scheduler) + sizeof((*dst)->_scheduler));
283
26.4k
    }
284
285
44.7k
    (*dst)->stream_id = src->stream_id;
286
44.7k
    h2o_http2_scheduler_relocate(&(*dst)->_scheduler, &src->_scheduler);
287
44.7k
    h2o_http2_scheduler_deactivate(&(*dst)->_scheduler);
288
44.7k
}
289
290
static void set_req_body_state(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, enum en_h2o_req_body_state_t new_state)
291
3.37k
{
292
3.37k
    assert(stream->req_body.state < new_state); /* use `<` instead of `<=` as we think we only use the function that way, and
293
                                                 * setting CLOSE_DELIVERED twice causes unnecessary decrements */
294
3.37k
    switch (new_state) {
295
0
    case H2O_HTTP2_REQ_BODY_NONE:
296
0
        h2o_fatal("invalid state");
297
0
        break;
298
1.18k
    case H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED:
299
1.18k
        assert(stream->req.proceed_req == NULL);
300
1.18k
        if (stream->req_body.streamed) {
301
470
            conn->num_streams._req_streaming_in_progress--;
302
470
            if (stream->req.is_tunnel_req)
303
19
                conn->num_streams.tunnel--;
304
470
        }
305
1.18k
        break;
306
2.19k
    default:
307
2.19k
        break;
308
3.37k
    }
309
3.37k
    stream->req_body.state = new_state;
310
3.37k
}
311
312
void h2o_http2_conn_unregister_stream(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
313
44.7k
{
314
44.7k
    h2o_http2_conn_preserve_stream_scheduler(conn, stream);
315
316
44.7k
    khiter_t iter = kh_get(h2o_http2_stream_t, conn->streams, stream->stream_id);
317
44.7k
    assert(iter != kh_end(conn->streams));
318
44.7k
    kh_del(h2o_http2_stream_t, conn->streams, iter);
319
320
44.7k
    if (stream->req_body.state != H2O_HTTP2_REQ_BODY_NONE && stream->req_body.state < H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED) {
321
845
        stream->req.proceed_req = NULL;
322
845
        set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED);
323
845
    }
324
325
44.7k
    if (stream->blocked_by_server)
326
566
        h2o_http2_stream_set_blocked_by_server(conn, stream, 0);
327
328
    /* Decrement reset_budget if the stream was reset by peer or by peer's invalid action, otherwise increment. By doing so, we
329
     * penalize connections that generate resets for >50% of requests. */
330
44.7k
    if (stream->reset_by_peer || stream->reset_by_peer_action) {
331
20.6k
        if (conn->dos_mitigation.reset_budget > 0)
332
17.5k
            --conn->dos_mitigation.reset_budget;
333
334
        /* setup process delay if we've just ran out of reset budget */
335
20.6k
        if (conn->dos_mitigation.reset_budget == 0 && conn->super.ctx->globalconf->http2.dos_delay != 0 &&
336
20.6k
            !h2o_timer_is_linked(&conn->dos_mitigation.process_delay))
337
66
            h2o_timer_link(conn->super.ctx->loop, conn->super.ctx->globalconf->http2.dos_delay, &conn->dos_mitigation.process_delay);
338
339
24.1k
    } else {
340
24.1k
        if (conn->dos_mitigation.reset_budget < conn->super.ctx->globalconf->http2.max_concurrent_requests_per_connection)
341
3.45k
            ++conn->dos_mitigation.reset_budget;
342
24.1k
    }
343
344
44.7k
    switch (stream->state) {
345
640
    case H2O_HTTP2_STREAM_STATE_RECV_BODY:
346
640
        if (h2o_linklist_is_linked(&stream->_link))
347
53
            h2o_linklist_unlink(&stream->_link);
348
    /* fallthru */
349
26.8k
    case H2O_HTTP2_STREAM_STATE_IDLE:
350
35.7k
    case H2O_HTTP2_STREAM_STATE_RECV_HEADERS:
351
35.7k
        assert(!h2o_linklist_is_linked(&stream->_link));
352
35.7k
        break;
353
35.7k
    case H2O_HTTP2_STREAM_STATE_REQ_PENDING:
354
8
        assert(h2o_linklist_is_linked(&stream->_link));
355
8
        h2o_linklist_unlink(&stream->_link);
356
8
        break;
357
252
    case H2O_HTTP2_STREAM_STATE_SEND_HEADERS:
358
339
    case H2O_HTTP2_STREAM_STATE_SEND_BODY:
359
4.01k
    case H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL:
360
9.05k
    case H2O_HTTP2_STREAM_STATE_END_STREAM:
361
9.05k
        if (h2o_linklist_is_linked(&stream->_link))
362
23
            h2o_linklist_unlink(&stream->_link);
363
9.05k
        break;
364
44.7k
    }
365
44.7k
    if (stream->state != H2O_HTTP2_STREAM_STATE_END_STREAM)
366
39.7k
        h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_END_STREAM);
367
368
44.7k
    if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING) {
369
25.5k
        run_pending_requests(conn);
370
25.5k
        update_idle_timeout(conn);
371
25.5k
    }
372
44.7k
}
373
374
void close_connection_now(h2o_http2_conn_t *conn)
375
12.1k
{
376
    /* mark as is_closing here to prevent sending any more frames */
377
12.1k
    conn->state = H2O_HTTP2_CONN_STATE_IS_CLOSING;
378
379
12.1k
    h2o_http2_stream_t *stream;
380
381
12.1k
    assert(!h2o_timer_is_linked(&conn->_write.timeout_entry));
382
383
12.1k
    kh_foreach_value(conn->streams, stream, { h2o_http2_stream_close(conn, stream); });
384
385
12.1k
    assert(conn->num_streams.pull.open == 0);
386
12.1k
    assert(conn->num_streams.pull.half_closed == 0);
387
12.1k
    assert(conn->num_streams.pull.send_body == 0);
388
12.1k
    assert(conn->num_streams.push.half_closed == 0);
389
12.1k
    assert(conn->num_streams.push.send_body == 0);
390
12.1k
    assert(conn->num_streams.priority.open == 0);
391
12.1k
    assert(conn->num_streams.blocked_by_server == 0);
392
12.1k
    assert(conn->num_streams._req_streaming_in_progress == 0);
393
12.1k
    assert(conn->num_streams.tunnel == 0);
394
12.1k
    kh_destroy(h2o_http2_stream_t, conn->streams);
395
12.1k
    assert(conn->_http1_req_input == NULL);
396
12.1k
    h2o_hpack_dispose_header_table(&conn->_input_header_table);
397
12.1k
    h2o_hpack_dispose_header_table(&conn->_output_header_table);
398
12.1k
    assert(h2o_linklist_is_empty(&conn->_pending_reqs));
399
12.1k
    h2o_timer_unlink(&conn->_timeout_entry);
400
401
12.1k
    if (h2o_timer_is_linked(&conn->_graceful_shutdown_timeout))
402
0
        h2o_timer_unlink(&conn->_graceful_shutdown_timeout);
403
404
12.1k
    if (h2o_timer_is_linked(&conn->dos_mitigation.process_delay))
405
64
        h2o_timer_unlink(&conn->dos_mitigation.process_delay);
406
407
12.1k
    h2o_buffer_dispose(&conn->_write.buf);
408
12.1k
    if (conn->_write.buf_in_flight != NULL)
409
7
        h2o_buffer_dispose(&conn->_write.buf_in_flight);
410
12.1k
    {
411
12.1k
        size_t i;
412
38.5k
        for (i = 0; i < sizeof(conn->_recently_closed_streams.streams) / sizeof(conn->_recently_closed_streams.streams[0]); ++i) {
413
37.6k
            h2o_http2_stream_t *closed_stream = conn->_recently_closed_streams.streams[i];
414
37.6k
            if (closed_stream == NULL)
415
11.2k
                break;
416
26.4k
            assert(h2o_http2_scheduler_is_open(&closed_stream->_scheduler));
417
26.4k
            h2o_http2_scheduler_close(&closed_stream->_scheduler);
418
26.4k
            free(closed_stream);
419
26.4k
        }
420
12.1k
    }
421
12.1k
    h2o_http2_scheduler_dispose(&conn->scheduler);
422
12.1k
    assert(h2o_linklist_is_empty(&conn->_write.streams_to_proceed));
423
12.1k
    assert(!h2o_timer_is_linked(&conn->_write.timeout_entry));
424
12.1k
    if (conn->_headers_unparsed != NULL)
425
294
        h2o_buffer_dispose(&conn->_headers_unparsed);
426
12.1k
    if (conn->push_memo != NULL)
427
0
        h2o_cache_destroy(conn->push_memo);
428
12.1k
    if (conn->casper != NULL)
429
0
        h2o_http2_casper_destroy(conn->casper);
430
431
12.1k
    if (conn->sock != NULL)
432
12.1k
        h2o_socket_close(conn->sock);
433
434
12.1k
    h2o_destroy_connection(&conn->super);
435
12.1k
}
436
437
int close_connection(h2o_http2_conn_t *conn)
438
25.0k
{
439
25.0k
    conn->state = H2O_HTTP2_CONN_STATE_IS_CLOSING;
440
441
25.0k
    if (conn->_write.buf_in_flight != NULL || h2o_timer_is_linked(&conn->_write.timeout_entry)) {
442
        /* there is a pending write, let on_write_complete actually close the connection */
443
12.9k
    } else {
444
12.1k
        close_connection_now(conn);
445
12.1k
        return -1;
446
12.1k
    }
447
12.9k
    return 0;
448
25.0k
}
449
450
static void stream_send_error(h2o_http2_conn_t *conn, uint32_t stream_id, int errnum)
451
25.5k
{
452
25.5k
    assert(stream_id != 0);
453
25.5k
    assert(conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING);
454
455
25.5k
    conn->super.ctx->http2.events.protocol_level_errors[-errnum]++;
456
457
25.5k
    h2o_http2_encode_rst_stream_frame(&conn->_write.buf, stream_id, -errnum);
458
25.5k
    h2o_http2_conn_request_write(conn);
459
25.5k
}
460
461
static void request_gathered_write(h2o_http2_conn_t *conn)
462
82.1k
{
463
82.1k
    assert(conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING);
464
82.1k
    if (!h2o_socket_is_writing(conn->sock) && !h2o_timer_is_linked(&conn->_write.timeout_entry)) {
465
15.1k
        h2o_timer_link(conn->super.ctx->loop, 0, &conn->_write.timeout_entry);
466
15.1k
    }
467
82.1k
}
468
469
static int update_stream_output_window(h2o_http2_stream_t *stream, ssize_t delta)
470
10.8k
{
471
10.8k
    ssize_t cur = h2o_http2_window_get_avail(&stream->output_window);
472
10.8k
    if (h2o_http2_window_update(&stream->output_window, delta) != 0)
473
903
        return -1;
474
9.94k
    if (cur <= 0 && h2o_http2_window_get_avail(&stream->output_window) > 0 &&
475
9.94k
        (h2o_http2_stream_has_pending_data(stream) || stream->state == H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL)) {
476
1.11k
        assert(!h2o_linklist_is_linked(&stream->_link));
477
1.11k
        h2o_http2_scheduler_activate(&stream->_scheduler);
478
1.11k
    }
479
9.94k
    return 0;
480
9.94k
}
481
482
static void write_streaming_body(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
483
246
{
484
246
    int is_end_stream = 0;
485
486
246
    assert(stream->req.entity.base == NULL);
487
488
    /* check state as well as update */
489
246
    switch (stream->req_body.state) {
490
0
    case H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME:
491
161
    case H2O_HTTP2_REQ_BODY_OPEN:
492
161
        assert(stream->req_body.buf->size != 0);
493
161
        break;
494
161
    case H2O_HTTP2_REQ_BODY_CLOSE_QUEUED:
495
85
        stream->req.proceed_req = NULL;
496
85
        set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED);
497
85
        is_end_stream = 1;
498
85
        break;
499
0
    default:
500
0
        h2o_fatal("unexpected req_body.state");
501
0
        break;
502
246
    }
503
504
    /* invoke write_req */
505
246
    stream->req.entity = h2o_iovec_init(stream->req_body.buf->bytes, stream->req_body.buf->size);
506
246
    if (stream->req.write_req.cb(stream->req.write_req.ctx, is_end_stream) != 0) {
507
0
        stream_send_error(conn, stream->stream_id, H2O_HTTP2_ERROR_STREAM_CLOSED);
508
0
        h2o_http2_stream_reset(conn, stream);
509
0
        return;
510
0
    }
511
512
    /* close the H2 stream if both sides are done */
513
246
    if (stream->req_body.state == H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED && stream->state == H2O_HTTP2_STREAM_STATE_END_STREAM)
514
13
        h2o_http2_stream_close(conn, stream);
515
246
}
516
517
static void handle_request_body_chunk(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, h2o_iovec_t payload, int is_end_stream)
518
2.96k
{
519
2.96k
    int is_first = 0;
520
521
2.96k
    switch (stream->req_body.state) {
522
919
    case H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME:
523
919
        is_first = 1;
524
919
        set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_OPEN);
525
919
        break;
526
2.04k
    case H2O_HTTP2_REQ_BODY_OPEN:
527
2.04k
        break;
528
0
    default:
529
0
        h2o_fatal("unexpected req_body.state");
530
0
        break;
531
2.96k
    }
532
533
2.96k
    stream->req.req_body_bytes_received += payload.len;
534
535
    /* check size */
536
2.96k
    if (stream->req.req_body_bytes_received > conn->super.ctx->globalconf->max_request_entity_size) {
537
0
        stream_send_error(conn, stream->stream_id, H2O_HTTP2_ERROR_REFUSED_STREAM);
538
0
        h2o_http2_stream_reset(conn, stream);
539
0
        return;
540
0
    }
541
2.96k
    if (stream->req.content_length != SIZE_MAX) {
542
434
        size_t received = stream->req.req_body_bytes_received, cl = stream->req.content_length;
543
434
        if (is_end_stream ? (received != cl) : (received > cl)) {
544
58
            stream_send_error(conn, stream->stream_id, H2O_HTTP2_ERROR_PROTOCOL);
545
58
            h2o_http2_stream_reset(conn, stream);
546
58
            return;
547
58
        }
548
434
    }
549
550
    /* update timer */
551
2.90k
    if (!stream->blocked_by_server)
552
1.08k
        h2o_http2_stream_set_blocked_by_server(conn, stream, 1);
553
554
    /* just reset the stream if the request is to be disregarded */
555
2.90k
    if (reset_stream_if_disregarded(conn, stream))
556
0
        return;
557
558
    /* update state, buffer the data */
559
2.90k
    int req_queued = stream->req.proceed_req != NULL;
560
2.90k
    if (is_end_stream) {
561
288
        if (stream->state < H2O_HTTP2_STREAM_STATE_REQ_PENDING) {
562
259
            h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_REQ_PENDING);
563
259
            if (stream->req.process_called)
564
77
                h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_SEND_HEADERS);
565
259
        }
566
288
        if (stream->req.write_req.cb != NULL) {
567
91
            set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_CLOSE_QUEUED);
568
197
        } else {
569
197
            stream->req.proceed_req = NULL;
570
197
            set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED);
571
197
        }
572
288
    }
573
2.90k
    h2o_buffer_append(&stream->req_body.buf, payload.base, payload.len);
574
575
    /* if in request streaming mode: either submit the chunk or just keep it, and return */
576
2.90k
    if (stream->req_body.streamed) {
577
1.17k
        if (stream->req.write_req.cb != NULL) {
578
766
            if (stream->req.entity.base == NULL)
579
221
                write_streaming_body(conn, stream);
580
766
        } else {
581
404
            stream->req.entity = h2o_iovec_init(stream->req_body.buf->bytes, stream->req_body.buf->size);
582
404
        }
583
1.17k
        return;
584
1.17k
    }
585
586
    /* not (yet) in streaming mode */
587
1.73k
    stream->req.entity = h2o_iovec_init(stream->req_body.buf->bytes, stream->req_body.buf->size);
588
589
    /* when receiving first DATA frame... */
590
1.73k
    if (is_first && !is_end_stream) {
591
        /* trigger request streaming mode if possible */
592
726
        if (h2o_req_can_stream_request(&stream->req)) {
593
515
            stream->req.proceed_req = proceed_request;
594
515
            execute_or_enqueue_request_core(conn, stream);
595
515
            return;
596
515
        }
597
        /* or, run in non-streaming mode (TODO elect input streams one by one for non-streaming case as well?) */
598
211
        update_stream_input_window(conn, stream,
599
211
                                   conn->super.ctx->globalconf->http2.active_stream_window_size -
600
211
                                       H2O_HTTP2_SETTINGS_HOST_STREAM_INITIAL_WINDOW_SIZE);
601
211
    }
602
603
    /* run or queue the request when all input is available (and if the request has not been queued for streaming processing) */
604
1.21k
    if (is_end_stream && !req_queued)
605
171
        execute_or_enqueue_request(conn, stream);
606
1.21k
}
607
608
static int send_invalid_request_error(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, const char *err_desc)
609
2.88k
{
610
    /* fast forward the stream's state so that we can start sending the response */
611
2.88k
    h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_REQ_PENDING);
612
2.88k
    h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_SEND_HEADERS);
613
2.88k
    h2o_send_error_400(&stream->req, "Invalid Request", err_desc, 0);
614
2.88k
    return 0;
615
2.88k
}
616
617
static int handle_incoming_request(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, const uint8_t *src, size_t len,
618
                                   const char **err_desc)
619
18.1k
{
620
18.1k
    int ret, header_exists_map = 0;
621
18.1k
    h2o_iovec_t expect = h2o_iovec_init(NULL, 0);
622
623
18.1k
    assert(stream->state == H2O_HTTP2_STREAM_STATE_RECV_HEADERS);
624
625
18.1k
    if ((ret = h2o_hpack_parse_request(&stream->req.pool, h2o_hpack_decode_header, &conn->_input_header_table,
626
18.1k
                                       &stream->req.input.method, &stream->req.input.scheme, &stream->req.input.authority,
627
18.1k
                                       &stream->req.input.path, &stream->req.upgrade, &stream->req.headers, &header_exists_map,
628
18.1k
                                       &stream->req.content_length, &expect, &stream->cache_digests, NULL, src, len, err_desc)) !=
629
18.1k
        0) {
630
        /* all errors except invalid-header-char are connection errors */
631
7.38k
        if (ret != H2O_HTTP2_ERROR_INVALID_HEADER_CHAR)
632
4.12k
            return ret;
633
7.38k
    }
634
635
14.0k
    h2o_probe_log_request(&stream->req, stream->stream_id);
636
637
    /* fixup the scheme so that it would never be a NULL pointer (note: checks below are done using `header_exists_map`) */
638
14.0k
    if (stream->req.input.scheme == NULL)
639
4.40k
        stream->req.input.scheme = conn->sock->ssl != NULL ? &H2O_URL_SCHEME_HTTPS : &H2O_URL_SCHEME_HTTP;
640
641
14.0k
    int is_connect, must_exist_map, may_exist_map;
642
14.0k
    if (h2o_memis(stream->req.input.method.base, stream->req.input.method.len, H2O_STRLIT("CONNECT"))) {
643
23
        is_connect = 1;
644
23
        must_exist_map = H2O_HPACK_PARSE_HEADERS_METHOD_EXISTS | H2O_HPACK_PARSE_HEADERS_AUTHORITY_EXISTS;
645
23
        may_exist_map = 0;
646
        /* extended connect looks like an ordinary request plus an upgrade token (:protocol) */
647
23
        if ((header_exists_map & H2O_HPACK_PARSE_HEADERS_PROTOCOL_EXISTS) != 0)
648
0
            must_exist_map |= H2O_HPACK_PARSE_HEADERS_SCHEME_EXISTS | H2O_HPACK_PARSE_HEADERS_PATH_EXISTS |
649
0
                              H2O_HPACK_PARSE_HEADERS_PROTOCOL_EXISTS;
650
14.0k
    } else if (h2o_memis(stream->req.input.method.base, stream->req.input.method.len, H2O_STRLIT("CONNECT-UDP"))) {
651
        /* Handling of masque draft-03. Method is CONNECT-UDP and :protocol is not used, so we set `:protocol` to "connect-udp" to
652
         * make it look like an upgrade. The method is preserved and can be used to distinguish between RFC 9298 version which uses
653
         * "CONNECT". The draft requires "masque" in `:scheme` but we need to support clients that put "https" there instead. */
654
3
        if (!((header_exists_map & H2O_HPACK_PARSE_HEADERS_PROTOCOL_EXISTS) == 0 &&
655
3
              h2o_memis(stream->req.input.path.base, stream->req.input.path.len, H2O_STRLIT("/")))) {
656
2
            ret = H2O_HTTP2_ERROR_PROTOCOL;
657
2
            goto SendRSTStream;
658
2
        }
659
1
        assert(stream->req.upgrade.base == NULL); /* otherwise PROTOCOL_EXISTS will be set */
660
1
        is_connect = 1;
661
1
        must_exist_map = H2O_HPACK_PARSE_HEADERS_METHOD_EXISTS | H2O_HPACK_PARSE_HEADERS_SCHEME_EXISTS |
662
1
                         H2O_HPACK_PARSE_HEADERS_AUTHORITY_EXISTS | H2O_HPACK_PARSE_HEADERS_PATH_EXISTS;
663
1
        may_exist_map = 0;
664
14.0k
    } else {
665
        /* normal request */
666
14.0k
        is_connect = 0;
667
14.0k
        must_exist_map =
668
14.0k
            H2O_HPACK_PARSE_HEADERS_METHOD_EXISTS | H2O_HPACK_PARSE_HEADERS_SCHEME_EXISTS | H2O_HPACK_PARSE_HEADERS_PATH_EXISTS;
669
14.0k
        may_exist_map = H2O_HPACK_PARSE_HEADERS_AUTHORITY_EXISTS;
670
14.0k
    }
671
672
    /* check that all MUST pseudo headers exist, and that there are no other pseudo headers than MUST or MAY */
673
14.0k
    if (!((header_exists_map & must_exist_map) == must_exist_map && (header_exists_map & ~(must_exist_map | may_exist_map)) == 0)) {
674
4.47k
        ret = H2O_HTTP2_ERROR_PROTOCOL;
675
4.47k
        goto SendRSTStream;
676
4.47k
    }
677
678
9.58k
    if (conn->num_streams.pull.open > conn->super.ctx->globalconf->http2.max_streams) {
679
0
        ret = H2O_HTTP2_ERROR_REFUSED_STREAM;
680
0
        goto SendRSTStream;
681
0
    }
682
683
    /* send 400 if the request contains invalid header characters */
684
9.58k
    if (ret != 0) {
685
2.88k
        assert(ret == H2O_HTTP2_ERROR_INVALID_HEADER_CHAR);
686
2.88k
        return send_invalid_request_error(conn, stream, *err_desc);
687
2.88k
    }
688
689
    /* special handling of CONNECT method */
690
6.70k
    if (is_connect) {
691
        /* reject the request if content-length is specified or if the stream has been closed */
692
22
        if (stream->req.content_length != SIZE_MAX || stream->req_body.buf == NULL)
693
3
            return send_invalid_request_error(conn, stream, "Invalid CONNECT request");
694
        /* handle the request */
695
19
        stream->req.is_tunnel_req = 1;
696
19
        goto ProcessImmediately;
697
0
        return 0;
698
22
    }
699
700
    /* handle expect: 100-continue */
701
6.68k
    if (expect.base != NULL) {
702
354
        if (!h2o_lcstris(expect.base, expect.len, H2O_STRLIT("100-continue"))) {
703
354
            h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_REQ_PENDING);
704
354
            h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_SEND_HEADERS);
705
354
            h2o_send_error_417(&stream->req, "Expectation Failed", "unknown expectation", 0);
706
354
            return 0;
707
354
        }
708
0
        if (h2o_req_should_forward_expect(&stream->req)) {
709
0
            h2o_add_header(&stream->req.pool, &stream->req.headers, H2O_TOKEN_EXPECT, NULL, expect.base, expect.len);
710
0
            goto ProcessImmediately;
711
0
        } else {
712
0
            stream->req.res.status = 100;
713
0
            h2o_send_informational(&stream->req);
714
0
        }
715
0
    }
716
717
    /* handle the request */
718
6.33k
    if (stream->req_body.buf == NULL) {
719
5.16k
        execute_or_enqueue_request(conn, stream);
720
5.16k
    } else {
721
1.16k
        h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_RECV_BODY);
722
1.16k
        set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME);
723
1.16k
    }
724
6.33k
    return 0;
725
726
4.47k
SendRSTStream:
727
4.47k
    stream->reset_by_peer_action = 1;
728
4.47k
    stream_send_error(conn, stream->stream_id, ret);
729
4.47k
    h2o_http2_stream_reset(conn, stream);
730
4.47k
    return 0;
731
732
19
ProcessImmediately:
733
19
    stream->req.entity = h2o_iovec_init("", 0); /* setting to non-NULL pointer indicates the presence of HTTP payload */
734
19
    stream->req.proceed_req = proceed_request;
735
19
    h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_RECV_BODY);
736
19
    set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_OPEN);
737
19
    process_request(conn, stream);
738
19
    return 0;
739
6.68k
}
740
741
static int handle_trailing_headers(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, const uint8_t *src, size_t len,
742
                                   const char **err_desc)
743
59
{
744
59
    size_t dummy_content_length;
745
59
    h2o_iovec_t dummy_expect = h2o_iovec_init(NULL, 0);
746
59
    int ret;
747
748
59
    if ((ret = h2o_hpack_parse_request(&stream->req.pool, h2o_hpack_decode_header, &conn->_input_header_table, NULL, NULL, NULL,
749
59
                                       NULL, NULL, &stream->req.headers, NULL, &dummy_content_length, &dummy_expect, NULL, NULL,
750
59
                                       src, len, err_desc)) != 0)
751
11
        return ret;
752
48
    handle_request_body_chunk(conn, stream, h2o_iovec_init(NULL, 0), 1);
753
48
    return 0;
754
59
}
755
756
static ssize_t expect_continuation_of_headers(h2o_http2_conn_t *conn, const uint8_t *src, size_t len, const char **err_desc)
757
1.71k
{
758
1.71k
    h2o_http2_frame_t frame;
759
1.71k
    ssize_t ret;
760
1.71k
    h2o_http2_stream_t *stream;
761
1.71k
    int hret;
762
763
1.71k
    if ((ret = h2o_http2_decode_frame(&frame, src, len, H2O_HTTP2_SETTINGS_HOST_MAX_FRAME_SIZE, err_desc)) < 0)
764
235
        return ret;
765
1.47k
    if (frame.type != H2O_HTTP2_FRAME_TYPE_CONTINUATION) {
766
36
        *err_desc = "expected CONTINUATION frame";
767
36
        return H2O_HTTP2_ERROR_PROTOCOL;
768
36
    }
769
770
1.44k
    if ((stream = h2o_http2_conn_get_stream(conn, frame.stream_id)) == NULL ||
771
1.44k
        !(stream->state == H2O_HTTP2_STREAM_STATE_RECV_HEADERS || stream->state == H2O_HTTP2_STREAM_STATE_RECV_BODY)) {
772
86
        *err_desc = "unexpected stream id in CONTINUATION frame";
773
86
        return H2O_HTTP2_ERROR_PROTOCOL;
774
86
    }
775
776
1.35k
    if (conn->_headers_unparsed->size + frame.length <= H2O_MAX_REQLEN) {
777
1.35k
        h2o_buffer_reserve(&conn->_headers_unparsed, frame.length);
778
1.35k
        memcpy(conn->_headers_unparsed->bytes + conn->_headers_unparsed->size, frame.payload, frame.length);
779
1.35k
        conn->_headers_unparsed->size += frame.length;
780
781
1.35k
        if ((frame.flags & H2O_HTTP2_FRAME_FLAG_END_HEADERS) != 0) {
782
17
            conn->_read_expect = expect_default;
783
17
            if (stream->state == H2O_HTTP2_STREAM_STATE_RECV_HEADERS) {
784
12
                hret = handle_incoming_request(conn, stream, (const uint8_t *)conn->_headers_unparsed->bytes,
785
12
                                               conn->_headers_unparsed->size, err_desc);
786
12
            } else {
787
5
                hret = handle_trailing_headers(conn, stream, (const uint8_t *)conn->_headers_unparsed->bytes,
788
5
                                               conn->_headers_unparsed->size, err_desc);
789
5
            }
790
17
            if (hret != 0)
791
7
                ret = hret;
792
17
            h2o_buffer_dispose(&conn->_headers_unparsed);
793
17
            conn->_headers_unparsed = NULL;
794
17
        }
795
1.35k
    } else {
796
        /* request is too large (TODO log) */
797
0
        stream_send_error(conn, stream->stream_id, H2O_HTTP2_ERROR_REFUSED_STREAM);
798
0
        h2o_http2_stream_reset(conn, stream);
799
0
    }
800
801
1.35k
    return ret;
802
1.44k
}
803
804
static void send_window_update(h2o_http2_conn_t *conn, uint32_t stream_id, h2o_http2_window_t *window, size_t delta)
805
681
{
806
681
    assert(delta <= INT32_MAX);
807
681
    h2o_http2_encode_window_update_frame(&conn->_write.buf, stream_id, (int32_t)delta);
808
681
    h2o_http2_conn_request_write(conn);
809
681
    h2o_http2_window_update(window, delta);
810
681
}
811
812
void update_stream_input_window(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, size_t delta)
813
2.55k
{
814
2.55k
    stream->input_window.bytes_unnotified += delta;
815
2.55k
    if (stream->input_window.bytes_unnotified >= h2o_http2_window_get_avail(&stream->input_window.window)) {
816
681
        send_window_update(conn, stream->stream_id, &stream->input_window.window, stream->input_window.bytes_unnotified);
817
681
        stream->input_window.bytes_unnotified = 0;
818
681
    }
819
2.55k
}
820
821
static void set_priority(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, const h2o_http2_priority_t *priority,
822
                         int scheduler_is_open)
823
60.2k
{
824
60.2k
    h2o_http2_scheduler_node_t *parent_sched = NULL;
825
826
    /* determine the parent */
827
60.2k
    if (priority->dependency != 0) {
828
47.1k
        size_t i;
829
        /* First look for "recently closed" stream priorities.
830
         * This includes not only actually closed streams but also streams whose priority was modified
831
         * by H2O (e.g. through priority header).
832
         * By searching this list first, priority of a newly arrived stream can correctly refer to a priority
833
         * specified by client before. */
834
444k
        for (i = 0; i < HTTP2_CLOSED_STREAM_PRIORITIES; i++) {
835
406k
            if (conn->_recently_closed_streams.streams[i] &&
836
406k
                conn->_recently_closed_streams.streams[i]->stream_id == priority->dependency) {
837
9.82k
                parent_sched = &conn->_recently_closed_streams.streams[i]->_scheduler.node;
838
9.82k
                break;
839
9.82k
            }
840
406k
        }
841
47.1k
        if (parent_sched == NULL) {
842
            /* If the above search for recently closed streams did not succeed (either the parent was not closed
843
             * recently or modified priority), get the priority scheduler currently associated with the parent
844
             * stream.
845
             */
846
37.3k
            h2o_http2_stream_t *parent_stream = h2o_http2_conn_get_stream(conn, priority->dependency);
847
37.3k
            if (parent_stream != NULL) {
848
5.00k
                parent_sched = &parent_stream->_scheduler.node;
849
32.3k
            } else {
850
                /* A dependency on a stream that is not currently in the tree - such as a stream in the "idle" state - results in
851
                 * that stream being given a default priority. (RFC 7540 5.3.1) It is possible for a stream to become closed while
852
                 * prioritization information that creates a dependency on that stream is in transit. If a stream identified in a
853
                 * dependency has no associated priority information, then the dependent stream is instead assigned a default
854
                 * priority. (RFC 7540 5.3.4)
855
                 */
856
32.3k
                parent_sched = &conn->scheduler;
857
32.3k
                priority = &h2o_http2_default_priority;
858
32.3k
            }
859
37.3k
        } else if (conn->is_chromium_dependency_tree) {
860
            /* Parent stream was found in the recently closed streams.
861
             * There are two possible cases for this.
862
             * 1) the parent stream was actually closed recently
863
             * 2) the parent stream's priority was modified by H2O (e.g. priority headers)
864
             * In case of 2), we might need to ignore the original dependency specified by the client,
865
             * if such a modification was a demotion (decreasing urgency/weight).
866
             *
867
             * This block handles case 2).
868
             */
869
4.56k
            h2o_http2_scheduler_openref_t *orig_parent_ref =
870
4.56k
                H2O_STRUCT_FROM_MEMBER(h2o_http2_scheduler_openref_t, node, parent_sched);
871
4.56k
            if (orig_parent_ref->weight < priority->weight || !priority->exclusive) {
872
                /* Turns out the client's dependency tree does not look like Chromium's */
873
9
                conn->is_chromium_dependency_tree = 0;
874
4.55k
            } else {
875
4.55k
                h2o_http2_stream_t *current_parent_stream = h2o_http2_conn_get_stream(conn, priority->dependency);
876
4.55k
                if (current_parent_stream != NULL && orig_parent_ref->weight > current_parent_stream->_scheduler.weight &&
877
4.55k
                    priority->exclusive) {
878
                    /* Parent stream was demoted as a result of reprioritization via priority header.
879
                     * In this case, search the new parent from the root so that this stream is handled before
880
                     * the parent originally specified by the client.
881
                     * This entire logic assumes Chromium-type dependency tree, thus guarded by
882
                     * `chromium_dependency_tree` */
883
2.77k
                    parent_sched = h2o_http2_scheduler_find_parent_by_weight(&conn->scheduler, priority->weight);
884
2.77k
                    if (parent_sched == &stream->_scheduler.node) {
885
                        /* h2o_http2_scheduler_find_parent_by_weight may return the current node itself.
886
                         * In such a case, correct parent should be the parent of the current node. */
887
688
                        parent_sched = &current_parent_stream->_scheduler.node;
888
688
                    }
889
2.77k
                }
890
4.55k
            }
891
4.56k
        }
892
47.1k
    } else {
893
13.1k
        parent_sched = &conn->scheduler;
894
13.1k
    }
895
896
    /* Verify if the client's dependency tree looks like Chromium's */
897
60.2k
    if (priority->exclusive && conn->is_chromium_dependency_tree) {
898
7.49k
        int parent_weight = 256;
899
7.49k
        if (parent_sched->_parent != NULL && parent_sched->_parent->_parent != NULL) {
900
3.25k
            h2o_http2_scheduler_openref_t *parent_ref =
901
3.25k
                H2O_STRUCT_FROM_MEMBER(h2o_http2_scheduler_openref_t, node, parent_sched->_parent);
902
3.25k
            parent_weight = parent_ref->weight;
903
3.25k
        }
904
7.49k
        if (parent_weight < priority->weight) {
905
            /* Child's weight is bigger than parent's -- not Chromium */
906
14
            conn->is_chromium_dependency_tree = 0;
907
14
        }
908
52.7k
    } else {
909
        /* Stream doesn't have the exclusive flag -- not Chromium */
910
52.7k
        conn->is_chromium_dependency_tree = 0;
911
52.7k
    }
912
913
    /* setup the scheduler */
914
60.2k
    if (!scheduler_is_open) {
915
44.6k
        h2o_http2_scheduler_open(&stream->_scheduler, parent_sched, priority->weight, priority->exclusive);
916
44.6k
    } else {
917
15.6k
        h2o_http2_scheduler_rebind(&stream->_scheduler, parent_sched, priority->weight, priority->exclusive);
918
15.6k
    }
919
60.2k
}
920
921
void proceed_request(h2o_req_t *req, const char *errstr)
922
562
{
923
562
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
924
562
    h2o_http2_conn_t *conn = (h2o_http2_conn_t *)stream->req.conn;
925
926
562
    assert(stream->req_body.streamed);
927
928
    /* consume bytes */
929
562
    size_t written = stream->req.entity.len;
930
562
    h2o_buffer_consume(&stream->req_body.buf, written);
931
562
    stream->req.entity = h2o_iovec_init(NULL, 0);
932
933
    /* handle error */
934
562
    if (errstr != NULL) {
935
57
        stream->req.proceed_req = NULL;
936
57
        set_req_body_state(conn, stream, H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED);
937
57
        if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING) {
938
            /* Send error and close. State disposal is delayed so as to avoid freeing `req` within this function, which might
939
             * trigger the destruction of the generator being the caller. */
940
57
            stream_send_error(conn, stream->stream_id, H2O_HTTP2_ERROR_STREAM_CLOSED);
941
57
            h2o_http2_scheduler_deactivate(&stream->_scheduler);
942
57
            if (!h2o_linklist_is_linked(&stream->_link))
943
57
                h2o_linklist_insert(&conn->_write.streams_to_proceed, &stream->_link);
944
57
            h2o_http2_stream_reset(conn, stream);
945
57
        }
946
57
        return;
947
57
    }
948
949
505
    switch (stream->req_body.state) {
950
499
    case H2O_HTTP2_REQ_BODY_OPEN:
951
499
        update_stream_input_window(conn, stream, written);
952
499
        if (stream->blocked_by_server && h2o_http2_window_get_avail(&stream->input_window.window) > 0) {
953
482
            h2o_http2_stream_set_blocked_by_server(conn, stream, 0);
954
482
            update_idle_timeout(conn);
955
482
        }
956
499
        if (stream->req_body.buf->size != 0)
957
19
            write_streaming_body(conn, stream);
958
499
        break;
959
6
    case H2O_HTTP2_REQ_BODY_CLOSE_QUEUED:
960
6
        assert(written != 0);
961
6
        write_streaming_body(conn, stream);
962
6
        break;
963
0
    default:
964
0
        h2o_fatal("unexpected req_body_state");
965
505
    }
966
505
}
967
968
static int handle_data_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
969
17.3k
{
970
17.3k
    h2o_http2_data_payload_t payload;
971
17.3k
    h2o_http2_stream_t *stream;
972
17.3k
    int ret;
973
974
17.3k
    if ((ret = h2o_http2_decode_data_payload(&payload, frame, err_desc)) != 0)
975
63
        return ret;
976
977
    /* update connection-level window */
978
17.3k
    h2o_http2_window_consume_window(&conn->_input_window, frame->length);
979
17.3k
    if (h2o_http2_window_get_avail(&conn->_input_window) <= H2O_HTTP2_SETTINGS_HOST_CONNECTION_WINDOW_SIZE / 2)
980
0
        send_window_update(conn, 0, &conn->_input_window,
981
0
                           H2O_HTTP2_SETTINGS_HOST_CONNECTION_WINDOW_SIZE - h2o_http2_window_get_avail(&conn->_input_window));
982
983
    /* check state */
984
17.3k
    if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) == NULL) {
985
3.14k
        if (frame->stream_id <= conn->pull_stream_ids.max_open) {
986
2.85k
            stream_send_error(conn, frame->stream_id, H2O_HTTP2_ERROR_STREAM_CLOSED);
987
2.85k
            return 0;
988
2.85k
        } else {
989
282
            *err_desc = "invalid DATA frame";
990
282
            return H2O_HTTP2_ERROR_PROTOCOL;
991
282
        }
992
3.14k
    }
993
14.1k
    if (!(stream->req_body.state == H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME ||
994
14.1k
          stream->req_body.state == H2O_HTTP2_REQ_BODY_OPEN)) {
995
10.6k
        stream->reset_by_peer_action = 1;
996
10.6k
        stream_send_error(conn, frame->stream_id, H2O_HTTP2_ERROR_STREAM_CLOSED);
997
10.6k
        h2o_http2_stream_reset(conn, stream);
998
10.6k
        return 0;
999
10.6k
    }
1000
1001
    /* update stream-level window (doing it here could end up in sending multiple WINDOW_UPDATE frames if the receive window is
1002
     * fully-used, but no need to worry; in such case we'd be sending ACKs at a very fast rate anyways) */
1003
3.53k
    h2o_http2_window_consume_window(&stream->input_window.window, frame->length);
1004
3.53k
    if (frame->length != payload.length)
1005
1.37k
        update_stream_input_window(conn, stream, frame->length - payload.length);
1006
1007
    /* actually handle the input */
1008
3.53k
    if (payload.length != 0 || (frame->flags & H2O_HTTP2_FRAME_FLAG_END_STREAM) != 0)
1009
2.91k
        handle_request_body_chunk(conn, stream, h2o_iovec_init(payload.data, payload.length),
1010
2.91k
                                  (frame->flags & H2O_HTTP2_FRAME_FLAG_END_STREAM) != 0);
1011
1012
3.53k
    return 0;
1013
14.1k
}
1014
1015
static int handle_headers_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1016
18.7k
{
1017
18.7k
    h2o_http2_headers_payload_t payload;
1018
18.7k
    h2o_http2_stream_t *stream;
1019
18.7k
    int ret;
1020
1021
    /* decode */
1022
18.7k
    if ((ret = h2o_http2_decode_headers_payload(&payload, frame, err_desc)) != 0)
1023
36
        return ret;
1024
18.6k
    if ((frame->stream_id & 1) == 0) {
1025
23
        *err_desc = "invalid stream id in HEADERS frame";
1026
23
        return H2O_HTTP2_ERROR_PROTOCOL;
1027
23
    }
1028
18.6k
    if (frame->stream_id <= conn->pull_stream_ids.max_open) {
1029
171
        if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) == NULL) {
1030
97
            *err_desc = "closed stream id in HEADERS frame";
1031
97
            return H2O_HTTP2_ERROR_STREAM_CLOSED;
1032
97
        }
1033
74
        if (!(stream->req_body.state == H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME ||
1034
74
              stream->req_body.state == H2O_HTTP2_REQ_BODY_OPEN)) {
1035
10
            *err_desc = "invalid stream id in HEADERS frame";
1036
10
            return H2O_HTTP2_ERROR_PROTOCOL;
1037
10
        }
1038
1039
        /* is a trailer */
1040
64
        if (stream->req.is_tunnel_req) {
1041
1
            *err_desc = "trailer cannot be used in a CONNECT request";
1042
1
            return H2O_HTTP2_ERROR_PROTOCOL;
1043
1
        }
1044
63
        if ((frame->flags & H2O_HTTP2_FRAME_FLAG_END_STREAM) == 0) {
1045
4
            *err_desc = "trailing HEADERS frame MUST have END_STREAM flag set";
1046
4
            return H2O_HTTP2_ERROR_PROTOCOL;
1047
4
        }
1048
59
        if ((frame->flags & H2O_HTTP2_FRAME_FLAG_END_HEADERS) == 0)
1049
5
            goto PREPARE_FOR_CONTINUATION;
1050
54
        return handle_trailing_headers(conn, stream, payload.headers, payload.headers_len, err_desc);
1051
59
    }
1052
18.4k
    if (frame->stream_id == payload.priority.dependency) {
1053
5
        *err_desc = "stream cannot depend on itself";
1054
5
        return H2O_HTTP2_ERROR_PROTOCOL;
1055
5
    }
1056
1057
    /* open or determine the stream and prepare */
1058
18.4k
    if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) != NULL) {
1059
55
        if ((frame->flags & H2O_HTTP2_FRAME_FLAG_PRIORITY) != 0) {
1060
48
            set_priority(conn, stream, &payload.priority, 1);
1061
48
            stream->received_priority = payload.priority;
1062
48
        }
1063
18.4k
    } else {
1064
18.4k
        conn->received_any_request = 1;
1065
18.4k
        stream = h2o_http2_stream_open(conn, frame->stream_id, NULL, &payload.priority);
1066
18.4k
        set_priority(conn, stream, &payload.priority, 0);
1067
18.4k
    }
1068
18.4k
    h2o_http2_stream_prepare_for_request(conn, stream);
1069
1070
    /* setup container for request body if it is expected to arrive */
1071
18.4k
    if ((frame->flags & H2O_HTTP2_FRAME_FLAG_END_STREAM) == 0)
1072
6.38k
        h2o_buffer_init(&stream->req_body.buf, &h2o_socket_buffer_prototype);
1073
1074
18.4k
    if ((frame->flags & H2O_HTTP2_FRAME_FLAG_END_HEADERS) != 0) {
1075
        /* request headers are complete, handle it */
1076
18.1k
        return handle_incoming_request(conn, stream, payload.headers, payload.headers_len, err_desc);
1077
18.1k
    }
1078
1079
311
PREPARE_FOR_CONTINUATION:
1080
    /* request is not complete, store in buffer */
1081
311
    conn->_read_expect = expect_continuation_of_headers;
1082
311
    h2o_buffer_init(&conn->_headers_unparsed, &h2o_socket_buffer_prototype);
1083
311
    h2o_buffer_reserve(&conn->_headers_unparsed, payload.headers_len);
1084
311
    memcpy(conn->_headers_unparsed->bytes, payload.headers, payload.headers_len);
1085
311
    conn->_headers_unparsed->size = payload.headers_len;
1086
311
    return 0;
1087
18.4k
}
1088
1089
static int handle_priority_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1090
44.1k
{
1091
44.1k
    h2o_http2_priority_t payload;
1092
44.1k
    h2o_http2_stream_t *stream;
1093
44.1k
    int ret;
1094
1095
44.1k
    if ((ret = h2o_http2_decode_priority_payload(&payload, frame, err_desc)) != 0)
1096
46
        return ret;
1097
44.1k
    if (frame->stream_id == payload.dependency) {
1098
4
        *err_desc = "stream cannot depend on itself";
1099
4
        return H2O_HTTP2_ERROR_PROTOCOL;
1100
4
    }
1101
1102
44.1k
    if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) != NULL) {
1103
15.5k
        stream->received_priority = payload;
1104
        /* ignore priority changes to pushed streams with weight=257, since that is where we are trying to be smarter than the web
1105
         * browsers
1106
         */
1107
15.5k
        if (h2o_http2_scheduler_get_weight(&stream->_scheduler) != 257)
1108
15.5k
            set_priority(conn, stream, &payload, 1);
1109
28.5k
    } else {
1110
28.5k
        if (h2o_http2_stream_is_push(frame->stream_id)) {
1111
            /* Ignore PRIORITY frames for closed or idle pushed streams */
1112
1.49k
            return 0;
1113
27.0k
        } else {
1114
            /* Ignore PRIORITY frames for closed pull streams */
1115
27.0k
            if (frame->stream_id <= conn->pull_stream_ids.max_open)
1116
808
                return 0;
1117
27.0k
        }
1118
26.2k
        if (conn->num_streams.priority.open >= conn->super.ctx->globalconf->http2.max_streams_for_priority) {
1119
10
            *err_desc = "too many streams in idle/closed state";
1120
            /* RFC 7540 10.5: An endpoint MAY treat activity that is suspicious as a connection error (Section 5.4.1) of type
1121
             * ENHANCE_YOUR_CALM.
1122
             */
1123
10
            return H2O_HTTP2_ERROR_ENHANCE_YOUR_CALM;
1124
10
        }
1125
26.2k
        stream = h2o_http2_stream_open(conn, frame->stream_id, NULL, &payload);
1126
26.2k
        set_priority(conn, stream, &payload, 0);
1127
26.2k
    }
1128
1129
41.8k
    return 0;
1130
44.1k
}
1131
1132
static void resume_send(h2o_http2_conn_t *conn)
1133
10.6k
{
1134
10.6k
    if (h2o_http2_conn_get_buffer_window(conn) <= 0)
1135
0
        return;
1136
#if 0 /* TODO reenable this check for performance? */
1137
    if (conn->scheduler.list.size == 0)
1138
        return;
1139
#endif
1140
10.6k
    request_gathered_write(conn);
1141
10.6k
}
1142
1143
static int handle_settings_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1144
9.51k
{
1145
9.51k
    if (frame->stream_id != 0) {
1146
88
        *err_desc = "invalid stream id in SETTINGS frame";
1147
88
        return H2O_HTTP2_ERROR_PROTOCOL;
1148
88
    }
1149
1150
9.42k
    if ((frame->flags & H2O_HTTP2_FRAME_FLAG_ACK) != 0) {
1151
740
        if (frame->length != 0) {
1152
6
            *err_desc = "invalid SETTINGS frame (+ACK)";
1153
6
            return H2O_HTTP2_ERROR_FRAME_SIZE;
1154
6
        }
1155
734
        if (h2o_timeval_is_null(&conn->timestamps.settings_acked_at) && !h2o_timeval_is_null(&conn->timestamps.settings_sent_at)) {
1156
248
            conn->timestamps.settings_acked_at = h2o_gettimeofday(conn->super.ctx->loop);
1157
248
        }
1158
8.68k
    } else {
1159
8.68k
        uint32_t prev_initial_window_size = conn->peer_settings.initial_window_size;
1160
8.68k
        int ret = h2o_http2_update_peer_settings(&conn->peer_settings, frame->payload, frame->length, err_desc);
1161
8.68k
        if (ret != 0)
1162
238
            return ret;
1163
8.45k
        { /* schedule ack */
1164
8.45k
            h2o_iovec_t header_buf = h2o_buffer_reserve(&conn->_write.buf, H2O_HTTP2_FRAME_HEADER_SIZE);
1165
8.45k
            h2o_http2_encode_frame_header((void *)header_buf.base, 0, H2O_HTTP2_FRAME_TYPE_SETTINGS, H2O_HTTP2_FRAME_FLAG_ACK, 0);
1166
8.45k
            conn->_write.buf->size += H2O_HTTP2_FRAME_HEADER_SIZE;
1167
8.45k
            h2o_http2_conn_request_write(conn);
1168
8.45k
        }
1169
        /* apply the change to window size (to all the streams but not the connection, see 6.9.2 of draft-15) */
1170
8.45k
        if (prev_initial_window_size != conn->peer_settings.initial_window_size) {
1171
5.76k
            ssize_t delta = (int32_t)conn->peer_settings.initial_window_size - (int32_t)prev_initial_window_size;
1172
5.76k
            h2o_http2_stream_t *stream;
1173
5.76k
            kh_foreach_value(conn->streams, stream, { update_stream_output_window(stream, delta); });
1174
5.76k
            resume_send(conn);
1175
5.76k
        }
1176
8.45k
    }
1177
1178
9.18k
    return 0;
1179
9.42k
}
1180
1181
static int handle_window_update_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1182
12.3k
{
1183
12.3k
    h2o_http2_window_update_payload_t payload;
1184
12.3k
    int ret, err_is_stream_level;
1185
1186
12.3k
    if ((ret = h2o_http2_decode_window_update_payload(&payload, frame, err_desc, &err_is_stream_level)) != 0) {
1187
7.43k
        if (err_is_stream_level) {
1188
7.41k
            h2o_http2_stream_t *stream = h2o_http2_conn_get_stream(conn, frame->stream_id);
1189
7.41k
            if (stream != NULL) {
1190
5.53k
                stream->reset_by_peer_action = 1;
1191
5.53k
                h2o_http2_stream_reset(conn, stream);
1192
5.53k
            }
1193
7.41k
            stream_send_error(conn, frame->stream_id, ret);
1194
7.41k
            return 0;
1195
7.41k
        } else {
1196
22
            return ret;
1197
22
        }
1198
7.43k
    }
1199
1200
4.94k
    if (frame->stream_id == 0) {
1201
1.29k
        if (h2o_http2_window_update(&conn->_write.window, payload.window_size_increment) != 0) {
1202
6
            *err_desc = "flow control window overflow";
1203
6
            return H2O_HTTP2_ERROR_FLOW_CONTROL;
1204
6
        }
1205
3.65k
    } else if (!is_idle_stream_id(conn, frame->stream_id)) {
1206
3.57k
        h2o_http2_stream_t *stream = h2o_http2_conn_get_stream(conn, frame->stream_id);
1207
3.57k
        if (stream != NULL) {
1208
1.80k
            if (update_stream_output_window(stream, payload.window_size_increment) != 0) {
1209
17
                stream->reset_by_peer_action = 1;
1210
17
                h2o_http2_stream_reset(conn, stream);
1211
17
                stream_send_error(conn, frame->stream_id, H2O_HTTP2_ERROR_FLOW_CONTROL);
1212
17
                return 0;
1213
17
            }
1214
1.80k
        }
1215
3.57k
    } else {
1216
79
        *err_desc = "invalid stream id in WINDOW_UPDATE frame";
1217
79
        return H2O_HTTP2_ERROR_PROTOCOL;
1218
79
    }
1219
1220
4.84k
    resume_send(conn);
1221
1222
4.84k
    return 0;
1223
4.94k
}
1224
1225
static int handle_goaway_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1226
644
{
1227
644
    h2o_http2_goaway_payload_t payload;
1228
644
    int ret;
1229
1230
644
    if ((ret = h2o_http2_decode_goaway_payload(&payload, frame, err_desc)) != 0)
1231
77
        return ret;
1232
1233
    /* stop opening new push streams hereafter */
1234
567
    conn->push_stream_ids.max_open = 0x7ffffffe;
1235
1236
567
    return 0;
1237
644
}
1238
1239
static int handle_ping_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1240
957
{
1241
957
    h2o_http2_ping_payload_t payload;
1242
957
    int ret;
1243
1244
957
    if ((ret = h2o_http2_decode_ping_payload(&payload, frame, err_desc)) != 0)
1245
69
        return ret;
1246
1247
888
    if ((frame->flags & H2O_HTTP2_FRAME_FLAG_ACK) == 0) {
1248
368
        h2o_http2_encode_ping_frame(&conn->_write.buf, 1, payload.data);
1249
368
        h2o_http2_conn_request_write(conn);
1250
368
    }
1251
1252
888
    return 0;
1253
957
}
1254
1255
static int handle_rst_stream_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1256
1.59k
{
1257
1.59k
    h2o_http2_rst_stream_payload_t payload;
1258
1.59k
    h2o_http2_stream_t *stream;
1259
1.59k
    int ret;
1260
1261
1.59k
    if ((ret = h2o_http2_decode_rst_stream_payload(&payload, frame, err_desc)) != 0)
1262
42
        return ret;
1263
1.55k
    if (is_idle_stream_id(conn, frame->stream_id)) {
1264
49
        *err_desc = "unexpected stream id in RST_STREAM frame";
1265
49
        return H2O_HTTP2_ERROR_PROTOCOL;
1266
49
    }
1267
1268
1.50k
    if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) == NULL)
1269
1.49k
        return 0;
1270
1271
    /* reset the stream */
1272
13
    stream->reset_by_peer = 1;
1273
13
    h2o_http2_stream_reset(conn, stream);
1274
1275
    /* TODO log */
1276
1277
13
    return 0;
1278
1.50k
}
1279
1280
static int handle_push_promise_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1281
30
{
1282
30
    *err_desc = "received PUSH_PROMISE frame";
1283
30
    return H2O_HTTP2_ERROR_PROTOCOL;
1284
30
}
1285
1286
static int handle_invalid_continuation_frame(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc)
1287
4
{
1288
4
    *err_desc = "received invalid CONTINUATION frame";
1289
4
    return H2O_HTTP2_ERROR_PROTOCOL;
1290
4
}
1291
1292
ssize_t expect_default(h2o_http2_conn_t *conn, const uint8_t *src, size_t len, const char **err_desc)
1293
114k
{
1294
114k
    h2o_http2_frame_t frame;
1295
114k
    ssize_t ret;
1296
114k
    static int (*FRAME_HANDLERS[])(h2o_http2_conn_t *conn, h2o_http2_frame_t *frame, const char **err_desc) = {
1297
114k
        handle_data_frame,                /* DATA */
1298
114k
        handle_headers_frame,             /* HEADERS */
1299
114k
        handle_priority_frame,            /* PRIORITY */
1300
114k
        handle_rst_stream_frame,          /* RST_STREAM */
1301
114k
        handle_settings_frame,            /* SETTINGS */
1302
114k
        handle_push_promise_frame,        /* PUSH_PROMISE */
1303
114k
        handle_ping_frame,                /* PING */
1304
114k
        handle_goaway_frame,              /* GOAWAY */
1305
114k
        handle_window_update_frame,       /* WINDOW_UPDATE */
1306
114k
        handle_invalid_continuation_frame /* CONTINUATION */
1307
114k
    };
1308
1309
114k
    if ((ret = h2o_http2_decode_frame(&frame, src, len, H2O_HTTP2_SETTINGS_HOST_MAX_FRAME_SIZE, err_desc)) < 0)
1310
5.63k
        return ret;
1311
1312
108k
    if (frame.type < sizeof(FRAME_HANDLERS) / sizeof(FRAME_HANDLERS[0])) {
1313
105k
        int hret = FRAME_HANDLERS[frame.type](conn, &frame, err_desc);
1314
105k
        if (hret != 0)
1315
5.41k
            ret = hret;
1316
105k
    } else {
1317
3.16k
        H2O_PROBE_CONN(H2_UNKNOWN_FRAME_TYPE, &conn->super, frame.type);
1318
3.16k
    }
1319
1320
108k
    return ret;
1321
114k
}
1322
1323
static ssize_t expect_preface(h2o_http2_conn_t *conn, const uint8_t *src, size_t len, const char **err_desc)
1324
12.3k
{
1325
12.3k
    if (len < CONNECTION_PREFACE.len) {
1326
342
        return H2O_HTTP2_ERROR_INCOMPLETE;
1327
342
    }
1328
11.9k
    if (memcmp(src, CONNECTION_PREFACE.base, CONNECTION_PREFACE.len) != 0) {
1329
172
        return H2O_HTTP2_ERROR_PROTOCOL_CLOSE_IMMEDIATELY;
1330
172
    }
1331
1332
11.8k
    {
1333
11.8k
        enqueue_server_preface(conn);
1334
11.8k
        if (conn->http2_origin_frame) {
1335
            /* write origin frame */
1336
0
            h2o_http2_encode_origin_frame(&conn->_write.buf, *conn->http2_origin_frame);
1337
0
        }
1338
11.8k
        if (h2o_timeval_is_null(&conn->timestamps.settings_sent_at)) {
1339
11.8k
            conn->timestamps.settings_sent_at = h2o_gettimeofday(conn->super.ctx->loop);
1340
11.8k
        }
1341
11.8k
        h2o_http2_conn_request_write(conn);
1342
11.8k
    }
1343
1344
11.8k
    conn->_read_expect = expect_default;
1345
11.8k
    return CONNECTION_PREFACE.len;
1346
11.9k
}
1347
1348
static int parse_input(h2o_http2_conn_t *conn)
1349
15.9k
{
1350
    /* handle the input */
1351
132k
    while (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING && conn->sock->input->size != 0) {
1352
        /* process a frame */
1353
128k
        const char *err_desc = NULL;
1354
128k
        ssize_t ret = conn->_read_expect(conn, (uint8_t *)conn->sock->input->bytes, conn->sock->input->size, &err_desc);
1355
128k
        if (ret == H2O_HTTP2_ERROR_INCOMPLETE) {
1356
5.32k
            break;
1357
122k
        } else if (ret < 0) {
1358
6.61k
            if (ret != H2O_HTTP2_ERROR_PROTOCOL_CLOSE_IMMEDIATELY) {
1359
6.43k
                enqueue_goaway(conn, (int)ret,
1360
6.43k
                               err_desc != NULL ? (h2o_iovec_t){(char *)err_desc, strlen(err_desc)} : (h2o_iovec_t){NULL});
1361
6.43k
            }
1362
6.61k
            return close_connection(conn);
1363
6.61k
        }
1364
        /* advance to the next frame */
1365
116k
        h2o_buffer_consume(&conn->sock->input, ret);
1366
116k
    }
1367
9.33k
    return 0;
1368
15.9k
}
1369
1370
static void on_read(h2o_socket_t *sock, const char *err)
1371
21.4k
{
1372
21.4k
    h2o_http2_conn_t *conn = sock->data;
1373
1374
21.4k
    if (err != NULL) {
1375
5.50k
        conn->super.ctx->http2.events.read_closed++;
1376
5.50k
        h2o_socket_read_stop(conn->sock);
1377
5.50k
        close_connection(conn);
1378
5.50k
        return;
1379
5.50k
    }
1380
1381
    /* dispatch requests blocked by 425 when TLS handshake is complete */
1382
15.9k
    if (!h2o_linklist_is_empty(&conn->early_data.blocked_streams)) {
1383
0
        assert(conn->sock->ssl != NULL);
1384
0
        if (!h2o_socket_ssl_is_early_data(conn->sock)) {
1385
0
            while (conn->early_data.blocked_streams.next != &conn->early_data.blocked_streams) {
1386
0
                h2o_http2_stream_t *stream =
1387
0
                    H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _link, conn->early_data.blocked_streams.next);
1388
0
                h2o_linklist_unlink(&stream->_link);
1389
0
                if (!stream->blocked_by_server)
1390
0
                    h2o_http2_stream_set_blocked_by_server(conn, stream, 1);
1391
0
                h2o_replay_request(&stream->req);
1392
0
            }
1393
0
        }
1394
0
    }
1395
1396
15.9k
    if (parse_input(conn) != 0)
1397
167
        return;
1398
15.7k
    update_idle_timeout(conn);
1399
1400
    /* write immediately, if there is no write in flight and if pending write exists */
1401
15.7k
    if (h2o_timer_is_linked(&conn->_write.timeout_entry)) {
1402
14.0k
        h2o_timer_unlink(&conn->_write.timeout_entry);
1403
14.0k
        do_emit_writereq(conn);
1404
14.0k
    }
1405
15.7k
}
1406
1407
static void on_upgrade_complete(void *_conn, h2o_socket_t *sock, size_t reqsize)
1408
116
{
1409
116
    h2o_http2_conn_t *conn = _conn;
1410
1411
116
    if (sock == NULL) {
1412
0
        close_connection(conn);
1413
0
        return;
1414
0
    }
1415
1416
116
    conn->sock = sock;
1417
116
    sock->data = conn;
1418
116
    conn->_http1_req_input = sock->input;
1419
116
    h2o_buffer_init(&sock->input, &h2o_socket_buffer_prototype);
1420
1421
116
    enqueue_server_preface(conn);
1422
116
    h2o_http2_conn_request_write(conn);
1423
1424
    /* setup inbound */
1425
116
    h2o_socket_read_start(conn->sock, on_read);
1426
1427
    /* handle the request */
1428
116
    execute_or_enqueue_request(conn, h2o_http2_conn_get_stream(conn, 1));
1429
1430
116
    if (conn->_http1_req_input->size > reqsize) {
1431
59
        size_t remaining_bytes = conn->_http1_req_input->size - reqsize;
1432
59
        h2o_buffer_reserve(&sock->input, remaining_bytes);
1433
59
        memcpy(sock->input->bytes, conn->_http1_req_input->bytes + reqsize, remaining_bytes);
1434
59
        sock->input->size += remaining_bytes;
1435
59
        on_read(conn->sock, NULL);
1436
59
    }
1437
116
}
1438
1439
static size_t bytes_in_buf(h2o_http2_conn_t *conn)
1440
71.3k
{
1441
71.3k
    size_t size = conn->_write.buf->size;
1442
71.3k
    if (conn->_write.buf_in_flight != 0)
1443
5
        size += conn->_write.buf_in_flight->size;
1444
71.3k
    return size;
1445
71.3k
}
1446
1447
void h2o_http2_conn_request_write(h2o_http2_conn_t *conn)
1448
71.5k
{
1449
71.5k
    if (conn->state == H2O_HTTP2_CONN_STATE_IS_CLOSING)
1450
0
        return;
1451
71.5k
    if (h2o_socket_is_reading(conn->sock) && bytes_in_buf(conn) >= H2O_HTTP2_DEFAULT_OUTBUF_SOFT_MAX_SIZE)
1452
0
        h2o_socket_read_stop(conn->sock);
1453
71.5k
    request_gathered_write(conn);
1454
71.5k
}
1455
1456
void h2o_http2_conn_register_for_proceed_callback(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
1457
9.32k
{
1458
9.32k
    h2o_http2_conn_request_write(conn);
1459
1460
9.32k
    if (h2o_http2_stream_has_pending_data(stream) || stream->state >= H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL) {
1461
9.32k
        if (h2o_http2_window_get_avail(&stream->output_window) > 0) {
1462
9.04k
            assert(!h2o_linklist_is_linked(&stream->_link));
1463
9.04k
            h2o_http2_scheduler_activate(&stream->_scheduler);
1464
9.04k
        }
1465
9.32k
    } else {
1466
0
        h2o_linklist_insert(&conn->_write.streams_to_proceed, &stream->_link);
1467
0
    }
1468
9.32k
}
1469
1470
void h2o_http2_conn_register_for_replay(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
1471
0
{
1472
0
    if (conn->sock->ssl != NULL && h2o_socket_ssl_is_early_data(conn->sock)) {
1473
0
        h2o_linklist_insert(&conn->early_data.blocked_streams, &stream->_link);
1474
0
    } else {
1475
0
        h2o_replay_request_deferred(&stream->req);
1476
0
    }
1477
0
}
1478
1479
static void on_notify_write(h2o_socket_t *sock, const char *err)
1480
75
{
1481
75
    h2o_http2_conn_t *conn = sock->data;
1482
1483
75
    if (err != NULL) {
1484
0
        close_connection_now(conn);
1485
0
        return;
1486
0
    }
1487
75
    do_emit_writereq(conn);
1488
75
}
1489
1490
static void on_write_complete(h2o_socket_t *sock, const char *err)
1491
14.8k
{
1492
14.8k
    h2o_http2_conn_t *conn = sock->data;
1493
1494
14.8k
    assert(conn->_write.buf_in_flight != NULL);
1495
1496
    /* close by error if necessary */
1497
14.8k
    if (err != NULL) {
1498
7
        conn->super.ctx->http2.events.write_closed++;
1499
7
        close_connection_now(conn);
1500
7
        return;
1501
7
    }
1502
1503
    /* reset the other memory pool */
1504
14.8k
    h2o_buffer_dispose(&conn->_write.buf_in_flight);
1505
14.8k
    assert(conn->_write.buf_in_flight == NULL);
1506
1507
    /* call the proceed callback of the streams that have been flushed (while unlinking them from the list) */
1508
14.8k
    if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING) {
1509
13.9k
        while (!h2o_linklist_is_empty(&conn->_write.streams_to_proceed)) {
1510
5.53k
            h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _link, conn->_write.streams_to_proceed.next);
1511
5.53k
            assert(!h2o_http2_stream_has_pending_data(stream));
1512
5.53k
            h2o_linklist_unlink(&stream->_link);
1513
5.53k
            h2o_http2_stream_proceed(conn, stream);
1514
5.53k
        }
1515
8.39k
    }
1516
1517
    /* update the timeout now that the states have been updated */
1518
14.8k
    update_idle_timeout(conn);
1519
1520
    /* cancel the write callback if scheduled (as the generator may have scheduled a write just before this function gets called) */
1521
14.8k
    if (h2o_timer_is_linked(&conn->_write.timeout_entry))
1522
86
        h2o_timer_unlink(&conn->_write.timeout_entry);
1523
1524
14.8k
    if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING) {
1525
8.39k
        if (!h2o_socket_is_reading(conn->sock) && bytes_in_buf(conn) < H2O_HTTP2_DEFAULT_OUTBUF_SOFT_MAX_SIZE)
1526
0
            h2o_socket_read_start(conn->sock, on_read);
1527
8.39k
    }
1528
1529
14.8k
#if !H2O_USE_LIBUV
1530
14.8k
    if (conn->state == H2O_HTTP2_CONN_STATE_OPEN) {
1531
8.39k
        if (conn->_write.buf->size != 0 || h2o_http2_scheduler_is_active(&conn->scheduler))
1532
88
            h2o_socket_notify_write(sock, on_notify_write);
1533
8.39k
        return;
1534
8.39k
    }
1535
6.48k
#endif
1536
1537
    /* write more, if possible */
1538
6.48k
    do_emit_writereq(conn);
1539
6.48k
}
1540
1541
static int emit_writereq_of_openref(h2o_http2_scheduler_openref_t *ref, int *still_is_active, void *cb_arg)
1542
6.46k
{
1543
6.46k
    h2o_http2_conn_t *conn = cb_arg;
1544
6.46k
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _scheduler, ref);
1545
1546
6.46k
    assert(h2o_http2_stream_has_pending_data(stream) || stream->state >= H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL);
1547
1548
6.46k
    *still_is_active = 0;
1549
1550
6.46k
    h2o_http2_stream_send_pending_data(conn, stream);
1551
6.46k
    if (h2o_http2_stream_has_pending_data(stream) || stream->state == H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL) {
1552
971
        if (h2o_http2_window_get_avail(&stream->output_window) <= 0) {
1553
            /* is blocked */
1554
971
        } else {
1555
0
            *still_is_active = 1;
1556
0
        }
1557
5.49k
    } else {
1558
5.49k
        if (stream->state == H2O_HTTP2_STREAM_STATE_END_STREAM) {
1559
4.94k
            h2o_iovec_t server_timing;
1560
4.94k
            if (stream->req.send_server_timing &&
1561
4.94k
                (server_timing = h2o_build_server_timing_trailer(&stream->req, NULL, 0, NULL, 0)).len != 0) {
1562
0
                static const h2o_iovec_t name = {H2O_STRLIT("server-timing")};
1563
0
                h2o_vector_reserve(&stream->req.pool, &stream->req.res.trailers, stream->req.res.trailers.size + 1);
1564
0
                stream->req.res.trailers.entries[stream->req.res.trailers.size++] =
1565
0
                    (h2o_header_t){(h2o_iovec_t *)&name, NULL, server_timing};
1566
0
            }
1567
4.94k
            if (stream->req.res.trailers.size != 0) {
1568
0
                h2o_hpack_flatten_trailers(&conn->_write.buf, &conn->_output_header_table, conn->peer_settings.header_table_size,
1569
0
                                           stream->stream_id, conn->peer_settings.max_frame_size, stream->req.res.trailers.entries,
1570
0
                                           stream->req.res.trailers.size);
1571
0
            }
1572
4.94k
        }
1573
5.49k
        h2o_linklist_insert(&conn->_write.streams_to_proceed, &stream->_link);
1574
5.49k
    }
1575
1576
6.46k
    return h2o_http2_conn_get_buffer_window(conn) > 0 ? 0 : -1;
1577
6.46k
}
1578
1579
void do_emit_writereq(h2o_http2_conn_t *conn)
1580
21.6k
{
1581
21.6k
    assert(conn->_write.buf_in_flight == NULL);
1582
1583
    /* push DATA frames */
1584
21.6k
    if (conn->state < H2O_HTTP2_CONN_STATE_IS_CLOSING && h2o_http2_conn_get_buffer_window(conn) > 0)
1585
8.64k
        h2o_http2_scheduler_run(&conn->scheduler, emit_writereq_of_openref, conn);
1586
1587
21.6k
    if (conn->_write.buf->size != 0) {
1588
        /* write and wait for completion */
1589
14.8k
        h2o_iovec_t buf = {conn->_write.buf->bytes, conn->_write.buf->size};
1590
14.8k
        h2o_socket_write(conn->sock, &buf, 1, on_write_complete);
1591
14.8k
        conn->_write.buf_in_flight = conn->_write.buf;
1592
14.8k
        h2o_buffer_init(&conn->_write.buf, &h2o_http2_wbuf_buffer_prototype);
1593
14.8k
        h2o_timer_unlink(&conn->_timeout_entry);
1594
14.8k
        h2o_timer_link(conn->super.ctx->loop, H2O_HTTP2_DEFAULT_OUTBUF_WRITE_TIMEOUT, &conn->_timeout_entry);
1595
14.8k
    }
1596
1597
    /* close the connection if necessary */
1598
21.6k
    switch (conn->state) {
1599
8.64k
    case H2O_HTTP2_CONN_STATE_OPEN:
1600
8.64k
        break;
1601
0
    case H2O_HTTP2_CONN_STATE_HALF_CLOSED:
1602
0
        if (conn->num_streams.pull.open + conn->num_streams.push.open != 0)
1603
0
            break;
1604
0
        conn->state = H2O_HTTP2_CONN_STATE_IS_CLOSING;
1605
    /* fall-thru */
1606
12.9k
    case H2O_HTTP2_CONN_STATE_IS_CLOSING:
1607
12.9k
        close_connection(conn);
1608
12.9k
        break;
1609
21.6k
    }
1610
21.6k
}
1611
1612
static void emit_writereq(h2o_timer_t *entry)
1613
1.02k
{
1614
1.02k
    h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, _write.timeout_entry, entry);
1615
1616
1.02k
    do_emit_writereq(conn);
1617
1.02k
}
1618
1619
static socklen_t get_sockname(h2o_conn_t *_conn, struct sockaddr *sa)
1620
0
{
1621
0
    h2o_http2_conn_t *conn = (void *)_conn;
1622
0
    return h2o_socket_getsockname(conn->sock, sa);
1623
0
}
1624
1625
static socklen_t get_peername(h2o_conn_t *_conn, struct sockaddr *sa)
1626
948
{
1627
948
    h2o_http2_conn_t *conn = (void *)_conn;
1628
948
    return h2o_socket_getpeername(conn->sock, sa);
1629
948
}
1630
1631
static ptls_t *get_ptls(h2o_conn_t *_conn)
1632
948
{
1633
948
    struct st_h2o_http2_conn_t *conn = (void *)_conn;
1634
948
    assert(conn->sock != NULL && "it never becomes NULL, right?");
1635
948
    return h2o_socket_get_ptls(conn->sock);
1636
948
}
1637
1638
static const char *get_ssl_server_name(h2o_conn_t *_conn)
1639
0
{
1640
0
    struct st_h2o_http2_conn_t *conn = (void *)_conn;
1641
0
    assert(conn->sock != NULL && "it never becomes NULL, right?");
1642
0
    return h2o_socket_get_ssl_server_name(conn->sock);
1643
0
}
1644
1645
static ptls_log_conn_state_t *log_state(h2o_conn_t *_conn)
1646
0
{
1647
0
    struct st_h2o_http2_conn_t *conn = (void *)_conn;
1648
0
    assert(conn->sock != NULL && "it never becomes NULL, right?");
1649
0
    return h2o_socket_log_state(conn->sock);
1650
0
}
1651
1652
static uint64_t get_req_id(h2o_req_t *req)
1653
0
{
1654
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1655
0
    return stream->stream_id;
1656
0
}
1657
1658
static int64_t get_rtt(h2o_conn_t *_conn)
1659
0
{
1660
0
    struct st_h2o_http2_conn_t *conn = (void *)_conn;
1661
0
    if (!h2o_timeval_is_null(&conn->timestamps.settings_sent_at) && !h2o_timeval_is_null(&conn->timestamps.settings_acked_at)) {
1662
0
        return h2o_timeval_subtract(&conn->timestamps.settings_sent_at, &conn->timestamps.settings_acked_at);
1663
0
    } else {
1664
0
        return -1;
1665
0
    }
1666
0
}
1667
1668
#define DEFINE_LOGGER(name)                                                                                                        \
1669
    static h2o_iovec_t log_##name(h2o_req_t *req)                                                                                  \
1670
0
    {                                                                                                                              \
1671
0
        h2o_http2_conn_t *conn = (void *)req->conn;                                                                                \
1672
0
        return h2o_socket_log_##name(conn->sock, &req->pool);                                                                      \
1673
0
    }
Unexecuted instantiation: connection.c:log_tcp_congestion_controller
Unexecuted instantiation: connection.c:log_tcp_delivery_rate
Unexecuted instantiation: connection.c:log_ssl_protocol_version
Unexecuted instantiation: connection.c:log_ssl_session_reused
Unexecuted instantiation: connection.c:log_ssl_cipher
Unexecuted instantiation: connection.c:log_ssl_cipher_bits
Unexecuted instantiation: connection.c:log_ssl_session_id
Unexecuted instantiation: connection.c:log_ssl_negotiated_protocol
Unexecuted instantiation: connection.c:log_ssl_ech_config_id
Unexecuted instantiation: connection.c:log_ssl_ech_kem
Unexecuted instantiation: connection.c:log_ssl_ech_cipher
Unexecuted instantiation: connection.c:log_ssl_ech_cipher_bits
Unexecuted instantiation: connection.c:log_ssl_backend
1674
DEFINE_LOGGER(tcp_congestion_controller)
1675
DEFINE_LOGGER(tcp_delivery_rate)
1676
DEFINE_LOGGER(ssl_protocol_version)
1677
DEFINE_LOGGER(ssl_session_reused)
1678
DEFINE_LOGGER(ssl_cipher)
1679
DEFINE_LOGGER(ssl_cipher_bits)
1680
DEFINE_LOGGER(ssl_session_id)
1681
DEFINE_LOGGER(ssl_negotiated_protocol)
1682
DEFINE_LOGGER(ssl_ech_config_id)
1683
DEFINE_LOGGER(ssl_ech_kem)
1684
DEFINE_LOGGER(ssl_ech_cipher)
1685
DEFINE_LOGGER(ssl_ech_cipher_bits)
1686
DEFINE_LOGGER(ssl_backend)
1687
#undef DEFINE_LOGGER
1688
1689
static h2o_iovec_t log_stream_id(h2o_req_t *req)
1690
0
{
1691
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1692
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT32_LONGEST_STR));
1693
0
    size_t len = (size_t)sprintf(s, "%" PRIu32, stream->stream_id);
1694
0
    return h2o_iovec_init(s, len);
1695
0
}
1696
1697
static h2o_iovec_t log_priority_received(h2o_req_t *req)
1698
0
{
1699
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1700
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof("1:" H2O_UINT32_LONGEST_STR ":" H2O_UINT16_LONGEST_STR));
1701
0
    size_t len = (size_t)sprintf(s, "%c:%" PRIu32 ":%" PRIu16, stream->received_priority.exclusive ? '1' : '0',
1702
0
                                 stream->received_priority.dependency, stream->received_priority.weight);
1703
0
    return h2o_iovec_init(s, len);
1704
0
}
1705
1706
static h2o_iovec_t log_priority_received_exclusive(h2o_req_t *req)
1707
0
{
1708
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1709
0
    return h2o_iovec_init(stream->received_priority.exclusive ? "1" : "0", 1);
1710
0
}
1711
1712
static h2o_iovec_t log_priority_received_parent(h2o_req_t *req)
1713
0
{
1714
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1715
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT32_LONGEST_STR));
1716
0
    size_t len = sprintf(s, "%" PRIu32, stream->received_priority.dependency);
1717
0
    return h2o_iovec_init(s, len);
1718
0
}
1719
1720
static h2o_iovec_t log_priority_received_weight(h2o_req_t *req)
1721
0
{
1722
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1723
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT16_LONGEST_STR));
1724
0
    size_t len = sprintf(s, "%" PRIu16, stream->received_priority.weight);
1725
0
    return h2o_iovec_init(s, len);
1726
0
}
1727
1728
static uint32_t get_parent_stream_id(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
1729
0
{
1730
0
    h2o_http2_scheduler_node_t *parent_sched = h2o_http2_scheduler_get_parent(&stream->_scheduler);
1731
0
    if (parent_sched == &conn->scheduler) {
1732
0
        return 0;
1733
0
    } else {
1734
0
        h2o_http2_stream_t *parent_stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _scheduler, parent_sched);
1735
0
        return parent_stream->stream_id;
1736
0
    }
1737
0
}
1738
1739
static h2o_iovec_t log_priority_actual(h2o_req_t *req)
1740
0
{
1741
0
    h2o_http2_conn_t *conn = (void *)req->conn;
1742
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1743
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT32_LONGEST_STR ":" H2O_UINT16_LONGEST_STR));
1744
0
    size_t len = (size_t)sprintf(s, "%" PRIu32 ":%" PRIu16, get_parent_stream_id(conn, stream),
1745
0
                                 h2o_http2_scheduler_get_weight(&stream->_scheduler));
1746
0
    return h2o_iovec_init(s, len);
1747
0
}
1748
1749
static h2o_iovec_t log_priority_actual_parent(h2o_req_t *req)
1750
0
{
1751
0
    h2o_http2_conn_t *conn = (void *)req->conn;
1752
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1753
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT32_LONGEST_STR));
1754
0
    size_t len = (size_t)sprintf(s, "%" PRIu32, get_parent_stream_id(conn, stream));
1755
0
    return h2o_iovec_init(s, len);
1756
0
}
1757
1758
static h2o_iovec_t log_priority_actual_weight(h2o_req_t *req)
1759
0
{
1760
0
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, req);
1761
0
    char *s = h2o_mem_alloc_pool(&stream->req.pool, *s, sizeof(H2O_UINT16_LONGEST_STR));
1762
0
    size_t len = (size_t)sprintf(s, "%" PRIu16, h2o_http2_scheduler_get_weight(&stream->_scheduler));
1763
0
    return h2o_iovec_init(s, len);
1764
0
}
1765
1766
static void on_dos_process_delay(h2o_timer_t *timer)
1767
2
{
1768
2
    h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, dos_mitigation.process_delay, timer);
1769
1770
2
    assert(!h2o_timer_is_linked(&conn->dos_mitigation.process_delay));
1771
2
    run_pending_requests(conn);
1772
2
}
1773
1774
static h2o_http2_conn_t *create_conn(h2o_context_t *ctx, h2o_hostconf_t **hosts, h2o_socket_t *sock, struct timeval connected_at)
1775
12.4k
{
1776
12.4k
    static const h2o_conn_callbacks_t callbacks = {
1777
12.4k
        .get_sockname = get_sockname,
1778
12.4k
        .get_peername = get_peername,
1779
12.4k
        .get_ptls = get_ptls,
1780
12.4k
        .get_ssl_server_name = get_ssl_server_name,
1781
12.4k
        .log_state = log_state,
1782
12.4k
        .get_req_id = get_req_id,
1783
12.4k
        .push_path = push_path,
1784
12.4k
        .get_debug_state = h2o_http2_get_debug_state,
1785
12.4k
        .close_idle_connection = close_idle_connection,
1786
12.4k
        .foreach_request = foreach_request,
1787
12.4k
        .request_shutdown = initiate_graceful_shutdown,
1788
12.4k
        .get_rtt = get_rtt,
1789
12.4k
        .log_ = {{
1790
12.4k
            .transport =
1791
12.4k
                {
1792
12.4k
                    .cc_name = log_tcp_congestion_controller,
1793
12.4k
                    .delivery_rate = log_tcp_delivery_rate,
1794
12.4k
                },
1795
12.4k
            .ssl =
1796
12.4k
                {
1797
12.4k
                    .protocol_version = log_ssl_protocol_version,
1798
12.4k
                    .session_reused = log_ssl_session_reused,
1799
12.4k
                    .cipher = log_ssl_cipher,
1800
12.4k
                    .cipher_bits = log_ssl_cipher_bits,
1801
12.4k
                    .session_id = log_ssl_session_id,
1802
12.4k
                    .negotiated_protocol = log_ssl_negotiated_protocol,
1803
12.4k
                    .ech_config_id = log_ssl_ech_config_id,
1804
12.4k
                    .ech_kem = log_ssl_ech_kem,
1805
12.4k
                    .ech_cipher = log_ssl_ech_cipher,
1806
12.4k
                    .ech_cipher_bits = log_ssl_ech_cipher_bits,
1807
12.4k
                    .backend = log_ssl_backend,
1808
12.4k
                },
1809
12.4k
            .http2 =
1810
12.4k
                {
1811
12.4k
                    .stream_id = log_stream_id,
1812
12.4k
                    .priority_received = log_priority_received,
1813
12.4k
                    .priority_received_exclusive = log_priority_received_exclusive,
1814
12.4k
                    .priority_received_parent = log_priority_received_parent,
1815
12.4k
                    .priority_received_weight = log_priority_received_weight,
1816
12.4k
                    .priority_actual = log_priority_actual,
1817
12.4k
                    .priority_actual_parent = log_priority_actual_parent,
1818
12.4k
                    .priority_actual_weight = log_priority_actual_weight,
1819
12.4k
                },
1820
12.4k
        }},
1821
12.4k
    };
1822
1823
12.4k
    h2o_http2_conn_t *conn = (void *)h2o_create_connection(sizeof(*conn), ctx, hosts, connected_at, &callbacks);
1824
1825
12.4k
    memset((char *)conn + sizeof(conn->super), 0, sizeof(*conn) - sizeof(conn->super));
1826
12.4k
    conn->sock = sock;
1827
12.4k
    conn->peer_settings = H2O_HTTP2_SETTINGS_DEFAULT;
1828
12.4k
    conn->streams = kh_init(h2o_http2_stream_t);
1829
12.4k
    h2o_http2_scheduler_init(&conn->scheduler);
1830
12.4k
    conn->state = H2O_HTTP2_CONN_STATE_OPEN;
1831
12.4k
    conn->_read_expect = expect_preface;
1832
12.4k
    conn->_input_header_table.hpack_capacity = conn->_input_header_table.hpack_max_capacity =
1833
12.4k
        H2O_HTTP2_SETTINGS_DEFAULT.header_table_size;
1834
12.4k
    h2o_http2_window_init(&conn->_input_window, H2O_HTTP2_SETTINGS_HOST_CONNECTION_WINDOW_SIZE);
1835
12.4k
    conn->_output_header_table.hpack_capacity = H2O_HTTP2_SETTINGS_DEFAULT.header_table_size;
1836
12.4k
    h2o_linklist_init_anchor(&conn->_pending_reqs);
1837
12.4k
    h2o_buffer_init(&conn->_write.buf, &h2o_http2_wbuf_buffer_prototype);
1838
12.4k
    h2o_linklist_init_anchor(&conn->_write.streams_to_proceed);
1839
12.4k
    conn->_write.timeout_entry.cb = emit_writereq;
1840
12.4k
    h2o_http2_window_init(&conn->_write.window, conn->peer_settings.initial_window_size);
1841
12.4k
    h2o_linklist_init_anchor(&conn->early_data.blocked_streams);
1842
12.4k
    conn->is_chromium_dependency_tree = 1; /* initially assume the client is Chromium until proven otherwise */
1843
12.4k
    conn->received_any_request = 0;
1844
12.4k
    conn->dos_mitigation.process_delay.cb = on_dos_process_delay;
1845
12.4k
    conn->dos_mitigation.reset_budget = conn->super.ctx->globalconf->http2.max_concurrent_requests_per_connection;
1846
1847
12.4k
    return conn;
1848
12.4k
}
1849
1850
static int update_push_memo(h2o_http2_conn_t *conn, h2o_req_t *src_req, const char *abspath, size_t abspath_len)
1851
0
{
1852
1853
0
    if (conn->push_memo == NULL)
1854
0
        conn->push_memo = h2o_cache_create(0, 1024, 1, NULL);
1855
1856
    /* uses the hash as the key */
1857
0
    h2o_cache_hashcode_t url_hash = h2o_cache_calchash(src_req->input.scheme->name.base, src_req->input.scheme->name.len) ^
1858
0
                                    h2o_cache_calchash(src_req->input.authority.base, src_req->input.authority.len) ^
1859
0
                                    h2o_cache_calchash(abspath, abspath_len);
1860
0
    return h2o_cache_set(conn->push_memo, 0, h2o_iovec_init(&url_hash, sizeof(url_hash)), url_hash, h2o_iovec_init(NULL, 0));
1861
0
}
1862
1863
static void push_path(h2o_req_t *src_req, const char *abspath, size_t abspath_len, int is_critical)
1864
0
{
1865
0
    h2o_http2_conn_t *conn = (void *)src_req->conn;
1866
0
    h2o_http2_stream_t *src_stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, req, src_req);
1867
1868
    /* RFC 7540 8.2.1: PUSH_PROMISE frames can be sent by the server in response to any client-initiated stream */
1869
0
    if (h2o_http2_stream_is_push(src_stream->stream_id))
1870
0
        return;
1871
1872
0
    if (!src_stream->req.hostconf->http2.push_preload || !conn->peer_settings.enable_push ||
1873
0
        conn->num_streams.push.open >= conn->peer_settings.max_concurrent_streams)
1874
0
        return;
1875
1876
0
    if (conn->state >= H2O_HTTP2_CONN_STATE_IS_CLOSING)
1877
0
        return;
1878
0
    if (conn->push_stream_ids.max_open >= 0x7ffffff0)
1879
0
        return;
1880
0
    if (!(h2o_linklist_is_empty(&conn->_pending_reqs) && can_run_requests(conn)))
1881
0
        return;
1882
1883
0
    if (h2o_find_header(&src_stream->req.headers, H2O_TOKEN_X_FORWARDED_FOR, -1) != -1)
1884
0
        return;
1885
1886
0
    if (src_stream->cache_digests != NULL) {
1887
0
        h2o_iovec_t url = h2o_concat(&src_stream->req.pool, src_stream->req.input.scheme->name, h2o_iovec_init(H2O_STRLIT("://")),
1888
0
                                     src_stream->req.input.authority, h2o_iovec_init(abspath, abspath_len));
1889
0
        if (h2o_cache_digests_lookup_by_url(src_stream->cache_digests, url.base, url.len) == H2O_CACHE_DIGESTS_STATE_FRESH)
1890
0
            return;
1891
0
    }
1892
1893
    /* delayed initialization of casper (cookie-based), that MAY be used together to cache-digests */
1894
0
    if (src_stream->req.hostconf->http2.casper.capacity_bits != 0) {
1895
0
        if (!src_stream->pull.casper_is_ready) {
1896
0
            src_stream->pull.casper_is_ready = 1;
1897
0
            if (conn->casper == NULL)
1898
0
                h2o_http2_conn_init_casper(conn, src_stream->req.hostconf->http2.casper.capacity_bits);
1899
0
            ssize_t header_index;
1900
0
            for (header_index = -1;
1901
0
                 (header_index = h2o_find_header(&src_stream->req.headers, H2O_TOKEN_COOKIE, header_index)) != -1;) {
1902
0
                h2o_header_t *header = src_stream->req.headers.entries + header_index;
1903
0
                h2o_http2_casper_consume_cookie(conn->casper, header->value.base, header->value.len);
1904
0
            }
1905
0
        }
1906
0
    }
1907
1908
    /* update the push memo, and if it already pushed on the same connection, return */
1909
0
    if (update_push_memo(conn, &src_stream->req, abspath, abspath_len))
1910
0
        return;
1911
1912
    /* open the stream */
1913
0
    h2o_http2_stream_t *stream = h2o_http2_stream_open(conn, conn->push_stream_ids.max_open + 2, NULL, &h2o_http2_default_priority);
1914
0
    stream->received_priority.dependency = src_stream->stream_id;
1915
0
    stream->push.parent_stream_id = src_stream->stream_id;
1916
0
    if (is_critical) {
1917
0
        h2o_http2_scheduler_open(&stream->_scheduler, &conn->scheduler, 257, 0);
1918
0
    } else {
1919
0
        h2o_http2_scheduler_open(&stream->_scheduler, &src_stream->_scheduler.node, 16, 0);
1920
0
    }
1921
0
    h2o_http2_stream_prepare_for_request(conn, stream);
1922
1923
    /* setup request */
1924
0
    stream->req.input.method = (h2o_iovec_t){H2O_STRLIT("GET")};
1925
0
    stream->req.input.scheme = src_stream->req.input.scheme;
1926
0
    stream->req.input.authority =
1927
0
        h2o_strdup(&stream->req.pool, src_stream->req.input.authority.base, src_stream->req.input.authority.len);
1928
0
    stream->req.input.path = h2o_strdup(&stream->req.pool, abspath, abspath_len);
1929
0
    stream->req.version = 0x200;
1930
1931
0
    { /* copy headers that may affect the response (of a cacheable response) */
1932
0
        size_t i;
1933
0
        for (i = 0; i != src_stream->req.headers.size; ++i) {
1934
0
            h2o_header_t *src_header = src_stream->req.headers.entries + i;
1935
            /* currently only predefined headers are copiable */
1936
0
            if (h2o_iovec_is_token(src_header->name)) {
1937
0
                h2o_token_t *token = H2O_STRUCT_FROM_MEMBER(h2o_token_t, buf, src_header->name);
1938
0
                if (token->flags.copy_for_push_request)
1939
0
                    h2o_add_header(&stream->req.pool, &stream->req.headers, token, NULL,
1940
0
                                   h2o_strdup(&stream->req.pool, src_header->value.base, src_header->value.len).base,
1941
0
                                   src_header->value.len);
1942
0
            }
1943
0
        }
1944
0
    }
1945
1946
0
    execute_or_enqueue_request(conn, stream);
1947
1948
    /* send push-promise ASAP (before the parent stream gets closed), even if execute_or_enqueue_request did not trigger the
1949
     * invocation of send_headers */
1950
0
    if (!stream->push.promise_sent && stream->state != H2O_HTTP2_STREAM_STATE_END_STREAM)
1951
0
        h2o_http2_stream_send_push_promise(conn, stream);
1952
0
}
1953
1954
static int foreach_request(h2o_conn_t *_conn, int (*cb)(h2o_req_t *req, void *cbdata), void *cbdata)
1955
0
{
1956
0
    h2o_http2_conn_t *conn = (void *)_conn;
1957
0
    h2o_http2_stream_t *stream;
1958
0
    kh_foreach_value(conn->streams, stream, {
1959
0
        int ret = cb(&stream->req, cbdata);
1960
0
        if (ret != 0)
1961
0
            return ret;
1962
0
    });
1963
0
    return 0;
1964
0
}
1965
1966
void h2o_http2_accept(h2o_accept_ctx_t *ctx, h2o_socket_t *sock, struct timeval connected_at)
1967
12.0k
{
1968
12.0k
    h2o_http2_conn_t *conn = create_conn(ctx->ctx, ctx->hosts, sock, connected_at);
1969
12.0k
    conn->http2_origin_frame = ctx->http2_origin_frame;
1970
12.0k
    sock->data = conn;
1971
12.0k
    h2o_socket_read_start(conn->sock, on_read);
1972
12.0k
    update_idle_timeout(conn);
1973
12.0k
    if (sock->input->size != 0)
1974
4.85k
        on_read(sock, 0);
1975
12.0k
}
1976
1977
int h2o_http2_handle_upgrade(h2o_req_t *req, struct timeval connected_at)
1978
475
{
1979
475
    h2o_http2_conn_t *http2conn = create_conn(req->conn->ctx, req->conn->hosts, NULL, connected_at);
1980
475
    h2o_http2_stream_t *stream;
1981
475
    ssize_t connection_index, settings_index;
1982
475
    h2o_iovec_t settings_decoded;
1983
475
    const char *err_desc;
1984
1985
475
    assert(req->version < 0x200); /* from HTTP/1.x */
1986
1987
    /* check that "HTTP2-Settings" is declared in the connection header */
1988
475
    connection_index = h2o_find_header(&req->headers, H2O_TOKEN_CONNECTION, -1);
1989
475
    assert(connection_index != -1);
1990
475
    if (!h2o_contains_token(req->headers.entries[connection_index].value.base, req->headers.entries[connection_index].value.len,
1991
475
                            H2O_STRLIT("http2-settings"), ',')) {
1992
178
        goto Error;
1993
178
    }
1994
1995
    /* decode the settings */
1996
297
    if ((settings_index = h2o_find_header(&req->headers, H2O_TOKEN_HTTP2_SETTINGS, -1)) == -1) {
1997
64
        goto Error;
1998
64
    }
1999
233
    if ((settings_decoded = h2o_decode_base64url(&req->pool, req->headers.entries[settings_index].value.base,
2000
233
                                                 req->headers.entries[settings_index].value.len))
2001
233
            .base == NULL) {
2002
26
        goto Error;
2003
26
    }
2004
207
    if (h2o_http2_update_peer_settings(&http2conn->peer_settings, (uint8_t *)settings_decoded.base, settings_decoded.len,
2005
207
                                       &err_desc) != 0) {
2006
91
        goto Error;
2007
91
    }
2008
2009
    /* open the stream, now that the function is guaranteed to succeed */
2010
116
    stream = h2o_http2_stream_open(http2conn, 1, req, &h2o_http2_default_priority);
2011
116
    h2o_http2_scheduler_open(&stream->_scheduler, &http2conn->scheduler, h2o_http2_default_priority.weight, 0);
2012
116
    h2o_http2_stream_prepare_for_request(http2conn, stream);
2013
2014
    /* send response */
2015
116
    req->res.status = 101;
2016
116
    req->res.reason = "Switching Protocols";
2017
116
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_UPGRADE, NULL, H2O_STRLIT("h2c"));
2018
116
    h2o_http1_upgrade(req, NULL, 0, on_upgrade_complete, http2conn);
2019
2020
116
    return 0;
2021
359
Error:
2022
359
    kh_destroy(h2o_http2_stream_t, http2conn->streams);
2023
359
    h2o_destroy_connection(&http2conn->super);
2024
359
    return -1;
2025
207
}