diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 02fc53122da..42664a753e5 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1121,6 +1121,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx, // GRPC_CHTTP2_IF_TRACING( // gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg)); t->seen_goaway = 1; + t->goaway_error = goaway_error; /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug * data equal to "too_many_pings", it should log the occurrence at a log level @@ -2074,7 +2075,6 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_status_code status; grpc_slice slice; grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, NULL); - if (status != GRPC_STATUS_OK) { s->seen_error = true; } @@ -2542,6 +2542,15 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, "Transport closed", &t->closed_with_error, 1); } if (error != GRPC_ERROR_NONE) { + /* If a goaway frame was received, this might be the reason why the read + * failed. Add this info to the error */ + if (t->seen_goaway) { + error = grpc_error_add_child( + error, grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), + GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)t->goaway_error)); + } + close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; } else if (t->closed_with_error == GRPC_ERROR_NONE) { diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 9e0796e8207..bd25e51ec06 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -310,6 +310,9 @@ struct grpc_chttp2_transport { bool seen_goaway; /** have we sent a goaway */ grpc_chttp2_sent_goaway_state sent_goaway_state; + /** http2 error code received in the GOAWAY frame. Only relevant if + * seen_goaway is true */ + uint32_t goaway_error; /** are the local settings dirty and need to be sent? */ bool dirtied_local_settings; @@ -376,11 +379,6 @@ struct grpc_chttp2_transport { grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last); - /* goaway data */ - grpc_status_code goaway_error; - uint32_t goaway_last_stream_index; - grpc_slice goaway_text; - grpc_chttp2_write_cb *write_cb_pool; /* bdp estimator */