blob: caf2092a18a36194b842482e607c2a28bc2f4a90 [file] [log] [blame]
Craig Tiller9b8671c2015-06-12 07:41:54 -07001#ifndef GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
2#define GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
3
4#include "src/core/transport/transport_impl.h"
5
Craig Tillerb084d902015-06-12 07:50:02 -07006typedef struct grpc_chttp2_transport grpc_chttp2_transport;
7typedef struct grpc_chttp2_stream grpc_chttp2_stream;
Craig Tiller9b8671c2015-06-12 07:41:54 -07008
9/* streams are kept in various linked lists depending on what things need to
10 happen to them... this enum labels each list */
11typedef enum {
12 /* streams that have pending writes */
13 WRITABLE = 0,
14 /* streams that have been selected to be written */
15 WRITING,
16 /* streams that have just been written, and included a close */
17 WRITTEN_CLOSED,
18 /* streams that have been cancelled and have some pending state updates
19 to perform */
20 CANCELLED,
21 /* streams that want to send window updates */
22 WINDOW_UPDATE,
23 /* streams that are waiting to start because there are too many concurrent
24 streams on the connection */
25 WAITING_FOR_CONCURRENCY,
26 /* streams that have finished reading: we wait until unlock to coalesce
27 all changes into one callback */
28 FINISHED_READ_OP,
29 MAYBE_FINISH_READ_AFTER_PARSE,
30 PARSER_CHECK_WINDOW_UPDATES_AFTER_PARSE,
31 OTHER_CHECK_WINDOW_UPDATES_AFTER_PARSE,
32 NEW_OUTGOING_WINDOW,
33 STREAM_LIST_COUNT /* must be last */
Craig Tillerb084d902015-06-12 07:50:02 -070034} grpc_chttp2_stream_list_id;
Craig Tiller9b8671c2015-06-12 07:41:54 -070035
36/* deframer state for the overall http2 stream of bytes */
37typedef enum {
38 /* prefix: one entry per http2 connection prefix byte */
39 DTS_CLIENT_PREFIX_0 = 0,
40 DTS_CLIENT_PREFIX_1,
41 DTS_CLIENT_PREFIX_2,
42 DTS_CLIENT_PREFIX_3,
43 DTS_CLIENT_PREFIX_4,
44 DTS_CLIENT_PREFIX_5,
45 DTS_CLIENT_PREFIX_6,
46 DTS_CLIENT_PREFIX_7,
47 DTS_CLIENT_PREFIX_8,
48 DTS_CLIENT_PREFIX_9,
49 DTS_CLIENT_PREFIX_10,
50 DTS_CLIENT_PREFIX_11,
51 DTS_CLIENT_PREFIX_12,
52 DTS_CLIENT_PREFIX_13,
53 DTS_CLIENT_PREFIX_14,
54 DTS_CLIENT_PREFIX_15,
55 DTS_CLIENT_PREFIX_16,
56 DTS_CLIENT_PREFIX_17,
57 DTS_CLIENT_PREFIX_18,
58 DTS_CLIENT_PREFIX_19,
59 DTS_CLIENT_PREFIX_20,
60 DTS_CLIENT_PREFIX_21,
61 DTS_CLIENT_PREFIX_22,
62 DTS_CLIENT_PREFIX_23,
63 /* frame header byte 0... */
64 /* must follow from the prefix states */
65 DTS_FH_0,
66 DTS_FH_1,
67 DTS_FH_2,
68 DTS_FH_3,
69 DTS_FH_4,
70 DTS_FH_5,
71 DTS_FH_6,
72 DTS_FH_7,
73 /* ... frame header byte 8 */
74 DTS_FH_8,
75 /* inside a http2 frame */
76 DTS_FRAME
Craig Tillerb084d902015-06-12 07:50:02 -070077} grpc_chttp2_deframe_transport_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -070078
79typedef enum {
80 WRITE_STATE_OPEN,
81 WRITE_STATE_QUEUED_CLOSE,
82 WRITE_STATE_SENT_CLOSE
Craig Tillerb084d902015-06-12 07:50:02 -070083} grpc_chttp2_write_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -070084
85typedef enum {
86 DONT_SEND_CLOSED = 0,
87 SEND_CLOSED,
88 SEND_CLOSED_WITH_RST_STREAM
Craig Tillerb084d902015-06-12 07:50:02 -070089} grpc_chttp2_send_closed;
Craig Tiller9b8671c2015-06-12 07:41:54 -070090
91typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -070092 grpc_chttp2_stream *head;
93 grpc_chttp2_stream *tail;
94} grpc_chttp2_stream_list;
Craig Tiller9b8671c2015-06-12 07:41:54 -070095
96typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -070097 grpc_chttp2_stream *next;
98 grpc_chttp2_stream *prev;
99} grpc_chttp2_stream_link;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700100
101typedef enum {
102 ERROR_STATE_NONE,
103 ERROR_STATE_SEEN,
104 ERROR_STATE_NOTIFIED
Craig Tillerb084d902015-06-12 07:50:02 -0700105} grpc_chttp2_error_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700106
107/* We keep several sets of connection wide parameters */
108typedef enum {
109 /* The settings our peer has asked for (and we have acked) */
110 PEER_SETTINGS = 0,
111 /* The settings we'd like to have */
112 LOCAL_SETTINGS,
113 /* The settings we've published to our peer */
114 SENT_SETTINGS,
115 /* The settings the peer has acked */
116 ACKED_SETTINGS,
117 NUM_SETTING_SETS
Craig Tillerb084d902015-06-12 07:50:02 -0700118} grpc_chttp2_setting_set;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700119
120/* Outstanding ping request data */
121typedef struct {
122 gpr_uint8 id[8];
123 void (*cb)(void *user_data);
124 void *user_data;
Craig Tillerb084d902015-06-12 07:50:02 -0700125} grpc_chttp2_outstanding_ping;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700126
127typedef struct {
128 grpc_status_code status;
129 gpr_slice debug;
Craig Tillerb084d902015-06-12 07:50:02 -0700130} grpc_chttp2_pending_goaway;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700131
Craig Tillerb084d902015-06-12 07:50:02 -0700132struct grpc_chttp2_transport {
Craig Tiller9b8671c2015-06-12 07:41:54 -0700133 grpc_transport base; /* must be first */
134 grpc_endpoint *ep;
135 grpc_mdctx *metadata_context;
136 gpr_refcount refs;
137 gpr_uint8 is_client;
138
139 gpr_mu mu;
140 gpr_cv cv;
141
142 /* basic state management - what are we doing at the moment? */
143 gpr_uint8 reading;
144 /** are we calling back any grpc_transport_op completion events */
145 gpr_uint8 calling_back_ops;
146 gpr_uint8 destroying;
147 gpr_uint8 closed;
Craig Tillerb084d902015-06-12 07:50:02 -0700148 grpc_chttp2_error_state error_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700149
150 /* stream indexing */
151 gpr_uint32 next_stream_id;
152 gpr_uint32 last_incoming_stream_id;
153
154 /* settings */
155 gpr_uint32 settings[NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS];
156 gpr_uint32 force_send_settings; /* bitmask of setting indexes to send out */
157 gpr_uint8 sent_local_settings; /* have local settings been sent? */
158 gpr_uint8 dirtied_local_settings; /* are the local settings dirty? */
159
160 /* window management */
161 gpr_uint32 outgoing_window;
162 gpr_uint32 outgoing_window_update;
163 gpr_uint32 incoming_window;
164 gpr_uint32 connection_window_target;
165
166 /* deframing */
Craig Tillerb084d902015-06-12 07:50:02 -0700167 grpc_chttp2_deframe_transport_state deframe_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700168 gpr_uint8 incoming_frame_type;
169 gpr_uint8 incoming_frame_flags;
170 gpr_uint8 header_eof;
171 gpr_uint32 expect_continuation_stream_id;
172 gpr_uint32 incoming_frame_size;
173 gpr_uint32 incoming_stream_id;
174
175 /* goaway */
Craig Tillerb084d902015-06-12 07:50:02 -0700176 grpc_chttp2_pending_goaway *pending_goaways;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700177 size_t num_pending_goaways;
178 size_t cap_pending_goaways;
179
180 /* state for a stream that's not yet been created */
181 grpc_stream_op_buffer new_stream_sopb;
182
183 /* stream ops that need to be destroyed, but outside of the lock */
184 grpc_stream_op_buffer nuke_later_sopb;
185
186 /* active parser */
187 void *parser_data;
Craig Tillerb084d902015-06-12 07:50:02 -0700188 grpc_chttp2_stream *incoming_stream;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700189 grpc_chttp2_parse_error (*parser)(void *parser_user_data,
190 grpc_chttp2_parse_state *state,
191 gpr_slice slice, int is_last);
192
Craig Tillerb084d902015-06-12 07:50:02 -0700193 grpc_chttp2_stream_list lists[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700194 grpc_chttp2_stream_map stream_map;
195
196 /* pings */
Craig Tillerb084d902015-06-12 07:50:02 -0700197 grpc_chttp2_outstanding_ping *pings;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700198 size_t ping_count;
199 size_t ping_capacity;
200 gpr_int64 ping_counter;
201
202 struct {
203 /* metadata object cache */
204 grpc_mdstr *str_grpc_timeout;
205 } constants;
206
207 struct {
208 /** data to write next write */
209 gpr_slice_buffer qbuf;
210 /* queued callbacks */
211 grpc_iomgr_closure *pending_closures;
212 } global;
213
214 struct {
215 /** is a thread currently writing */
216 gpr_uint8 executing;
217 /** closure to execute this action */
218 grpc_iomgr_closure action;
219 /** data to write now */
220 gpr_slice_buffer outbuf;
221 /* hpack encoding */
222 grpc_chttp2_hpack_compressor hpack_compressor;
223 } writing;
224
225 struct {
226 /** is a thread currently parsing */
227 gpr_uint8 executing;
228 /** data to write later - after parsing */
229 gpr_slice_buffer qbuf;
230 /** parser for headers */
231 grpc_chttp2_hpack_parser hpack_parser;
232 /** simple one shot parsers */
233 union {
234 grpc_chttp2_window_update_parser window_update;
235 grpc_chttp2_settings_parser settings;
236 grpc_chttp2_ping_parser ping;
237 grpc_chttp2_rst_stream_parser rst_stream;
238 } simple;
239 /** parser for goaway frames */
240 grpc_chttp2_goaway_parser goaway_parser;
241 } parsing;
242
243 struct {
244 /** is a thread currently performing channel callbacks */
245 gpr_uint8 executing;
246 /** transport channel-level callback */
247 const grpc_transport_callbacks *cb;
248 /** user data for cb calls */
249 void *cb_user_data;
250 /** closure for notifying transport closure */
251 grpc_iomgr_closure notify_closed;
252 } channel_callback;
253};
254
Craig Tillerb084d902015-06-12 07:50:02 -0700255struct grpc_chttp2_stream {
Craig Tiller9b8671c2015-06-12 07:41:54 -0700256 struct {
257 grpc_iomgr_closure *send_done_closure;
258 grpc_iomgr_closure *recv_done_closure;
259 } global;
260
261 struct {
262 /* sops that have passed flow control to be written */
263 grpc_stream_op_buffer sopb;
264 /* how strongly should we indicate closure with the next write */
Craig Tillerb084d902015-06-12 07:50:02 -0700265 grpc_chttp2_send_closed send_closed;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700266 } writing;
267
268 struct {
269 int unused;
270 } parsing;
271
272 gpr_uint32 id;
273
274 gpr_uint32 incoming_window;
275 gpr_int64 outgoing_window;
276 gpr_uint32 outgoing_window_update;
277 /* when the application requests writes be closed, the write_closed is
278 'queued'; when the close is flow controlled into the send path, we are
279 'sending' it; when the write has been performed it is 'sent' */
Craig Tillerb084d902015-06-12 07:50:02 -0700280 grpc_chttp2_write_state write_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700281 gpr_uint8 read_closed;
282 gpr_uint8 cancelled;
283
Craig Tillerb084d902015-06-12 07:50:02 -0700284 grpc_chttp2_stream_link links[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700285 gpr_uint8 included[STREAM_LIST_COUNT];
286
287 /* incoming metadata */
288 grpc_linked_mdelem *incoming_metadata;
289 size_t incoming_metadata_count;
290 size_t incoming_metadata_capacity;
291 grpc_linked_mdelem *old_incoming_metadata;
292 gpr_timespec incoming_deadline;
293
294 /* sops from application */
295 grpc_stream_op_buffer *outgoing_sopb;
296 grpc_stream_op_buffer *incoming_sopb;
297 grpc_stream_state *publish_state;
298 grpc_stream_state published_state;
299
300 grpc_chttp2_data_parser parser;
301
302 grpc_stream_state callback_state;
303 grpc_stream_op_buffer callback_sopb;
304};
305
306#endif