blob: 2e7b334426fd365f3c9c1ad0d85a3cd61f20a696 [file] [log] [blame]
Craig Tiller640d3bd2015-06-12 07:51:51 -07001/*
2 *
murgatroid993466c4b2016-01-12 10:26:04 -08003 * Copyright 2015-2016, Google Inc.
Craig Tiller640d3bd2015-06-12 07:51:51 -07004 * 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 Tiller9a4dddd2016-03-25 17:08:13 -070034#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H
35#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H
Craig Tiller9b8671c2015-06-12 07:41:54 -070036
Craig Tiller9d35a1f2015-11-02 14:16:12 -080037#include <assert.h>
yang-g55b1b592016-01-28 12:03:03 -080038#include <stdbool.h>
Craig Tiller9d35a1f2015-11-02 14:16:12 -080039
Craig Tiller3208e392015-06-12 08:17:02 -070040#include "src/core/iomgr/endpoint.h"
Craig Tillerd20efd22015-06-12 16:17:09 -070041#include "src/core/transport/chttp2/frame.h"
Craig Tiller3208e392015-06-12 08:17:02 -070042#include "src/core/transport/chttp2/frame_data.h"
43#include "src/core/transport/chttp2/frame_goaway.h"
44#include "src/core/transport/chttp2/frame_ping.h"
45#include "src/core/transport/chttp2/frame_rst_stream.h"
46#include "src/core/transport/chttp2/frame_settings.h"
47#include "src/core/transport/chttp2/frame_window_update.h"
Craig Tiller9d35a1f2015-11-02 14:16:12 -080048#include "src/core/transport/chttp2/hpack_encoder.h"
Craig Tiller3208e392015-06-12 08:17:02 -070049#include "src/core/transport/chttp2/hpack_parser.h"
Craig Tiller5dc3b302015-06-15 16:06:50 -070050#include "src/core/transport/chttp2/incoming_metadata.h"
Craig Tiller5dc3b302015-06-15 16:06:50 -070051#include "src/core/transport/chttp2/stream_map.h"
Craig Tiller08a1cf82015-06-29 09:37:52 -070052#include "src/core/transport/connectivity_state.h"
53#include "src/core/transport/transport_impl.h"
Craig Tiller9b8671c2015-06-12 07:41:54 -070054
Craig Tillerb084d902015-06-12 07:50:02 -070055typedef struct grpc_chttp2_transport grpc_chttp2_transport;
56typedef struct grpc_chttp2_stream grpc_chttp2_stream;
Craig Tiller9b8671c2015-06-12 07:41:54 -070057
58/* streams are kept in various linked lists depending on what things need to
59 happen to them... this enum labels each list */
Craig Tillera82950e2015-09-22 12:33:20 -070060typedef enum {
Craig Tiller5dc3b302015-06-15 16:06:50 -070061 GRPC_CHTTP2_LIST_ALL_STREAMS,
Craig Tiller9d35a1f2015-11-02 14:16:12 -080062 GRPC_CHTTP2_LIST_CHECK_READ_OPS,
63 GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE,
Craig Tiller5dc3b302015-06-15 16:06:50 -070064 GRPC_CHTTP2_LIST_WRITABLE,
Craig Tiller6459db42015-06-15 17:11:45 -070065 GRPC_CHTTP2_LIST_WRITING,
66 GRPC_CHTTP2_LIST_WRITTEN,
Craig Tiller6459db42015-06-15 17:11:45 -070067 GRPC_CHTTP2_LIST_PARSING_SEEN,
Craig Tiller83fb0702015-06-16 21:13:07 -070068 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING,
Craig Tillerabb2e3d2015-12-15 06:23:59 -080069 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING,
Craig Tiller9d35a1f2015-11-02 14:16:12 -080070 GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT,
yang-g348f3a22016-01-27 16:17:32 -080071 /* streams waiting for the outgoing window in the writing path, they will be
72 * merged to the stalled list or writable list under transport lock. */
73 GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT,
Craig Tiller5dc3b302015-06-15 16:06:50 -070074 /** streams that are waiting to start because there are too many concurrent
75 streams on the connection */
76 GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY,
Craig Tillera82950e2015-09-22 12:33:20 -070077 STREAM_LIST_COUNT /* must be last */
Craig Tillerb084d902015-06-12 07:50:02 -070078} grpc_chttp2_stream_list_id;
Craig Tiller9b8671c2015-06-12 07:41:54 -070079
80/* deframer state for the overall http2 stream of bytes */
Craig Tillera82950e2015-09-22 12:33:20 -070081typedef enum {
Craig Tiller9b8671c2015-06-12 07:41:54 -070082 /* prefix: one entry per http2 connection prefix byte */
Craig Tillerab630732015-06-25 11:20:01 -070083 GRPC_DTS_CLIENT_PREFIX_0 = 0,
84 GRPC_DTS_CLIENT_PREFIX_1,
85 GRPC_DTS_CLIENT_PREFIX_2,
86 GRPC_DTS_CLIENT_PREFIX_3,
87 GRPC_DTS_CLIENT_PREFIX_4,
88 GRPC_DTS_CLIENT_PREFIX_5,
89 GRPC_DTS_CLIENT_PREFIX_6,
90 GRPC_DTS_CLIENT_PREFIX_7,
91 GRPC_DTS_CLIENT_PREFIX_8,
92 GRPC_DTS_CLIENT_PREFIX_9,
93 GRPC_DTS_CLIENT_PREFIX_10,
94 GRPC_DTS_CLIENT_PREFIX_11,
95 GRPC_DTS_CLIENT_PREFIX_12,
96 GRPC_DTS_CLIENT_PREFIX_13,
97 GRPC_DTS_CLIENT_PREFIX_14,
98 GRPC_DTS_CLIENT_PREFIX_15,
99 GRPC_DTS_CLIENT_PREFIX_16,
100 GRPC_DTS_CLIENT_PREFIX_17,
101 GRPC_DTS_CLIENT_PREFIX_18,
102 GRPC_DTS_CLIENT_PREFIX_19,
103 GRPC_DTS_CLIENT_PREFIX_20,
104 GRPC_DTS_CLIENT_PREFIX_21,
105 GRPC_DTS_CLIENT_PREFIX_22,
106 GRPC_DTS_CLIENT_PREFIX_23,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700107 /* frame header byte 0... */
108 /* must follow from the prefix states */
Craig Tillerab630732015-06-25 11:20:01 -0700109 GRPC_DTS_FH_0,
110 GRPC_DTS_FH_1,
111 GRPC_DTS_FH_2,
112 GRPC_DTS_FH_3,
113 GRPC_DTS_FH_4,
114 GRPC_DTS_FH_5,
115 GRPC_DTS_FH_6,
116 GRPC_DTS_FH_7,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700117 /* ... frame header byte 8 */
Craig Tillerab630732015-06-25 11:20:01 -0700118 GRPC_DTS_FH_8,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700119 /* inside a http2 frame */
Craig Tillerab630732015-06-25 11:20:01 -0700120 GRPC_DTS_FRAME
Craig Tillerb084d902015-06-12 07:50:02 -0700121} grpc_chttp2_deframe_transport_state;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700122
Craig Tillera82950e2015-09-22 12:33:20 -0700123typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -0700124 grpc_chttp2_stream *head;
125 grpc_chttp2_stream *tail;
126} grpc_chttp2_stream_list;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700127
Craig Tillera82950e2015-09-22 12:33:20 -0700128typedef struct {
Craig Tillerb084d902015-06-12 07:50:02 -0700129 grpc_chttp2_stream *next;
130 grpc_chttp2_stream *prev;
131} grpc_chttp2_stream_link;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700132
Craig Tiller9b8671c2015-06-12 07:41:54 -0700133/* We keep several sets of connection wide parameters */
Craig Tillera82950e2015-09-22 12:33:20 -0700134typedef enum {
Craig Tiller9b8671c2015-06-12 07:41:54 -0700135 /* The settings our peer has asked for (and we have acked) */
Craig Tillerab630732015-06-25 11:20:01 -0700136 GRPC_PEER_SETTINGS = 0,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700137 /* The settings we'd like to have */
Craig Tillerab630732015-06-25 11:20:01 -0700138 GRPC_LOCAL_SETTINGS,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700139 /* The settings we've published to our peer */
Craig Tillerab630732015-06-25 11:20:01 -0700140 GRPC_SENT_SETTINGS,
Craig Tiller9b8671c2015-06-12 07:41:54 -0700141 /* The settings the peer has acked */
Craig Tillerab630732015-06-25 11:20:01 -0700142 GRPC_ACKED_SETTINGS,
143 GRPC_NUM_SETTING_SETS
Craig Tillerb084d902015-06-12 07:50:02 -0700144} grpc_chttp2_setting_set;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700145
146/* Outstanding ping request data */
Craig Tillera82950e2015-09-22 12:33:20 -0700147typedef struct grpc_chttp2_outstanding_ping {
Craig Tiller7536af02015-12-22 13:49:30 -0800148 uint8_t id[8];
Craig Tiller33825112015-09-18 07:44:19 -0700149 grpc_closure *on_recv;
Craig Tiller3719f072015-06-12 17:19:51 -0700150 struct grpc_chttp2_outstanding_ping *next;
151 struct grpc_chttp2_outstanding_ping *prev;
Craig Tillerb084d902015-06-12 07:50:02 -0700152} grpc_chttp2_outstanding_ping;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700153
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800154/* forward declared in frame_data.h */
155struct grpc_chttp2_incoming_byte_stream {
156 grpc_byte_stream base;
157 gpr_refcount refs;
158 struct grpc_chttp2_incoming_byte_stream *next_message;
Craig Tiller38edec62015-12-14 15:01:29 -0800159 int failed;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800160
161 grpc_chttp2_transport *transport;
162 grpc_chttp2_stream *stream;
163 int is_tail;
164 gpr_slice_buffer slices;
165 grpc_closure *on_next;
166 gpr_slice *next;
167};
168
Craig Tillera82950e2015-09-22 12:33:20 -0700169typedef struct {
Craig Tillerd20efd22015-06-12 16:17:09 -0700170 /** data to write next write */
171 gpr_slice_buffer qbuf;
Craig Tillerd20efd22015-06-12 16:17:09 -0700172
173 /** window available for us to send to peer */
Craig Tiller7536af02015-12-22 13:49:30 -0800174 int64_t outgoing_window;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800175 /** window available to announce to peer */
Craig Tiller7536af02015-12-22 13:49:30 -0800176 int64_t announce_incoming_window;
Craig Tillerd20efd22015-06-12 16:17:09 -0700177 /** how much window would we like to have for incoming_window */
Craig Tiller7536af02015-12-22 13:49:30 -0800178 uint32_t connection_window_target;
Craig Tillerd20efd22015-06-12 16:17:09 -0700179
Craig Tiller1064f8b2015-06-25 13:52:57 -0700180 /** have we seen a goaway */
Craig Tiller7536af02015-12-22 13:49:30 -0800181 uint8_t seen_goaway;
Craig Tiller9188d7a2015-07-05 12:44:37 -0700182 /** have we sent a goaway */
Craig Tiller7536af02015-12-22 13:49:30 -0800183 uint8_t sent_goaway;
Craig Tiller1064f8b2015-06-25 13:52:57 -0700184
Craig Tiller3719f072015-06-12 17:19:51 -0700185 /** is this transport a client? */
Craig Tiller7536af02015-12-22 13:49:30 -0800186 uint8_t is_client;
Craig Tillerd20efd22015-06-12 16:17:09 -0700187 /** are the local settings dirty and need to be sent? */
Craig Tiller7536af02015-12-22 13:49:30 -0800188 uint8_t dirtied_local_settings;
Craig Tillerd20efd22015-06-12 16:17:09 -0700189 /** have local settings been sent? */
Craig Tiller7536af02015-12-22 13:49:30 -0800190 uint8_t sent_local_settings;
Craig Tillerd20efd22015-06-12 16:17:09 -0700191 /** bitmask of setting indexes to send out */
Craig Tiller7536af02015-12-22 13:49:30 -0800192 uint32_t force_send_settings;
Craig Tillerd20efd22015-06-12 16:17:09 -0700193 /** settings values */
Craig Tiller7536af02015-12-22 13:49:30 -0800194 uint32_t settings[GRPC_NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS];
Craig Tillerd20efd22015-06-12 16:17:09 -0700195
Craig Tiller606d8742015-06-15 06:58:50 -0700196 /** what is the next stream id to be allocated by this peer?
197 copied to next_stream_id in parsing when parsing commences */
Craig Tiller7536af02015-12-22 13:49:30 -0800198 uint32_t next_stream_id;
Craig Tiller606d8742015-06-15 06:58:50 -0700199
Craig Tillera8d68092015-11-17 08:02:29 -0800200 /** how far to lookahead in a stream? */
Craig Tiller7536af02015-12-22 13:49:30 -0800201 uint32_t stream_lookahead;
Craig Tillera8d68092015-11-17 08:02:29 -0800202
Craig Tillerd20efd22015-06-12 16:17:09 -0700203 /** last received stream id */
Craig Tiller7536af02015-12-22 13:49:30 -0800204 uint32_t last_incoming_stream_id;
Craig Tiller3719f072015-06-12 17:19:51 -0700205
206 /** pings awaiting responses */
207 grpc_chttp2_outstanding_ping pings;
Craig Tiller606d8742015-06-15 06:58:50 -0700208 /** next payload for an outgoing ping */
Craig Tiller7536af02015-12-22 13:49:30 -0800209 uint64_t ping_counter;
Craig Tiller606d8742015-06-15 06:58:50 -0700210
211 /** concurrent stream count: updated when not parsing,
212 so this is a strict over-estimation on the client */
Craig Tiller7536af02015-12-22 13:49:30 -0800213 uint32_t concurrent_stream_count;
Craig Tillerd20efd22015-06-12 16:17:09 -0700214} grpc_chttp2_transport_global;
215
Craig Tillera82950e2015-09-22 12:33:20 -0700216typedef struct {
Craig Tillerd20efd22015-06-12 16:17:09 -0700217 /** data to write now */
218 gpr_slice_buffer outbuf;
219 /** hpack encoding */
220 grpc_chttp2_hpack_compressor hpack_compressor;
Craig Tiller7536af02015-12-22 13:49:30 -0800221 int64_t outgoing_window;
Craig Tiller285b8822015-06-17 15:58:13 -0700222 /** is this a client? */
Craig Tiller7536af02015-12-22 13:49:30 -0800223 uint8_t is_client;
Craig Tillerb0298592015-08-27 07:38:01 -0700224 /** callback for when writing is done */
Craig Tiller33825112015-09-18 07:44:19 -0700225 grpc_closure done_cb;
Craig Tillerd20efd22015-06-12 16:17:09 -0700226} grpc_chttp2_transport_writing;
227
Craig Tillera82950e2015-09-22 12:33:20 -0700228struct grpc_chttp2_transport_parsing {
Craig Tillerd20efd22015-06-12 16:17:09 -0700229 /** is this transport a client? (boolean) */
Craig Tiller7536af02015-12-22 13:49:30 -0800230 uint8_t is_client;
Craig Tillerd20efd22015-06-12 16:17:09 -0700231
232 /** were settings updated? */
Craig Tiller7536af02015-12-22 13:49:30 -0800233 uint8_t settings_updated;
Craig Tillerd20efd22015-06-12 16:17:09 -0700234 /** was a settings ack received? */
Craig Tiller7536af02015-12-22 13:49:30 -0800235 uint8_t settings_ack_received;
Craig Tillerd20efd22015-06-12 16:17:09 -0700236 /** was a goaway frame received? */
Craig Tiller7536af02015-12-22 13:49:30 -0800237 uint8_t goaway_received;
Craig Tillerd20efd22015-06-12 16:17:09 -0700238
Craig Tiller027a74c2015-11-10 08:37:46 +0000239 /** the last sent max_table_size setting */
Craig Tiller7536af02015-12-22 13:49:30 -0800240 uint32_t last_sent_max_table_size;
Craig Tiller027a74c2015-11-10 08:37:46 +0000241
Craig Tiller3719f072015-06-12 17:19:51 -0700242 /** initial window change */
Craig Tiller7536af02015-12-22 13:49:30 -0800243 int64_t initial_window_update;
Craig Tiller3719f072015-06-12 17:19:51 -0700244
Craig Tillerd20efd22015-06-12 16:17:09 -0700245 /** data to write later - after parsing */
246 gpr_slice_buffer qbuf;
Craig Tillerd20efd22015-06-12 16:17:09 -0700247 /** parser for headers */
248 grpc_chttp2_hpack_parser hpack_parser;
249 /** simple one shot parsers */
Craig Tillera82950e2015-09-22 12:33:20 -0700250 union {
Craig Tillerd20efd22015-06-12 16:17:09 -0700251 grpc_chttp2_window_update_parser window_update;
252 grpc_chttp2_settings_parser settings;
253 grpc_chttp2_ping_parser ping;
254 grpc_chttp2_rst_stream_parser rst_stream;
255 } simple;
256 /** parser for goaway frames */
257 grpc_chttp2_goaway_parser goaway_parser;
258
259 /** window available for peer to send to us */
Craig Tiller7536af02015-12-22 13:49:30 -0800260 int64_t incoming_window;
Craig Tillerd20efd22015-06-12 16:17:09 -0700261
262 /** next stream id available at the time of beginning parsing */
Craig Tiller7536af02015-12-22 13:49:30 -0800263 uint32_t next_stream_id;
264 uint32_t last_incoming_stream_id;
Craig Tillerd20efd22015-06-12 16:17:09 -0700265
266 /* deframing */
267 grpc_chttp2_deframe_transport_state deframe_state;
Craig Tiller7536af02015-12-22 13:49:30 -0800268 uint8_t incoming_frame_type;
269 uint8_t incoming_frame_flags;
270 uint8_t header_eof;
271 uint32_t expect_continuation_stream_id;
272 uint32_t incoming_frame_size;
273 uint32_t incoming_stream_id;
Craig Tillerd20efd22015-06-12 16:17:09 -0700274
275 /* active parser */
276 void *parser_data;
277 grpc_chttp2_stream_parsing *incoming_stream;
Craig Tillera82950e2015-09-22 12:33:20 -0700278 grpc_chttp2_parse_error (*parser)(
279 grpc_exec_ctx *exec_ctx, void *parser_user_data,
280 grpc_chttp2_transport_parsing *transport_parsing,
281 grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
Craig Tillerd20efd22015-06-12 16:17:09 -0700282
283 /* received settings */
Craig Tiller7536af02015-12-22 13:49:30 -0800284 uint32_t settings[GRPC_CHTTP2_NUM_SETTINGS];
Craig Tillerd20efd22015-06-12 16:17:09 -0700285
286 /* goaway data */
287 grpc_status_code goaway_error;
Craig Tiller7536af02015-12-22 13:49:30 -0800288 uint32_t goaway_last_stream_index;
Craig Tillerd20efd22015-06-12 16:17:09 -0700289 gpr_slice goaway_text;
Craig Tiller3719f072015-06-12 17:19:51 -0700290
Craig Tiller7536af02015-12-22 13:49:30 -0800291 int64_t outgoing_window;
Craig Tillerd20efd22015-06-12 16:17:09 -0700292};
293
Craig Tillera82950e2015-09-22 12:33:20 -0700294struct grpc_chttp2_transport {
295 grpc_transport base; /* must be first */
Craig Tiller9b8671c2015-06-12 07:41:54 -0700296 grpc_endpoint *ep;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700297 gpr_refcount refs;
Craig Tiller1b22b9d2015-07-20 13:42:22 -0700298 char *peer_string;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700299
Craig Tiller9f80fcf2015-08-28 08:22:48 -0700300 /** when this drops to zero it's safe to shutdown the endpoint */
301 gpr_refcount shutdown_ep_refs;
302
Craig Tiller9b8671c2015-06-12 07:41:54 -0700303 gpr_mu mu;
Craig Tiller606d8742015-06-15 06:58:50 -0700304
305 /** is the transport destroying itself? */
Craig Tiller7536af02015-12-22 13:49:30 -0800306 uint8_t destroying;
Craig Tiller606d8742015-06-15 06:58:50 -0700307 /** has the upper layer closed the transport? */
Craig Tiller7536af02015-12-22 13:49:30 -0800308 uint8_t closed;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700309
Craig Tillerd20efd22015-06-12 16:17:09 -0700310 /** is a thread currently writing */
Craig Tiller7536af02015-12-22 13:49:30 -0800311 uint8_t writing_active;
Craig Tiller606d8742015-06-15 06:58:50 -0700312 /** is a thread currently parsing */
Craig Tiller7536af02015-12-22 13:49:30 -0800313 uint8_t parsing_active;
Craig Tillerd20efd22015-06-12 16:17:09 -0700314
Craig Tiller606d8742015-06-15 06:58:50 -0700315 /** is there a read request to the endpoint outstanding? */
Craig Tiller7536af02015-12-22 13:49:30 -0800316 uint8_t endpoint_reading;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700317
Craig Tiller606d8742015-06-15 06:58:50 -0700318 /** various lists of streams */
Craig Tillerb084d902015-06-12 07:50:02 -0700319 grpc_chttp2_stream_list lists[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700320
Craig Tiller606d8742015-06-15 06:58:50 -0700321 /** global state for reading/writing */
Craig Tillerd20efd22015-06-12 16:17:09 -0700322 grpc_chttp2_transport_global global;
Craig Tiller606d8742015-06-15 06:58:50 -0700323 /** state only accessible by the chain of execution that
324 set writing_active=1 */
Craig Tillerd20efd22015-06-12 16:17:09 -0700325 grpc_chttp2_transport_writing writing;
Craig Tiller606d8742015-06-15 06:58:50 -0700326 /** state only accessible by the chain of execution that
327 set parsing_active=1 */
Craig Tillerd20efd22015-06-12 16:17:09 -0700328 grpc_chttp2_transport_parsing parsing;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700329
Craig Tiller606d8742015-06-15 06:58:50 -0700330 /** maps stream id to grpc_chttp2_stream objects;
331 owned by the parsing thread when parsing */
332 grpc_chttp2_stream_map parsing_stream_map;
333
334 /** streams created by the client (possibly during parsing);
335 merged with parsing_stream_map during unlock when no
336 parsing is occurring */
337 grpc_chttp2_stream_map new_stream_map;
338
Craig Tillerd20efd22015-06-12 16:17:09 -0700339 /** closure to execute writing */
Craig Tiller33825112015-09-18 07:44:19 -0700340 grpc_closure writing_action;
Craig Tillerb0298592015-08-27 07:38:01 -0700341 /** closure to finish reading from the endpoint */
Craig Tiller33825112015-09-18 07:44:19 -0700342 grpc_closure recv_data;
Craig Tillerb0298592015-08-27 07:38:01 -0700343
344 /** incoming read bytes */
345 gpr_slice_buffer read_buffer;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700346
Craig Tiller4aa71a12015-06-15 13:00:55 -0700347 /** address to place a newly accepted stream - set and unset by
Craig Tiller606d8742015-06-15 06:58:50 -0700348 grpc_chttp2_parsing_accept_stream; used by init_stream to
349 publish the accepted server stream */
350 grpc_chttp2_stream **accepting_stream;
351
Craig Tillera82950e2015-09-22 12:33:20 -0700352 struct {
Craig Tiller1064f8b2015-06-25 13:52:57 -0700353 /* accept stream callback */
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800354 void (*accept_stream)(grpc_exec_ctx *exec_ctx, void *user_data,
355 grpc_transport *transport, const void *server_data);
Craig Tiller1064f8b2015-06-25 13:52:57 -0700356 void *accept_stream_user_data;
357
358 /** connectivity tracking */
Craig Tiller08a1cf82015-06-29 09:37:52 -0700359 grpc_connectivity_state_tracker state_tracker;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700360 } channel_callback;
Craig Tillerd7f12e32016-03-03 10:08:31 -0800361
362 /** Transport op to be applied post-parsing */
363 grpc_transport_op *post_parsing_op;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700364};
365
Craig Tillera82950e2015-09-22 12:33:20 -0700366typedef struct {
Craig Tillerd20efd22015-06-12 16:17:09 -0700367 /** HTTP2 stream id for this stream, or zero if one has not been assigned */
Craig Tiller7536af02015-12-22 13:49:30 -0800368 uint32_t id;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700369
Craig Tillerd20efd22015-06-12 16:17:09 -0700370 /** window available for us to send to peer */
Craig Tiller7536af02015-12-22 13:49:30 -0800371 int64_t outgoing_window;
Craig Tiller27166a62015-07-05 21:08:33 -0700372 /** The number of bytes the upper layers have offered to receive.
373 As the upper layer offers more bytes, this value increases.
374 As bytes are read, this value decreases. */
Craig Tiller7536af02015-12-22 13:49:30 -0800375 uint32_t max_recv_bytes;
Craig Tiller27166a62015-07-05 21:08:33 -0700376 /** The number of bytes the upper layer has offered to read but we have
377 not yet announced to HTTP2 flow control.
378 As the upper layers offer to read more bytes, this value increases.
379 As we advertise incoming flow control window, this value decreases. */
Craig Tiller7536af02015-12-22 13:49:30 -0800380 uint32_t unannounced_incoming_window_for_parse;
381 uint32_t unannounced_incoming_window_for_writing;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800382 /** things the upper layers would like to send */
383 grpc_metadata_batch *send_initial_metadata;
384 grpc_closure *send_initial_metadata_finished;
385 grpc_byte_stream *send_message;
386 grpc_closure *send_message_finished;
387 grpc_metadata_batch *send_trailing_metadata;
388 grpc_closure *send_trailing_metadata_finished;
389
390 grpc_metadata_batch *recv_initial_metadata;
Craig Tillera44cbfc2016-02-03 16:02:49 -0800391 grpc_closure *recv_initial_metadata_ready;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800392 grpc_byte_stream **recv_message;
393 grpc_closure *recv_message_ready;
394 grpc_metadata_batch *recv_trailing_metadata;
395 grpc_closure *recv_trailing_metadata_finished;
396
Craig Tillerd20efd22015-06-12 16:17:09 -0700397 /** when the application requests writes be closed, the write_closed is
398 'queued'; when the close is flow controlled into the send path, we are
399 'sending' it; when the write has been performed it is 'sent' */
Craig Tiller7536af02015-12-22 13:49:30 -0800400 uint8_t write_closed;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800401 /** is this stream reading half-closed (boolean) */
Craig Tiller7536af02015-12-22 13:49:30 -0800402 uint8_t read_closed;
Craig Tiller5dc3b302015-06-15 16:06:50 -0700403 /** is this stream in the stream map? (boolean) */
Craig Tiller7536af02015-12-22 13:49:30 -0800404 uint8_t in_stream_map;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800405 /** has this stream seen an error? if 1, then pending incoming frames
406 can be thrown away */
Craig Tiller7536af02015-12-22 13:49:30 -0800407 uint8_t seen_error;
Craig Tiller606d8742015-06-15 06:58:50 -0700408
Craig Tiller7536af02015-12-22 13:49:30 -0800409 uint8_t published_initial_metadata;
410 uint8_t published_trailing_metadata;
411 uint8_t faked_trailing_metadata;
Craig Tiller5dc3b302015-06-15 16:06:50 -0700412
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800413 grpc_chttp2_incoming_metadata_buffer received_initial_metadata;
414 grpc_chttp2_incoming_metadata_buffer received_trailing_metadata;
415
416 grpc_chttp2_incoming_frame_queue incoming_frames;
Craig Tillerd20efd22015-06-12 16:17:09 -0700417} grpc_chttp2_stream_global;
418
Craig Tillera82950e2015-09-22 12:33:20 -0700419typedef struct {
Craig Tillerd20efd22015-06-12 16:17:09 -0700420 /** HTTP2 stream id for this stream, or zero if one has not been assigned */
Craig Tiller7536af02015-12-22 13:49:30 -0800421 uint32_t id;
422 uint8_t fetching;
Craig Tiller0cb803d2016-03-02 22:17:24 -0800423 bool sent_initial_metadata;
Craig Tiller7536af02015-12-22 13:49:30 -0800424 uint8_t sent_message;
425 uint8_t sent_trailing_metadata;
426 uint8_t read_closed;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800427 /** send this initial metadata */
428 grpc_metadata_batch *send_initial_metadata;
429 grpc_byte_stream *send_message;
430 grpc_metadata_batch *send_trailing_metadata;
Craig Tiller7536af02015-12-22 13:49:30 -0800431 int64_t outgoing_window;
Craig Tiller86316522015-07-15 11:35:07 -0700432 /** how much window should we announce? */
Craig Tiller7536af02015-12-22 13:49:30 -0800433 uint32_t announce_window;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800434 gpr_slice_buffer flow_controlled_buffer;
435 gpr_slice fetching_slice;
436 size_t stream_fetched;
437 grpc_closure finished_fetch;
Craig Tillerd20efd22015-06-12 16:17:09 -0700438} grpc_chttp2_stream_writing;
439
Craig Tillera82950e2015-09-22 12:33:20 -0700440struct grpc_chttp2_stream_parsing {
Craig Tillerd20efd22015-06-12 16:17:09 -0700441 /** HTTP2 stream id for this stream, or zero if one has not been assigned */
Craig Tiller7536af02015-12-22 13:49:30 -0800442 uint32_t id;
Craig Tillerd20efd22015-06-12 16:17:09 -0700443 /** has this stream received a close */
Craig Tiller7536af02015-12-22 13:49:30 -0800444 uint8_t received_close;
Craig Tiller3719f072015-06-12 17:19:51 -0700445 /** saw a rst_stream */
Craig Tiller7536af02015-12-22 13:49:30 -0800446 uint8_t saw_rst_stream;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800447 /** how many header frames have we received? */
Craig Tiller7536af02015-12-22 13:49:30 -0800448 uint8_t header_frames_received;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800449 /** which metadata did we get (on this parse) */
Craig Tiller7536af02015-12-22 13:49:30 -0800450 uint8_t got_metadata_on_parse[2];
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800451 /** should we raise the seen_error flag in transport_global */
Craig Tiller7536af02015-12-22 13:49:30 -0800452 uint8_t seen_error;
Craig Tillerd20efd22015-06-12 16:17:09 -0700453 /** window available for peer to send to us */
Craig Tiller7536af02015-12-22 13:49:30 -0800454 int64_t incoming_window;
Craig Tillerd20efd22015-06-12 16:17:09 -0700455 /** parsing state for data frames */
456 grpc_chttp2_data_parser data_parser;
Craig Tiller3719f072015-06-12 17:19:51 -0700457 /** reason give to rst_stream */
Craig Tiller7536af02015-12-22 13:49:30 -0800458 uint32_t rst_stream_reason;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800459 /** amount of window given */
Craig Tiller7536af02015-12-22 13:49:30 -0800460 int64_t outgoing_window;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800461 /** number of bytes received - reset at end of parse thread execution */
Craig Tiller7536af02015-12-22 13:49:30 -0800462 int64_t received_bytes;
Craig Tiller9b8671c2015-06-12 07:41:54 -0700463
Craig Tiller5dc3b302015-06-15 16:06:50 -0700464 /** incoming metadata */
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800465 grpc_chttp2_incoming_metadata_buffer metadata_buffer[2];
Craig Tillerd20efd22015-06-12 16:17:09 -0700466};
467
Craig Tillera82950e2015-09-22 12:33:20 -0700468struct grpc_chttp2_stream {
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800469 grpc_stream_refcount *refcount;
Craig Tillerd20efd22015-06-12 16:17:09 -0700470 grpc_chttp2_stream_global global;
471 grpc_chttp2_stream_writing writing;
Craig Tiller606d8742015-06-15 06:58:50 -0700472 grpc_chttp2_stream_parsing parsing;
Craig Tillerd20efd22015-06-12 16:17:09 -0700473
474 grpc_chttp2_stream_link links[STREAM_LIST_COUNT];
Craig Tiller7536af02015-12-22 13:49:30 -0800475 uint8_t included[STREAM_LIST_COUNT];
Craig Tiller9b8671c2015-06-12 07:41:54 -0700476};
477
Craig Tillerd20efd22015-06-12 16:17:09 -0700478/** Transport writing call flow:
Craig Tiller4aa71a12015-06-15 13:00:55 -0700479 chttp2_transport.c calls grpc_chttp2_unlocking_check_writes to see if writes
480 are required;
481 if they are, chttp2_transport.c calls grpc_chttp2_perform_writes to do the
482 writes.
483 Once writes have been completed (meaning another write could potentially be
484 started),
485 grpc_chttp2_terminate_writing is called. This will call
486 grpc_chttp2_cleanup_writing, at which
Craig Tillerd20efd22015-06-12 16:17:09 -0700487 point the write phase is complete. */
488
Craig Tiller3208e392015-06-12 08:17:02 -0700489/** Someone is unlocking the transport mutex: check to see if writes
490 are required, and schedule them if so */
yang-g276e32d2016-02-22 13:15:30 -0800491int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx,
492 grpc_chttp2_transport_global *global,
Craig Tiller027a74c2015-11-10 08:37:46 +0000493 grpc_chttp2_transport_writing *writing,
494 int is_parsing);
Craig Tillera82950e2015-09-22 12:33:20 -0700495void grpc_chttp2_perform_writes(
496 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
497 grpc_endpoint *endpoint);
498void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx,
Craig Tiller6c396862016-01-28 13:53:40 -0800499 void *transport_writing, bool success);
Craig Tillera82950e2015-09-22 12:33:20 -0700500void grpc_chttp2_cleanup_writing(grpc_exec_ctx *exec_ctx,
501 grpc_chttp2_transport_global *global,
502 grpc_chttp2_transport_writing *writing);
Craig Tillerd20efd22015-06-12 16:17:09 -0700503
Craig Tillera82950e2015-09-22 12:33:20 -0700504void grpc_chttp2_prepare_to_read(grpc_chttp2_transport_global *global,
505 grpc_chttp2_transport_parsing *parsing);
Craig Tillerab630732015-06-25 11:20:01 -0700506/** Process one slice of incoming data; return 1 if the connection is still
507 viable after reading, or 0 if the connection should be torn down */
Craig Tillera82950e2015-09-22 12:33:20 -0700508int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
509 grpc_chttp2_transport_parsing *transport_parsing,
510 gpr_slice slice);
511void grpc_chttp2_publish_reads(grpc_exec_ctx *exec_ctx,
512 grpc_chttp2_transport_global *global,
513 grpc_chttp2_transport_parsing *parsing);
Craig Tillerd20efd22015-06-12 16:17:09 -0700514
Craig Tiller0cb803d2016-03-02 22:17:24 -0800515bool grpc_chttp2_list_add_writable_stream(
Craig Tillera82950e2015-09-22 12:33:20 -0700516 grpc_chttp2_transport_global *transport_global,
517 grpc_chttp2_stream_global *stream_global);
yang-g348f3a22016-01-27 16:17:32 -0800518/** Get a writable stream
519 returns non-zero if there was a stream available */
Craig Tillera82950e2015-09-22 12:33:20 -0700520int grpc_chttp2_list_pop_writable_stream(
521 grpc_chttp2_transport_global *transport_global,
522 grpc_chttp2_transport_writing *transport_writing,
523 grpc_chttp2_stream_global **stream_global,
524 grpc_chttp2_stream_writing **stream_writing);
Craig Tiller0cb803d2016-03-02 22:17:24 -0800525bool grpc_chttp2_list_remove_writable_stream(
Craig Tillera82950e2015-09-22 12:33:20 -0700526 grpc_chttp2_transport_global *transport_global,
Craig Tiller0cb803d2016-03-02 22:17:24 -0800527 grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT;
Craig Tillerd20efd22015-06-12 16:17:09 -0700528
Craig Tiller0cb803d2016-03-02 22:17:24 -0800529void grpc_chttp2_list_add_writing_stream(
Craig Tillera82950e2015-09-22 12:33:20 -0700530 grpc_chttp2_transport_writing *transport_writing,
Craig Tiller0cb803d2016-03-02 22:17:24 -0800531 grpc_chttp2_stream_writing *stream_writing);
Craig Tillera82950e2015-09-22 12:33:20 -0700532int grpc_chttp2_list_have_writing_streams(
533 grpc_chttp2_transport_writing *transport_writing);
534int grpc_chttp2_list_pop_writing_stream(
535 grpc_chttp2_transport_writing *transport_writing,
536 grpc_chttp2_stream_writing **stream_writing);
Craig Tillerd20efd22015-06-12 16:17:09 -0700537
Craig Tillera82950e2015-09-22 12:33:20 -0700538void grpc_chttp2_list_add_written_stream(
539 grpc_chttp2_transport_writing *transport_writing,
540 grpc_chttp2_stream_writing *stream_writing);
541int grpc_chttp2_list_pop_written_stream(
542 grpc_chttp2_transport_global *transport_global,
543 grpc_chttp2_transport_writing *transport_writing,
544 grpc_chttp2_stream_global **stream_global,
545 grpc_chttp2_stream_writing **stream_writing);
Craig Tillerd20efd22015-06-12 16:17:09 -0700546
Craig Tillera82950e2015-09-22 12:33:20 -0700547void grpc_chttp2_list_add_parsing_seen_stream(
548 grpc_chttp2_transport_parsing *transport_parsing,
549 grpc_chttp2_stream_parsing *stream_parsing);
550int grpc_chttp2_list_pop_parsing_seen_stream(
551 grpc_chttp2_transport_global *transport_global,
552 grpc_chttp2_transport_parsing *transport_parsing,
553 grpc_chttp2_stream_global **stream_global,
554 grpc_chttp2_stream_parsing **stream_parsing);
Craig Tillerd20efd22015-06-12 16:17:09 -0700555
Craig Tillera82950e2015-09-22 12:33:20 -0700556void grpc_chttp2_list_add_waiting_for_concurrency(
557 grpc_chttp2_transport_global *transport_global,
558 grpc_chttp2_stream_global *stream_global);
559int grpc_chttp2_list_pop_waiting_for_concurrency(
560 grpc_chttp2_transport_global *transport_global,
561 grpc_chttp2_stream_global **stream_global);
Craig Tiller5dc3b302015-06-15 16:06:50 -0700562
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800563void grpc_chttp2_list_add_check_read_ops(
564 grpc_chttp2_transport_global *transport_global,
565 grpc_chttp2_stream_global *stream_global);
566int grpc_chttp2_list_pop_check_read_ops(
567 grpc_chttp2_transport_global *transport_global,
568 grpc_chttp2_stream_global **stream_global);
569
yang-g348f3a22016-01-27 16:17:32 -0800570void grpc_chttp2_list_add_writing_stalled_by_transport(
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800571 grpc_chttp2_transport_writing *transport_writing,
572 grpc_chttp2_stream_writing *stream_writing);
yang-g348f3a22016-01-27 16:17:32 -0800573void grpc_chttp2_list_flush_writing_stalled_by_transport(
yang-g276e32d2016-02-22 13:15:30 -0800574 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
575 bool is_window_available);
yang-g348f3a22016-01-27 16:17:32 -0800576
yang-g276e32d2016-02-22 13:15:30 -0800577void grpc_chttp2_list_add_stalled_by_transport(
578 grpc_chttp2_transport_writing *transport_writing,
579 grpc_chttp2_stream_writing *stream_writing);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800580int grpc_chttp2_list_pop_stalled_by_transport(
581 grpc_chttp2_transport_global *transport_global,
582 grpc_chttp2_stream_global **stream_global);
yang-g0db90322015-12-21 13:38:56 -0800583void grpc_chttp2_list_remove_stalled_by_transport(
584 grpc_chttp2_transport_global *transport_global,
585 grpc_chttp2_stream_global *stream_global);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800586
587void grpc_chttp2_list_add_unannounced_incoming_window_available(
588 grpc_chttp2_transport_global *transport_global,
589 grpc_chttp2_stream_global *stream_global);
590void grpc_chttp2_list_remove_unannounced_incoming_window_available(
591 grpc_chttp2_transport_global *transport_global,
592 grpc_chttp2_stream_global *stream_global);
593int grpc_chttp2_list_pop_unannounced_incoming_window_available(
594 grpc_chttp2_transport_global *transport_global,
595 grpc_chttp2_transport_parsing *transport_parsing,
596 grpc_chttp2_stream_global **stream_global,
597 grpc_chttp2_stream_parsing **stream_parsing);
598
Craig Tillera82950e2015-09-22 12:33:20 -0700599void grpc_chttp2_list_add_closed_waiting_for_parsing(
600 grpc_chttp2_transport_global *transport_global,
601 grpc_chttp2_stream_global *stream_global);
602int grpc_chttp2_list_pop_closed_waiting_for_parsing(
603 grpc_chttp2_transport_global *transport_global,
604 grpc_chttp2_stream_global **stream_global);
Craig Tiller5dc3b302015-06-15 16:06:50 -0700605
Craig Tillerabb2e3d2015-12-15 06:23:59 -0800606void grpc_chttp2_list_add_closed_waiting_for_writing(
607 grpc_chttp2_transport_global *transport_global,
608 grpc_chttp2_stream_global *stream_global);
609int grpc_chttp2_list_pop_closed_waiting_for_writing(
610 grpc_chttp2_transport_global *transport_global,
611 grpc_chttp2_stream_global **stream_global);
612
Craig Tillera82950e2015-09-22 12:33:20 -0700613grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream(
Craig Tiller7536af02015-12-22 13:49:30 -0800614 grpc_chttp2_transport_parsing *transport_parsing, uint32_t id);
Craig Tillera82950e2015-09-22 12:33:20 -0700615grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream(
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800616 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing,
Craig Tiller7536af02015-12-22 13:49:30 -0800617 uint32_t id);
Craig Tillerd20efd22015-06-12 16:17:09 -0700618
Craig Tillera82950e2015-09-22 12:33:20 -0700619void grpc_chttp2_add_incoming_goaway(
620 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
Craig Tiller7536af02015-12-22 13:49:30 -0800621 uint32_t goaway_error, gpr_slice goaway_text);
Craig Tiller4aa71a12015-06-15 13:00:55 -0700622
Craig Tillera82950e2015-09-22 12:33:20 -0700623void grpc_chttp2_register_stream(grpc_chttp2_transport *t,
624 grpc_chttp2_stream *s);
Craig Tiller9188d7a2015-07-05 12:44:37 -0700625/* returns 1 if this is the last stream, 0 otherwise */
Craig Tillera82950e2015-09-22 12:33:20 -0700626int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t,
627 grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT;
628int grpc_chttp2_has_streams(grpc_chttp2_transport *t);
629void grpc_chttp2_for_all_streams(
630 grpc_chttp2_transport_global *transport_global, void *user_data,
631 void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data,
632 grpc_chttp2_stream_global *stream_global));
Craig Tiller5dc3b302015-06-15 16:06:50 -0700633
Craig Tillera82950e2015-09-22 12:33:20 -0700634void grpc_chttp2_parsing_become_skip_parser(
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800635 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing);
636
637void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
638 grpc_closure **pclosure, int success);
Craig Tiller66abdaa2015-06-17 08:00:39 -0700639
Craig Tillerd20efd22015-06-12 16:17:09 -0700640#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
Craig Tiller4aa71a12015-06-15 13:00:55 -0700641#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \
642 (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1)
Craig Tillerd20efd22015-06-12 16:17:09 -0700643
Craig Tillera82950e2015-09-22 12:33:20 -0700644extern int grpc_http_trace;
645extern int grpc_flowctl_trace;
Craig Tillerd20efd22015-06-12 16:17:09 -0700646
Craig Tillerab630732015-06-25 11:20:01 -0700647#define GRPC_CHTTP2_IF_TRACING(stmt) \
648 if (!(grpc_http_trace)) \
649 ; \
650 else \
Craig Tillerd20efd22015-06-12 16:17:09 -0700651 stmt
Craig Tiller3208e392015-06-12 08:17:02 -0700652
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800653typedef enum {
654 GRPC_CHTTP2_FLOWCTL_MOVE,
655 GRPC_CHTTP2_FLOWCTL_CREDIT,
656 GRPC_CHTTP2_FLOWCTL_DEBIT
657} grpc_chttp2_flowctl_op;
Craig Tiller285b8822015-06-17 15:58:13 -0700658
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800659#define GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, id1, id2, dst_context, \
660 dst_var, src_context, src_var) \
661 do { \
662 assert(id1 == id2); \
663 if (grpc_flowctl_trace) { \
664 grpc_chttp2_flowctl_trace( \
665 __FILE__, __LINE__, phase, GRPC_CHTTP2_FLOWCTL_MOVE, #dst_context, \
666 #dst_var, #src_context, #src_var, transport->is_client, id1, \
667 dst_context->dst_var, src_context->src_var); \
668 } \
669 dst_context->dst_var += src_context->src_var; \
670 src_context->src_var = 0; \
671 } while (0)
Craig Tiller285b8822015-06-17 15:58:13 -0700672
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800673#define GRPC_CHTTP2_FLOW_MOVE_STREAM(phase, transport, dst_context, dst_var, \
674 src_context, src_var) \
675 GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, dst_context->id, \
676 src_context->id, dst_context, dst_var, \
677 src_context, src_var)
678#define GRPC_CHTTP2_FLOW_MOVE_TRANSPORT(phase, dst_context, dst_var, \
679 src_context, src_var) \
680 GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, dst_context, 0, 0, dst_context, dst_var, \
681 src_context, src_var)
682
683#define GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, id, dst_context, \
684 dst_var, amount) \
685 do { \
686 if (grpc_flowctl_trace) { \
687 grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \
688 GRPC_CHTTP2_FLOWCTL_CREDIT, #dst_context, \
689 #dst_var, NULL, #amount, transport->is_client, \
690 id, dst_context->dst_var, amount); \
691 } \
692 dst_context->dst_var += amount; \
693 } while (0)
694
695#define GRPC_CHTTP2_FLOW_CREDIT_STREAM(phase, transport, dst_context, dst_var, \
696 amount) \
697 GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, dst_context->id, \
698 dst_context, dst_var, amount)
699#define GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT(phase, dst_context, dst_var, amount) \
700 GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \
701 amount)
702
703#define GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, id, dst_context, \
704 dst_var, amount) \
705 do { \
706 if (grpc_flowctl_trace) { \
707 grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \
708 GRPC_CHTTP2_FLOWCTL_DEBIT, #dst_context, \
709 #dst_var, NULL, #amount, transport->is_client, \
710 id, dst_context->dst_var, amount); \
711 } \
712 dst_context->dst_var -= amount; \
713 } while (0)
714
715#define GRPC_CHTTP2_FLOW_DEBIT_STREAM(phase, transport, dst_context, dst_var, \
716 amount) \
717 GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, dst_context->id, \
718 dst_context, dst_var, amount)
719#define GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT(phase, dst_context, dst_var, amount) \
720 GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \
721 amount)
722
723void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
724 grpc_chttp2_flowctl_op op, const char *context1,
725 const char *var1, const char *context2,
726 const char *var2, int is_client,
Craig Tiller7536af02015-12-22 13:49:30 -0800727 uint32_t stream_id, int64_t val1, int64_t val2);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800728
729void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
730 grpc_chttp2_transport_global *transport_global,
731 grpc_chttp2_stream_global *stream,
732 grpc_status_code status, gpr_slice *details);
733void grpc_chttp2_mark_stream_closed(
734 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
735 grpc_chttp2_stream_global *stream_global, int close_reads,
736 int close_writes);
737void grpc_chttp2_start_writing(grpc_exec_ctx *exec_ctx,
738 grpc_chttp2_transport_global *transport_global);
739
740#ifdef GRPC_STREAM_REFCOUNT_DEBUG
741#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \
742 grpc_chttp2_stream_ref(stream_global, reason)
743#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \
744 grpc_chttp2_stream_unref(exec_ctx, stream_global, reason)
745void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global,
746 const char *reason);
747void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx,
748 grpc_chttp2_stream_global *stream_global,
749 const char *reason);
750#else
751#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \
752 grpc_chttp2_stream_ref(stream_global)
753#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \
754 grpc_chttp2_stream_unref(exec_ctx, stream_global)
755void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global);
756void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx,
757 grpc_chttp2_stream_global *stream_global);
758#endif
759
760grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
Craig Tiller20df14e2015-11-06 09:10:49 -0800761 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing,
Craig Tiller7536af02015-12-22 13:49:30 -0800762 grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size,
763 uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800764void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
765 grpc_chttp2_incoming_byte_stream *bs,
766 gpr_slice slice);
767void grpc_chttp2_incoming_byte_stream_finished(
Craig Tiller38edec62015-12-14 15:01:29 -0800768 grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, int success,
769 int from_parsing_thread);
Craig Tiller285b8822015-06-17 15:58:13 -0700770
Craig Tiller28bf8912015-12-07 16:07:04 -0800771void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx,
772 grpc_chttp2_transport_parsing *parsing,
Craig Tiller7536af02015-12-22 13:49:30 -0800773 const uint8_t *opaque_8bytes);
Craig Tiller28bf8912015-12-07 16:07:04 -0800774
Craig Tiller0cb803d2016-03-02 22:17:24 -0800775/** add a ref to the stream and add it to the writable list;
776 ref will be dropped in writing.c */
777void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
778 grpc_chttp2_stream_global *stream_global);
779
Craig Tiller9a4dddd2016-03-25 17:08:13 -0700780#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H */