blob: a21a7a4d759b38523c29c9328f4a25ba0c8051b9 [file] [log] [blame]
Craig Tiller640d3bd2015-06-12 07:51:51 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9b8671c2015-06-12 07:41:54 -070034#ifndef GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
35#define GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
36
37#include "src/core/transport/transport_impl.h"
Craig Tiller3208e392015-06-12 08:17:02 -070038#include "src/core/iomgr/endpoint.h"
39#include "src/core/transport/chttp2/frame_data.h"
40#include "src/core/transport/chttp2/frame_goaway.h"
41#include "src/core/transport/chttp2/frame_ping.h"
42#include "src/core/transport/chttp2/frame_rst_stream.h"
43#include "src/core/transport/chttp2/frame_settings.h"
44#include "src/core/transport/chttp2/frame_window_update.h"
45#include "src/core/transport/chttp2/stream_map.h"
46#include "src/core/transport/chttp2/hpack_parser.h"
47#include "src/core/transport/chttp2/stream_encoder.h"
Craig Tiller9b8671c2015-06-12 07:41:54 -070048
Craig Tillerb084d902015-06-12 07:50:02 -070049typedef struct grpc_chttp2_transport grpc_chttp2_transport;
50typedef struct grpc_chttp2_stream grpc_chttp2_stream;
Craig Tiller9b8671c2015-06-12 07:41:54 -070051
52/* streams are kept in various linked lists depending on what things need to
53 happen to them... this enum labels each list */
54typedef enum {
55 /* streams that have pending writes */
56 WRITABLE = 0,
57 /* streams that have been selected to be written */
58 WRITING,
59 /* streams that have just been written, and included a close */
60 WRITTEN_CLOSED,
61 /* streams that have been cancelled and have some pending state updates
62 to perform */
63 CANCELLED,
64 /* streams that want to send window updates */
65 WINDOW_UPDATE,
66 /* streams that are waiting to start because there are too many concurrent
67 streams on the connection */
68 WAITING_FOR_CONCURRENCY,
69 /* streams that have finished reading: we wait until unlock to coalesce
70 all changes into one callback */
71 FINISHED_READ_OP,
72 MAYBE_FINISH_READ_AFTER_PARSE,
73 PARSER_CHECK_WINDOW_UPDATES_AFTER_PARSE,
74 OTHER_CHECK_WINDOW_UPDATES_AFTER_PARSE,
75 NEW_OUTGOING_WINDOW,
76 STREAM_LIST_COUNT /* must be last */
Craig Tillerb084d902015-06-12 07:50:02 -070077} grpc_chttp2_stream_list_id;
Craig Tiller9b8671c2015-06-12 07:41:54 -070078
79/* deframer state for the overall http2 stream of bytes */
80typedef enum {
81 /* prefix: one entry per http2 connection prefix byte */
82 DTS_CLIENT_PREFIX_0 = 0,
83 DTS_CLIENT_PREFIX_1,
84 DTS_CLIENT_PREFIX_2,
85 DTS_CLIENT_PREFIX_3,
86 DTS_CLIENT_PREFIX_4,
87 DTS_CLIENT_PREFIX_5,
88 DTS_CLIENT_PREFIX_6,
89 DTS_CLIENT_PREFIX_7,
90 DTS_CLIENT_PREFIX_8,
91 DTS_CLIENT_PREFIX_9,
92 DTS_CLIENT_PREFIX_10,
93 DTS_CLIENT_PREFIX_11,
94 DTS_CLIENT_PREFIX_12,
95 DTS_CLIENT_PREFIX_13,
96 DTS_CLIENT_PREFIX_14,
97 DTS_CLIENT_PREFIX_15,
98 DTS_CLIENT_PREFIX_16,
99 DTS_CLIENT_PREFIX_17,
100 DTS_CLIENT_PREFIX_18,
101 DTS_CLIENT_PREFIX_19,
102 DTS_CLIENT_PREFIX_20,
103 DTS_CLIENT_PREFIX_21,
104 DTS_CLIENT_PREFIX_22,
105 DTS_CLIENT_PREFIX_23,
106 /* frame header byte 0... */
107 /* must follow from the prefix states */
108 DTS_FH_0,
109 DTS_FH_1,
110 DTS_FH_2,
111 DTS_FH_3,
112 DTS_FH_4,
113 DTS_FH_5,
114 DTS_FH_6,
115 DTS_FH_7,
116 /* ... frame header byte 8 */
117 DTS_FH_8,
118 /* inside a http2 frame */
119 DTS_FRAME
Craig Tillerb084d902015-06-12 07:50:02 -0700120} grpc_chttp2_deframe_transport_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700121
122typedef enum {
123 WRITE_STATE_OPEN,
124 WRITE_STATE_QUEUED_CLOSE,
125 WRITE_STATE_SENT_CLOSE
Craig Tillerb084d902015-06-12 07:50:02 -0700126} grpc_chttp2_write_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700127
128typedef enum {
129 DONT_SEND_CLOSED = 0,
130 SEND_CLOSED,
131 SEND_CLOSED_WITH_RST_STREAM
Craig Tillerb084d902015-06-12 07:50:02 -0700132} grpc_chttp2_send_closed;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700133
134typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -0700135 grpc_chttp2_stream *head;
136 grpc_chttp2_stream *tail;
137} grpc_chttp2_stream_list;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700138
139typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -0700140 grpc_chttp2_stream *next;
141 grpc_chttp2_stream *prev;
142} grpc_chttp2_stream_link;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700143
144typedef enum {
145 ERROR_STATE_NONE,
146 ERROR_STATE_SEEN,
147 ERROR_STATE_NOTIFIED
Craig Tillerb084d902015-06-12 07:50:02 -0700148} grpc_chttp2_error_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700149
150/* We keep several sets of connection wide parameters */
151typedef enum {
152 /* The settings our peer has asked for (and we have acked) */
153 PEER_SETTINGS = 0,
154 /* The settings we'd like to have */
155 LOCAL_SETTINGS,
156 /* The settings we've published to our peer */
157 SENT_SETTINGS,
158 /* The settings the peer has acked */
159 ACKED_SETTINGS,
160 NUM_SETTING_SETS
Craig Tillerb084d902015-06-12 07:50:02 -0700161} grpc_chttp2_setting_set;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700162
163/* Outstanding ping request data */
164typedef struct {
165 gpr_uint8 id[8];
166 void (*cb)(void *user_data);
167 void *user_data;
Craig Tillerb084d902015-06-12 07:50:02 -0700168} grpc_chttp2_outstanding_ping;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700169
170typedef struct {
171 grpc_status_code status;
172 gpr_slice debug;
Craig Tillerb084d902015-06-12 07:50:02 -0700173} grpc_chttp2_pending_goaway;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700174
Craig Tillerb084d902015-06-12 07:50:02 -0700175struct grpc_chttp2_transport {
Craig Tiller9b8671c2015-06-12 07:41:54 -0700176 grpc_transport base; /* must be first */
177 grpc_endpoint *ep;
178 grpc_mdctx *metadata_context;
179 gpr_refcount refs;
180 gpr_uint8 is_client;
181
182 gpr_mu mu;
183 gpr_cv cv;
184
185 /* basic state management - what are we doing at the moment? */
186 gpr_uint8 reading;
187 /** are we calling back any grpc_transport_op completion events */
188 gpr_uint8 calling_back_ops;
189 gpr_uint8 destroying;
190 gpr_uint8 closed;
Craig Tillerb084d902015-06-12 07:50:02 -0700191 grpc_chttp2_error_state error_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700192
193 /* stream indexing */
194 gpr_uint32 next_stream_id;
195 gpr_uint32 last_incoming_stream_id;
196
197 /* settings */
198 gpr_uint32 settings[NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS];
199 gpr_uint32 force_send_settings; /* bitmask of setting indexes to send out */
200 gpr_uint8 sent_local_settings; /* have local settings been sent? */
201 gpr_uint8 dirtied_local_settings; /* are the local settings dirty? */
202
203 /* window management */
204 gpr_uint32 outgoing_window;
205 gpr_uint32 outgoing_window_update;
206 gpr_uint32 incoming_window;
207 gpr_uint32 connection_window_target;
208
209 /* deframing */
Craig Tillerb084d902015-06-12 07:50:02 -0700210 grpc_chttp2_deframe_transport_state deframe_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700211 gpr_uint8 incoming_frame_type;
212 gpr_uint8 incoming_frame_flags;
213 gpr_uint8 header_eof;
214 gpr_uint32 expect_continuation_stream_id;
215 gpr_uint32 incoming_frame_size;
216 gpr_uint32 incoming_stream_id;
217
218 /* goaway */
Craig Tillerb084d902015-06-12 07:50:02 -0700219 grpc_chttp2_pending_goaway *pending_goaways;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700220 size_t num_pending_goaways;
221 size_t cap_pending_goaways;
222
223 /* state for a stream that's not yet been created */
224 grpc_stream_op_buffer new_stream_sopb;
225
226 /* stream ops that need to be destroyed, but outside of the lock */
227 grpc_stream_op_buffer nuke_later_sopb;
228
229 /* active parser */
230 void *parser_data;
Craig Tillerb084d902015-06-12 07:50:02 -0700231 grpc_chttp2_stream *incoming_stream;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700232 grpc_chttp2_parse_error (*parser)(void *parser_user_data,
233 grpc_chttp2_parse_state *state,
234 gpr_slice slice, int is_last);
235
Craig Tillerb084d902015-06-12 07:50:02 -0700236 grpc_chttp2_stream_list lists[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700237 grpc_chttp2_stream_map stream_map;
238
239 /* pings */
Craig Tillerb084d902015-06-12 07:50:02 -0700240 grpc_chttp2_outstanding_ping *pings;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700241 size_t ping_count;
242 size_t ping_capacity;
243 gpr_int64 ping_counter;
244
245 struct {
246 /* metadata object cache */
247 grpc_mdstr *str_grpc_timeout;
248 } constants;
249
250 struct {
251 /** data to write next write */
252 gpr_slice_buffer qbuf;
253 /* queued callbacks */
254 grpc_iomgr_closure *pending_closures;
255 } global;
256
257 struct {
258 /** is a thread currently writing */
259 gpr_uint8 executing;
260 /** closure to execute this action */
261 grpc_iomgr_closure action;
262 /** data to write now */
263 gpr_slice_buffer outbuf;
264 /* hpack encoding */
265 grpc_chttp2_hpack_compressor hpack_compressor;
266 } writing;
267
268 struct {
269 /** is a thread currently parsing */
270 gpr_uint8 executing;
271 /** data to write later - after parsing */
272 gpr_slice_buffer qbuf;
273 /** parser for headers */
274 grpc_chttp2_hpack_parser hpack_parser;
275 /** simple one shot parsers */
276 union {
277 grpc_chttp2_window_update_parser window_update;
278 grpc_chttp2_settings_parser settings;
279 grpc_chttp2_ping_parser ping;
280 grpc_chttp2_rst_stream_parser rst_stream;
281 } simple;
282 /** parser for goaway frames */
283 grpc_chttp2_goaway_parser goaway_parser;
284 } parsing;
285
286 struct {
287 /** is a thread currently performing channel callbacks */
288 gpr_uint8 executing;
289 /** transport channel-level callback */
290 const grpc_transport_callbacks *cb;
291 /** user data for cb calls */
292 void *cb_user_data;
293 /** closure for notifying transport closure */
294 grpc_iomgr_closure notify_closed;
295 } channel_callback;
296};
297
Craig Tillerb084d902015-06-12 07:50:02 -0700298struct grpc_chttp2_stream {
Craig Tiller9b8671c2015-06-12 07:41:54 -0700299 struct {
300 grpc_iomgr_closure *send_done_closure;
301 grpc_iomgr_closure *recv_done_closure;
302 } global;
303
304 struct {
305 /* sops that have passed flow control to be written */
306 grpc_stream_op_buffer sopb;
307 /* how strongly should we indicate closure with the next write */
Craig Tillerb084d902015-06-12 07:50:02 -0700308 grpc_chttp2_send_closed send_closed;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700309 } writing;
310
311 struct {
312 int unused;
313 } parsing;
314
315 gpr_uint32 id;
316
317 gpr_uint32 incoming_window;
318 gpr_int64 outgoing_window;
319 gpr_uint32 outgoing_window_update;
320 /* when the application requests writes be closed, the write_closed is
321 'queued'; when the close is flow controlled into the send path, we are
322 'sending' it; when the write has been performed it is 'sent' */
Craig Tillerb084d902015-06-12 07:50:02 -0700323 grpc_chttp2_write_state write_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700324 gpr_uint8 read_closed;
325 gpr_uint8 cancelled;
326
Craig Tillerb084d902015-06-12 07:50:02 -0700327 grpc_chttp2_stream_link links[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700328 gpr_uint8 included[STREAM_LIST_COUNT];
329
330 /* incoming metadata */
331 grpc_linked_mdelem *incoming_metadata;
332 size_t incoming_metadata_count;
333 size_t incoming_metadata_capacity;
334 grpc_linked_mdelem *old_incoming_metadata;
335 gpr_timespec incoming_deadline;
336
337 /* sops from application */
338 grpc_stream_op_buffer *outgoing_sopb;
339 grpc_stream_op_buffer *incoming_sopb;
340 grpc_stream_state *publish_state;
341 grpc_stream_state published_state;
342
343 grpc_chttp2_data_parser parser;
344
345 grpc_stream_state callback_state;
346 grpc_stream_op_buffer callback_sopb;
347};
348
Craig Tiller3208e392015-06-12 08:17:02 -0700349/** Someone is unlocking the transport mutex: check to see if writes
350 are required, and schedule them if so */
351void grpc_chttp2_unlocking_check_writes(grpc_chttp2_transport_global *global, grpc_chttp2_transport_writing *writing);
352
Craig Tiller9b8671c2015-06-12 07:41:54 -0700353#endif