diff options
author | 2015-09-22 12:33:20 -0700 | |
---|---|---|
committer | 2015-09-22 12:33:20 -0700 | |
commit | a82950e68318a6aab6fe894fa39f7fa616c4647b (patch) | |
tree | 7d02bd1e9e1cbae1f14ad4ad1e06d3ae81a96dfe /src/core/transport/chttp2/parsing.c | |
parent | 8af4c337181322cc4fb396199c90f574cfb4163f (diff) |
clang-format all core files
Diffstat (limited to 'src/core/transport/chttp2/parsing.c')
-rw-r--r-- | src/core/transport/chttp2/parsing.c | 1155 |
1 files changed, 599 insertions, 556 deletions
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c index 9e19590e72..f7a0a10581 100644 --- a/src/core/transport/chttp2/parsing.c +++ b/src/core/transport/chttp2/parsing.c @@ -42,46 +42,58 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -static int init_frame_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_header_frame_parser (grpc_chttp2_transport_parsing * transport_parsing, int is_continuation); -static int init_data_frame_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_rst_stream_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_settings_frame_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_window_update_frame_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_ping_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_goaway_parser (grpc_chttp2_transport_parsing * transport_parsing); -static int init_skip_frame_parser (grpc_chttp2_transport_parsing * transport_parsing, int is_header); - -static int parse_frame_slice (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_parsing * transport_parsing, gpr_slice slice, int is_last); - -void -grpc_chttp2_prepare_to_read (grpc_chttp2_transport_global * transport_global, grpc_chttp2_transport_parsing * transport_parsing) -{ +static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing); +static int init_header_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing, int is_continuation); +static int init_data_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing); +static int init_rst_stream_parser( + grpc_chttp2_transport_parsing *transport_parsing); +static int init_settings_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing); +static int init_window_update_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing); +static int init_ping_parser(grpc_chttp2_transport_parsing *transport_parsing); +static int init_goaway_parser(grpc_chttp2_transport_parsing *transport_parsing); +static int init_skip_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing, int is_header); + +static int parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice, int is_last); + +void grpc_chttp2_prepare_to_read( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing) { grpc_chttp2_stream_global *stream_global; grpc_chttp2_stream_parsing *stream_parsing; transport_parsing->next_stream_id = transport_global->next_stream_id; /* update the parsing view of incoming window */ - if (transport_parsing->incoming_window != transport_global->incoming_window) - { - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("parse", transport_parsing, incoming_window, (gpr_int64) transport_global->incoming_window - (gpr_int64) transport_parsing->incoming_window); - transport_parsing->incoming_window = transport_global->incoming_window; - } - while (grpc_chttp2_list_pop_incoming_window_updated (transport_global, transport_parsing, &stream_global, &stream_parsing)) - { - stream_parsing->id = stream_global->id; - if (stream_parsing->incoming_window != stream_global->incoming_window) - { - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parse", transport_parsing, stream_parsing, incoming_window, (gpr_int64) stream_global->incoming_window - (gpr_int64) stream_parsing->incoming_window); - stream_parsing->incoming_window = stream_global->incoming_window; - } - } + if (transport_parsing->incoming_window != transport_global->incoming_window) { + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "parse", transport_parsing, incoming_window, + (gpr_int64)transport_global->incoming_window - + (gpr_int64)transport_parsing->incoming_window); + transport_parsing->incoming_window = transport_global->incoming_window; + } + while (grpc_chttp2_list_pop_incoming_window_updated( + transport_global, transport_parsing, &stream_global, &stream_parsing)) { + stream_parsing->id = stream_global->id; + if (stream_parsing->incoming_window != stream_global->incoming_window) { + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "parse", transport_parsing, stream_parsing, incoming_window, + (gpr_int64)stream_global->incoming_window - + (gpr_int64)stream_parsing->incoming_window); + stream_parsing->incoming_window = stream_global->incoming_window; + } + } } -void -grpc_chttp2_publish_reads (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_global * transport_global, grpc_chttp2_transport_parsing * transport_parsing) -{ +void grpc_chttp2_publish_reads( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing) { grpc_chttp2_stream_global *stream_global; grpc_chttp2_stream_parsing *stream_parsing; @@ -93,126 +105,146 @@ grpc_chttp2_publish_reads (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_globa ID. So, since we don't have server pushed streams, client should send GOAWAY last-grpc_chttp2_stream-id=0 in this case. */ - if (!transport_parsing->is_client) - { - transport_global->last_incoming_stream_id = transport_parsing->incoming_stream_id; - } + if (!transport_parsing->is_client) { + transport_global->last_incoming_stream_id = + transport_parsing->incoming_stream_id; + } /* copy parsing qbuf to global qbuf */ - gpr_slice_buffer_move_into (&transport_parsing->qbuf, &transport_global->qbuf); + gpr_slice_buffer_move_into(&transport_parsing->qbuf, &transport_global->qbuf); /* update global settings */ - if (transport_parsing->settings_updated) - { - memcpy (transport_global->settings[GRPC_PEER_SETTINGS], transport_parsing->settings, sizeof (transport_parsing->settings)); - transport_parsing->settings_updated = 0; - } + if (transport_parsing->settings_updated) { + memcpy(transport_global->settings[GRPC_PEER_SETTINGS], + transport_parsing->settings, sizeof(transport_parsing->settings)); + transport_parsing->settings_updated = 0; + } /* update settings based on ack if received */ - if (transport_parsing->settings_ack_received) - { - memcpy (transport_global->settings[GRPC_ACKED_SETTINGS], transport_global->settings[GRPC_SENT_SETTINGS], GRPC_CHTTP2_NUM_SETTINGS * sizeof (gpr_uint32)); - transport_parsing->settings_ack_received = 0; - } + if (transport_parsing->settings_ack_received) { + memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], + transport_global->settings[GRPC_SENT_SETTINGS], + GRPC_CHTTP2_NUM_SETTINGS * sizeof(gpr_uint32)); + transport_parsing->settings_ack_received = 0; + } /* move goaway to the global state if we received one (it will be published later */ - if (transport_parsing->goaway_received) - { - grpc_chttp2_add_incoming_goaway (exec_ctx,transport_global, ( gpr_uint32) transport_parsing->goaway_error, transport_parsing->goaway_text); - transport_parsing->goaway_text = gpr_empty_slice (); - transport_parsing->goaway_received = 0; - } + if (transport_parsing->goaway_received) { + grpc_chttp2_add_incoming_goaway(exec_ctx, transport_global, + (gpr_uint32)transport_parsing->goaway_error, + transport_parsing->goaway_text); + transport_parsing->goaway_text = gpr_empty_slice(); + transport_parsing->goaway_received = 0; + } /* propagate flow control tokens to global state */ - if (transport_parsing->outgoing_window_update) - { - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("parsed", transport_global, outgoing_window, transport_parsing->outgoing_window_update); - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("parsed", transport_parsing, outgoing_window_update, -(gpr_int64) transport_parsing->outgoing_window_update); - transport_global->outgoing_window += transport_parsing->outgoing_window_update; - transport_parsing->outgoing_window_update = 0; - } - - if (transport_parsing->incoming_window_delta) - { - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("parsed", transport_global, incoming_window, -(gpr_int64) transport_parsing->incoming_window_delta); - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("parsed", transport_parsing, incoming_window_delta, -(gpr_int64) transport_parsing->incoming_window_delta); - transport_global->incoming_window -= transport_parsing->incoming_window_delta; - transport_parsing->incoming_window_delta = 0; - } + if (transport_parsing->outgoing_window_update) { + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "parsed", transport_global, outgoing_window, + transport_parsing->outgoing_window_update); + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "parsed", transport_parsing, outgoing_window_update, + -(gpr_int64)transport_parsing->outgoing_window_update); + transport_global->outgoing_window += + transport_parsing->outgoing_window_update; + transport_parsing->outgoing_window_update = 0; + } + + if (transport_parsing->incoming_window_delta) { + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "parsed", transport_global, incoming_window, + -(gpr_int64)transport_parsing->incoming_window_delta); + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "parsed", transport_parsing, incoming_window_delta, + -(gpr_int64)transport_parsing->incoming_window_delta); + transport_global->incoming_window -= + transport_parsing->incoming_window_delta; + transport_parsing->incoming_window_delta = 0; + } /* for each stream that saw an update, fixup global state */ - while (grpc_chttp2_list_pop_parsing_seen_stream (transport_global, transport_parsing, &stream_global, &stream_parsing)) - { - /* update incoming flow control window */ - if (stream_parsing->incoming_window_delta) - { - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parsed", transport_parsing, stream_global, incoming_window, -(gpr_int64) stream_parsing->incoming_window_delta); - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parsed", transport_parsing, stream_parsing, incoming_window_delta, -(gpr_int64) stream_parsing->incoming_window_delta); - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parsed", transport_parsing, stream_global, max_recv_bytes, -(gpr_int64) stream_parsing->incoming_window_delta); - stream_global->incoming_window -= stream_parsing->incoming_window_delta; - GPR_ASSERT (stream_global->max_recv_bytes >= stream_parsing->incoming_window_delta); - stream_global->max_recv_bytes -= stream_parsing->incoming_window_delta; - stream_parsing->incoming_window_delta = 0; - grpc_chttp2_list_add_writable_stream (transport_global, stream_global); - } - - /* update outgoing flow control window */ - if (stream_parsing->outgoing_window_update) - { - int was_zero = stream_global->outgoing_window <= 0; - int is_zero; - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parsed", transport_parsing, stream_global, outgoing_window, stream_parsing->outgoing_window_update); - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("parsed", transport_parsing, stream_parsing, outgoing_window_update, -(gpr_int64) stream_parsing->outgoing_window_update); - GPR_ASSERT (stream_parsing->outgoing_window_update <= GPR_UINT32_MAX); - stream_global->outgoing_window += (gpr_uint32) stream_parsing->outgoing_window_update; - stream_parsing->outgoing_window_update = 0; - is_zero = stream_global->outgoing_window <= 0; - if (was_zero && !is_zero) - { - grpc_chttp2_list_add_writable_stream (transport_global, stream_global); - } - } - - /* updating closed status */ - if (stream_parsing->received_close) - { - stream_global->read_closed = 1; - grpc_chttp2_list_add_read_write_state_changed (transport_global, stream_global); - } - if (stream_parsing->saw_rst_stream) - { - stream_global->cancelled = 1; - stream_global->cancelled_status = grpc_chttp2_http2_error_to_grpc_status ((grpc_chttp2_error_code) stream_parsing->rst_stream_reason); - if (stream_parsing->rst_stream_reason == GRPC_CHTTP2_NO_ERROR) - { - stream_global->published_cancelled = 1; - } - grpc_chttp2_list_add_read_write_state_changed (transport_global, stream_global); - } - - /* publish incoming stream ops */ - if (stream_parsing->data_parser.incoming_sopb.nops > 0) - { - grpc_incoming_metadata_buffer_move_to_referencing_sopb (&stream_parsing->incoming_metadata, &stream_global->incoming_metadata, &stream_parsing->data_parser.incoming_sopb); - grpc_sopb_move_to (&stream_parsing->data_parser.incoming_sopb, &stream_global->incoming_sopb); - grpc_chttp2_list_add_read_write_state_changed (transport_global, stream_global); - } - } + while (grpc_chttp2_list_pop_parsing_seen_stream( + transport_global, transport_parsing, &stream_global, &stream_parsing)) { + /* update incoming flow control window */ + if (stream_parsing->incoming_window_delta) { + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "parsed", transport_parsing, stream_global, incoming_window, + -(gpr_int64)stream_parsing->incoming_window_delta); + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "parsed", transport_parsing, stream_parsing, incoming_window_delta, + -(gpr_int64)stream_parsing->incoming_window_delta); + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "parsed", transport_parsing, stream_global, max_recv_bytes, + -(gpr_int64)stream_parsing->incoming_window_delta); + stream_global->incoming_window -= stream_parsing->incoming_window_delta; + GPR_ASSERT(stream_global->max_recv_bytes >= + stream_parsing->incoming_window_delta); + stream_global->max_recv_bytes -= stream_parsing->incoming_window_delta; + stream_parsing->incoming_window_delta = 0; + grpc_chttp2_list_add_writable_stream(transport_global, stream_global); + } + + /* update outgoing flow control window */ + if (stream_parsing->outgoing_window_update) { + int was_zero = stream_global->outgoing_window <= 0; + int is_zero; + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("parsed", transport_parsing, + stream_global, outgoing_window, + stream_parsing->outgoing_window_update); + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "parsed", transport_parsing, stream_parsing, outgoing_window_update, + -(gpr_int64)stream_parsing->outgoing_window_update); + GPR_ASSERT(stream_parsing->outgoing_window_update <= GPR_UINT32_MAX); + stream_global->outgoing_window += + (gpr_uint32)stream_parsing->outgoing_window_update; + stream_parsing->outgoing_window_update = 0; + is_zero = stream_global->outgoing_window <= 0; + if (was_zero && !is_zero) { + grpc_chttp2_list_add_writable_stream(transport_global, stream_global); + } + } + + /* updating closed status */ + if (stream_parsing->received_close) { + stream_global->read_closed = 1; + grpc_chttp2_list_add_read_write_state_changed(transport_global, + stream_global); + } + if (stream_parsing->saw_rst_stream) { + stream_global->cancelled = 1; + stream_global->cancelled_status = grpc_chttp2_http2_error_to_grpc_status( + (grpc_chttp2_error_code)stream_parsing->rst_stream_reason); + if (stream_parsing->rst_stream_reason == GRPC_CHTTP2_NO_ERROR) { + stream_global->published_cancelled = 1; + } + grpc_chttp2_list_add_read_write_state_changed(transport_global, + stream_global); + } + + /* publish incoming stream ops */ + if (stream_parsing->data_parser.incoming_sopb.nops > 0) { + grpc_incoming_metadata_buffer_move_to_referencing_sopb( + &stream_parsing->incoming_metadata, &stream_global->incoming_metadata, + &stream_parsing->data_parser.incoming_sopb); + grpc_sopb_move_to(&stream_parsing->data_parser.incoming_sopb, + &stream_global->incoming_sopb); + grpc_chttp2_list_add_read_write_state_changed(transport_global, + stream_global); + } + } } -int -grpc_chttp2_perform_read (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_parsing * transport_parsing, gpr_slice slice) -{ - gpr_uint8 *beg = GPR_SLICE_START_PTR (slice); - gpr_uint8 *end = GPR_SLICE_END_PTR (slice); +int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice) { + gpr_uint8 *beg = GPR_SLICE_START_PTR(slice); + gpr_uint8 *end = GPR_SLICE_END_PTR(slice); gpr_uint8 *cur = beg; - if (cur == end) - return 1; + if (cur == end) return 1; - switch (transport_parsing->deframe_state) - { + switch (transport_parsing->deframe_state) { case GRPC_DTS_CLIENT_PREFIX_0: case GRPC_DTS_CLIENT_PREFIX_1: case GRPC_DTS_CLIENT_PREFIX_2: @@ -237,294 +269,300 @@ grpc_chttp2_perform_read (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_parsin case GRPC_DTS_CLIENT_PREFIX_21: case GRPC_DTS_CLIENT_PREFIX_22: case GRPC_DTS_CLIENT_PREFIX_23: - while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) - { - if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing->deframe_state]) - { - gpr_log (GPR_INFO, "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing->deframe_state], (int) (gpr_uint8) GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing->deframe_state], *cur, (int) *cur, transport_parsing->deframe_state); - return 0; - } - ++cur; - ++transport_parsing->deframe_state; - } - if (cur == end) - { - return 1; - } - /* fallthrough */ + while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) { + if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + ->deframe_state]) { + gpr_log(GPR_INFO, + "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " + "at byte %d", + GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + ->deframe_state], + (int)(gpr_uint8)GRPC_CHTTP2_CLIENT_CONNECT_STRING + [transport_parsing->deframe_state], + *cur, (int)*cur, transport_parsing->deframe_state); + return 0; + } + ++cur; + ++transport_parsing->deframe_state; + } + if (cur == end) { + return 1; + } + /* fallthrough */ dts_fh_0: case GRPC_DTS_FH_0: - GPR_ASSERT (cur < end); - transport_parsing->incoming_frame_size = ((gpr_uint32) * cur) << 16; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_1; - return 1; - } - /* fallthrough */ + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_size = ((gpr_uint32)*cur) << 16; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_1; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_1: - GPR_ASSERT (cur < end); - transport_parsing->incoming_frame_size |= ((gpr_uint32) * cur) << 8; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_2; - return 1; - } - /* fallthrough */ + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_size |= ((gpr_uint32)*cur) << 8; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_2; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_2: - GPR_ASSERT (cur < end); + GPR_ASSERT(cur < end); transport_parsing->incoming_frame_size |= *cur; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_3; - return 1; - } - /* fallthrough */ + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_3; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_3: - GPR_ASSERT (cur < end); + GPR_ASSERT(cur < end); transport_parsing->incoming_frame_type = *cur; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_4; - return 1; - } - /* fallthrough */ + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_4; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_4: - GPR_ASSERT (cur < end); + GPR_ASSERT(cur < end); transport_parsing->incoming_frame_flags = *cur; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_5; - return 1; - } - /* fallthrough */ + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_5; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_5: - GPR_ASSERT (cur < end); - transport_parsing->incoming_stream_id = (((gpr_uint32) * cur) & 0x7f) << 24; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_6; - return 1; - } - /* fallthrough */ + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id = (((gpr_uint32)*cur) & 0x7f) << 24; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_6; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_6: - GPR_ASSERT (cur < end); - transport_parsing->incoming_stream_id |= ((gpr_uint32) * cur) << 16; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_7; - return 1; - } - /* fallthrough */ + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur) << 16; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_7; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_7: - GPR_ASSERT (cur < end); - transport_parsing->incoming_stream_id |= ((gpr_uint32) * cur) << 8; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_8; - return 1; - } - /* fallthrough */ + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur) << 8; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_8; + return 1; + } + /* fallthrough */ case GRPC_DTS_FH_8: - GPR_ASSERT (cur < end); - transport_parsing->incoming_stream_id |= ((gpr_uint32) * cur); + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur); transport_parsing->deframe_state = GRPC_DTS_FRAME; - if (!init_frame_parser (transport_parsing)) - { - return 0; - } - if (transport_parsing->incoming_stream_id) - { - transport_parsing->last_incoming_stream_id = transport_parsing->incoming_stream_id; - } - if (transport_parsing->incoming_frame_size == 0) - { - if (!parse_frame_slice (exec_ctx, transport_parsing, gpr_empty_slice (), 1)) - { - return 0; - } - transport_parsing->incoming_stream = NULL; - if (++cur == end) - { - transport_parsing->deframe_state = GRPC_DTS_FH_0; - return 1; - } - goto dts_fh_0; /* loop */ - } - if (++cur == end) - { - return 1; - } - /* fallthrough */ + if (!init_frame_parser(transport_parsing)) { + return 0; + } + if (transport_parsing->incoming_stream_id) { + transport_parsing->last_incoming_stream_id = + transport_parsing->incoming_stream_id; + } + if (transport_parsing->incoming_frame_size == 0) { + if (!parse_frame_slice(exec_ctx, transport_parsing, gpr_empty_slice(), + 1)) { + return 0; + } + transport_parsing->incoming_stream = NULL; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_0; + return 1; + } + goto dts_fh_0; /* loop */ + } + if (++cur == end) { + return 1; + } + /* fallthrough */ case GRPC_DTS_FRAME: - GPR_ASSERT (cur < end); - if ((gpr_uint32) (end - cur) == transport_parsing->incoming_frame_size) - { - if (!parse_frame_slice (exec_ctx, transport_parsing, gpr_slice_sub_no_ref (slice, (size_t) (cur - beg), (size_t) (end - beg)), 1)) - { - return 0; - } - transport_parsing->deframe_state = GRPC_DTS_FH_0; - transport_parsing->incoming_stream = NULL; - return 1; - } - else if ((gpr_uint32) (end - cur) > transport_parsing->incoming_frame_size) - { - size_t cur_offset = (size_t) (cur - beg); - if (!parse_frame_slice (exec_ctx, transport_parsing, gpr_slice_sub_no_ref (slice, cur_offset, cur_offset + transport_parsing->incoming_frame_size), 1)) - { - return 0; - } - cur += transport_parsing->incoming_frame_size; - transport_parsing->incoming_stream = NULL; - goto dts_fh_0; /* loop */ - } - else - { - if (!parse_frame_slice (exec_ctx, transport_parsing, gpr_slice_sub_no_ref (slice, (size_t) (cur - beg), (size_t) (end - beg)), 0)) - { - return 0; - } - transport_parsing->incoming_frame_size -= (gpr_uint32) (end - cur); - return 1; - } - gpr_log (GPR_ERROR, "should never reach here"); - abort (); - } - - gpr_log (GPR_ERROR, "should never reach here"); - abort (); + GPR_ASSERT(cur < end); + if ((gpr_uint32)(end - cur) == transport_parsing->incoming_frame_size) { + if (!parse_frame_slice(exec_ctx, transport_parsing, + gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 1)) { + return 0; + } + transport_parsing->deframe_state = GRPC_DTS_FH_0; + transport_parsing->incoming_stream = NULL; + return 1; + } else if ((gpr_uint32)(end - cur) > + transport_parsing->incoming_frame_size) { + size_t cur_offset = (size_t)(cur - beg); + if (!parse_frame_slice( + exec_ctx, transport_parsing, + gpr_slice_sub_no_ref( + slice, cur_offset, + cur_offset + transport_parsing->incoming_frame_size), + 1)) { + return 0; + } + cur += transport_parsing->incoming_frame_size; + transport_parsing->incoming_stream = NULL; + goto dts_fh_0; /* loop */ + } else { + if (!parse_frame_slice(exec_ctx, transport_parsing, + gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 0)) { + return 0; + } + transport_parsing->incoming_frame_size -= (gpr_uint32)(end - cur); + return 1; + } + gpr_log(GPR_ERROR, "should never reach here"); + abort(); + } + + gpr_log(GPR_ERROR, "should never reach here"); + abort(); return 0; } -static int -init_frame_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - if (transport_parsing->expect_continuation_stream_id != 0) - { - if (transport_parsing->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) - { - gpr_log (GPR_ERROR, "Expected CONTINUATION frame, got frame type %02x", transport_parsing->incoming_frame_type); - return 0; - } - if (transport_parsing->expect_continuation_stream_id != transport_parsing->incoming_stream_id) - { - gpr_log (GPR_ERROR, "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " "grpc_chttp2_stream %08x", transport_parsing->expect_continuation_stream_id, transport_parsing->incoming_stream_id); - return 0; - } - return init_header_frame_parser (transport_parsing, 1); +static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing) { + if (transport_parsing->expect_continuation_stream_id != 0) { + if (transport_parsing->incoming_frame_type != + GRPC_CHTTP2_FRAME_CONTINUATION) { + gpr_log(GPR_ERROR, "Expected CONTINUATION frame, got frame type %02x", + transport_parsing->incoming_frame_type); + return 0; + } + if (transport_parsing->expect_continuation_stream_id != + transport_parsing->incoming_stream_id) { + gpr_log(GPR_ERROR, + "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " + "grpc_chttp2_stream %08x", + transport_parsing->expect_continuation_stream_id, + transport_parsing->incoming_stream_id); + return 0; } - switch (transport_parsing->incoming_frame_type) - { + return init_header_frame_parser(transport_parsing, 1); + } + switch (transport_parsing->incoming_frame_type) { case GRPC_CHTTP2_FRAME_DATA: - return init_data_frame_parser (transport_parsing); + return init_data_frame_parser(transport_parsing); case GRPC_CHTTP2_FRAME_HEADER: - return init_header_frame_parser (transport_parsing, 0); + return init_header_frame_parser(transport_parsing, 0); case GRPC_CHTTP2_FRAME_CONTINUATION: - gpr_log (GPR_ERROR, "Unexpected CONTINUATION frame"); + gpr_log(GPR_ERROR, "Unexpected CONTINUATION frame"); return 0; case GRPC_CHTTP2_FRAME_RST_STREAM: - return init_rst_stream_parser (transport_parsing); + return init_rst_stream_parser(transport_parsing); case GRPC_CHTTP2_FRAME_SETTINGS: - return init_settings_frame_parser (transport_parsing); + return init_settings_frame_parser(transport_parsing); case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: - return init_window_update_frame_parser (transport_parsing); + return init_window_update_frame_parser(transport_parsing); case GRPC_CHTTP2_FRAME_PING: - return init_ping_parser (transport_parsing); + return init_ping_parser(transport_parsing); case GRPC_CHTTP2_FRAME_GOAWAY: - return init_goaway_parser (transport_parsing); + return init_goaway_parser(transport_parsing); default: - gpr_log (GPR_ERROR, "Unknown frame type %02x", transport_parsing->incoming_frame_type); - return init_skip_frame_parser (transport_parsing, 0); - } + gpr_log(GPR_ERROR, "Unknown frame type %02x", + transport_parsing->incoming_frame_type); + return init_skip_frame_parser(transport_parsing, 0); + } } -static grpc_chttp2_parse_error -skip_parser (grpc_exec_ctx * exec_ctx, void *parser, grpc_chttp2_transport_parsing * transport_parsing, grpc_chttp2_stream_parsing * stream_parsing, gpr_slice slice, int is_last) -{ +static grpc_chttp2_parse_error skip_parser( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { return GRPC_CHTTP2_PARSE_OK; } -static void -skip_header (void *tp, grpc_mdelem * md) -{ - GRPC_MDELEM_UNREF (md); -} - -static int -init_skip_frame_parser (grpc_chttp2_transport_parsing * transport_parsing, int is_header) -{ - if (is_header) - { - gpr_uint8 is_eoh = transport_parsing->expect_continuation_stream_id != 0; - transport_parsing->parser = grpc_chttp2_header_parser_parse; - transport_parsing->parser_data = &transport_parsing->hpack_parser; - transport_parsing->hpack_parser.on_header = skip_header; - transport_parsing->hpack_parser.on_header_user_data = NULL; - transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = (gpr_uint8) (is_eoh ? transport_parsing->header_eof : 0); - } - else - { - transport_parsing->parser = skip_parser; - } +static void skip_header(void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } + +static int init_skip_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing, int is_header) { + if (is_header) { + gpr_uint8 is_eoh = transport_parsing->expect_continuation_stream_id != 0; + transport_parsing->parser = grpc_chttp2_header_parser_parse; + transport_parsing->parser_data = &transport_parsing->hpack_parser; + transport_parsing->hpack_parser.on_header = skip_header; + transport_parsing->hpack_parser.on_header_user_data = NULL; + transport_parsing->hpack_parser.is_boundary = is_eoh; + transport_parsing->hpack_parser.is_eof = + (gpr_uint8)(is_eoh ? transport_parsing->header_eof : 0); + } else { + transport_parsing->parser = skip_parser; + } return 1; } -void -grpc_chttp2_parsing_become_skip_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - init_skip_frame_parser (transport_parsing, transport_parsing->parser == grpc_chttp2_header_parser_parse); +void grpc_chttp2_parsing_become_skip_parser( + grpc_chttp2_transport_parsing *transport_parsing) { + init_skip_frame_parser( + transport_parsing, + transport_parsing->parser == grpc_chttp2_header_parser_parse); } -static grpc_chttp2_parse_error -update_incoming_window (grpc_chttp2_transport_parsing * transport_parsing, grpc_chttp2_stream_parsing * stream_parsing) -{ - if (transport_parsing->incoming_frame_size > transport_parsing->incoming_window) - { - gpr_log (GPR_ERROR, "frame of size %d overflows incoming window of %d", transport_parsing->incoming_frame_size, transport_parsing->incoming_window); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - - if (transport_parsing->incoming_frame_size > stream_parsing->incoming_window) - { - gpr_log (GPR_ERROR, "frame of size %d overflows incoming window of %d", transport_parsing->incoming_frame_size, stream_parsing->incoming_window); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("data", transport_parsing, incoming_window, -(gpr_int64) transport_parsing->incoming_frame_size); - GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT ("data", transport_parsing, incoming_window_delta, transport_parsing->incoming_frame_size); - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("data", transport_parsing, stream_parsing, incoming_window, -(gpr_int64) transport_parsing->incoming_frame_size); - GRPC_CHTTP2_FLOWCTL_TRACE_STREAM ("data", transport_parsing, stream_parsing, incoming_window_delta, transport_parsing->incoming_frame_size); +static grpc_chttp2_parse_error update_incoming_window( + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing) { + if (transport_parsing->incoming_frame_size > + transport_parsing->incoming_window) { + gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", + transport_parsing->incoming_frame_size, + transport_parsing->incoming_window); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + + if (transport_parsing->incoming_frame_size > + stream_parsing->incoming_window) { + gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", + transport_parsing->incoming_frame_size, + stream_parsing->incoming_window); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT( + "data", transport_parsing, incoming_window, + -(gpr_int64)transport_parsing->incoming_frame_size); + GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT("data", transport_parsing, + incoming_window_delta, + transport_parsing->incoming_frame_size); + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( + "data", transport_parsing, stream_parsing, incoming_window, + -(gpr_int64)transport_parsing->incoming_frame_size); + GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("data", transport_parsing, stream_parsing, + incoming_window_delta, + transport_parsing->incoming_frame_size); transport_parsing->incoming_window -= transport_parsing->incoming_frame_size; - transport_parsing->incoming_window_delta += transport_parsing->incoming_frame_size; + transport_parsing->incoming_window_delta += + transport_parsing->incoming_frame_size; stream_parsing->incoming_window -= transport_parsing->incoming_frame_size; - stream_parsing->incoming_window_delta += transport_parsing->incoming_frame_size; - grpc_chttp2_list_add_parsing_seen_stream (transport_parsing, stream_parsing); + stream_parsing->incoming_window_delta += + transport_parsing->incoming_frame_size; + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); return GRPC_CHTTP2_PARSE_OK; } -static int -init_data_frame_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - grpc_chttp2_stream_parsing *stream_parsing = grpc_chttp2_parsing_lookup_stream (transport_parsing, - transport_parsing->incoming_stream_id); +static int init_data_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing) { + grpc_chttp2_stream_parsing *stream_parsing = + grpc_chttp2_parsing_lookup_stream(transport_parsing, + transport_parsing->incoming_stream_id); grpc_chttp2_parse_error err = GRPC_CHTTP2_PARSE_OK; if (!stream_parsing || stream_parsing->received_close) - return init_skip_frame_parser (transport_parsing, 0); - if (err == GRPC_CHTTP2_PARSE_OK) - { - err = update_incoming_window (transport_parsing, stream_parsing); - } - if (err == GRPC_CHTTP2_PARSE_OK) - { - err = grpc_chttp2_data_parser_begin_frame (&stream_parsing->data_parser, transport_parsing->incoming_frame_flags); - } - switch (err) - { + return init_skip_frame_parser(transport_parsing, 0); + if (err == GRPC_CHTTP2_PARSE_OK) { + err = update_incoming_window(transport_parsing, stream_parsing); + } + if (err == GRPC_CHTTP2_PARSE_OK) { + err = grpc_chttp2_data_parser_begin_frame( + &stream_parsing->data_parser, transport_parsing->incoming_frame_flags); + } + switch (err) { case GRPC_CHTTP2_PARSE_OK: transport_parsing->incoming_stream = stream_parsing; transport_parsing->parser = grpc_chttp2_data_parser_parse; @@ -534,214 +572,215 @@ init_data_frame_parser (grpc_chttp2_transport_parsing * transport_parsing) stream_parsing->received_close = 1; stream_parsing->saw_rst_stream = 1; stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; - gpr_slice_buffer_add (&transport_parsing->qbuf, grpc_chttp2_rst_stream_create (transport_parsing->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR)); - return init_skip_frame_parser (transport_parsing, 0); + gpr_slice_buffer_add( + &transport_parsing->qbuf, + grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR)); + return init_skip_frame_parser(transport_parsing, 0); case GRPC_CHTTP2_CONNECTION_ERROR: return 0; - } - gpr_log (GPR_ERROR, "should never reach here"); - abort (); + } + gpr_log(GPR_ERROR, "should never reach here"); + abort(); return 0; } -static void -free_timeout (void *p) -{ - gpr_free (p); -} +static void free_timeout(void *p) { gpr_free(p); } -static void -on_header (void *tp, grpc_mdelem * md) -{ +static void on_header(void *tp, grpc_mdelem *md) { grpc_chttp2_transport_parsing *transport_parsing = tp; - grpc_chttp2_stream_parsing *stream_parsing = transport_parsing->incoming_stream; - - GPR_ASSERT (stream_parsing); - - GRPC_CHTTP2_IF_TRACING (gpr_log (GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_parsing->id, transport_parsing->is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string (md->key), grpc_mdstr_as_c_string (md->value))); - - if (md->key == transport_parsing->str_grpc_timeout) - { - gpr_timespec *cached_timeout = grpc_mdelem_get_user_data (md, free_timeout); - if (!cached_timeout) - { - /* not already parsed: parse it now, and store the result away */ - cached_timeout = gpr_malloc (sizeof (gpr_timespec)); - if (!grpc_chttp2_decode_timeout (grpc_mdstr_as_c_string (md->value), cached_timeout)) - { - gpr_log (GPR_ERROR, "Ignoring bad timeout value '%s'", grpc_mdstr_as_c_string (md->value)); - *cached_timeout = gpr_inf_future (GPR_CLOCK_REALTIME); - } - grpc_mdelem_set_user_data (md, free_timeout, cached_timeout); - } - grpc_chttp2_incoming_metadata_buffer_set_deadline (&stream_parsing->incoming_metadata, gpr_time_add (gpr_now (GPR_CLOCK_MONOTONIC), *cached_timeout)); - GRPC_MDELEM_UNREF (md); - } - else - { - grpc_chttp2_incoming_metadata_buffer_add (&stream_parsing->incoming_metadata, md); - } - - grpc_chttp2_list_add_parsing_seen_stream (transport_parsing, stream_parsing); + grpc_chttp2_stream_parsing *stream_parsing = + transport_parsing->incoming_stream; + + GPR_ASSERT(stream_parsing); + + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_parsing->id, + transport_parsing->is_client ? "CLI" : "SVR", + grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); + + if (md->key == transport_parsing->str_grpc_timeout) { + gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout); + if (!cached_timeout) { + /* not already parsed: parse it now, and store the result away */ + cached_timeout = gpr_malloc(sizeof(gpr_timespec)); + if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value), + cached_timeout)) { + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", + grpc_mdstr_as_c_string(md->value)); + *cached_timeout = gpr_inf_future(GPR_CLOCK_REALTIME); + } + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + } + grpc_chttp2_incoming_metadata_buffer_set_deadline( + &stream_parsing->incoming_metadata, + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); + GRPC_MDELEM_UNREF(md); + } else { + grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->incoming_metadata, + md); + } + + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); } -static int -init_header_frame_parser (grpc_chttp2_transport_parsing * transport_parsing, int is_continuation) -{ - gpr_uint8 is_eoh = (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; +static int init_header_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing, int is_continuation) { + gpr_uint8 is_eoh = (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; int via_accept = 0; grpc_chttp2_stream_parsing *stream_parsing; - if (is_eoh) - { - transport_parsing->expect_continuation_stream_id = 0; - } - else - { - transport_parsing->expect_continuation_stream_id = transport_parsing->incoming_stream_id; - } + if (is_eoh) { + transport_parsing->expect_continuation_stream_id = 0; + } else { + transport_parsing->expect_continuation_stream_id = + transport_parsing->incoming_stream_id; + } - if (!is_continuation) - { - transport_parsing->header_eof = (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; - } + if (!is_continuation) { + transport_parsing->header_eof = (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; + } /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ - stream_parsing = grpc_chttp2_parsing_lookup_stream (transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) - { - if (is_continuation) - { - gpr_log (GPR_ERROR, "grpc_chttp2_stream disbanded before CONTINUATION received"); - return init_skip_frame_parser (transport_parsing, 1); - } - if (transport_parsing->is_client) - { - if ((transport_parsing->incoming_stream_id & 1) && transport_parsing->incoming_stream_id < transport_parsing->next_stream_id) - { - /* this is an old (probably cancelled) grpc_chttp2_stream */ - } - else - { - gpr_log (GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client"); - } - return init_skip_frame_parser (transport_parsing, 1); - } - else if (transport_parsing->last_incoming_stream_id > transport_parsing->incoming_stream_id) - { - gpr_log (GPR_ERROR, "ignoring out of order new grpc_chttp2_stream request on server; " "last grpc_chttp2_stream " "id=%d, new grpc_chttp2_stream id=%d", transport_parsing->last_incoming_stream_id, transport_parsing->incoming_stream_id); - return init_skip_frame_parser (transport_parsing, 1); - } - else if ((transport_parsing->incoming_stream_id & 1) == 0) - { - gpr_log (GPR_ERROR, "ignoring grpc_chttp2_stream with non-client generated index %d", transport_parsing->incoming_stream_id); - return init_skip_frame_parser (transport_parsing, 1); - } - stream_parsing = transport_parsing->incoming_stream = grpc_chttp2_parsing_accept_stream (transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) - { - gpr_log (GPR_ERROR, "grpc_chttp2_stream not accepted"); - return init_skip_frame_parser (transport_parsing, 1); - } - via_accept = 1; - } - else - { - transport_parsing->incoming_stream = stream_parsing; - } - GPR_ASSERT (stream_parsing != NULL && (via_accept == 0 || via_accept == 1)); - if (stream_parsing->received_close) - { - gpr_log (GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); - transport_parsing->incoming_stream = NULL; - return init_skip_frame_parser (transport_parsing, 1); - } + stream_parsing = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + if (stream_parsing == NULL) { + if (is_continuation) { + gpr_log(GPR_ERROR, + "grpc_chttp2_stream disbanded before CONTINUATION received"); + return init_skip_frame_parser(transport_parsing, 1); + } + if (transport_parsing->is_client) { + if ((transport_parsing->incoming_stream_id & 1) && + transport_parsing->incoming_stream_id < + transport_parsing->next_stream_id) { + /* this is an old (probably cancelled) grpc_chttp2_stream */ + } else { + gpr_log(GPR_ERROR, + "ignoring new grpc_chttp2_stream creation on client"); + } + return init_skip_frame_parser(transport_parsing, 1); + } else if (transport_parsing->last_incoming_stream_id > + transport_parsing->incoming_stream_id) { + gpr_log(GPR_ERROR, + "ignoring out of order new grpc_chttp2_stream request on server; " + "last grpc_chttp2_stream " + "id=%d, new grpc_chttp2_stream id=%d", + transport_parsing->last_incoming_stream_id, + transport_parsing->incoming_stream_id); + return init_skip_frame_parser(transport_parsing, 1); + } else if ((transport_parsing->incoming_stream_id & 1) == 0) { + gpr_log(GPR_ERROR, + "ignoring grpc_chttp2_stream with non-client generated index %d", + transport_parsing->incoming_stream_id); + return init_skip_frame_parser(transport_parsing, 1); + } + stream_parsing = transport_parsing->incoming_stream = + grpc_chttp2_parsing_accept_stream( + transport_parsing, transport_parsing->incoming_stream_id); + if (stream_parsing == NULL) { + gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); + return init_skip_frame_parser(transport_parsing, 1); + } + via_accept = 1; + } else { + transport_parsing->incoming_stream = stream_parsing; + } + GPR_ASSERT(stream_parsing != NULL && (via_accept == 0 || via_accept == 1)); + if (stream_parsing->received_close) { + gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); + transport_parsing->incoming_stream = NULL; + return init_skip_frame_parser(transport_parsing, 1); + } transport_parsing->parser = grpc_chttp2_header_parser_parse; transport_parsing->parser_data = &transport_parsing->hpack_parser; transport_parsing->hpack_parser.on_header = on_header; transport_parsing->hpack_parser.on_header_user_data = transport_parsing; transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = (gpr_uint8) (is_eoh ? transport_parsing->header_eof : 0); - if (!is_continuation && (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY)) - { - grpc_chttp2_hpack_parser_set_has_priority (&transport_parsing->hpack_parser); - } + transport_parsing->hpack_parser.is_eof = + (gpr_uint8)(is_eoh ? transport_parsing->header_eof : 0); + if (!is_continuation && (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { + grpc_chttp2_hpack_parser_set_has_priority(&transport_parsing->hpack_parser); + } return 1; } -static int -init_window_update_frame_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_window_update_parser_begin_frame (&transport_parsing->simple.window_update, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - if (transport_parsing->incoming_stream_id) - { - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream (transport_parsing, transport_parsing->incoming_stream_id); - } +static int init_window_update_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_window_update_parser_begin_frame( + &transport_parsing->simple.window_update, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + if (transport_parsing->incoming_stream_id) { + transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + } transport_parsing->parser = grpc_chttp2_window_update_parser_parse; transport_parsing->parser_data = &transport_parsing->simple.window_update; return ok; } -static int -init_ping_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_ping_parser_begin_frame (&transport_parsing->simple.ping, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); +static int init_ping_parser(grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_ping_parser_begin_frame( + &transport_parsing->simple.ping, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); transport_parsing->parser = grpc_chttp2_ping_parser_parse; transport_parsing->parser_data = &transport_parsing->simple.ping; return ok; } -static int -init_rst_stream_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_rst_stream_parser_begin_frame (&transport_parsing->simple.rst_stream, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream (transport_parsing, transport_parsing->incoming_stream_id); - if (!transport_parsing->incoming_stream) - { - return init_skip_frame_parser (transport_parsing, 0); - } +static int init_rst_stream_parser( + grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_rst_stream_parser_begin_frame( + &transport_parsing->simple.rst_stream, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + if (!transport_parsing->incoming_stream) { + return init_skip_frame_parser(transport_parsing, 0); + } transport_parsing->parser = grpc_chttp2_rst_stream_parser_parse; transport_parsing->parser_data = &transport_parsing->simple.rst_stream; return ok; } -static int -init_goaway_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_goaway_parser_begin_frame (&transport_parsing->goaway_parser, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); +static int init_goaway_parser( + grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_goaway_parser_begin_frame( + &transport_parsing->goaway_parser, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); transport_parsing->parser = grpc_chttp2_goaway_parser_parse; transport_parsing->parser_data = &transport_parsing->goaway_parser; return ok; } -static int -init_settings_frame_parser (grpc_chttp2_transport_parsing * transport_parsing) -{ +static int init_settings_frame_parser( + grpc_chttp2_transport_parsing *transport_parsing) { int ok; - if (transport_parsing->incoming_stream_id != 0) - { - gpr_log (GPR_ERROR, "settings frame received for grpc_chttp2_stream %d", transport_parsing->incoming_stream_id); - return 0; - } - - ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_settings_parser_begin_frame (&transport_parsing->simple.settings, transport_parsing->incoming_frame_size, transport_parsing->incoming_frame_flags, transport_parsing->settings); - if (!ok) - { - return 0; - } - if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) - { - transport_parsing->settings_ack_received = 1; - } + if (transport_parsing->incoming_stream_id != 0) { + gpr_log(GPR_ERROR, "settings frame received for grpc_chttp2_stream %d", + transport_parsing->incoming_stream_id); + return 0; + } + + ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_settings_parser_begin_frame( + &transport_parsing->simple.settings, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags, + transport_parsing->settings); + if (!ok) { + return 0; + } + if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { + transport_parsing->settings_ack_received = 1; + } transport_parsing->parser = grpc_chttp2_settings_parser_parse; transport_parsing->parser_data = &transport_parsing->simple.settings; return ok; @@ -753,31 +792,35 @@ static int is_window_update_legal(gpr_int64 window_update, gpr_int64 window) { } */ -static int -parse_frame_slice (grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_parsing * transport_parsing, gpr_slice slice, int is_last) -{ - grpc_chttp2_stream_parsing *stream_parsing = transport_parsing->incoming_stream; - switch (transport_parsing->parser (exec_ctx, transport_parsing->parser_data, transport_parsing, stream_parsing, slice, is_last)) - { +static int parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice, int is_last) { + grpc_chttp2_stream_parsing *stream_parsing = + transport_parsing->incoming_stream; + switch (transport_parsing->parser(exec_ctx, transport_parsing->parser_data, + transport_parsing, stream_parsing, slice, + is_last)) { case GRPC_CHTTP2_PARSE_OK: - if (stream_parsing) - { - grpc_chttp2_list_add_parsing_seen_stream (transport_parsing, stream_parsing); - } + if (stream_parsing) { + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + } return 1; case GRPC_CHTTP2_STREAM_ERROR: - grpc_chttp2_parsing_become_skip_parser (transport_parsing); - if (stream_parsing) - { - stream_parsing->saw_rst_stream = 1; - stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; - gpr_slice_buffer_add (&transport_parsing->qbuf, grpc_chttp2_rst_stream_create (transport_parsing->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR)); - } + grpc_chttp2_parsing_become_skip_parser(transport_parsing); + if (stream_parsing) { + stream_parsing->saw_rst_stream = 1; + stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; + gpr_slice_buffer_add( + &transport_parsing->qbuf, + grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR)); + } return 1; case GRPC_CHTTP2_CONNECTION_ERROR: return 0; - } - gpr_log (GPR_ERROR, "should never reach here"); - abort (); + } + gpr_log(GPR_ERROR, "should never reach here"); + abort(); return 0; } |