From 66abdaad3274b33e99042b5e493e749991201f81 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 17 Jun 2015 08:00:39 -0700 Subject: Properly deal with streams closing during parsing --- src/core/transport/chttp2/internal.h | 2 ++ src/core/transport/chttp2/parsing.c | 7 +++++-- src/core/transport/chttp2_transport.c | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h index 078d1501bb..644523e810 100644 --- a/src/core/transport/chttp2/internal.h +++ b/src/core/transport/chttp2/internal.h @@ -601,6 +601,8 @@ void grpc_chttp2_for_all_streams( void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, grpc_chttp2_stream_global *stream_global)); +void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport_parsing *transport_parsing); + #define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" #define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1) diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c index cea10b592e..93e8dcc1c8 100644 --- a/src/core/transport/chttp2/parsing.c +++ b/src/core/transport/chttp2/parsing.c @@ -327,6 +327,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing, if (!parse_frame_slice(transport_parsing, gpr_empty_slice(), 1)) { return 0; } + transport_parsing->incoming_stream = NULL; if (++cur == end) { transport_parsing->deframe_state = DTS_FH_0; return 1; @@ -346,6 +347,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing, return 0; } transport_parsing->deframe_state = DTS_FH_0; + transport_parsing->incoming_stream = NULL; return 1; } else if ((gpr_uint32)(end - cur) > transport_parsing->incoming_frame_size) { @@ -358,6 +360,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing, return 0; } cur += transport_parsing->incoming_frame_size; + transport_parsing->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { if (!parse_frame_slice( @@ -447,7 +450,7 @@ static int init_skip_frame_parser( return 1; } -static void become_skip_parser( +void grpc_chttp2_parsing_become_skip_parser( grpc_chttp2_transport_parsing *transport_parsing) { init_skip_frame_parser( transport_parsing, @@ -736,7 +739,7 @@ static int parse_frame_slice(grpc_chttp2_transport_parsing *transport_parsing, } return 1; case GRPC_CHTTP2_STREAM_ERROR: - become_skip_parser(transport_parsing); + 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; diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 582b7ae42a..3cd6c1f67b 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -702,6 +702,10 @@ static void remove_stream(grpc_chttp2_transport *t, gpr_uint32 id) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id); GPR_ASSERT(s); s->global.in_stream_map = 0; + if (t->parsing.incoming_stream == &s->parsing) { + t->parsing.incoming_stream = NULL; + grpc_chttp2_parsing_become_skip_parser(&t->parsing); + } grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global); } -- cgit v1.2.3