Merge pull request #6966 from ctiller/get_settings_first

Force receiving a SETTINGS frame as the first frame
pull/6981/head
Jan Tattermusch 9 years ago committed by GitHub
commit 7bfa751404
  1. 6
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  2. 4
      src/core/ext/transport/chttp2/transport/internal.h
  3. 11
      src/core/ext/transport/chttp2/transport/parsing.c
  4. 4
      src/core/ext/transport/chttp2/transport/writing.c

@ -264,6 +264,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->parsing.is_client = is_client; t->parsing.is_client = is_client;
t->parsing.deframe_state = t->parsing.deframe_state =
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->parsing.is_first_frame = true;
t->writing.is_client = is_client; t->writing.is_client = is_client;
t->optional_drop_message = gpr_empty_slice(); t->optional_drop_message = gpr_empty_slice();
grpc_connectivity_state_init( grpc_connectivity_state_init(
@ -643,8 +644,7 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx,
for (;;) { for (;;) {
if (!t->executor.writing_active && !t->closed && if (!t->executor.writing_active && !t->closed &&
grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing, grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) {
t->executor.parsing_active)) {
t->executor.writing_active = 1; t->executor.writing_active = 1;
REF_TRANSPORT(t, "writing"); REF_TRANSPORT(t, "writing");
prevent_endpoint_shutdown(t); prevent_endpoint_shutdown(t);
@ -1805,7 +1805,7 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
UNREF_TRANSPORT(exec_ctx, t, "reading_action"); UNREF_TRANSPORT(exec_ctx, t, "reading_action");
} }
GRPC_ERROR_UNREF(error); GRPC_LOG_IF_ERROR("close_transport", error);
} }
/******************************************************************************* /*******************************************************************************

@ -265,6 +265,7 @@ struct grpc_chttp2_transport_parsing {
uint8_t incoming_frame_type; uint8_t incoming_frame_type;
uint8_t incoming_frame_flags; uint8_t incoming_frame_flags;
uint8_t header_eof; uint8_t header_eof;
bool is_first_frame;
uint32_t expect_continuation_stream_id; uint32_t expect_continuation_stream_id;
uint32_t incoming_frame_size; uint32_t incoming_frame_size;
uint32_t incoming_stream_id; uint32_t incoming_stream_id;
@ -524,8 +525,7 @@ struct grpc_chttp2_stream {
are required, and schedule them if so */ are required, and schedule them if so */
int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx, int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_global *global, grpc_chttp2_transport_global *global,
grpc_chttp2_transport_writing *writing, grpc_chttp2_transport_writing *writing);
int is_parsing);
void grpc_chttp2_perform_writes( void grpc_chttp2_perform_writes(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
grpc_endpoint *endpoint); grpc_endpoint *endpoint);

@ -468,6 +468,17 @@ grpc_error *grpc_chttp2_perform_read(
static grpc_error *init_frame_parser( static grpc_error *init_frame_parser(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) {
if (transport_parsing->is_first_frame &&
transport_parsing->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) {
char *msg;
gpr_asprintf(
&msg, "Expected SETTINGS frame as the first frame, got frame type %d",
transport_parsing->incoming_frame_type);
grpc_error *err = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
return err;
}
transport_parsing->is_first_frame = false;
if (transport_parsing->expect_continuation_stream_id != 0) { if (transport_parsing->expect_continuation_stream_id != 0) {
if (transport_parsing->incoming_frame_type != if (transport_parsing->incoming_frame_type !=
GRPC_CHTTP2_FRAME_CONTINUATION) { GRPC_CHTTP2_FRAME_CONTINUATION) {

@ -45,7 +45,7 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
int grpc_chttp2_unlocking_check_writes( int grpc_chttp2_unlocking_check_writes(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
grpc_chttp2_transport_writing *transport_writing, int is_parsing) { grpc_chttp2_transport_writing *transport_writing) {
grpc_chttp2_stream_global *stream_global; grpc_chttp2_stream_global *stream_global;
grpc_chttp2_stream_writing *stream_writing; grpc_chttp2_stream_writing *stream_writing;
@ -61,7 +61,7 @@ int grpc_chttp2_unlocking_check_writes(
[GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
if (transport_global->dirtied_local_settings && if (transport_global->dirtied_local_settings &&
!transport_global->sent_local_settings && !is_parsing) { !transport_global->sent_local_settings) {
gpr_slice_buffer_add( gpr_slice_buffer_add(
&transport_writing->outbuf, &transport_writing->outbuf,
grpc_chttp2_settings_create( grpc_chttp2_settings_create(

Loading…
Cancel
Save