|
|
|
@ -187,7 +187,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, |
|
|
|
|
|
|
|
|
|
GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport"); |
|
|
|
|
|
|
|
|
|
cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed")); |
|
|
|
|
cancel_pings(exec_ctx, t, |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed")); |
|
|
|
|
|
|
|
|
|
while (t->write_cb_pool) { |
|
|
|
|
grpc_chttp2_write_cb *next = t->write_cb_pool->next; |
|
|
|
@ -494,8 +495,9 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
t->destroying = 1; |
|
|
|
|
close_transport_locked( |
|
|
|
|
exec_ctx, t, |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE("Transport destroyed"), |
|
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"), |
|
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); |
|
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -514,7 +516,8 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, |
|
|
|
|
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) { |
|
|
|
|
if (t->close_transport_on_writes_finished == NULL) { |
|
|
|
|
t->close_transport_on_writes_finished = |
|
|
|
|
GRPC_ERROR_CREATE("Delayed close due to in-progress write"); |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Delayed close due to in-progress write"); |
|
|
|
|
} |
|
|
|
|
t->close_transport_on_writes_finished = |
|
|
|
|
grpc_error_add_child(t->close_transport_on_writes_finished, error); |
|
|
|
@ -833,7 +836,8 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) { |
|
|
|
|
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT; |
|
|
|
|
if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { |
|
|
|
|
close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE("goaway sent")); |
|
|
|
|
close_transport_locked( |
|
|
|
|
exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -905,9 +909,9 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx, |
|
|
|
|
connectivity_state_set( |
|
|
|
|
exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, |
|
|
|
|
grpc_error_set_str( |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, |
|
|
|
|
(intptr_t)goaway_error), |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)goaway_error), |
|
|
|
|
GRPC_ERROR_STR_RAW_BYTES, goaway_text), |
|
|
|
|
"got_goaway"); |
|
|
|
|
} |
|
|
|
@ -932,9 +936,10 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, |
|
|
|
|
t->next_stream_id += 2; |
|
|
|
|
|
|
|
|
|
if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { |
|
|
|
|
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, |
|
|
|
|
GRPC_ERROR_CREATE("Stream IDs exhausted"), |
|
|
|
|
"no_more_stream_ids"); |
|
|
|
|
connectivity_state_set( |
|
|
|
|
exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), |
|
|
|
|
"no_more_stream_ids"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); |
|
|
|
@ -948,9 +953,9 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) { |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
exec_ctx, t, s, |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
|
GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -999,11 +1004,11 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, |
|
|
|
|
} |
|
|
|
|
if (error != GRPC_ERROR_NONE) { |
|
|
|
|
if (closure->error_data.error == GRPC_ERROR_NONE) { |
|
|
|
|
closure->error_data.error = |
|
|
|
|
GRPC_ERROR_CREATE("Error in HTTP transport completing operation"); |
|
|
|
|
closure->error_data.error = |
|
|
|
|
grpc_error_set_str(closure->error_data.error, |
|
|
|
|
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(t->peer_string)); |
|
|
|
|
closure->error_data.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Error in HTTP transport completing operation"); |
|
|
|
|
closure->error_data.error = grpc_error_set_str( |
|
|
|
|
closure->error_data.error, GRPC_ERROR_STR_TARGET_ADDRESS, |
|
|
|
|
grpc_slice_from_copied_string(t->peer_string)); |
|
|
|
|
} |
|
|
|
|
closure->error_data.error = |
|
|
|
|
grpc_error_add_child(closure->error_data.error, error); |
|
|
|
@ -1178,10 +1183,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
exec_ctx, t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE("to-be-sent initial metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size), |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"to-be-sent initial metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, |
|
|
|
|
(intptr_t)metadata_size), |
|
|
|
|
GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); |
|
|
|
|
} else { |
|
|
|
@ -1197,9 +1203,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
} else { |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
exec_ctx, t, s, |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE("Transport closed"), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
|
GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
GPR_ASSERT(s->id != 0); |
|
|
|
@ -1211,7 +1217,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
s->send_initial_metadata = NULL; |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
exec_ctx, t, s, &s->send_initial_metadata_finished, |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send initial metadata after stream was closed", |
|
|
|
|
&s->write_closed_error, 1), |
|
|
|
|
"send_initial_metadata_finished"); |
|
|
|
@ -1225,7 +1231,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
if (s->write_closed) { |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
exec_ctx, t, s, &s->fetching_send_message_finished, |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send message after stream was closed", |
|
|
|
|
&s->write_closed_error, 1), |
|
|
|
|
"fetching_send_message_finished"); |
|
|
|
@ -1273,10 +1279,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
exec_ctx, t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE("to-be-sent trailing metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size), |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"to-be-sent trailing metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, |
|
|
|
|
(intptr_t)metadata_size), |
|
|
|
|
GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); |
|
|
|
|
} else { |
|
|
|
@ -1289,8 +1296,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, |
|
|
|
|
exec_ctx, t, s, &s->send_trailing_metadata_finished, |
|
|
|
|
grpc_metadata_batch_is_empty(op->send_trailing_metadata) |
|
|
|
|
? GRPC_ERROR_NONE |
|
|
|
|
: GRPC_ERROR_CREATE("Attempt to send trailing metadata after " |
|
|
|
|
"stream was closed"), |
|
|
|
|
: GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send trailing metadata after " |
|
|
|
|
"stream was closed"), |
|
|
|
|
"send_trailing_metadata_finished"); |
|
|
|
|
} else if (s->id != 0) { |
|
|
|
|
/* TODO(ctiller): check if there's flow control for any outstanding
|
|
|
|
@ -1406,8 +1414,8 @@ static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, |
|
|
|
|
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED; |
|
|
|
|
grpc_http2_error_code http_error; |
|
|
|
|
grpc_slice slice; |
|
|
|
|
grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL, &slice, |
|
|
|
|
&http_error); |
|
|
|
|
grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL, |
|
|
|
|
&slice, &http_error); |
|
|
|
|
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error, |
|
|
|
|
grpc_slice_ref_internal(slice), &t->qbuf); |
|
|
|
|
grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent"); |
|
|
|
@ -1569,7 +1577,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, |
|
|
|
|
if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SENT) { |
|
|
|
|
close_transport_locked( |
|
|
|
|
exec_ctx, t, |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Last stream closed after sending GOAWAY", &error, 1)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1661,7 +1669,8 @@ static grpc_error *removal_error(grpc_error *extra_error, grpc_chttp2_stream *s, |
|
|
|
|
add_error(extra_error, refs, &nrefs); |
|
|
|
|
grpc_error *error = GRPC_ERROR_NONE; |
|
|
|
|
if (nrefs > 0) { |
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING(master_error_msg, refs, nrefs); |
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(master_error_msg, |
|
|
|
|
refs, nrefs); |
|
|
|
|
} |
|
|
|
|
GRPC_ERROR_UNREF(extra_error); |
|
|
|
|
return error; |
|
|
|
@ -1912,9 +1921,9 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, |
|
|
|
|
if (parse_error == GRPC_ERROR_NONE && |
|
|
|
|
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) { |
|
|
|
|
error = grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE("Trying to connect an http1.x server"), |
|
|
|
|
GRPC_ERROR_INT_HTTP_STATUS, response.status), |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Trying to connect an http1.x server"), |
|
|
|
|
GRPC_ERROR_INT_HTTP_STATUS, response.status), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); |
|
|
|
|
} |
|
|
|
|
GRPC_ERROR_UNREF(parse_error); |
|
|
|
@ -1935,9 +1944,10 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
|
|
|
|
|
grpc_error *err = error; |
|
|
|
|
if (err != GRPC_ERROR_NONE) { |
|
|
|
|
err = grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING("Endpoint read failed", &err, 1), |
|
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state); |
|
|
|
|
err = grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Endpoint read failed", &err, 1), |
|
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, |
|
|
|
|
t->write_state); |
|
|
|
|
} |
|
|
|
|
GPR_SWAP(grpc_error *, err, error); |
|
|
|
|
GRPC_ERROR_UNREF(err); |
|
|
|
@ -1958,8 +1968,8 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
if (errors[1] != GRPC_ERROR_NONE) { |
|
|
|
|
errors[2] = try_http_parsing(exec_ctx, t); |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, |
|
|
|
|
GPR_ARRAY_SIZE(errors)); |
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors)); |
|
|
|
|
} |
|
|
|
|
for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { |
|
|
|
|
GRPC_ERROR_UNREF(errors[i]); |
|
|
|
@ -1984,7 +1994,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
GPR_TIMER_BEGIN("post_reading_action_locked", 0); |
|
|
|
|
bool keep_reading = false; |
|
|
|
|
if (error == GRPC_ERROR_NONE && t->closed) { |
|
|
|
|
error = GRPC_ERROR_CREATE("Transport closed"); |
|
|
|
|
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"); |
|
|
|
|
} |
|
|
|
|
if (error != GRPC_ERROR_NONE) { |
|
|
|
|
close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); |
|
|
|
@ -2119,8 +2129,8 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { |
|
|
|
|
if (error == GRPC_ERROR_NONE) { |
|
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; |
|
|
|
|
close_transport_locked(exec_ctx, t, |
|
|
|
|
GRPC_ERROR_CREATE("keepalive watchdog timeout")); |
|
|
|
|
close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"keepalive watchdog timeout")); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
/** The watchdog timer should have been cancelled by
|
|
|
|
@ -2319,7 +2329,8 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, |
|
|
|
|
gpr_mu_lock(&bs->slice_mu); |
|
|
|
|
if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { |
|
|
|
|
incoming_byte_stream_publish_error( |
|
|
|
|
exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); |
|
|
|
|
exec_ctx, bs, |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream")); |
|
|
|
|
} else { |
|
|
|
|
bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); |
|
|
|
|
if (bs->on_next != NULL) { |
|
|
|
@ -2339,7 +2350,7 @@ void grpc_chttp2_incoming_byte_stream_finished( |
|
|
|
|
if (error == GRPC_ERROR_NONE) { |
|
|
|
|
gpr_mu_lock(&bs->slice_mu); |
|
|
|
|
if (bs->remaining_bytes != 0) { |
|
|
|
|
error = GRPC_ERROR_CREATE("Truncated message"); |
|
|
|
|
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&bs->slice_mu); |
|
|
|
|
} |
|
|
|
@ -2419,9 +2430,9 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
t->peer_string); |
|
|
|
|
} |
|
|
|
|
send_goaway(exec_ctx, t, |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, |
|
|
|
|
GRPC_HTTP2_ENHANCE_YOUR_CALM)); |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); |
|
|
|
|
} else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR |
|
|
|
@ -2448,9 +2459,10 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
s->id); |
|
|
|
|
} |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, |
|
|
|
|
GRPC_HTTP2_ENHANCE_YOUR_CALM)); |
|
|
|
|
exec_ctx, t, s, |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), |
|
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, |
|
|
|
|
GRPC_HTTP2_ENHANCE_YOUR_CALM)); |
|
|
|
|
if (n > 1) { |
|
|
|
|
/* Since we cancel one stream per destructive reclamation, if
|
|
|
|
|
there are more streams left, we can immediately post a new |
|
|
|
|