1 /*
2  * Copyright (c) 2014,2015 DeNA Co., Ltd.
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 #ifndef h2o__http2__internal_h
23 #define h2o__http2__internal_h
24 
25 #include <assert.h>
26 #include <stdint.h>
27 #include "khash.h"
28 #include "h2o/cache.h"
29 #include "h2o/http2_casper.h"
30 #include "h2o/http2_scheduler.h"
31 
32 typedef struct st_h2o_http2_conn_t h2o_http2_conn_t;
33 typedef struct st_h2o_http2_stream_t h2o_http2_stream_t;
34 
35 typedef enum enum_h2o_http2_stream_state_t {
36     /**
37      * stream in idle state (but registered; i.e. priority stream)
38      */
39     H2O_HTTP2_STREAM_STATE_IDLE,
40     /**
41      * receiving headers
42      */
43     H2O_HTTP2_STREAM_STATE_RECV_HEADERS,
44     /**
45      * receiving body (or trailers), waiting for the arrival of END_STREAM
46      */
47     H2O_HTTP2_STREAM_STATE_RECV_BODY,
48     /**
49      * received request but haven't been assigned a handler
50      */
51     H2O_HTTP2_STREAM_STATE_REQ_PENDING,
52     /**
53      * waiting for receiving response headers from the handler
54      */
55     H2O_HTTP2_STREAM_STATE_SEND_HEADERS,
56     /**
57      * sending body
58      */
59     H2O_HTTP2_STREAM_STATE_SEND_BODY,
60     /**
61      * received EOS from handler but still is sending body to client
62      */
63     H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL,
64     /**
65      * closed
66      */
67     H2O_HTTP2_STREAM_STATE_END_STREAM
68 } h2o_http2_stream_state_t;
69 
70 typedef struct st_h2o_http2_conn_num_streams_t {
71     uint32_t open;
72     uint32_t half_closed;
73     uint32_t send_body;
74 } h2o_http2_conn_num_streams_t;
75 
76 struct st_h2o_http2_stream_t {
77     /**
78      * stream-id
79      */
80     uint32_t stream_id;
81     /**
82      * scheduler (entries below scheduler are not maintained after the stream is closed, see ...)
83      */
84     h2o_http2_scheduler_openref_t _scheduler;
85     /**
86      * link-list of streams govered by connection.c
87      */
88     h2o_linklist_t _link;
89     /**
90      * the final ostream
91      */
92     h2o_ostream_t _ostr_final;
93     h2o_http2_stream_state_t state;
94     h2o_http2_window_t output_window;
95     struct {
96         h2o_http2_window_t window;
97         size_t bytes_unnotified;
98     } input_window;
99     h2o_http2_priority_t received_priority;
100     H2O_VECTOR(h2o_sendvec_t) _data;
101     size_t _data_off; /* offset within _data.entries[0] */
102     /**
103      * points to http2_conn_t::num_streams::* in which the stream is counted
104      */
105     h2o_http2_conn_num_streams_t *_num_streams_slot;
106     h2o_cache_digests_t *cache_digests;
107     union {
108         struct {
109             uint32_t parent_stream_id;
110             unsigned promise_sent : 1;
111         } push;
112         struct {
113             unsigned casper_is_ready : 1;
114         } pull;
115     };
116     unsigned blocked_by_server : 1;
117     /**
118      *  state of the ostream, only used in push mode
119      */
120     h2o_send_state_t send_state;
121     /**
122      * request body (not available when `buf` is NULL
123      */
124     struct {
125         h2o_buffer_t *buf;
126         enum en_h2o_req_body_state_t {
127             H2O_HTTP2_REQ_BODY_NONE,
128             H2O_HTTP2_REQ_BODY_OPEN_BEFORE_FIRST_FRAME,
129             H2O_HTTP2_REQ_BODY_OPEN,
130             H2O_HTTP2_REQ_BODY_CLOSE_QUEUED,
131             H2O_HTTP2_REQ_BODY_CLOSE_DELIVERED
132         } state;
133         /**
134          * if the response body is streaming or was streamed, including tunnels
135          */
136         unsigned streamed : 1;
137     } req_body;
138     /**
139      * the request object; placed at last since it is large and has it's own ctor
140      */
141     h2o_req_t req;
142 };
143 
144 KHASH_MAP_INIT_INT64(h2o_http2_stream_t, h2o_http2_stream_t *)
145 
146 typedef enum enum_h2o_http2_conn_state_t {
147     H2O_HTTP2_CONN_STATE_OPEN,        /* accepting new connections */
148     H2O_HTTP2_CONN_STATE_HALF_CLOSED, /* no more accepting new streams */
149     H2O_HTTP2_CONN_STATE_IS_CLOSING   /* nothing should be sent */
150 } h2o_http2_conn_state_t;
151 
152 struct st_h2o_http2_conn_t {
153     h2o_conn_t super;
154     h2o_socket_t *sock;
155     /* settings */
156     h2o_http2_settings_t peer_settings;
157     /* streams */
158     khash_t(h2o_http2_stream_t) * streams;
159     struct {
160         uint32_t max_open;
161         uint32_t max_processed;
162     } pull_stream_ids;
163     struct {
164         uint32_t max_open;
165     } push_stream_ids;
166     struct {
167         h2o_http2_conn_num_streams_t priority;
168         h2o_http2_conn_num_streams_t pull;
169         h2o_http2_conn_num_streams_t push;
170         uint32_t blocked_by_server;
171         /**
172          * number of streams that have the flag with the same name being set
173          */
174         uint32_t _req_streaming_in_progress;
175         /**
176          * number of CONNECT tunnels inflight (this is a proper subset of `_req_streaming_in_progress`)
177          */
178         uint32_t tunnel;
179     } num_streams;
180     /* internal */
181     h2o_http2_scheduler_node_t scheduler;
182     h2o_http2_conn_state_t state;
183     int is_chromium_dependency_tree; /* indicates whether the client-generated dependency tree is from Chromium
184                                       * Dependency tree from Chromium satisfies the following properties:
185                                       * 1) Every stream has the exclusive bit set
186                                       * 2) On a dependency tree, child's weight is lower than or equal to parent's
187                                       */
188 
189     h2o_linklist_t _conns; /* linklist to h2o_context_t::http2._conns */
190     ssize_t (*_read_expect)(h2o_http2_conn_t *conn, const uint8_t *src, size_t len, const char **err_desc);
191     h2o_buffer_t *_http1_req_input; /* contains data referred to by original request via HTTP/1.1 */
192     h2o_hpack_header_table_t _input_header_table;
193     h2o_http2_window_t _input_window;
194     h2o_hpack_header_table_t _output_header_table;
195     h2o_linklist_t _pending_reqs; /* list of h2o_http2_stream_t that contain pending requests */
196     h2o_timer_t _timeout_entry;
197     h2o_buffer_t *_headers_unparsed; /* for temporary storing HEADERS|CONTINUATION frames without END_HEADERS flag set */
198     struct {
199         h2o_buffer_t *buf;
200         h2o_buffer_t *buf_in_flight;
201         h2o_linklist_t streams_to_proceed;
202         h2o_timer_t timeout_entry;
203         h2o_http2_window_t window;
204     } _write;
205     h2o_cache_t *push_memo;
206     h2o_http2_casper_t *casper;
207     struct {
208         h2o_linklist_t blocked_streams;
209     } early_data;
210     h2o_iovec_t *http2_origin_frame;
211     /**
212      * Ring buffer of closed streams. `next_slot` points to the next write position. The stored object is shrinked to only contain
213      * stream_id and _scheduler.
214      */
215     struct {
216 #define HTTP2_CLOSED_STREAM_PRIORITIES 10
217         h2o_http2_stream_t *streams[HTTP2_CLOSED_STREAM_PRIORITIES];
218         size_t next_slot;
219     } _recently_closed_streams;
220     struct {
221         struct timeval settings_sent_at;
222         struct timeval settings_acked_at;
223     } timestamps;
224 };
225 
226 /* connection */
227 void h2o_http2_conn_register_stream(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
228 void h2o_http2_conn_unregister_stream(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
229 static h2o_http2_stream_t *h2o_http2_conn_get_stream(h2o_http2_conn_t *conn, uint32_t stream_id);
230 void h2o_http2_conn_push_path(h2o_http2_conn_t *conn, h2o_iovec_t path, h2o_http2_stream_t *src_stream);
231 void h2o_http2_conn_request_write(h2o_http2_conn_t *conn);
232 void h2o_http2_conn_register_for_proceed_callback(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
233 static ssize_t h2o_http2_conn_get_buffer_window(h2o_http2_conn_t *conn);
234 static void h2o_http2_conn_init_casper(h2o_http2_conn_t *conn, unsigned capacity_bits);
235 void h2o_http2_conn_register_for_replay(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
236 void h2o_http2_conn_preserve_stream_scheduler(h2o_http2_conn_t *conn, h2o_http2_stream_t *src);
237 
238 /* stream */
239 static int h2o_http2_stream_is_push(uint32_t stream_id);
240 h2o_http2_stream_t *h2o_http2_stream_open(h2o_http2_conn_t *conn, uint32_t stream_id, h2o_req_t *src_req,
241                                           const h2o_http2_priority_t *received_priority);
242 static void h2o_http2_stream_update_open_slot(h2o_http2_stream_t *stream, h2o_http2_conn_num_streams_t *slot);
243 static void h2o_http2_stream_set_blocked_by_server(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, unsigned on);
244 static void h2o_http2_stream_set_state(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, h2o_http2_stream_state_t new_state);
245 static void h2o_http2_stream_prepare_for_request(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
246 void h2o_http2_stream_close(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
247 void h2o_http2_stream_reset(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
248 void h2o_http2_stream_send_pending_data(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
249 static int h2o_http2_stream_has_pending_data(h2o_http2_stream_t *stream);
250 void h2o_http2_stream_proceed(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
251 static void h2o_http2_stream_send_push_promise(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream);
252 h2o_http2_debug_state_t *h2o_http2_get_debug_state(h2o_req_t *req, int hpack_enabled);
253 
254 /* inline definitions */
255 
h2o_http2_conn_get_stream(h2o_http2_conn_t * conn,uint32_t stream_id)256 inline h2o_http2_stream_t *h2o_http2_conn_get_stream(h2o_http2_conn_t *conn, uint32_t stream_id)
257 {
258     khiter_t iter = kh_get(h2o_http2_stream_t, conn->streams, stream_id);
259     if (iter != kh_end(conn->streams))
260         return kh_val(conn->streams, iter);
261     return NULL;
262 }
263 
h2o_http2_stream_is_push(uint32_t stream_id)264 inline int h2o_http2_stream_is_push(uint32_t stream_id)
265 {
266     return stream_id % 2 == 0;
267 }
268 
h2o_http2_conn_get_buffer_window(h2o_http2_conn_t * conn)269 inline ssize_t h2o_http2_conn_get_buffer_window(h2o_http2_conn_t *conn)
270 {
271     ssize_t ret, winsz;
272     size_t capacity, cwnd_left;
273 
274     capacity = conn->_write.buf->capacity;
275     if ((cwnd_left = h2o_socket_prepare_for_latency_optimized_write(
276              conn->sock, &conn->super.ctx->globalconf->http2.latency_optimization)) < capacity) {
277         capacity = cwnd_left;
278         if (capacity < conn->_write.buf->size)
279             return 0;
280     }
281 
282     ret = capacity - conn->_write.buf->size;
283     if (ret < H2O_HTTP2_FRAME_HEADER_SIZE)
284         return 0;
285     ret -= H2O_HTTP2_FRAME_HEADER_SIZE;
286     winsz = h2o_http2_window_get_avail(&conn->_write.window);
287     if (winsz < ret)
288         ret = winsz;
289     return ret;
290 }
291 
h2o_http2_conn_init_casper(h2o_http2_conn_t * conn,unsigned capacity_bits)292 inline void h2o_http2_conn_init_casper(h2o_http2_conn_t *conn, unsigned capacity_bits)
293 {
294     assert(conn->casper == NULL);
295     conn->casper = h2o_http2_casper_create(capacity_bits, 6);
296 }
297 
h2o_http2_stream_update_open_slot(h2o_http2_stream_t * stream,h2o_http2_conn_num_streams_t * slot)298 inline void h2o_http2_stream_update_open_slot(h2o_http2_stream_t *stream, h2o_http2_conn_num_streams_t *slot)
299 {
300     --stream->_num_streams_slot->open;
301     ++slot->open;
302     stream->_num_streams_slot = slot;
303 }
304 
h2o_http2_stream_set_blocked_by_server(h2o_http2_conn_t * conn,h2o_http2_stream_t * stream,unsigned on)305 inline void h2o_http2_stream_set_blocked_by_server(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, unsigned on)
306 {
307     if (on) {
308         assert(!stream->blocked_by_server);
309         stream->blocked_by_server = 1;
310         ++conn->num_streams.blocked_by_server;
311     } else {
312         assert(stream->blocked_by_server);
313         stream->blocked_by_server = 0;
314         --conn->num_streams.blocked_by_server;
315     }
316 }
317 
h2o_http2_stream_set_state(h2o_http2_conn_t * conn,h2o_http2_stream_t * stream,h2o_http2_stream_state_t new_state)318 inline void h2o_http2_stream_set_state(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream, h2o_http2_stream_state_t new_state)
319 {
320     switch (new_state) {
321     case H2O_HTTP2_STREAM_STATE_IDLE:
322         assert(!"FIXME");
323         break;
324     case H2O_HTTP2_STREAM_STATE_RECV_HEADERS:
325         assert(stream->state == H2O_HTTP2_STREAM_STATE_IDLE);
326         if (h2o_http2_stream_is_push(stream->stream_id))
327             h2o_http2_stream_update_open_slot(stream, &conn->num_streams.push);
328         else
329             h2o_http2_stream_update_open_slot(stream, &conn->num_streams.pull);
330         stream->state = new_state;
331         stream->req.timestamps.request_begin_at = h2o_gettimeofday(conn->super.ctx->loop);
332         break;
333     case H2O_HTTP2_STREAM_STATE_RECV_BODY:
334         stream->state = new_state;
335         stream->req.timestamps.request_body_begin_at = h2o_gettimeofday(conn->super.ctx->loop);
336         break;
337     case H2O_HTTP2_STREAM_STATE_REQ_PENDING:
338         stream->state = new_state;
339         break;
340     case H2O_HTTP2_STREAM_STATE_SEND_HEADERS:
341         assert(stream->state == H2O_HTTP2_STREAM_STATE_REQ_PENDING);
342         ++stream->_num_streams_slot->half_closed;
343         stream->state = new_state;
344         break;
345     case H2O_HTTP2_STREAM_STATE_SEND_BODY:
346         assert(stream->state == H2O_HTTP2_STREAM_STATE_SEND_HEADERS);
347         stream->state = new_state;
348         ++stream->_num_streams_slot->send_body;
349         break;
350     case H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL:
351         assert(stream->state == H2O_HTTP2_STREAM_STATE_SEND_BODY);
352         stream->state = new_state;
353         break;
354     case H2O_HTTP2_STREAM_STATE_END_STREAM:
355         switch (stream->state) {
356         case H2O_HTTP2_STREAM_STATE_IDLE:
357         case H2O_HTTP2_STREAM_STATE_RECV_BODY:
358         case H2O_HTTP2_STREAM_STATE_RECV_HEADERS:
359             break;
360         case H2O_HTTP2_STREAM_STATE_REQ_PENDING:
361             break;
362         case H2O_HTTP2_STREAM_STATE_SEND_HEADERS:
363             --stream->_num_streams_slot->half_closed;
364             break;
365         case H2O_HTTP2_STREAM_STATE_SEND_BODY:
366         case H2O_HTTP2_STREAM_STATE_SEND_BODY_IS_FINAL:
367             --stream->_num_streams_slot->half_closed;
368             --stream->_num_streams_slot->send_body;
369             break;
370         case H2O_HTTP2_STREAM_STATE_END_STREAM:
371             assert(!"FIXME");
372             break;
373         }
374         stream->state = new_state;
375         stream->req.timestamps.response_end_at = h2o_gettimeofday(conn->super.ctx->loop);
376         --stream->_num_streams_slot->open;
377         stream->_num_streams_slot = NULL;
378         if (stream->blocked_by_server)
379             h2o_http2_stream_set_blocked_by_server(conn, stream, 0);
380         break;
381     }
382 }
383 
h2o_http2_stream_prepare_for_request(h2o_http2_conn_t * conn,h2o_http2_stream_t * stream)384 inline void h2o_http2_stream_prepare_for_request(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
385 {
386     assert(conn->state != H2O_HTTP2_CONN_STATE_IS_CLOSING);
387     assert(h2o_http2_scheduler_is_open(&stream->_scheduler));
388 
389     /* adjust max-open */
390     uint32_t *max_open = NULL;
391     if (h2o_http2_stream_is_push(stream->stream_id)) {
392         max_open = &conn->push_stream_ids.max_open;
393     } else if (conn->state == H2O_HTTP2_CONN_STATE_OPEN) {
394         max_open = &conn->pull_stream_ids.max_open;
395     }
396     if (max_open != NULL && *max_open < stream->stream_id)
397         *max_open = stream->stream_id;
398 
399     h2o_http2_stream_set_state(conn, stream, H2O_HTTP2_STREAM_STATE_RECV_HEADERS);
400     h2o_http2_window_init(&stream->output_window, conn->peer_settings.initial_window_size);
401 }
402 
h2o_http2_stream_has_pending_data(h2o_http2_stream_t * stream)403 inline int h2o_http2_stream_has_pending_data(h2o_http2_stream_t *stream)
404 {
405     return stream->_data.size != 0;
406 }
407 
h2o_http2_stream_send_push_promise(h2o_http2_conn_t * conn,h2o_http2_stream_t * stream)408 inline void h2o_http2_stream_send_push_promise(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream)
409 {
410     assert(!stream->push.promise_sent);
411     h2o_hpack_flatten_push_promise(&conn->_write.buf, &conn->_output_header_table, conn->peer_settings.header_table_size,
412                                    stream->stream_id, conn->peer_settings.max_frame_size, stream->req.input.scheme,
413                                    stream->req.input.authority, stream->req.input.method, stream->req.input.path,
414                                    stream->req.headers.entries, stream->req.headers.size, stream->push.parent_stream_id);
415     stream->push.promise_sent = 1;
416 }
417 
418 #endif
419