grpc 1.1.2 → 1.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +1257 -404
- data/etc/roots.pem +189 -102
- data/include/grpc/census.h +7 -7
- data/include/grpc/compression.h +4 -4
- data/include/grpc/grpc.h +13 -7
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
- data/include/grpc/impl/codegen/grpc_types.h +39 -30
- data/include/grpc/impl/codegen/slice.h +24 -6
- data/include/grpc/impl/codegen/sync.h +8 -0
- data/include/grpc/load_reporting.h +63 -0
- data/include/grpc/slice.h +37 -1
- data/include/grpc/slice_buffer.h +7 -0
- data/include/grpc/support/alloc.h +3 -0
- data/include/grpc/support/useful.h +3 -0
- data/src/core/ext/census/gen/census.pb.h +1 -1
- data/src/core/ext/census/gen/trace_context.pb.c +9 -36
- data/src/core/ext/census/gen/trace_context.pb.h +20 -26
- data/src/core/ext/census/grpc_filter.c +3 -5
- data/src/core/ext/census/trace_context.c +1 -1
- data/src/core/ext/census/trace_context.h +3 -0
- data/src/core/ext/census/trace_label.h +61 -0
- data/src/core/ext/census/trace_propagation.h +63 -0
- data/src/core/ext/census/trace_status.h +45 -0
- data/src/core/ext/census/trace_string.h +50 -0
- data/src/core/ext/census/tracing.c +31 -11
- data/src/core/ext/census/tracing.h +124 -0
- data/src/core/ext/client_channel/client_channel.c +456 -368
- data/src/core/ext/client_channel/client_channel.h +4 -0
- data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
- data/src/core/ext/client_channel/connector.c +3 -3
- data/src/core/ext/client_channel/connector.h +4 -3
- data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
- data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
- data/src/core/ext/client_channel/http_proxy.c +125 -0
- data/src/core/ext/client_channel/http_proxy.h +39 -0
- data/src/core/ext/client_channel/lb_policy.c +56 -35
- data/src/core/ext/client_channel/lb_policy.h +46 -39
- data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
- data/src/core/ext/client_channel/parse_address.c +32 -6
- data/src/core/ext/client_channel/proxy_mapper.c +63 -0
- data/src/core/ext/client_channel/proxy_mapper.h +89 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
- data/src/core/ext/client_channel/resolver.c +16 -9
- data/src/core/ext/client_channel/resolver.h +23 -12
- data/src/core/ext/client_channel/resolver_factory.h +1 -0
- data/src/core/ext/client_channel/resolver_registry.c +15 -11
- data/src/core/ext/client_channel/resolver_registry.h +5 -3
- data/src/core/ext/client_channel/subchannel.c +44 -27
- data/src/core/ext/client_channel/subchannel.h +6 -2
- data/src/core/ext/client_channel/uri_parser.c +26 -14
- data/src/core/ext/client_channel/uri_parser.h +3 -1
- data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
- data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
- data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
- data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
- data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
- data/src/core/ext/load_reporting/load_reporting.c +20 -0
- data/src/core/ext/load_reporting/load_reporting.h +1 -16
- data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
- data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
- data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
- data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
- data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
- data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
- data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
- data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
- data/src/core/lib/channel/channel_stack.c +14 -44
- data/src/core/lib/channel/channel_stack.h +10 -17
- data/src/core/lib/channel/channel_stack_builder.c +2 -3
- data/src/core/lib/channel/compress_filter.c +54 -46
- data/src/core/lib/channel/connected_channel.c +4 -4
- data/src/core/lib/channel/connected_channel.h +5 -0
- data/src/core/lib/channel/context.h +3 -0
- data/src/core/lib/channel/deadline_filter.c +61 -61
- data/src/core/lib/channel/deadline_filter.h +8 -5
- data/src/core/lib/channel/handshaker.c +47 -7
- data/src/core/lib/channel/handshaker.h +21 -3
- data/src/core/lib/channel/http_client_filter.c +149 -99
- data/src/core/lib/channel/http_server_filter.c +163 -147
- data/src/core/lib/channel/message_size_filter.c +15 -10
- data/src/core/lib/compression/algorithm_metadata.h +4 -4
- data/src/core/lib/compression/compression.c +17 -23
- data/src/core/lib/http/httpcli.c +3 -2
- data/src/core/lib/http/httpcli.h +2 -1
- data/src/core/lib/http/httpcli_security_connector.c +2 -3
- data/src/core/lib/http/parser.c +2 -2
- data/src/core/lib/iomgr/closure.c +6 -3
- data/src/core/lib/iomgr/closure.h +4 -2
- data/src/core/lib/iomgr/combiner.c +35 -5
- data/src/core/lib/iomgr/combiner.h +21 -2
- data/src/core/lib/iomgr/endpoint.c +3 -2
- data/src/core/lib/iomgr/endpoint.h +3 -2
- data/src/core/lib/iomgr/error.c +60 -94
- data/src/core/lib/iomgr/error.h +7 -10
- data/src/core/lib/iomgr/error_internal.h +54 -0
- data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
- data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
- data/src/core/lib/iomgr/ev_posix.c +7 -8
- data/src/core/lib/iomgr/ev_posix.h +4 -4
- data/src/core/lib/iomgr/exec_ctx.c +11 -6
- data/src/core/lib/iomgr/exec_ctx.h +11 -14
- data/src/core/lib/iomgr/executor.c +2 -2
- data/src/core/lib/iomgr/load_file.c +1 -1
- data/src/core/lib/iomgr/network_status_tracker.c +5 -81
- data/src/core/lib/iomgr/pollset.h +1 -3
- data/src/core/lib/iomgr/pollset_set.h +2 -1
- data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
- data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
- data/src/core/lib/iomgr/pollset_uv.c +25 -11
- data/src/core/lib/iomgr/pollset_windows.c +0 -11
- data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
- data/src/core/lib/iomgr/resource_quota.c +41 -11
- data/src/core/lib/iomgr/resource_quota.h +6 -0
- data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
- data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
- data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
- data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
- data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
- data/src/core/lib/iomgr/tcp_posix.c +4 -5
- data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
- data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
- data/src/core/lib/iomgr/tcp_uv.c +11 -5
- data/src/core/lib/iomgr/tcp_windows.c +20 -7
- data/src/core/lib/iomgr/timer_generic.c +15 -22
- data/src/core/lib/iomgr/timer_generic.h +1 -1
- data/src/core/lib/iomgr/timer_uv.c +10 -6
- data/src/core/lib/iomgr/timer_uv.h +1 -1
- data/src/core/lib/iomgr/udp_server.c +45 -6
- data/src/core/lib/iomgr/udp_server.h +7 -1
- data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
- data/src/core/lib/json/json.c +1 -2
- data/src/core/lib/profiling/basic_timers.c +17 -3
- data/src/core/lib/security/context/security_context.c +3 -10
- data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
- data/src/core/lib/security/credentials/credentials.c +48 -2
- data/src/core/lib/security/credentials/credentials.h +13 -0
- data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
- data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
- data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
- data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
- data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
- data/src/core/lib/security/transport/client_auth_filter.c +72 -47
- data/src/core/lib/security/transport/lb_targets_info.c +70 -0
- data/src/core/lib/security/transport/lb_targets_info.h +47 -0
- data/src/core/lib/security/transport/secure_endpoint.c +3 -3
- data/src/core/lib/security/transport/security_connector.c +125 -28
- data/src/core/lib/security/transport/security_connector.h +4 -3
- data/src/core/lib/security/transport/security_handshaker.c +13 -9
- data/src/core/lib/security/transport/server_auth_filter.c +31 -40
- data/src/core/lib/security/util/b64.c +1 -1
- data/src/core/lib/slice/slice.c +110 -20
- data/src/core/lib/slice/slice_buffer.c +92 -39
- data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
- data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
- data/src/core/lib/slice/slice_intern.c +346 -0
- data/src/core/lib/slice/slice_internal.h +15 -0
- data/src/core/lib/slice/slice_string_helpers.c +5 -0
- data/src/core/lib/slice/slice_string_helpers.h +5 -0
- data/src/core/lib/support/alloc.c +26 -1
- data/src/core/lib/support/cmdline.c +2 -4
- data/src/core/lib/support/cpu_posix.c +2 -7
- data/src/core/lib/support/histogram.c +1 -2
- data/src/core/lib/support/log_posix.c +8 -4
- data/src/core/lib/support/spinlock.h +52 -0
- data/src/core/lib/support/subprocess_posix.c +1 -2
- data/src/core/lib/support/sync.c +7 -1
- data/src/core/lib/support/sync_posix.c +9 -0
- data/src/core/lib/support/time_windows.c +7 -1
- data/src/core/lib/surface/call.c +647 -629
- data/src/core/lib/surface/call.h +4 -1
- data/src/core/lib/surface/call_details.c +8 -2
- data/src/core/lib/surface/call_log_batch.c +17 -6
- data/src/core/lib/surface/channel.c +49 -59
- data/src/core/lib/surface/channel.h +5 -6
- data/src/core/lib/surface/completion_queue.c +16 -45
- data/src/core/lib/surface/completion_queue.h +0 -3
- data/src/core/lib/surface/init.c +6 -2
- data/src/core/lib/surface/init_secure.c +1 -1
- data/src/core/lib/surface/lame_client.c +14 -4
- data/src/core/lib/surface/server.c +79 -82
- data/src/core/lib/surface/validate_metadata.c +46 -15
- data/src/core/lib/surface/validate_metadata.h +43 -0
- data/src/core/lib/surface/version.c +2 -2
- data/src/core/lib/transport/bdp_estimator.c +104 -0
- data/src/core/lib/transport/bdp_estimator.h +76 -0
- data/src/core/lib/transport/connectivity_state.c +33 -13
- data/src/core/lib/transport/connectivity_state.h +15 -5
- data/src/core/lib/transport/error_utils.c +124 -0
- data/src/core/lib/transport/error_utils.h +56 -0
- data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
- data/src/core/lib/transport/metadata.c +259 -503
- data/src/core/lib/transport/metadata.h +69 -68
- data/src/core/lib/transport/metadata_batch.c +183 -63
- data/src/core/lib/transport/metadata_batch.h +50 -26
- data/src/core/lib/transport/pid_controller.c +28 -8
- data/src/core/lib/transport/pid_controller.h +15 -2
- data/src/core/lib/transport/service_config.c +21 -18
- data/src/core/lib/transport/service_config.h +5 -5
- data/src/core/lib/transport/static_metadata.c +753 -112
- data/src/core/lib/transport/static_metadata.h +403 -264
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
- data/src/core/lib/transport/timeout_encoding.c +11 -9
- data/src/core/lib/transport/timeout_encoding.h +3 -1
- data/src/core/lib/transport/transport.c +47 -87
- data/src/core/lib/transport/transport.h +20 -25
- data/src/core/lib/transport/transport_op_string.c +7 -19
- data/src/core/lib/tsi/fake_transport_security.c +2 -4
- data/src/core/lib/tsi/ssl_transport_security.c +7 -16
- data/src/core/lib/tsi/transport_security.c +2 -4
- data/src/ruby/ext/grpc/extconf.rb +4 -1
- data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
- data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
- data/src/ruby/ext/grpc/rb_call.c +47 -46
- data/src/ruby/ext/grpc/rb_channel.c +21 -6
- data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
- data/src/ruby/ext/grpc/rb_server.c +6 -4
- data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +33 -9
@@ -55,11 +55,6 @@
|
|
55
55
|
#include "src/core/lib/surface/api_trace.h"
|
56
56
|
#include "src/core/lib/surface/server.h"
|
57
57
|
|
58
|
-
typedef struct pending_handshake_manager_node {
|
59
|
-
grpc_handshake_manager *handshake_mgr;
|
60
|
-
struct pending_handshake_manager_node *next;
|
61
|
-
} pending_handshake_manager_node;
|
62
|
-
|
63
58
|
typedef struct {
|
64
59
|
grpc_server *server;
|
65
60
|
grpc_tcp_server *tcp_server;
|
@@ -68,7 +63,7 @@ typedef struct {
|
|
68
63
|
bool shutdown;
|
69
64
|
grpc_closure tcp_server_shutdown_complete;
|
70
65
|
grpc_closure *server_destroy_listener_done;
|
71
|
-
|
66
|
+
grpc_handshake_manager *pending_handshake_mgrs;
|
72
67
|
} server_state;
|
73
68
|
|
74
69
|
typedef struct {
|
@@ -78,41 +73,6 @@ typedef struct {
|
|
78
73
|
grpc_handshake_manager *handshake_mgr;
|
79
74
|
} server_connection_state;
|
80
75
|
|
81
|
-
static void pending_handshake_manager_add_locked(
|
82
|
-
server_state *state, grpc_handshake_manager *handshake_mgr) {
|
83
|
-
pending_handshake_manager_node *node = gpr_malloc(sizeof(*node));
|
84
|
-
node->handshake_mgr = handshake_mgr;
|
85
|
-
node->next = state->pending_handshake_mgrs;
|
86
|
-
state->pending_handshake_mgrs = node;
|
87
|
-
}
|
88
|
-
|
89
|
-
static void pending_handshake_manager_remove_locked(
|
90
|
-
server_state *state, grpc_handshake_manager *handshake_mgr) {
|
91
|
-
pending_handshake_manager_node **prev_node = &state->pending_handshake_mgrs;
|
92
|
-
for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
|
93
|
-
node != NULL; node = node->next) {
|
94
|
-
if (node->handshake_mgr == handshake_mgr) {
|
95
|
-
*prev_node = node->next;
|
96
|
-
gpr_free(node);
|
97
|
-
break;
|
98
|
-
}
|
99
|
-
prev_node = &node->next;
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
static void pending_handshake_manager_shutdown_locked(grpc_exec_ctx *exec_ctx,
|
104
|
-
server_state *state) {
|
105
|
-
pending_handshake_manager_node *prev_node = NULL;
|
106
|
-
for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
|
107
|
-
node != NULL; node = node->next) {
|
108
|
-
grpc_handshake_manager_shutdown(exec_ctx, node->handshake_mgr);
|
109
|
-
gpr_free(prev_node);
|
110
|
-
prev_node = node;
|
111
|
-
}
|
112
|
-
gpr_free(prev_node);
|
113
|
-
state->pending_handshake_mgrs = NULL;
|
114
|
-
}
|
115
|
-
|
116
76
|
static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
117
77
|
grpc_error *error) {
|
118
78
|
grpc_handshaker_args *args = arg;
|
@@ -121,7 +81,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
121
81
|
if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) {
|
122
82
|
const char *error_str = grpc_error_string(error);
|
123
83
|
gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
|
124
|
-
|
84
|
+
|
125
85
|
if (error == GRPC_ERROR_NONE && args->endpoint != NULL) {
|
126
86
|
// We were shut down after handshaking completed successfully, so
|
127
87
|
// destroy the endpoint here.
|
@@ -129,7 +89,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
129
89
|
// before destroying them, even if we know that there are no
|
130
90
|
// pending read/write callbacks. This should be fixed, at which
|
131
91
|
// point this can be removed.
|
132
|
-
grpc_endpoint_shutdown(exec_ctx, args->endpoint);
|
92
|
+
grpc_endpoint_shutdown(exec_ctx, args->endpoint, GRPC_ERROR_NONE);
|
133
93
|
grpc_endpoint_destroy(exec_ctx, args->endpoint);
|
134
94
|
grpc_channel_args_destroy(exec_ctx, args->args);
|
135
95
|
grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
|
@@ -150,8 +110,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
150
110
|
grpc_channel_args_destroy(exec_ctx, args->args);
|
151
111
|
}
|
152
112
|
}
|
153
|
-
|
154
|
-
|
113
|
+
grpc_handshake_manager_pending_list_remove(
|
114
|
+
&connection_state->server_state->pending_handshake_mgrs,
|
115
|
+
connection_state->handshake_mgr);
|
155
116
|
gpr_mu_unlock(&connection_state->server_state->mu);
|
156
117
|
grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
|
157
118
|
grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp_server);
|
@@ -171,7 +132,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
|
|
171
132
|
return;
|
172
133
|
}
|
173
134
|
grpc_handshake_manager *handshake_mgr = grpc_handshake_manager_create();
|
174
|
-
|
135
|
+
grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs,
|
136
|
+
handshake_mgr);
|
175
137
|
gpr_mu_unlock(&state->mu);
|
176
138
|
grpc_tcp_server_ref(state->tcp_server);
|
177
139
|
server_connection_state *connection_state =
|
@@ -210,7 +172,8 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *arg,
|
|
210
172
|
gpr_mu_lock(&state->mu);
|
211
173
|
grpc_closure *destroy_done = state->server_destroy_listener_done;
|
212
174
|
GPR_ASSERT(state->shutdown);
|
213
|
-
|
175
|
+
grpc_handshake_manager_pending_list_shutdown_all(
|
176
|
+
exec_ctx, state->pending_handshake_mgrs, GRPC_ERROR_REF(error));
|
214
177
|
gpr_mu_unlock(&state->mu);
|
215
178
|
// Flush queued work before destroying handshaker factory, since that
|
216
179
|
// may do a synchronous unref.
|
@@ -259,8 +222,7 @@ grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
|
|
259
222
|
if (err != GRPC_ERROR_NONE) {
|
260
223
|
goto error;
|
261
224
|
}
|
262
|
-
state =
|
263
|
-
memset(state, 0, sizeof(*state));
|
225
|
+
state = gpr_zalloc(sizeof(*state));
|
264
226
|
grpc_closure_init(&state->tcp_server_shutdown_complete,
|
265
227
|
tcp_server_shutdown_complete, state,
|
266
228
|
grpc_schedule_on_exec_ctx);
|
@@ -307,7 +269,7 @@ grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
|
|
307
269
|
|
308
270
|
const char *warning_message = grpc_error_string(err);
|
309
271
|
gpr_log(GPR_INFO, "WARNING: %s", warning_message);
|
310
|
-
|
272
|
+
|
311
273
|
/* we managed to bind some addresses: continue */
|
312
274
|
}
|
313
275
|
grpc_resolved_addresses_destroy(resolved);
|
@@ -51,7 +51,7 @@ int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
|
|
51
51
|
if (err != GRPC_ERROR_NONE) {
|
52
52
|
const char *msg = grpc_error_string(err);
|
53
53
|
gpr_log(GPR_ERROR, "%s", msg);
|
54
|
-
|
54
|
+
|
55
55
|
GRPC_ERROR_UNREF(err);
|
56
56
|
}
|
57
57
|
grpc_exec_ctx_finish(&exec_ctx);
|
@@ -157,7 +157,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
|
|
157
157
|
"grpc_chttp2_base64_decode has a length of %d, which is not a "
|
158
158
|
"multiple of 4.\n",
|
159
159
|
(int)input_length);
|
160
|
-
return
|
160
|
+
return grpc_empty_slice();
|
161
161
|
}
|
162
162
|
|
163
163
|
if (input_length > 0) {
|
@@ -178,11 +178,11 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
|
|
178
178
|
ctx.contains_tail = false;
|
179
179
|
|
180
180
|
if (!grpc_base64_decode_partial(&ctx)) {
|
181
|
-
char *s =
|
181
|
+
char *s = grpc_slice_to_c_string(input);
|
182
182
|
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
|
183
183
|
gpr_free(s);
|
184
184
|
grpc_slice_unref_internal(exec_ctx, output);
|
185
|
-
return
|
185
|
+
return grpc_empty_slice();
|
186
186
|
}
|
187
187
|
GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
|
188
188
|
GPR_ASSERT(ctx.input_cur == GRPC_SLICE_END_PTR(input));
|
@@ -204,7 +204,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
|
|
204
204
|
"has a tail of 1 byte.\n",
|
205
205
|
(int)input_length);
|
206
206
|
grpc_slice_unref_internal(exec_ctx, output);
|
207
|
-
return
|
207
|
+
return grpc_empty_slice();
|
208
208
|
}
|
209
209
|
|
210
210
|
if (output_length > input_length / 4 * 3 + tail_xtra[input_length % 4]) {
|
@@ -214,7 +214,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
|
|
214
214
|
(int)output_length,
|
215
215
|
(int)(input_length / 4 * 3 + tail_xtra[input_length % 4]));
|
216
216
|
grpc_slice_unref_internal(exec_ctx, output);
|
217
|
-
return
|
217
|
+
return grpc_empty_slice();
|
218
218
|
}
|
219
219
|
|
220
220
|
ctx.input_cur = GRPC_SLICE_START_PTR(input);
|
@@ -224,11 +224,11 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
|
|
224
224
|
ctx.contains_tail = true;
|
225
225
|
|
226
226
|
if (!grpc_base64_decode_partial(&ctx)) {
|
227
|
-
char *s =
|
227
|
+
char *s = grpc_slice_to_c_string(input);
|
228
228
|
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
|
229
229
|
gpr_free(s);
|
230
230
|
grpc_slice_unref_internal(exec_ctx, output);
|
231
|
-
return
|
231
|
+
return grpc_empty_slice();
|
232
232
|
}
|
233
233
|
GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
|
234
234
|
GPR_ASSERT(ctx.input_cur <= GRPC_SLICE_END_PTR(input));
|
@@ -177,8 +177,7 @@ static void enc_add1(huff_out *out, uint8_t a) {
|
|
177
177
|
enc_flush_some(out);
|
178
178
|
}
|
179
179
|
|
180
|
-
grpc_slice
|
181
|
-
grpc_slice input) {
|
180
|
+
grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) {
|
182
181
|
size_t input_length = GRPC_SLICE_LENGTH(input);
|
183
182
|
size_t input_triplets = input_length / 3;
|
184
183
|
size_t tail_case = input_length % 3;
|
@@ -49,7 +49,6 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input);
|
|
49
49
|
grpc_slice y = grpc_chttp2_huffman_compress(x);
|
50
50
|
grpc_slice_unref_internal(exec_ctx, x);
|
51
51
|
return y; */
|
52
|
-
grpc_slice
|
53
|
-
grpc_slice input);
|
52
|
+
grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input);
|
54
53
|
|
55
54
|
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */
|
@@ -31,14 +31,11 @@
|
|
31
31
|
*
|
32
32
|
*/
|
33
33
|
|
34
|
-
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
|
35
34
|
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
|
36
35
|
#include "src/core/lib/debug/trace.h"
|
37
36
|
#include "src/core/lib/transport/metadata.h"
|
38
37
|
|
39
38
|
void grpc_chttp2_plugin_init(void) {
|
40
|
-
grpc_chttp2_base64_encode_and_huffman_compress =
|
41
|
-
grpc_chttp2_base64_encode_and_huffman_compress_impl;
|
42
39
|
grpc_register_tracer("http", &grpc_http_trace);
|
43
40
|
grpc_register_tracer("flowctl", &grpc_flowctl_trace);
|
44
41
|
}
|
@@ -44,19 +44,23 @@
|
|
44
44
|
#include <grpc/support/string_util.h>
|
45
45
|
#include <grpc/support/useful.h>
|
46
46
|
|
47
|
-
#include "src/core/ext/transport/chttp2/transport/http2_errors.h"
|
48
47
|
#include "src/core/ext/transport/chttp2/transport/internal.h"
|
49
|
-
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
|
50
48
|
#include "src/core/ext/transport/chttp2/transport/varint.h"
|
51
49
|
#include "src/core/lib/channel/channel_args.h"
|
52
50
|
#include "src/core/lib/http/parser.h"
|
51
|
+
#include "src/core/lib/iomgr/timer.h"
|
53
52
|
#include "src/core/lib/iomgr/workqueue.h"
|
54
53
|
#include "src/core/lib/profiling/timers.h"
|
55
54
|
#include "src/core/lib/slice/slice_internal.h"
|
56
55
|
#include "src/core/lib/slice/slice_string_helpers.h"
|
56
|
+
#include "src/core/lib/support/env.h"
|
57
57
|
#include "src/core/lib/support/string.h"
|
58
|
+
#include "src/core/lib/transport/error_utils.h"
|
59
|
+
#include "src/core/lib/transport/http2_errors.h"
|
58
60
|
#include "src/core/lib/transport/static_metadata.h"
|
61
|
+
#include "src/core/lib/transport/status_conversion.h"
|
59
62
|
#include "src/core/lib/transport/timeout_encoding.h"
|
63
|
+
#include "src/core/lib/transport/transport.h"
|
60
64
|
#include "src/core/lib/transport/transport_impl.h"
|
61
65
|
|
62
66
|
#define DEFAULT_WINDOW 65535
|
@@ -65,6 +69,10 @@
|
|
65
69
|
#define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
|
66
70
|
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
|
67
71
|
|
72
|
+
#define DEFAULT_KEEPALIVE_TIME_SECOND INT_MAX
|
73
|
+
#define DEFAULT_KEEPALIVE_TIMEOUT_SECOND 20
|
74
|
+
#define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false
|
75
|
+
|
68
76
|
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
|
69
77
|
int grpc_http_trace = 0;
|
70
78
|
int grpc_flowctl_trace = 0;
|
@@ -123,6 +131,31 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
123
131
|
static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
124
132
|
grpc_error *error);
|
125
133
|
|
134
|
+
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
135
|
+
grpc_error *error);
|
136
|
+
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
137
|
+
grpc_error *error);
|
138
|
+
|
139
|
+
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
140
|
+
grpc_error *error);
|
141
|
+
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
142
|
+
grpc_chttp2_ping_type ping_type,
|
143
|
+
grpc_closure *on_initiate,
|
144
|
+
grpc_closure *on_complete);
|
145
|
+
|
146
|
+
#define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
|
147
|
+
#define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
|
148
|
+
|
149
|
+
/** keepalive-relevant functions */
|
150
|
+
static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
151
|
+
grpc_error *error);
|
152
|
+
static void start_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
153
|
+
grpc_error *error);
|
154
|
+
static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
155
|
+
grpc_error *error);
|
156
|
+
static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
157
|
+
grpc_error *error);
|
158
|
+
|
126
159
|
/*******************************************************************************
|
127
160
|
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
|
128
161
|
*/
|
@@ -152,18 +185,9 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
152
185
|
grpc_chttp2_stream_map_destroy(&t->stream_map);
|
153
186
|
grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker);
|
154
187
|
|
155
|
-
|
188
|
+
GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport");
|
156
189
|
|
157
|
-
|
158
|
-
and maybe they hold resources that need to be freed */
|
159
|
-
while (t->pings.next != &t->pings) {
|
160
|
-
grpc_chttp2_outstanding_ping *ping = t->pings.next;
|
161
|
-
grpc_closure_sched(exec_ctx, ping->on_recv,
|
162
|
-
GRPC_ERROR_CREATE("Transport closed"));
|
163
|
-
ping->next->prev = ping->prev;
|
164
|
-
ping->prev->next = ping->next;
|
165
|
-
gpr_free(ping);
|
166
|
-
}
|
190
|
+
cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
|
167
191
|
|
168
192
|
while (t->write_cb_pool) {
|
169
193
|
grpc_chttp2_write_cb *next = t->write_cb_pool->next;
|
@@ -171,6 +195,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
171
195
|
t->write_cb_pool = next;
|
172
196
|
}
|
173
197
|
|
198
|
+
gpr_free(t->ping_acks);
|
174
199
|
gpr_free(t->peer_string);
|
175
200
|
gpr_free(t);
|
176
201
|
}
|
@@ -210,8 +235,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
210
235
|
GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) ==
|
211
236
|
GRPC_CHTTP2_CLIENT_CONNECT_STRLEN);
|
212
237
|
|
213
|
-
memset(t, 0, sizeof(*t));
|
214
|
-
|
215
238
|
t->base.vtable = &vtable;
|
216
239
|
t->ep = ep;
|
217
240
|
/* one ref is for destroy */
|
@@ -223,10 +246,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
223
246
|
t->is_client = is_client;
|
224
247
|
t->outgoing_window = DEFAULT_WINDOW;
|
225
248
|
t->incoming_window = DEFAULT_WINDOW;
|
226
|
-
t->stream_lookahead = DEFAULT_WINDOW;
|
227
|
-
t->connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET;
|
228
|
-
t->ping_counter = 1;
|
229
|
-
t->pings.next = t->pings.prev = &t->pings;
|
230
249
|
t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
|
231
250
|
t->is_first_frame = true;
|
232
251
|
grpc_connectivity_state_init(
|
@@ -247,6 +266,33 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
247
266
|
grpc_closure_init(&t->destructive_reclaimer_locked,
|
248
267
|
destructive_reclaimer_locked, t,
|
249
268
|
grpc_combiner_scheduler(t->combiner, false));
|
269
|
+
grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
|
270
|
+
grpc_combiner_scheduler(t->combiner, false));
|
271
|
+
grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
|
272
|
+
grpc_combiner_scheduler(t->combiner, false));
|
273
|
+
grpc_closure_init(&t->init_keepalive_ping_locked, init_keepalive_ping_locked,
|
274
|
+
t, grpc_combiner_scheduler(t->combiner, false));
|
275
|
+
grpc_closure_init(&t->start_keepalive_ping_locked,
|
276
|
+
start_keepalive_ping_locked, t,
|
277
|
+
grpc_combiner_scheduler(t->combiner, false));
|
278
|
+
grpc_closure_init(&t->finish_keepalive_ping_locked,
|
279
|
+
finish_keepalive_ping_locked, t,
|
280
|
+
grpc_combiner_scheduler(t->combiner, false));
|
281
|
+
grpc_closure_init(&t->keepalive_watchdog_fired_locked,
|
282
|
+
keepalive_watchdog_fired_locked, t,
|
283
|
+
grpc_combiner_scheduler(t->combiner, false));
|
284
|
+
|
285
|
+
grpc_bdp_estimator_init(&t->bdp_estimator, t->peer_string);
|
286
|
+
t->last_pid_update = gpr_now(GPR_CLOCK_MONOTONIC);
|
287
|
+
grpc_pid_controller_init(
|
288
|
+
&t->pid_controller,
|
289
|
+
(grpc_pid_controller_args){.gain_p = 4,
|
290
|
+
.gain_i = 8,
|
291
|
+
.gain_d = 0,
|
292
|
+
.initial_control_value = log2(DEFAULT_WINDOW),
|
293
|
+
.min_control_value = -1,
|
294
|
+
.max_control_value = 25,
|
295
|
+
.integral_range = 10});
|
250
296
|
|
251
297
|
grpc_chttp2_goaway_parser_init(&t->goaway_parser);
|
252
298
|
grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
|
@@ -272,6 +318,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
272
318
|
t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
273
319
|
t->sent_local_settings = 0;
|
274
320
|
t->write_buffer_size = DEFAULT_WINDOW;
|
321
|
+
t->enable_bdp_probe = true;
|
275
322
|
|
276
323
|
if (is_client) {
|
277
324
|
grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
|
@@ -289,6 +336,24 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
289
336
|
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
290
337
|
DEFAULT_MAX_HEADER_LIST_SIZE);
|
291
338
|
|
339
|
+
t->ping_policy = (grpc_chttp2_repeated_ping_policy){
|
340
|
+
.max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA,
|
341
|
+
.min_time_between_pings =
|
342
|
+
gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN),
|
343
|
+
};
|
344
|
+
|
345
|
+
/* client-side keepalive setting */
|
346
|
+
t->keepalive_time =
|
347
|
+
DEFAULT_KEEPALIVE_TIME_SECOND == INT_MAX
|
348
|
+
? gpr_inf_future(GPR_TIMESPAN)
|
349
|
+
: gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIME_SECOND, GPR_TIMESPAN);
|
350
|
+
t->keepalive_timeout =
|
351
|
+
DEFAULT_KEEPALIVE_TIMEOUT_SECOND == INT_MAX
|
352
|
+
? gpr_inf_future(GPR_TIMESPAN)
|
353
|
+
: gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIMEOUT_SECOND,
|
354
|
+
GPR_TIMESPAN);
|
355
|
+
t->keepalive_permit_without_calls = DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
|
356
|
+
|
292
357
|
if (channel_args) {
|
293
358
|
for (i = 0; i < channel_args->num_args; i++) {
|
294
359
|
if (0 == strcmp(channel_args->args[i].key,
|
@@ -305,14 +370,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
305
370
|
t->next_stream_id = (uint32_t)value;
|
306
371
|
}
|
307
372
|
}
|
308
|
-
} else if (0 == strcmp(channel_args->args[i].key,
|
309
|
-
GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) {
|
310
|
-
const grpc_integer_options options = {-1, 5, INT_MAX};
|
311
|
-
const int value =
|
312
|
-
grpc_channel_arg_get_integer(&channel_args->args[i], options);
|
313
|
-
if (value >= 0) {
|
314
|
-
t->stream_lookahead = (uint32_t)value;
|
315
|
-
}
|
316
373
|
} else if (0 == strcmp(channel_args->args[i].key,
|
317
374
|
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) {
|
318
375
|
const grpc_integer_options options = {-1, 0, INT_MAX};
|
@@ -322,35 +379,76 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
322
379
|
grpc_chttp2_hpack_compressor_set_max_usable_size(&t->hpack_compressor,
|
323
380
|
(uint32_t)value);
|
324
381
|
}
|
382
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
383
|
+
GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) {
|
384
|
+
t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer(
|
385
|
+
&channel_args->args[i],
|
386
|
+
(grpc_integer_options){DEFAULT_MAX_PINGS_BETWEEN_DATA, 0, INT_MAX});
|
387
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
388
|
+
GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS)) {
|
389
|
+
t->ping_policy.min_time_between_pings = gpr_time_from_millis(
|
390
|
+
grpc_channel_arg_get_integer(
|
391
|
+
&channel_args->args[i],
|
392
|
+
(grpc_integer_options){DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, 0,
|
393
|
+
INT_MAX}),
|
394
|
+
GPR_TIMESPAN);
|
325
395
|
} else if (0 == strcmp(channel_args->args[i].key,
|
326
396
|
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
|
327
397
|
t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
|
328
398
|
&channel_args->args[i],
|
329
399
|
(grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE});
|
400
|
+
} else if (0 ==
|
401
|
+
strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) {
|
402
|
+
t->enable_bdp_probe = grpc_channel_arg_get_integer(
|
403
|
+
&channel_args->args[i], (grpc_integer_options){1, 0, 1});
|
404
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
405
|
+
GRPC_ARG_HTTP2_KEEPALIVE_TIME)) {
|
406
|
+
const int value = grpc_channel_arg_get_integer(
|
407
|
+
&channel_args->args[i],
|
408
|
+
(grpc_integer_options){DEFAULT_KEEPALIVE_TIME_SECOND, 1, INT_MAX});
|
409
|
+
t->keepalive_time = value == INT_MAX
|
410
|
+
? gpr_inf_future(GPR_TIMESPAN)
|
411
|
+
: gpr_time_from_seconds(value, GPR_TIMESPAN);
|
412
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
413
|
+
GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT)) {
|
414
|
+
const int value = grpc_channel_arg_get_integer(
|
415
|
+
&channel_args->args[i],
|
416
|
+
(grpc_integer_options){DEFAULT_KEEPALIVE_TIMEOUT_SECOND, 0,
|
417
|
+
INT_MAX});
|
418
|
+
t->keepalive_timeout = value == INT_MAX
|
419
|
+
? gpr_inf_future(GPR_TIMESPAN)
|
420
|
+
: gpr_time_from_seconds(value, GPR_TIMESPAN);
|
421
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
422
|
+
GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
|
423
|
+
t->keepalive_permit_without_calls =
|
424
|
+
(uint32_t)grpc_channel_arg_get_integer(
|
425
|
+
&channel_args->args[i], (grpc_integer_options){0, 0, 1});
|
330
426
|
} else {
|
331
427
|
static const struct {
|
332
428
|
const char *channel_arg_name;
|
333
429
|
grpc_chttp2_setting_id setting_id;
|
334
430
|
grpc_integer_options integer_options;
|
335
431
|
bool availability[2] /* server, client */;
|
336
|
-
} settings_map[] = {
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
432
|
+
} settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS,
|
433
|
+
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
|
434
|
+
{-1, 0, INT32_MAX},
|
435
|
+
{true, false}},
|
436
|
+
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
|
437
|
+
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
|
438
|
+
{-1, 0, INT32_MAX},
|
439
|
+
{true, true}},
|
440
|
+
{GRPC_ARG_MAX_METADATA_SIZE,
|
441
|
+
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
442
|
+
{-1, 0, INT32_MAX},
|
443
|
+
{true, true}},
|
444
|
+
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
|
445
|
+
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
|
446
|
+
{-1, 16384, 16777215},
|
447
|
+
{true, true}},
|
448
|
+
{GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES,
|
449
|
+
GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
|
450
|
+
{-1, 5, INT32_MAX},
|
451
|
+
{true, true}}};
|
354
452
|
for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) {
|
355
453
|
if (0 == strcmp(channel_args->args[i].key,
|
356
454
|
settings_map[j].channel_arg_name)) {
|
@@ -373,6 +471,19 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
373
471
|
}
|
374
472
|
}
|
375
473
|
|
474
|
+
t->ping_state.pings_before_data_required =
|
475
|
+
t->ping_policy.max_pings_without_data;
|
476
|
+
|
477
|
+
/** Start client-side keepalive pings */
|
478
|
+
if (t->is_client) {
|
479
|
+
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING;
|
480
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
|
481
|
+
grpc_timer_init(
|
482
|
+
exec_ctx, &t->keepalive_ping_timer,
|
483
|
+
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
|
484
|
+
&t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
|
485
|
+
}
|
486
|
+
|
376
487
|
grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
|
377
488
|
post_benign_reclaimer(exec_ctx, t);
|
378
489
|
}
|
@@ -400,6 +511,10 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
400
511
|
grpc_chttp2_transport *t,
|
401
512
|
grpc_error *error) {
|
402
513
|
if (!t->closed) {
|
514
|
+
if (!grpc_error_has_clear_grpc_status(error)) {
|
515
|
+
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
|
516
|
+
GRPC_STATUS_UNAVAILABLE);
|
517
|
+
}
|
403
518
|
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
|
404
519
|
if (t->close_transport_on_writes_finished == NULL) {
|
405
520
|
t->close_transport_on_writes_finished =
|
@@ -409,14 +524,26 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
409
524
|
grpc_error_add_child(t->close_transport_on_writes_finished, error);
|
410
525
|
return;
|
411
526
|
}
|
412
|
-
if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
|
413
|
-
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
|
414
|
-
GRPC_STATUS_UNAVAILABLE);
|
415
|
-
}
|
416
527
|
t->closed = 1;
|
417
528
|
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
|
418
529
|
GRPC_ERROR_REF(error), "close_transport");
|
419
|
-
grpc_endpoint_shutdown(exec_ctx, t->ep);
|
530
|
+
grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error));
|
531
|
+
if (t->is_client) {
|
532
|
+
switch (t->keepalive_state) {
|
533
|
+
case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: {
|
534
|
+
grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
|
535
|
+
break;
|
536
|
+
}
|
537
|
+
case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING: {
|
538
|
+
grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
|
539
|
+
grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
|
540
|
+
break;
|
541
|
+
}
|
542
|
+
case GRPC_CHTTP2_KEEPALIVE_STATE_DYING: {
|
543
|
+
break;
|
544
|
+
}
|
545
|
+
}
|
546
|
+
}
|
420
547
|
|
421
548
|
/* flush writable stream list to avoid dangling references */
|
422
549
|
grpc_chttp2_stream *s;
|
@@ -424,6 +551,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
424
551
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close");
|
425
552
|
}
|
426
553
|
end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error));
|
554
|
+
cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error));
|
427
555
|
}
|
428
556
|
GRPC_ERROR_UNREF(error);
|
429
557
|
}
|
@@ -452,8 +580,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
452
580
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
453
581
|
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
|
454
582
|
|
455
|
-
memset(s, 0, sizeof(*s));
|
456
|
-
|
457
583
|
s->t = t;
|
458
584
|
s->refcount = refcount;
|
459
585
|
/* We reserve one 'active stream' that's dropped when the stream is
|
@@ -474,11 +600,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
474
600
|
|
475
601
|
if (server_data) {
|
476
602
|
s->id = (uint32_t)(uintptr_t)server_data;
|
477
|
-
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
|
478
|
-
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
479
|
-
s->incoming_window = s->max_recv_bytes =
|
480
|
-
t->settings[GRPC_SENT_SETTINGS]
|
481
|
-
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
482
603
|
*t->accepting_stream = s;
|
483
604
|
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
|
484
605
|
post_destructive_reclaimer(exec_ctx, t);
|
@@ -507,6 +628,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
|
|
507
628
|
}
|
508
629
|
|
509
630
|
grpc_chttp2_list_remove_stalled_by_transport(t, s);
|
631
|
+
grpc_chttp2_list_remove_stalled_by_stream(t, s);
|
510
632
|
|
511
633
|
for (int i = 0; i < STREAM_LIST_COUNT; i++) {
|
512
634
|
if (s->included[i]) {
|
@@ -531,6 +653,14 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
|
|
531
653
|
GRPC_ERROR_UNREF(s->read_closed_error);
|
532
654
|
GRPC_ERROR_UNREF(s->write_closed_error);
|
533
655
|
|
656
|
+
if (s->incoming_window_delta > 0) {
|
657
|
+
GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA(
|
658
|
+
"destroy", t, s, s->incoming_window_delta);
|
659
|
+
} else if (s->incoming_window_delta < 0) {
|
660
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM_INCOMING_WINDOW_DELTA(
|
661
|
+
"destroy", t, s, -s->incoming_window_delta);
|
662
|
+
}
|
663
|
+
|
534
664
|
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream");
|
535
665
|
|
536
666
|
GPR_TIMER_END("destroy_stream", 0);
|
@@ -646,13 +776,21 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
|
|
646
776
|
GPR_TIMER_END("grpc_chttp2_initiate_write", 0);
|
647
777
|
}
|
648
778
|
|
649
|
-
void grpc_chttp2_become_writable(
|
650
|
-
|
651
|
-
|
652
|
-
const char *reason) {
|
779
|
+
void grpc_chttp2_become_writable(
|
780
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
|
781
|
+
grpc_chttp2_stream_write_type stream_write_type, const char *reason) {
|
653
782
|
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) {
|
654
783
|
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become");
|
655
|
-
|
784
|
+
}
|
785
|
+
switch (stream_write_type) {
|
786
|
+
case GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK:
|
787
|
+
break;
|
788
|
+
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED:
|
789
|
+
grpc_chttp2_initiate_write(exec_ctx, t, true, reason);
|
790
|
+
break;
|
791
|
+
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED:
|
792
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, reason);
|
793
|
+
break;
|
656
794
|
}
|
657
795
|
}
|
658
796
|
|
@@ -780,7 +918,6 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
|
|
780
918
|
static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
|
781
919
|
grpc_chttp2_transport *t) {
|
782
920
|
grpc_chttp2_stream *s;
|
783
|
-
uint32_t stream_incoming_window;
|
784
921
|
/* start streams where we have free grpc_chttp2_stream ids and free
|
785
922
|
* concurrency */
|
786
923
|
while (t->next_stream_id <= MAX_CLIENT_STREAM_ID &&
|
@@ -803,15 +940,11 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
|
|
803
940
|
"no_more_stream_ids");
|
804
941
|
}
|
805
942
|
|
806
|
-
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
|
807
|
-
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
808
|
-
s->incoming_window = stream_incoming_window =
|
809
|
-
t->settings[GRPC_SENT_SETTINGS]
|
810
|
-
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
811
|
-
s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes);
|
812
943
|
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
|
813
944
|
post_destructive_reclaimer(exec_ctx, t);
|
814
|
-
grpc_chttp2_become_writable(exec_ctx, t, s,
|
945
|
+
grpc_chttp2_become_writable(exec_ctx, t, s,
|
946
|
+
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
|
947
|
+
"new_stream");
|
815
948
|
}
|
816
949
|
/* cancel out streams that will never be started */
|
817
950
|
while (t->next_stream_id >= MAX_CLIENT_STREAM_ID &&
|
@@ -866,7 +999,6 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
|
|
866
999
|
(int)(closure->next_data.scratch / CLOSURE_BARRIER_FIRST_REF_BIT),
|
867
1000
|
(int)(closure->next_data.scratch % CLOSURE_BARRIER_FIRST_REF_BIT),
|
868
1001
|
desc, errstr);
|
869
|
-
grpc_error_free_string(errstr);
|
870
1002
|
}
|
871
1003
|
if (error != GRPC_ERROR_NONE) {
|
872
1004
|
if (closure->error_data.error == GRPC_ERROR_NONE) {
|
@@ -895,12 +1027,9 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
|
|
895
1027
|
}
|
896
1028
|
|
897
1029
|
static bool contains_non_ok_status(grpc_metadata_batch *batch) {
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
l->md != GRPC_MDELEM_GRPC_STATUS_0) {
|
902
|
-
return true;
|
903
|
-
}
|
1030
|
+
if (batch->idx.named.grpc_status != NULL) {
|
1031
|
+
return !grpc_mdelem_eq(batch->idx.named.grpc_status->md,
|
1032
|
+
GRPC_MDELEM_GRPC_STATUS_0);
|
904
1033
|
}
|
905
1034
|
return false;
|
906
1035
|
}
|
@@ -910,7 +1039,9 @@ static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx *exec_ctx,
|
|
910
1039
|
grpc_chttp2_stream *s) {
|
911
1040
|
if (s->id != 0 && (!s->write_buffering ||
|
912
1041
|
s->flow_controlled_buffer.length > t->write_buffer_size)) {
|
913
|
-
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1042
|
+
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1043
|
+
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
|
1044
|
+
"op.send_message");
|
914
1045
|
}
|
915
1046
|
}
|
916
1047
|
|
@@ -980,9 +1111,12 @@ static void log_metadata(const grpc_metadata_batch *md_batch, uint32_t id,
|
|
980
1111
|
bool is_client, bool is_initial) {
|
981
1112
|
for (grpc_linked_mdelem *md = md_batch->list.head; md != md_batch->list.tail;
|
982
1113
|
md = md->next) {
|
1114
|
+
char *key = grpc_slice_to_c_string(GRPC_MDKEY(md->md));
|
1115
|
+
char *value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md));
|
983
1116
|
gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL",
|
984
|
-
is_client ? "CLI" : "SVR",
|
985
|
-
|
1117
|
+
is_client ? "CLI" : "SVR", key, value);
|
1118
|
+
gpr_free(key);
|
1119
|
+
gpr_free(value);
|
986
1120
|
}
|
987
1121
|
}
|
988
1122
|
|
@@ -991,8 +1125,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
991
1125
|
GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
|
992
1126
|
|
993
1127
|
grpc_transport_stream_op *op = stream_op;
|
994
|
-
grpc_chttp2_transport *t = op->
|
995
|
-
grpc_chttp2_stream *s = op->
|
1128
|
+
grpc_chttp2_transport *t = op->handler_private.args[0];
|
1129
|
+
grpc_chttp2_stream *s = op->handler_private.args[1];
|
996
1130
|
|
997
1131
|
if (grpc_http_trace) {
|
998
1132
|
char *str = grpc_transport_stream_op_string(op);
|
@@ -1025,11 +1159,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
1025
1159
|
}
|
1026
1160
|
|
1027
1161
|
if (op->cancel_error != GRPC_ERROR_NONE) {
|
1028
|
-
grpc_chttp2_cancel_stream(exec_ctx, t, s,
|
1029
|
-
}
|
1030
|
-
|
1031
|
-
if (op->close_error != GRPC_ERROR_NONE) {
|
1032
|
-
close_from_api(exec_ctx, t, s, GRPC_ERROR_REF(op->close_error));
|
1162
|
+
grpc_chttp2_cancel_stream(exec_ctx, t, s, op->cancel_error);
|
1033
1163
|
}
|
1034
1164
|
|
1035
1165
|
if (op->send_initial_metadata != NULL) {
|
@@ -1068,20 +1198,25 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
1068
1198
|
grpc_chttp2_list_add_waiting_for_concurrency(t, s);
|
1069
1199
|
maybe_start_some_streams(exec_ctx, t);
|
1070
1200
|
} else {
|
1071
|
-
grpc_chttp2_cancel_stream(
|
1072
|
-
|
1201
|
+
grpc_chttp2_cancel_stream(
|
1202
|
+
exec_ctx, t, s,
|
1203
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("Transport closed"),
|
1204
|
+
GRPC_ERROR_INT_GRPC_STATUS,
|
1205
|
+
GRPC_STATUS_UNAVAILABLE));
|
1073
1206
|
}
|
1074
1207
|
} else {
|
1075
1208
|
GPR_ASSERT(s->id != 0);
|
1076
|
-
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1209
|
+
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1210
|
+
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
|
1077
1211
|
"op.send_initial_metadata");
|
1078
1212
|
}
|
1079
1213
|
} else {
|
1080
1214
|
s->send_initial_metadata = NULL;
|
1081
1215
|
grpc_chttp2_complete_closure_step(
|
1082
1216
|
exec_ctx, t, s, &s->send_initial_metadata_finished,
|
1083
|
-
|
1084
|
-
"Attempt to send initial metadata after stream was closed"
|
1217
|
+
GRPC_ERROR_CREATE_REFERENCING(
|
1218
|
+
"Attempt to send initial metadata after stream was closed",
|
1219
|
+
&s->write_closed_error, 1),
|
1085
1220
|
"send_initial_metadata_finished");
|
1086
1221
|
}
|
1087
1222
|
}
|
@@ -1093,7 +1228,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
1093
1228
|
if (s->write_closed) {
|
1094
1229
|
grpc_chttp2_complete_closure_step(
|
1095
1230
|
exec_ctx, t, s, &s->fetching_send_message_finished,
|
1096
|
-
|
1231
|
+
GRPC_ERROR_CREATE_REFERENCING(
|
1232
|
+
"Attempt to send message after stream was closed",
|
1233
|
+
&s->write_closed_error, 1),
|
1097
1234
|
"fetching_send_message_finished");
|
1098
1235
|
} else {
|
1099
1236
|
GPR_ASSERT(s->fetching_send_message == NULL);
|
@@ -1161,7 +1298,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
1161
1298
|
} else if (s->id != 0) {
|
1162
1299
|
/* TODO(ctiller): check if there's flow control for any outstanding
|
1163
1300
|
bytes before going writable */
|
1164
|
-
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1301
|
+
grpc_chttp2_become_writable(exec_ctx, t, s,
|
1302
|
+
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
|
1165
1303
|
"op.send_trailing_metadata");
|
1166
1304
|
}
|
1167
1305
|
}
|
@@ -1180,8 +1318,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
1180
1318
|
s->recv_message = op->recv_message;
|
1181
1319
|
if (s->id != 0 &&
|
1182
1320
|
(s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
|
1183
|
-
incoming_byte_stream_update_flow_control(exec_ctx, t, s,
|
1184
|
-
t->stream_lookahead, 0);
|
1321
|
+
incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0);
|
1185
1322
|
}
|
1186
1323
|
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
1187
1324
|
}
|
@@ -1213,63 +1350,71 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1213
1350
|
gpr_free(str);
|
1214
1351
|
}
|
1215
1352
|
|
1216
|
-
op->
|
1217
|
-
op->
|
1353
|
+
op->handler_private.args[0] = gt;
|
1354
|
+
op->handler_private.args[1] = gs;
|
1218
1355
|
GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
|
1219
1356
|
grpc_closure_sched(
|
1220
1357
|
exec_ctx,
|
1221
1358
|
grpc_closure_init(
|
1222
|
-
&op->
|
1359
|
+
&op->handler_private.closure, perform_stream_op_locked, op,
|
1223
1360
|
grpc_combiner_scheduler(t->combiner, op->covered_by_poller)),
|
1224
1361
|
GRPC_ERROR_NONE);
|
1225
1362
|
GPR_TIMER_END("perform_stream_op", 0);
|
1226
1363
|
}
|
1227
1364
|
|
1365
|
+
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1366
|
+
grpc_error *error) {
|
1367
|
+
/* callback remaining pings: they're not allowed to call into the transpot,
|
1368
|
+
and maybe they hold resources that need to be freed */
|
1369
|
+
for (size_t i = 0; i < GRPC_CHTTP2_PING_TYPE_COUNT; i++) {
|
1370
|
+
grpc_chttp2_ping_queue *pq = &t->ping_queues[i];
|
1371
|
+
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) {
|
1372
|
+
grpc_closure_list_fail_all(&pq->lists[j], GRPC_ERROR_REF(error));
|
1373
|
+
grpc_closure_list_sched(exec_ctx, &pq->lists[j]);
|
1374
|
+
}
|
1375
|
+
}
|
1376
|
+
GRPC_ERROR_UNREF(error);
|
1377
|
+
}
|
1378
|
+
|
1228
1379
|
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
p->id[4] = (uint8_t)((t->ping_counter >> 24) & 0xff);
|
1239
|
-
p->id[5] = (uint8_t)((t->ping_counter >> 16) & 0xff);
|
1240
|
-
p->id[6] = (uint8_t)((t->ping_counter >> 8) & 0xff);
|
1241
|
-
p->id[7] = (uint8_t)(t->ping_counter & 0xff);
|
1242
|
-
t->ping_counter++;
|
1243
|
-
p->on_recv = on_recv;
|
1244
|
-
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id));
|
1245
|
-
grpc_chttp2_initiate_write(exec_ctx, t, true, "send_ping");
|
1380
|
+
grpc_chttp2_ping_type ping_type,
|
1381
|
+
grpc_closure *on_initiate, grpc_closure *on_ack) {
|
1382
|
+
grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
|
1383
|
+
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INITIATE], on_initiate,
|
1384
|
+
GRPC_ERROR_NONE);
|
1385
|
+
if (grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT], on_ack,
|
1386
|
+
GRPC_ERROR_NONE)) {
|
1387
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "send_ping");
|
1388
|
+
}
|
1246
1389
|
}
|
1247
1390
|
|
1248
1391
|
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1392
|
+
uint64_t id) {
|
1393
|
+
grpc_chttp2_ping_queue *pq =
|
1394
|
+
&t->ping_queues[id % GRPC_CHTTP2_PING_TYPE_COUNT];
|
1395
|
+
if (pq->inflight_id != id) {
|
1396
|
+
char *from = grpc_endpoint_get_peer(t->ep);
|
1397
|
+
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %" PRIx64, from, id);
|
1398
|
+
gpr_free(from);
|
1399
|
+
return;
|
1400
|
+
}
|
1401
|
+
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
|
1402
|
+
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
|
1403
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "continue_pings");
|
1259
1404
|
}
|
1260
|
-
char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX);
|
1261
|
-
char *from = grpc_endpoint_get_peer(t->ep);
|
1262
|
-
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg);
|
1263
|
-
gpr_free(from);
|
1264
|
-
gpr_free(msg);
|
1265
1405
|
}
|
1266
1406
|
|
1267
1407
|
static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1268
|
-
|
1408
|
+
grpc_error *error) {
|
1269
1409
|
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED;
|
1270
|
-
|
1271
|
-
|
1410
|
+
grpc_http2_error_code http_error;
|
1411
|
+
const char *msg;
|
1412
|
+
grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL, &msg,
|
1413
|
+
&http_error);
|
1414
|
+
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
|
1415
|
+
grpc_slice_from_copied_string(msg), &t->qbuf);
|
1272
1416
|
grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent");
|
1417
|
+
GRPC_ERROR_UNREF(error);
|
1273
1418
|
}
|
1274
1419
|
|
1275
1420
|
static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
@@ -1285,10 +1430,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1285
1430
|
op->on_connectivity_state_change);
|
1286
1431
|
}
|
1287
1432
|
|
1288
|
-
if (op->
|
1289
|
-
send_goaway(exec_ctx, t,
|
1290
|
-
grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
|
1291
|
-
grpc_slice_ref_internal(*op->goaway_message));
|
1433
|
+
if (op->goaway_error) {
|
1434
|
+
send_goaway(exec_ctx, t, op->goaway_error);
|
1292
1435
|
}
|
1293
1436
|
|
1294
1437
|
if (op->set_accept_stream) {
|
@@ -1306,7 +1449,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1306
1449
|
}
|
1307
1450
|
|
1308
1451
|
if (op->send_ping) {
|
1309
|
-
send_ping_locked(exec_ctx, t,
|
1452
|
+
send_ping_locked(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, NULL,
|
1453
|
+
op->send_ping);
|
1310
1454
|
}
|
1311
1455
|
|
1312
1456
|
if (close_transport != GRPC_ERROR_NONE) {
|
@@ -1348,8 +1492,8 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
|
|
1348
1492
|
incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
|
1349
1493
|
}
|
1350
1494
|
}
|
1351
|
-
grpc_chttp2_incoming_metadata_buffer_publish(
|
1352
|
-
|
1495
|
+
grpc_chttp2_incoming_metadata_buffer_publish(
|
1496
|
+
exec_ctx, &s->metadata_buffer[0], s->recv_initial_metadata);
|
1353
1497
|
null_then_run_closure(exec_ctx, &s->recv_initial_metadata_ready,
|
1354
1498
|
GRPC_ERROR_NONE);
|
1355
1499
|
}
|
@@ -1392,8 +1536,8 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
|
|
1392
1536
|
}
|
1393
1537
|
if (s->all_incoming_byte_streams_finished &&
|
1394
1538
|
s->recv_trailing_metadata_finished != NULL) {
|
1395
|
-
grpc_chttp2_incoming_metadata_buffer_publish(
|
1396
|
-
|
1539
|
+
grpc_chttp2_incoming_metadata_buffer_publish(
|
1540
|
+
exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata);
|
1397
1541
|
grpc_chttp2_complete_closure_step(
|
1398
1542
|
exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE,
|
1399
1543
|
"recv_trailing_metadata_finished");
|
@@ -1441,70 +1585,37 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1441
1585
|
maybe_start_some_streams(exec_ctx, t);
|
1442
1586
|
}
|
1443
1587
|
|
1444
|
-
static void status_codes_from_error(grpc_error *error, gpr_timespec deadline,
|
1445
|
-
grpc_chttp2_error_code *http2_error,
|
1446
|
-
grpc_status_code *grpc_status) {
|
1447
|
-
intptr_t ip_http;
|
1448
|
-
intptr_t ip_grpc;
|
1449
|
-
bool have_http =
|
1450
|
-
grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &ip_http);
|
1451
|
-
bool have_grpc =
|
1452
|
-
grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &ip_grpc);
|
1453
|
-
if (have_http) {
|
1454
|
-
*http2_error = (grpc_chttp2_error_code)ip_http;
|
1455
|
-
} else if (have_grpc) {
|
1456
|
-
*http2_error =
|
1457
|
-
grpc_chttp2_grpc_status_to_http2_error((grpc_status_code)ip_grpc);
|
1458
|
-
} else {
|
1459
|
-
*http2_error = GRPC_CHTTP2_INTERNAL_ERROR;
|
1460
|
-
}
|
1461
|
-
if (have_grpc) {
|
1462
|
-
*grpc_status = (grpc_status_code)ip_grpc;
|
1463
|
-
} else if (have_http) {
|
1464
|
-
*grpc_status = grpc_chttp2_http2_error_to_grpc_status(
|
1465
|
-
(grpc_chttp2_error_code)ip_http, deadline);
|
1466
|
-
} else {
|
1467
|
-
*grpc_status = GRPC_STATUS_INTERNAL;
|
1468
|
-
}
|
1469
|
-
}
|
1470
|
-
|
1471
1588
|
void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,
|
1472
1589
|
grpc_chttp2_transport *t, grpc_chttp2_stream *s,
|
1473
1590
|
grpc_error *due_to_error) {
|
1474
|
-
if (!
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1591
|
+
if (!t->is_client && !s->sent_trailing_metadata &&
|
1592
|
+
grpc_error_has_clear_grpc_status(due_to_error)) {
|
1593
|
+
close_from_api(exec_ctx, t, s, due_to_error);
|
1594
|
+
return;
|
1595
|
+
}
|
1479
1596
|
|
1597
|
+
if (!s->read_closed || !s->write_closed) {
|
1480
1598
|
if (s->id != 0) {
|
1599
|
+
grpc_http2_error_code http_error;
|
1600
|
+
grpc_error_get_status(due_to_error, s->deadline, NULL, NULL, &http_error);
|
1481
1601
|
grpc_slice_buffer_add(
|
1482
1602
|
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error,
|
1483
1603
|
&s->stats.outgoing));
|
1484
1604
|
grpc_chttp2_initiate_write(exec_ctx, t, false, "rst_stream");
|
1485
1605
|
}
|
1486
|
-
|
1487
|
-
const char *msg =
|
1488
|
-
grpc_error_get_str(due_to_error, GRPC_ERROR_STR_GRPC_MESSAGE);
|
1489
|
-
bool free_msg = false;
|
1490
|
-
if (msg == NULL) {
|
1491
|
-
free_msg = true;
|
1492
|
-
msg = grpc_error_string(due_to_error);
|
1493
|
-
}
|
1494
|
-
grpc_slice msg_slice = grpc_slice_from_copied_string(msg);
|
1495
|
-
grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice);
|
1496
|
-
if (free_msg) grpc_error_free_string(msg);
|
1497
1606
|
}
|
1498
1607
|
if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) {
|
1499
1608
|
s->seen_error = true;
|
1500
|
-
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1501
1609
|
}
|
1502
1610
|
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error);
|
1503
1611
|
}
|
1504
1612
|
|
1505
1613
|
void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1506
|
-
grpc_chttp2_stream *s,
|
1507
|
-
|
1614
|
+
grpc_chttp2_stream *s, grpc_error *error) {
|
1615
|
+
grpc_status_code status;
|
1616
|
+
const char *msg;
|
1617
|
+
grpc_error_get_status(error, s->deadline, &status, &msg, NULL);
|
1618
|
+
|
1508
1619
|
if (status != GRPC_STATUS_OK) {
|
1509
1620
|
s->seen_error = true;
|
1510
1621
|
}
|
@@ -1518,24 +1629,21 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1518
1629
|
s->recv_trailing_metadata_finished != NULL) {
|
1519
1630
|
char status_string[GPR_LTOA_MIN_BUFSIZE];
|
1520
1631
|
gpr_ltoa(status, status_string);
|
1521
|
-
|
1522
|
-
&s->metadata_buffer[1],
|
1523
|
-
|
1524
|
-
|
1525
|
-
if (
|
1526
|
-
|
1527
|
-
&s->metadata_buffer[1],
|
1528
|
-
|
1529
|
-
|
1530
|
-
grpc_mdstr_from_slice(exec_ctx,
|
1531
|
-
grpc_slice_ref_internal(*slice))));
|
1632
|
+
grpc_chttp2_incoming_metadata_buffer_replace_or_add(
|
1633
|
+
exec_ctx, &s->metadata_buffer[1],
|
1634
|
+
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
|
1635
|
+
grpc_slice_from_copied_string(status_string)));
|
1636
|
+
if (msg != NULL) {
|
1637
|
+
grpc_chttp2_incoming_metadata_buffer_replace_or_add(
|
1638
|
+
exec_ctx, &s->metadata_buffer[1],
|
1639
|
+
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
|
1640
|
+
grpc_slice_from_copied_string(msg)));
|
1532
1641
|
}
|
1533
1642
|
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
|
1534
1643
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1535
1644
|
}
|
1536
|
-
|
1537
|
-
|
1538
|
-
}
|
1645
|
+
|
1646
|
+
GRPC_ERROR_UNREF(error);
|
1539
1647
|
}
|
1540
1648
|
|
1541
1649
|
static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) {
|
@@ -1601,36 +1709,48 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
|
|
1601
1709
|
int close_writes, grpc_error *error) {
|
1602
1710
|
if (s->read_closed && s->write_closed) {
|
1603
1711
|
/* already closed */
|
1712
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1604
1713
|
GRPC_ERROR_UNREF(error);
|
1605
1714
|
return;
|
1606
1715
|
}
|
1716
|
+
bool closed_read = false;
|
1717
|
+
bool became_closed = false;
|
1607
1718
|
if (close_reads && !s->read_closed) {
|
1608
1719
|
s->read_closed_error = GRPC_ERROR_REF(error);
|
1609
1720
|
s->read_closed = true;
|
1610
|
-
|
1611
|
-
if (s->published_metadata[i] == GRPC_METADATA_NOT_PUBLISHED) {
|
1612
|
-
s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
|
1613
|
-
}
|
1614
|
-
}
|
1615
|
-
decrement_active_streams_locked(exec_ctx, t, s);
|
1616
|
-
grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
|
1617
|
-
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
1618
|
-
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1721
|
+
closed_read = true;
|
1619
1722
|
}
|
1620
1723
|
if (close_writes && !s->write_closed) {
|
1621
1724
|
s->write_closed_error = GRPC_ERROR_REF(error);
|
1622
1725
|
s->write_closed = true;
|
1623
1726
|
grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error));
|
1624
|
-
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1625
1727
|
}
|
1626
1728
|
if (s->read_closed && s->write_closed) {
|
1729
|
+
became_closed = true;
|
1730
|
+
grpc_error *overall_error =
|
1731
|
+
removal_error(GRPC_ERROR_REF(error), s, "Stream removed");
|
1627
1732
|
if (s->id != 0) {
|
1628
|
-
remove_stream(exec_ctx, t, s->id,
|
1629
|
-
removal_error(GRPC_ERROR_REF(error), s, "Stream removed"));
|
1733
|
+
remove_stream(exec_ctx, t, s->id, GRPC_ERROR_REF(overall_error));
|
1630
1734
|
} else {
|
1631
1735
|
/* Purge streams waiting on concurrency still waiting for id assignment */
|
1632
1736
|
grpc_chttp2_list_remove_waiting_for_concurrency(t, s);
|
1633
1737
|
}
|
1738
|
+
if (overall_error != GRPC_ERROR_NONE) {
|
1739
|
+
grpc_chttp2_fake_status(exec_ctx, t, s, overall_error);
|
1740
|
+
}
|
1741
|
+
}
|
1742
|
+
if (closed_read) {
|
1743
|
+
for (int i = 0; i < 2; i++) {
|
1744
|
+
if (s->published_metadata[i] == GRPC_METADATA_NOT_PUBLISHED) {
|
1745
|
+
s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
|
1746
|
+
}
|
1747
|
+
}
|
1748
|
+
decrement_active_streams_locked(exec_ctx, t, s);
|
1749
|
+
grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
|
1750
|
+
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
1751
|
+
}
|
1752
|
+
if (became_closed) {
|
1753
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
1634
1754
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2");
|
1635
1755
|
}
|
1636
1756
|
GRPC_ERROR_UNREF(error);
|
@@ -1644,112 +1764,92 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1644
1764
|
uint8_t *p;
|
1645
1765
|
uint32_t len = 0;
|
1646
1766
|
grpc_status_code grpc_status;
|
1647
|
-
|
1648
|
-
|
1767
|
+
const char *msg;
|
1768
|
+
grpc_error_get_status(error, s->deadline, &grpc_status, &msg, NULL);
|
1649
1769
|
|
1650
1770
|
GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
|
1651
1771
|
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1772
|
+
/* Hand roll a header block.
|
1773
|
+
This is unnecessarily ugly - at some point we should find a more
|
1774
|
+
elegant solution.
|
1775
|
+
It's complicated by the fact that our send machinery would be dead by
|
1776
|
+
the time we got around to sending this, so instead we ignore HPACK
|
1777
|
+
compression and just write the uncompressed bytes onto the wire. */
|
1778
|
+
status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10));
|
1779
|
+
p = GRPC_SLICE_START_PTR(status_hdr);
|
1780
|
+
*p++ = 0x00; /* literal header, not indexed */
|
1781
|
+
*p++ = 11; /* len(grpc-status) */
|
1782
|
+
*p++ = 'g';
|
1783
|
+
*p++ = 'r';
|
1784
|
+
*p++ = 'p';
|
1785
|
+
*p++ = 'c';
|
1786
|
+
*p++ = '-';
|
1787
|
+
*p++ = 's';
|
1788
|
+
*p++ = 't';
|
1789
|
+
*p++ = 'a';
|
1790
|
+
*p++ = 't';
|
1791
|
+
*p++ = 'u';
|
1792
|
+
*p++ = 's';
|
1793
|
+
if (grpc_status < 10) {
|
1794
|
+
*p++ = 1;
|
1795
|
+
*p++ = (uint8_t)('0' + grpc_status);
|
1796
|
+
} else {
|
1797
|
+
*p++ = 2;
|
1798
|
+
*p++ = (uint8_t)('0' + (grpc_status / 10));
|
1799
|
+
*p++ = (uint8_t)('0' + (grpc_status % 10));
|
1800
|
+
}
|
1801
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(status_hdr));
|
1802
|
+
len += (uint32_t)GRPC_SLICE_LENGTH(status_hdr);
|
1803
|
+
|
1804
|
+
if (msg != NULL) {
|
1805
|
+
size_t msg_len = strlen(msg);
|
1806
|
+
GPR_ASSERT(msg_len <= UINT32_MAX);
|
1807
|
+
uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
|
1808
|
+
message_pfx = grpc_slice_malloc(14 + msg_len_len);
|
1809
|
+
p = GRPC_SLICE_START_PTR(message_pfx);
|
1810
|
+
*p++ = 0x00; /* literal header, not indexed */
|
1811
|
+
*p++ = 12; /* len(grpc-message) */
|
1666
1812
|
*p++ = 'g';
|
1667
1813
|
*p++ = 'r';
|
1668
1814
|
*p++ = 'p';
|
1669
1815
|
*p++ = 'c';
|
1670
1816
|
*p++ = '-';
|
1817
|
+
*p++ = 'm';
|
1818
|
+
*p++ = 'e';
|
1671
1819
|
*p++ = 's';
|
1672
|
-
*p++ = 't';
|
1673
|
-
*p++ = 'a';
|
1674
|
-
*p++ = 't';
|
1675
|
-
*p++ = 'u';
|
1676
1820
|
*p++ = 's';
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
*p++ = 'g';
|
1710
|
-
*p++ = 'e';
|
1711
|
-
GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p,
|
1712
|
-
(uint32_t)msg_len_len);
|
1713
|
-
p += msg_len_len;
|
1714
|
-
GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
|
1715
|
-
len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
|
1716
|
-
len += (uint32_t)msg_len;
|
1717
|
-
}
|
1718
|
-
|
1719
|
-
hdr = grpc_slice_malloc(9);
|
1720
|
-
p = GRPC_SLICE_START_PTR(hdr);
|
1721
|
-
*p++ = (uint8_t)(len >> 16);
|
1722
|
-
*p++ = (uint8_t)(len >> 8);
|
1723
|
-
*p++ = (uint8_t)(len);
|
1724
|
-
*p++ = GRPC_CHTTP2_FRAME_HEADER;
|
1725
|
-
*p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
|
1726
|
-
*p++ = (uint8_t)(s->id >> 24);
|
1727
|
-
*p++ = (uint8_t)(s->id >> 16);
|
1728
|
-
*p++ = (uint8_t)(s->id >> 8);
|
1729
|
-
*p++ = (uint8_t)(s->id);
|
1730
|
-
GPR_ASSERT(p == GRPC_SLICE_END_PTR(hdr));
|
1731
|
-
|
1732
|
-
grpc_slice_buffer_add(&t->qbuf, hdr);
|
1733
|
-
grpc_slice_buffer_add(&t->qbuf, status_hdr);
|
1734
|
-
if (optional_message) {
|
1735
|
-
grpc_slice_buffer_add(&t->qbuf, message_pfx);
|
1736
|
-
grpc_slice_buffer_add(&t->qbuf,
|
1737
|
-
grpc_slice_from_copied_string(optional_message));
|
1738
|
-
}
|
1739
|
-
grpc_slice_buffer_add(
|
1740
|
-
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_CHTTP2_NO_ERROR,
|
1741
|
-
&s->stats.outgoing));
|
1742
|
-
}
|
1743
|
-
|
1744
|
-
const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
|
1745
|
-
bool free_msg = false;
|
1746
|
-
if (msg == NULL) {
|
1747
|
-
free_msg = true;
|
1748
|
-
msg = grpc_error_string(error);
|
1749
|
-
}
|
1750
|
-
grpc_slice msg_slice = grpc_slice_from_copied_string(msg);
|
1751
|
-
grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice);
|
1752
|
-
if (free_msg) grpc_error_free_string(msg);
|
1821
|
+
*p++ = 'a';
|
1822
|
+
*p++ = 'g';
|
1823
|
+
*p++ = 'e';
|
1824
|
+
GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p, (uint32_t)msg_len_len);
|
1825
|
+
p += msg_len_len;
|
1826
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
|
1827
|
+
len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
|
1828
|
+
len += (uint32_t)msg_len;
|
1829
|
+
}
|
1830
|
+
|
1831
|
+
hdr = grpc_slice_malloc(9);
|
1832
|
+
p = GRPC_SLICE_START_PTR(hdr);
|
1833
|
+
*p++ = (uint8_t)(len >> 16);
|
1834
|
+
*p++ = (uint8_t)(len >> 8);
|
1835
|
+
*p++ = (uint8_t)(len);
|
1836
|
+
*p++ = GRPC_CHTTP2_FRAME_HEADER;
|
1837
|
+
*p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
|
1838
|
+
*p++ = (uint8_t)(s->id >> 24);
|
1839
|
+
*p++ = (uint8_t)(s->id >> 16);
|
1840
|
+
*p++ = (uint8_t)(s->id >> 8);
|
1841
|
+
*p++ = (uint8_t)(s->id);
|
1842
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(hdr));
|
1843
|
+
|
1844
|
+
grpc_slice_buffer_add(&t->qbuf, hdr);
|
1845
|
+
grpc_slice_buffer_add(&t->qbuf, status_hdr);
|
1846
|
+
if (msg != NULL) {
|
1847
|
+
grpc_slice_buffer_add(&t->qbuf, message_pfx);
|
1848
|
+
grpc_slice_buffer_add(&t->qbuf, grpc_slice_from_copied_string(msg));
|
1849
|
+
}
|
1850
|
+
grpc_slice_buffer_add(
|
1851
|
+
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
|
1852
|
+
&s->stats.outgoing));
|
1753
1853
|
|
1754
1854
|
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error);
|
1755
1855
|
grpc_chttp2_initiate_write(exec_ctx, t, false, "close_from_api");
|
@@ -1775,40 +1875,34 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1775
1875
|
GRPC_ERROR_UNREF(error);
|
1776
1876
|
}
|
1777
1877
|
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
grpc_exec_ctx *exec_ctx;
|
1782
|
-
} update_global_window_args;
|
1878
|
+
/*******************************************************************************
|
1879
|
+
* INPUT PROCESSING - PARSING
|
1880
|
+
*/
|
1783
1881
|
|
1784
|
-
static void
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
if (initial_window_update > 0) {
|
1793
|
-
was_zero = s->outgoing_window <= 0;
|
1794
|
-
GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window,
|
1795
|
-
initial_window_update);
|
1796
|
-
is_zero = s->outgoing_window <= 0;
|
1797
|
-
|
1798
|
-
if (was_zero && !is_zero) {
|
1799
|
-
grpc_chttp2_become_writable(a->exec_ctx, t, s, true,
|
1800
|
-
"update_global_window");
|
1801
|
-
}
|
1882
|
+
static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1883
|
+
double bdp_dbl) {
|
1884
|
+
uint32_t bdp;
|
1885
|
+
if (bdp_dbl <= 0) {
|
1886
|
+
bdp = 0;
|
1887
|
+
} else if (bdp_dbl > UINT32_MAX) {
|
1888
|
+
bdp = UINT32_MAX;
|
1802
1889
|
} else {
|
1803
|
-
|
1804
|
-
-initial_window_update);
|
1890
|
+
bdp = (uint32_t)(bdp_dbl);
|
1805
1891
|
}
|
1892
|
+
int64_t delta =
|
1893
|
+
(int64_t)bdp -
|
1894
|
+
(int64_t)t->settings[GRPC_LOCAL_SETTINGS]
|
1895
|
+
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
1896
|
+
if (delta == 0 || (bdp != 0 && delta > -1024 && delta < 1024)) {
|
1897
|
+
return;
|
1898
|
+
}
|
1899
|
+
if (grpc_bdp_estimator_trace) {
|
1900
|
+
gpr_log(GPR_DEBUG, "%s: update initial window size to %d", t->peer_string,
|
1901
|
+
(int)bdp);
|
1902
|
+
}
|
1903
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
|
1806
1904
|
}
|
1807
1905
|
|
1808
|
-
/*******************************************************************************
|
1809
|
-
* INPUT PROCESSING - PARSING
|
1810
|
-
*/
|
1811
|
-
|
1812
1906
|
static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
1813
1907
|
grpc_chttp2_transport *t) {
|
1814
1908
|
grpc_http_parser parser;
|
@@ -1827,8 +1921,10 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
|
1827
1921
|
if (parse_error == GRPC_ERROR_NONE &&
|
1828
1922
|
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {
|
1829
1923
|
error = grpc_error_set_int(
|
1830
|
-
|
1831
|
-
|
1924
|
+
grpc_error_set_int(
|
1925
|
+
GRPC_ERROR_CREATE("Trying to connect an http1.x server"),
|
1926
|
+
GRPC_ERROR_INT_HTTP_STATUS, response.status),
|
1927
|
+
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
|
1832
1928
|
}
|
1833
1929
|
GRPC_ERROR_UNREF(parse_error);
|
1834
1930
|
|
@@ -1842,6 +1938,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1842
1938
|
GPR_TIMER_BEGIN("reading_action_locked", 0);
|
1843
1939
|
|
1844
1940
|
grpc_chttp2_transport *t = tp;
|
1941
|
+
bool need_bdp_ping = false;
|
1845
1942
|
|
1846
1943
|
GRPC_ERROR_REF(error);
|
1847
1944
|
|
@@ -1859,9 +1956,14 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1859
1956
|
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE,
|
1860
1957
|
GRPC_ERROR_NONE};
|
1861
1958
|
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) {
|
1959
|
+
if (grpc_bdp_estimator_add_incoming_bytes(
|
1960
|
+
&t->bdp_estimator,
|
1961
|
+
(int64_t)GRPC_SLICE_LENGTH(t->read_buffer.slices[i]))) {
|
1962
|
+
need_bdp_ping = true;
|
1963
|
+
}
|
1862
1964
|
errors[1] =
|
1863
1965
|
grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]);
|
1864
|
-
}
|
1966
|
+
}
|
1865
1967
|
if (errors[1] != GRPC_ERROR_NONE) {
|
1866
1968
|
errors[2] = try_http_parsing(exec_ctx, t);
|
1867
1969
|
GRPC_ERROR_UNREF(error);
|
@@ -1875,21 +1977,16 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1875
1977
|
|
1876
1978
|
GPR_TIMER_BEGIN("post_parse_locked", 0);
|
1877
1979
|
if (t->initial_window_update != 0) {
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1980
|
+
if (t->initial_window_update > 0) {
|
1981
|
+
grpc_chttp2_stream *s;
|
1982
|
+
while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) {
|
1983
|
+
grpc_chttp2_become_writable(
|
1984
|
+
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
|
1985
|
+
"unstalled");
|
1986
|
+
}
|
1987
|
+
}
|
1881
1988
|
t->initial_window_update = 0;
|
1882
1989
|
}
|
1883
|
-
/* handle higher level things */
|
1884
|
-
if (t->incoming_window < t->connection_window_target * 3 / 4) {
|
1885
|
-
int64_t announce_bytes = t->connection_window_target - t->incoming_window;
|
1886
|
-
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, announce_incoming_window,
|
1887
|
-
announce_bytes);
|
1888
|
-
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, incoming_window,
|
1889
|
-
announce_bytes);
|
1890
|
-
grpc_chttp2_initiate_write(exec_ctx, t, false, "global incoming window");
|
1891
|
-
}
|
1892
|
-
|
1893
1990
|
GPR_TIMER_END("post_parse_locked", 0);
|
1894
1991
|
}
|
1895
1992
|
|
@@ -1910,6 +2007,38 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1910
2007
|
if (keep_reading) {
|
1911
2008
|
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
|
1912
2009
|
&t->read_action_locked);
|
2010
|
+
|
2011
|
+
if (t->enable_bdp_probe) {
|
2012
|
+
if (need_bdp_ping) {
|
2013
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping");
|
2014
|
+
grpc_bdp_estimator_schedule_ping(&t->bdp_estimator);
|
2015
|
+
send_ping_locked(exec_ctx, t,
|
2016
|
+
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE,
|
2017
|
+
&t->start_bdp_ping_locked, &t->finish_bdp_ping_locked);
|
2018
|
+
}
|
2019
|
+
|
2020
|
+
int64_t estimate = -1;
|
2021
|
+
if (grpc_bdp_estimator_get_estimate(&t->bdp_estimator, &estimate)) {
|
2022
|
+
double target = 1 + log2((double)estimate);
|
2023
|
+
double memory_pressure = grpc_resource_quota_get_memory_pressure(
|
2024
|
+
grpc_resource_user_quota(grpc_endpoint_get_resource_user(t->ep)));
|
2025
|
+
if (memory_pressure > 0.8) {
|
2026
|
+
target *= 1 - GPR_MIN(1, (memory_pressure - 0.8) / 0.1);
|
2027
|
+
}
|
2028
|
+
double bdp_error =
|
2029
|
+
target - grpc_pid_controller_last(&t->pid_controller);
|
2030
|
+
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
|
2031
|
+
gpr_timespec dt_timespec = gpr_time_sub(now, t->last_pid_update);
|
2032
|
+
double dt = (double)dt_timespec.tv_sec + dt_timespec.tv_nsec * 1e-9;
|
2033
|
+
if (dt > 0.1) {
|
2034
|
+
dt = 0.1;
|
2035
|
+
}
|
2036
|
+
double log2_bdp_guess =
|
2037
|
+
grpc_pid_controller_update(&t->pid_controller, bdp_error, dt);
|
2038
|
+
update_bdp(exec_ctx, t, pow(2, log2_bdp_guess));
|
2039
|
+
t->last_pid_update = now;
|
2040
|
+
}
|
2041
|
+
}
|
1913
2042
|
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
|
1914
2043
|
} else {
|
1915
2044
|
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action");
|
@@ -1922,6 +2051,97 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1922
2051
|
GPR_TIMER_END("reading_action_locked", 0);
|
1923
2052
|
}
|
1924
2053
|
|
2054
|
+
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
2055
|
+
grpc_error *error) {
|
2056
|
+
grpc_chttp2_transport *t = tp;
|
2057
|
+
if (grpc_http_trace) {
|
2058
|
+
gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
|
2059
|
+
}
|
2060
|
+
grpc_bdp_estimator_start_ping(&t->bdp_estimator);
|
2061
|
+
}
|
2062
|
+
|
2063
|
+
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
2064
|
+
grpc_error *error) {
|
2065
|
+
grpc_chttp2_transport *t = tp;
|
2066
|
+
if (grpc_http_trace) {
|
2067
|
+
gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string);
|
2068
|
+
}
|
2069
|
+
grpc_bdp_estimator_complete_ping(&t->bdp_estimator);
|
2070
|
+
|
2071
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping");
|
2072
|
+
}
|
2073
|
+
|
2074
|
+
static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
2075
|
+
grpc_error *error) {
|
2076
|
+
grpc_chttp2_transport *t = arg;
|
2077
|
+
GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING);
|
2078
|
+
if (error == GRPC_ERROR_NONE && !(t->destroying || t->closed)) {
|
2079
|
+
if (t->keepalive_permit_without_calls || t->stream_map.count > 0) {
|
2080
|
+
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
|
2081
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end");
|
2082
|
+
send_ping_locked(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE,
|
2083
|
+
&t->start_keepalive_ping_locked,
|
2084
|
+
&t->finish_keepalive_ping_locked);
|
2085
|
+
} else {
|
2086
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
|
2087
|
+
grpc_timer_init(
|
2088
|
+
exec_ctx, &t->keepalive_ping_timer,
|
2089
|
+
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
|
2090
|
+
&t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
|
2091
|
+
}
|
2092
|
+
}
|
2093
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "init keepalive ping");
|
2094
|
+
}
|
2095
|
+
|
2096
|
+
static void start_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
2097
|
+
grpc_error *error) {
|
2098
|
+
grpc_chttp2_transport *t = arg;
|
2099
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog");
|
2100
|
+
grpc_timer_init(
|
2101
|
+
exec_ctx, &t->keepalive_watchdog_timer,
|
2102
|
+
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_timeout),
|
2103
|
+
&t->keepalive_watchdog_fired_locked, gpr_now(GPR_CLOCK_MONOTONIC));
|
2104
|
+
}
|
2105
|
+
|
2106
|
+
static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
2107
|
+
grpc_error *error) {
|
2108
|
+
grpc_chttp2_transport *t = arg;
|
2109
|
+
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) {
|
2110
|
+
if (error == GRPC_ERROR_NONE) {
|
2111
|
+
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING;
|
2112
|
+
grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
|
2113
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
|
2114
|
+
grpc_timer_init(
|
2115
|
+
exec_ctx, &t->keepalive_ping_timer,
|
2116
|
+
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
|
2117
|
+
grpc_closure_create(init_keepalive_ping_locked, t,
|
2118
|
+
grpc_combiner_scheduler(t->combiner, false)),
|
2119
|
+
gpr_now(GPR_CLOCK_MONOTONIC));
|
2120
|
+
}
|
2121
|
+
}
|
2122
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping end");
|
2123
|
+
}
|
2124
|
+
|
2125
|
+
static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
2126
|
+
grpc_error *error) {
|
2127
|
+
grpc_chttp2_transport *t = arg;
|
2128
|
+
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) {
|
2129
|
+
if (error == GRPC_ERROR_NONE) {
|
2130
|
+
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
|
2131
|
+
close_transport_locked(exec_ctx, t,
|
2132
|
+
GRPC_ERROR_CREATE("keepalive watchdog timeout"));
|
2133
|
+
}
|
2134
|
+
} else {
|
2135
|
+
/** The watchdog timer should have been cancelled by
|
2136
|
+
finish_keepalive_ping_locked. */
|
2137
|
+
if (error != GRPC_ERROR_CANCELLED) {
|
2138
|
+
gpr_log(GPR_ERROR, "keepalive_ping_end state error: %d (expect: %d)",
|
2139
|
+
t->keepalive_state, GRPC_CHTTP2_KEEPALIVE_STATE_PINGING);
|
2140
|
+
}
|
2141
|
+
}
|
2142
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive watchdog");
|
2143
|
+
}
|
2144
|
+
|
1925
2145
|
/*******************************************************************************
|
1926
2146
|
* CALLBACK LOOP
|
1927
2147
|
*/
|
@@ -1972,10 +2192,12 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
|
|
1972
2192
|
size_t max_size_hint,
|
1973
2193
|
size_t have_already) {
|
1974
2194
|
uint32_t max_recv_bytes;
|
2195
|
+
uint32_t initial_window_size =
|
2196
|
+
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
1975
2197
|
|
1976
2198
|
/* clamp max recv hint to an allowable size */
|
1977
|
-
if (max_size_hint >= UINT32_MAX -
|
1978
|
-
max_recv_bytes = UINT32_MAX -
|
2199
|
+
if (max_size_hint >= UINT32_MAX - initial_window_size) {
|
2200
|
+
max_recv_bytes = UINT32_MAX - initial_window_size;
|
1979
2201
|
} else {
|
1980
2202
|
max_recv_bytes = (uint32_t)max_size_hint;
|
1981
2203
|
}
|
@@ -1988,20 +2210,26 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
|
|
1988
2210
|
}
|
1989
2211
|
|
1990
2212
|
/* add some small lookahead to keep pipelines flowing */
|
1991
|
-
GPR_ASSERT(max_recv_bytes <= UINT32_MAX -
|
1992
|
-
max_recv_bytes
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2213
|
+
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - initial_window_size);
|
2214
|
+
if (s->incoming_window_delta < max_recv_bytes && !s->read_closed) {
|
2215
|
+
uint32_t add_max_recv_bytes =
|
2216
|
+
(uint32_t)(max_recv_bytes - s->incoming_window_delta);
|
2217
|
+
grpc_chttp2_stream_write_type write_type =
|
2218
|
+
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED;
|
2219
|
+
if (s->incoming_window_delta + initial_window_size <
|
2220
|
+
(int64_t)have_already) {
|
2221
|
+
write_type = GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED;
|
2222
|
+
}
|
2223
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM_INCOMING_WINDOW_DELTA("op", t, s,
|
2224
|
+
add_max_recv_bytes);
|
2001
2225
|
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window,
|
2002
2226
|
add_max_recv_bytes);
|
2003
|
-
|
2004
|
-
|
2227
|
+
if ((int64_t)s->incoming_window_delta + (int64_t)initial_window_size -
|
2228
|
+
(int64_t)s->announce_window >
|
2229
|
+
(int64_t)initial_window_size / 2) {
|
2230
|
+
write_type = GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK;
|
2231
|
+
}
|
2232
|
+
grpc_chttp2_become_writable(exec_ctx, t, s, write_type,
|
2005
2233
|
"read_incoming_stream");
|
2006
2234
|
}
|
2007
2235
|
}
|
@@ -2089,6 +2317,8 @@ static void incoming_byte_stream_publish_error(
|
|
2089
2317
|
grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error));
|
2090
2318
|
bs->on_next = NULL;
|
2091
2319
|
GRPC_ERROR_UNREF(bs->error);
|
2320
|
+
grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream,
|
2321
|
+
GRPC_ERROR_REF(error));
|
2092
2322
|
bs->error = error;
|
2093
2323
|
}
|
2094
2324
|
|
@@ -2197,8 +2427,10 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
2197
2427
|
gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
|
2198
2428
|
t->peer_string);
|
2199
2429
|
}
|
2200
|
-
send_goaway(exec_ctx, t,
|
2201
|
-
|
2430
|
+
send_goaway(exec_ctx, t,
|
2431
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
|
2432
|
+
GRPC_ERROR_INT_HTTP2_ERROR,
|
2433
|
+
GRPC_HTTP2_ENHANCE_YOUR_CALM));
|
2202
2434
|
} else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
|
2203
2435
|
gpr_log(GPR_DEBUG,
|
2204
2436
|
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
|
@@ -2227,7 +2459,7 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
2227
2459
|
grpc_chttp2_cancel_stream(
|
2228
2460
|
exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
|
2229
2461
|
GRPC_ERROR_INT_HTTP2_ERROR,
|
2230
|
-
|
2462
|
+
GRPC_HTTP2_ENHANCE_YOUR_CALM));
|
2231
2463
|
if (n > 1) {
|
2232
2464
|
/* Since we cancel one stream per destructive reclamation, if
|
2233
2465
|
there are more streams left, we can immediately post a new
|
@@ -2351,7 +2583,7 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
|
|
2351
2583
|
grpc_transport *grpc_create_chttp2_transport(
|
2352
2584
|
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
|
2353
2585
|
grpc_endpoint *ep, int is_client) {
|
2354
|
-
grpc_chttp2_transport *t =
|
2586
|
+
grpc_chttp2_transport *t = gpr_zalloc(sizeof(grpc_chttp2_transport));
|
2355
2587
|
init_transport(exec_ctx, t, channel_args, ep, is_client != 0);
|
2356
2588
|
return &t->base;
|
2357
2589
|
}
|