grpc 1.36.0 → 1.37.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 +65 -37
- data/include/grpc/grpc.h +15 -1
- data/include/grpc/impl/codegen/port_platform.h +2 -0
- data/src/core/ext/filters/client_channel/client_channel.cc +327 -305
- data/src/core/ext/filters/client_channel/client_channel_factory.h +2 -1
- data/src/core/ext/filters/client_channel/config_selector.h +8 -0
- data/src/core/ext/filters/client_channel/dynamic_filters.cc +9 -4
- data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +24 -142
- data/src/core/ext/filters/client_channel/global_subchannel_pool.h +15 -10
- data/src/core/ext/filters/client_channel/lb_policy.cc +3 -0
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +23 -0
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +27 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +7 -22
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +2 -2
- data/src/core/ext/filters/client_channel/local_subchannel_pool.cc +27 -67
- data/src/core/ext/filters/client_channel/local_subchannel_pool.h +10 -9
- data/src/core/ext/filters/client_channel/resolver.cc +3 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +3 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +5 -9
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +18 -3
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +295 -91
- data/src/core/ext/filters/client_channel/server_address.cc +3 -0
- data/src/core/ext/filters/client_channel/subchannel.cc +69 -146
- data/src/core/ext/filters/client_channel/subchannel.h +63 -95
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.cc +16 -2
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +10 -8
- data/src/core/ext/filters/client_idle/client_idle_filter.cc +1 -1
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +495 -0
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +39 -0
- data/src/core/ext/filters/fault_injection/service_config_parser.cc +189 -0
- data/src/core/ext/filters/fault_injection/service_config_parser.h +85 -0
- data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +1 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +1 -1
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +3 -2
- data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +3 -2
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +457 -170
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +39 -7
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +12 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +5 -1
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/internal.h +1 -0
- data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c +406 -0
- data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.h +1459 -0
- data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +350 -0
- data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +1348 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +6 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +25 -0
- data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c +144 -0
- data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.h +488 -0
- data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c +141 -0
- data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.h +452 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +15 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +44 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c +79 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.h +268 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c +78 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h +281 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +41 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +113 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +6 -5
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +13 -9
- data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c +93 -0
- data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h +323 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c +36 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.h +90 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c +46 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.h +124 -0
- data/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c +33 -0
- data/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h +77 -0
- data/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c +354 -0
- data/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.h +140 -0
- data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +383 -0
- data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.h +115 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c +10 -7
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.c +141 -0
- data/src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.h +70 -0
- data/src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.c +141 -0
- data/src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.h +70 -0
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c +13 -7
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c +102 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.h +55 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c +120 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.h +45 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c +76 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h +35 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +21 -20
- data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c +130 -0
- data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.h +50 -0
- data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.c +56 -0
- data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.h +35 -0
- data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c +63 -0
- data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.h +40 -0
- data/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c +44 -0
- data/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h +35 -0
- data/src/core/ext/xds/xds_api.cc +1591 -279
- data/src/core/ext/xds/xds_api.h +279 -39
- data/src/core/ext/xds/xds_bootstrap.cc +21 -5
- data/src/core/ext/xds/xds_bootstrap.h +5 -1
- data/src/core/ext/xds/xds_client.cc +168 -23
- data/src/core/ext/xds/xds_client.h +26 -0
- data/src/core/ext/xds/xds_client_stats.h +2 -2
- data/src/core/ext/xds/xds_http_fault_filter.cc +226 -0
- data/src/core/ext/xds/xds_http_fault_filter.h +63 -0
- data/src/core/ext/xds/xds_http_filters.cc +114 -0
- data/src/core/ext/xds/xds_http_filters.h +130 -0
- data/src/core/ext/xds/xds_server_config_fetcher.cc +391 -126
- data/src/core/lib/channel/channel_stack.cc +12 -0
- data/src/core/lib/channel/channel_stack.h +7 -0
- data/src/core/lib/channel/channelz.cc +92 -4
- data/src/core/lib/channel/channelz.h +30 -1
- data/src/core/lib/channel/channelz_registry.cc +14 -0
- data/src/core/lib/channel/handshaker.cc +0 -39
- data/src/core/lib/channel/handshaker.h +0 -17
- data/src/core/lib/channel/status_util.cc +12 -2
- data/src/core/lib/channel/status_util.h +5 -0
- data/src/core/lib/gpr/sync_abseil.cc +3 -6
- data/src/core/lib/gpr/sync_windows.cc +2 -2
- data/src/core/lib/gprpp/atomic.h +3 -3
- data/src/core/lib/gprpp/dual_ref_counted.h +3 -3
- data/src/core/lib/gprpp/ref_counted_ptr.h +2 -0
- data/src/core/lib/gprpp/thd.h +1 -1
- data/src/core/lib/iomgr/buffer_list.h +1 -1
- data/src/core/lib/iomgr/cfstream_handle.cc +2 -2
- data/src/core/lib/iomgr/error.h +1 -1
- data/src/core/lib/iomgr/ev_apple.cc +1 -1
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +3 -3
- data/src/core/lib/iomgr/ev_posix.cc +3 -3
- data/src/core/lib/iomgr/exec_ctx.cc +6 -2
- data/src/core/lib/iomgr/resource_quota.cc +1 -1
- data/src/core/lib/iomgr/sockaddr_utils.cc +120 -0
- data/src/core/lib/iomgr/sockaddr_utils.h +25 -0
- data/src/core/lib/iomgr/tcp_posix.cc +1 -4
- data/src/core/lib/iomgr/tcp_uv.cc +2 -2
- data/src/core/lib/iomgr/timer_generic.cc +2 -2
- data/src/core/lib/iomgr/timer_manager.cc +1 -1
- data/src/core/lib/iomgr/wakeup_fd_nospecial.cc +1 -1
- data/src/core/lib/{security/authorization → matchers}/matchers.cc +8 -8
- data/src/core/lib/{security/authorization → matchers}/matchers.h +14 -12
- data/src/core/lib/security/security_connector/ssl_utils.cc +6 -4
- data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +6 -0
- data/src/core/lib/security/transport/security_handshaker.cc +32 -2
- data/src/core/lib/slice/slice_intern.cc +6 -7
- data/src/core/lib/surface/channel.h +3 -3
- data/src/core/lib/surface/completion_queue.cc +1 -1
- data/src/core/lib/surface/lame_client.cc +38 -19
- data/src/core/lib/surface/lame_client.h +4 -3
- data/src/core/lib/surface/server.cc +40 -33
- data/src/core/lib/surface/server.h +74 -15
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/metadata_batch.cc +27 -0
- data/src/core/lib/transport/metadata_batch.h +14 -0
- data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -4
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +1 -1
- data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -3
- data/src/core/tsi/fake_transport_security.cc +10 -1
- data/src/ruby/ext/grpc/extconf.rb +9 -1
- data/src/ruby/ext/grpc/rb_channel.c +10 -1
- data/src/ruby/ext/grpc/rb_channel_credentials.c +11 -1
- data/src/ruby/ext/grpc/rb_channel_credentials.h +4 -0
- data/src/ruby/ext/grpc/rb_compression_options.c +1 -1
- data/src/ruby/ext/grpc/rb_enable_cpp.cc +1 -1
- data/src/ruby/ext/grpc/rb_grpc.c +4 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -1
- data/src/ruby/ext/grpc/rb_server.c +13 -1
- data/src/ruby/ext/grpc/rb_server_credentials.c +19 -3
- data/src/ruby/ext/grpc/rb_server_credentials.h +4 -0
- data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +215 -0
- data/src/ruby/ext/grpc/rb_xds_channel_credentials.h +35 -0
- data/src/ruby/ext/grpc/rb_xds_server_credentials.c +169 -0
- data/src/ruby/ext/grpc/rb_xds_server_credentials.h +35 -0
- data/src/ruby/lib/grpc/generic/client_stub.rb +4 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/call_spec.rb +1 -1
- data/src/ruby/spec/channel_credentials_spec.rb +32 -0
- data/src/ruby/spec/channel_spec.rb +17 -6
- data/src/ruby/spec/client_auth_spec.rb +27 -1
- data/src/ruby/spec/errors_spec.rb +1 -1
- data/src/ruby/spec/generic/active_call_spec.rb +2 -2
- data/src/ruby/spec/generic/client_stub_spec.rb +4 -4
- data/src/ruby/spec/generic/rpc_server_spec.rb +1 -1
- data/src/ruby/spec/server_credentials_spec.rb +25 -0
- data/src/ruby/spec/server_spec.rb +22 -0
- data/third_party/boringssl-with-bazel/err_data.c +255 -255
- data/third_party/boringssl-with-bazel/src/crypto/cpu-arm-linux.c +11 -2
- data/third_party/boringssl-with-bazel/src/crypto/cpu-arm.c +3 -3
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c +21 -13
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.c +7 -5
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +0 -28
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_attrib.c +22 -17
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c +3 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +4 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/cpu.h +22 -32
- data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +25 -9
- data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +0 -1
- data/third_party/boringssl-with-bazel/src/ssl/t1_lib.cc +33 -19
- data/third_party/xxhash/xxhash.h +5443 -0
- metadata +93 -49
- data/src/core/lib/security/authorization/authorization_engine.cc +0 -177
- data/src/core/lib/security/authorization/authorization_engine.h +0 -84
- data/src/core/lib/security/authorization/evaluate_args.cc +0 -148
- data/src/core/lib/security/authorization/evaluate_args.h +0 -59
- data/src/core/lib/security/authorization/mock_cel/activation.h +0 -57
- data/src/core/lib/security/authorization/mock_cel/cel_expr_builder_factory.h +0 -44
- data/src/core/lib/security/authorization/mock_cel/cel_expression.h +0 -69
- data/src/core/lib/security/authorization/mock_cel/cel_value.h +0 -99
- data/src/core/lib/security/authorization/mock_cel/evaluator_core.h +0 -67
- data/src/core/lib/security/authorization/mock_cel/flat_expr_builder.h +0 -57
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +0 -504
- data/third_party/upb/upb/json_decode.c +0 -1443
- data/third_party/upb/upb/json_decode.h +0 -23
- data/third_party/upb/upb/json_encode.c +0 -713
- data/third_party/upb/upb/json_encode.h +0 -36
@@ -0,0 +1,39 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2021 gRPC authors.
|
3
|
+
//
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
// you may not use this file except in compliance with the License.
|
6
|
+
// You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
// See the License for the specific language governing permissions and
|
14
|
+
// limitations under the License.
|
15
|
+
//
|
16
|
+
|
17
|
+
#ifndef GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_FAULT_INJECTION_FILTER_H
|
18
|
+
#define GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_FAULT_INJECTION_FILTER_H
|
19
|
+
|
20
|
+
#include <grpc/support/port_platform.h>
|
21
|
+
|
22
|
+
#include "src/core/ext/filters/fault_injection/service_config_parser.h"
|
23
|
+
#include "src/core/lib/channel/channel_stack.h"
|
24
|
+
|
25
|
+
// Channel arg key for enabling parsing fault injection via method config.
|
26
|
+
#define GRPC_ARG_PARSE_FAULT_INJECTION_METHOD_CONFIG \
|
27
|
+
"grpc.parse_fault_injection_method_config"
|
28
|
+
|
29
|
+
namespace grpc_core {
|
30
|
+
|
31
|
+
// This channel filter is intended to be used by the dynamic filters, instead
|
32
|
+
// of the ordinary channel stack. The fault injection filter fetches fault
|
33
|
+
// injection policy from the method config of service config returned by the
|
34
|
+
// resolver, and enforces the fault injection policy.
|
35
|
+
extern const grpc_channel_filter FaultInjectionFilterVtable;
|
36
|
+
|
37
|
+
} // namespace grpc_core
|
38
|
+
|
39
|
+
#endif // GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_FAULT_INJECTION_FILTER_H
|
@@ -0,0 +1,189 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2021 gRPC authors.
|
3
|
+
//
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
// you may not use this file except in compliance with the License.
|
6
|
+
// You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
// See the License for the specific language governing permissions and
|
14
|
+
// limitations under the License.
|
15
|
+
//
|
16
|
+
|
17
|
+
#include <grpc/support/port_platform.h>
|
18
|
+
|
19
|
+
#include "src/core/ext/filters/fault_injection/service_config_parser.h"
|
20
|
+
|
21
|
+
#include <vector>
|
22
|
+
|
23
|
+
#include "absl/strings/str_cat.h"
|
24
|
+
#include "absl/strings/string_view.h"
|
25
|
+
#include "src/core/ext/filters/client_channel/service_config.h"
|
26
|
+
#include "src/core/ext/filters/fault_injection/fault_injection_filter.h"
|
27
|
+
#include "src/core/lib/channel/channel_args.h"
|
28
|
+
#include "src/core/lib/channel/status_util.h"
|
29
|
+
#include "src/core/lib/gpr/string.h"
|
30
|
+
#include "src/core/lib/json/json_util.h"
|
31
|
+
|
32
|
+
namespace grpc_core {
|
33
|
+
|
34
|
+
namespace {
|
35
|
+
|
36
|
+
size_t g_fault_injection_parser_index;
|
37
|
+
|
38
|
+
std::vector<FaultInjectionMethodParsedConfig::FaultInjectionPolicy>
|
39
|
+
ParseFaultInjectionPolicy(const Json::Array& policies_json_array,
|
40
|
+
std::vector<grpc_error*>* error_list) {
|
41
|
+
std::vector<FaultInjectionMethodParsedConfig::FaultInjectionPolicy> policies;
|
42
|
+
for (size_t i = 0; i < policies_json_array.size(); i++) {
|
43
|
+
FaultInjectionMethodParsedConfig::FaultInjectionPolicy
|
44
|
+
fault_injection_policy;
|
45
|
+
std::vector<grpc_error*> sub_error_list;
|
46
|
+
if (policies_json_array[i].type() != Json::Type::OBJECT) {
|
47
|
+
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
48
|
+
absl::StrCat("faultInjectionPolicy index ", i,
|
49
|
+
" is not a JSON object")
|
50
|
+
.c_str()));
|
51
|
+
continue;
|
52
|
+
}
|
53
|
+
const Json::Object& json_object = policies_json_array[i].object_value();
|
54
|
+
// Parse abort_code
|
55
|
+
std::string abort_code_string;
|
56
|
+
if (ParseJsonObjectField(json_object, "abortCode", &abort_code_string,
|
57
|
+
&sub_error_list, false)) {
|
58
|
+
if (!grpc_status_code_from_string(abort_code_string.c_str(),
|
59
|
+
&(fault_injection_policy.abort_code))) {
|
60
|
+
sub_error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
61
|
+
"field:abortCode error:failed to parse status code"));
|
62
|
+
}
|
63
|
+
}
|
64
|
+
// Parse abort_message
|
65
|
+
if (!ParseJsonObjectField(json_object, "abortMessage",
|
66
|
+
&fault_injection_policy.abort_message,
|
67
|
+
&sub_error_list, false)) {
|
68
|
+
fault_injection_policy.abort_message = "Fault injected";
|
69
|
+
}
|
70
|
+
// Parse abort_code_header
|
71
|
+
ParseJsonObjectField(json_object, "abortCodeHeader",
|
72
|
+
&fault_injection_policy.abort_code_header,
|
73
|
+
&sub_error_list, false);
|
74
|
+
// Parse abort_percentage_header
|
75
|
+
ParseJsonObjectField(json_object, "abortPercentageHeader",
|
76
|
+
&fault_injection_policy.abort_percentage_header,
|
77
|
+
&sub_error_list, false);
|
78
|
+
// Parse abort_percentage_numerator
|
79
|
+
ParseJsonObjectField(json_object, "abortPercentageNumerator",
|
80
|
+
&fault_injection_policy.abort_percentage_numerator,
|
81
|
+
&sub_error_list, false);
|
82
|
+
// Parse abort_percentage_denominator
|
83
|
+
if (ParseJsonObjectField(
|
84
|
+
json_object, "abortPercentageDenominator",
|
85
|
+
&fault_injection_policy.abort_percentage_denominator,
|
86
|
+
&sub_error_list, false)) {
|
87
|
+
if (fault_injection_policy.abort_percentage_denominator != 100 &&
|
88
|
+
fault_injection_policy.abort_percentage_denominator != 10000 &&
|
89
|
+
fault_injection_policy.abort_percentage_denominator != 1000000) {
|
90
|
+
sub_error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
91
|
+
"field:abortPercentageDenominator error:Denominator can only be "
|
92
|
+
"one of "
|
93
|
+
"100, 10000, 1000000"));
|
94
|
+
}
|
95
|
+
}
|
96
|
+
// Parse delay
|
97
|
+
ParseJsonObjectFieldAsDuration(json_object, "delay",
|
98
|
+
&fault_injection_policy.delay,
|
99
|
+
&sub_error_list, false);
|
100
|
+
// Parse delay_header
|
101
|
+
ParseJsonObjectField(json_object, "delayHeader",
|
102
|
+
&fault_injection_policy.delay_header, &sub_error_list,
|
103
|
+
false);
|
104
|
+
// Parse delay_percentage_header
|
105
|
+
ParseJsonObjectField(json_object, "delayPercentageHeader",
|
106
|
+
&fault_injection_policy.delay_percentage_header,
|
107
|
+
&sub_error_list, false);
|
108
|
+
// Parse delay_percentage_numerator
|
109
|
+
ParseJsonObjectField(json_object, "delayPercentageNumerator",
|
110
|
+
&fault_injection_policy.delay_percentage_numerator,
|
111
|
+
&sub_error_list, false);
|
112
|
+
// Parse delay_percentage_denominator
|
113
|
+
if (ParseJsonObjectField(
|
114
|
+
json_object, "delayPercentageDenominator",
|
115
|
+
&fault_injection_policy.delay_percentage_denominator,
|
116
|
+
&sub_error_list, false)) {
|
117
|
+
if (fault_injection_policy.delay_percentage_denominator != 100 &&
|
118
|
+
fault_injection_policy.delay_percentage_denominator != 10000 &&
|
119
|
+
fault_injection_policy.delay_percentage_denominator != 1000000) {
|
120
|
+
sub_error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
121
|
+
"field:delayPercentageDenominator error:Denominator can only be "
|
122
|
+
"one of "
|
123
|
+
"100, 10000, 1000000"));
|
124
|
+
}
|
125
|
+
}
|
126
|
+
// Parse max_faults
|
127
|
+
if (ParseJsonObjectField(json_object, "maxFaults",
|
128
|
+
&fault_injection_policy.max_faults,
|
129
|
+
&sub_error_list, false)) {
|
130
|
+
if (fault_injection_policy.max_faults < 0) {
|
131
|
+
sub_error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
132
|
+
"field:maxFaults error:should be zero or positive"));
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if (!sub_error_list.empty()) {
|
136
|
+
// Can't use GRPC_ERROR_CREATE_FROM_VECTOR() here, because the error
|
137
|
+
// string is not static in this case.
|
138
|
+
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
139
|
+
absl::StrCat("failed to parse faultInjectionPolicy index ", i)
|
140
|
+
.c_str());
|
141
|
+
for (size_t i = 0; i < sub_error_list.size(); ++i) {
|
142
|
+
error = grpc_error_add_child(error, sub_error_list[i]);
|
143
|
+
}
|
144
|
+
error_list->push_back(error);
|
145
|
+
}
|
146
|
+
policies.push_back(std::move(fault_injection_policy));
|
147
|
+
}
|
148
|
+
return policies;
|
149
|
+
}
|
150
|
+
|
151
|
+
} // namespace
|
152
|
+
|
153
|
+
std::unique_ptr<ServiceConfigParser::ParsedConfig>
|
154
|
+
FaultInjectionServiceConfigParser::ParsePerMethodParams(
|
155
|
+
const grpc_channel_args* args, const Json& json, grpc_error** error) {
|
156
|
+
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
|
157
|
+
// Only parse fault injection policy if the following channel arg is present.
|
158
|
+
if (!grpc_channel_args_find_bool(
|
159
|
+
args, GRPC_ARG_PARSE_FAULT_INJECTION_METHOD_CONFIG, false)) {
|
160
|
+
return nullptr;
|
161
|
+
}
|
162
|
+
// Parse fault injection policy from given Json
|
163
|
+
std::vector<FaultInjectionMethodParsedConfig::FaultInjectionPolicy>
|
164
|
+
fault_injection_policies;
|
165
|
+
std::vector<grpc_error*> error_list;
|
166
|
+
const Json::Array* policies_json_array;
|
167
|
+
if (ParseJsonObjectField(json.object_value(), "faultInjectionPolicy",
|
168
|
+
&policies_json_array, &error_list)) {
|
169
|
+
fault_injection_policies =
|
170
|
+
ParseFaultInjectionPolicy(*policies_json_array, &error_list);
|
171
|
+
}
|
172
|
+
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Fault injection parser", &error_list);
|
173
|
+
if (*error != GRPC_ERROR_NONE || fault_injection_policies.empty()) {
|
174
|
+
return nullptr;
|
175
|
+
}
|
176
|
+
return absl::make_unique<FaultInjectionMethodParsedConfig>(
|
177
|
+
std::move(fault_injection_policies));
|
178
|
+
}
|
179
|
+
|
180
|
+
void FaultInjectionServiceConfigParser::Register() {
|
181
|
+
g_fault_injection_parser_index = ServiceConfigParser::RegisterParser(
|
182
|
+
absl::make_unique<FaultInjectionServiceConfigParser>());
|
183
|
+
}
|
184
|
+
|
185
|
+
size_t FaultInjectionServiceConfigParser::ParserIndex() {
|
186
|
+
return g_fault_injection_parser_index;
|
187
|
+
}
|
188
|
+
|
189
|
+
} // namespace grpc_core
|
@@ -0,0 +1,85 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2021 gRPC authors.
|
3
|
+
//
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
// you may not use this file except in compliance with the License.
|
6
|
+
// You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
// See the License for the specific language governing permissions and
|
14
|
+
// limitations under the License.
|
15
|
+
//
|
16
|
+
|
17
|
+
#ifndef GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_SERVICE_CONFIG_PARSER_H
|
18
|
+
#define GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_SERVICE_CONFIG_PARSER_H
|
19
|
+
|
20
|
+
#include <grpc/support/port_platform.h>
|
21
|
+
|
22
|
+
#include <vector>
|
23
|
+
|
24
|
+
#include "src/core/ext/filters/client_channel/service_config.h"
|
25
|
+
#include "src/core/lib/iomgr/exec_ctx.h"
|
26
|
+
|
27
|
+
namespace grpc_core {
|
28
|
+
|
29
|
+
class FaultInjectionMethodParsedConfig
|
30
|
+
: public ServiceConfigParser::ParsedConfig {
|
31
|
+
public:
|
32
|
+
struct FaultInjectionPolicy {
|
33
|
+
grpc_status_code abort_code = GRPC_STATUS_OK;
|
34
|
+
std::string abort_message;
|
35
|
+
std::string abort_code_header;
|
36
|
+
std::string abort_percentage_header;
|
37
|
+
uint32_t abort_percentage_numerator = 0;
|
38
|
+
uint32_t abort_percentage_denominator = 100;
|
39
|
+
|
40
|
+
grpc_millis delay = 0;
|
41
|
+
std::string delay_header;
|
42
|
+
std::string delay_percentage_header;
|
43
|
+
uint32_t delay_percentage_numerator = 0;
|
44
|
+
uint32_t delay_percentage_denominator = 100;
|
45
|
+
|
46
|
+
// By default, the max allowed active faults are unlimited.
|
47
|
+
uint32_t max_faults = std::numeric_limits<uint32_t>::max();
|
48
|
+
};
|
49
|
+
|
50
|
+
explicit FaultInjectionMethodParsedConfig(
|
51
|
+
std::vector<FaultInjectionPolicy> fault_injection_policies)
|
52
|
+
: fault_injection_policies_(std::move(fault_injection_policies)) {}
|
53
|
+
|
54
|
+
// Returns the fault injection policy at certain index.
|
55
|
+
// There might be multiple fault injection policies functioning at the same
|
56
|
+
// time. The order between the policies are stable, and an index is used to
|
57
|
+
// keep track of their relative positions. The FaultInjectionFilter uses this
|
58
|
+
// method to access the parsed fault injection policy in service config,
|
59
|
+
// whether it came from xDS resolver or directly from service config
|
60
|
+
const FaultInjectionPolicy* fault_injection_policy(int index) const {
|
61
|
+
if (static_cast<size_t>(index) >= fault_injection_policies_.size()) {
|
62
|
+
return nullptr;
|
63
|
+
}
|
64
|
+
return &fault_injection_policies_[index];
|
65
|
+
}
|
66
|
+
|
67
|
+
private:
|
68
|
+
std::vector<FaultInjectionPolicy> fault_injection_policies_;
|
69
|
+
};
|
70
|
+
|
71
|
+
class FaultInjectionServiceConfigParser : public ServiceConfigParser::Parser {
|
72
|
+
public:
|
73
|
+
// Parses the per-method service config for fault injection filter.
|
74
|
+
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
|
75
|
+
const grpc_channel_args* args, const Json& json,
|
76
|
+
grpc_error** error) override;
|
77
|
+
// Returns the parser index for FaultInjectionServiceConfigParser.
|
78
|
+
static size_t ParserIndex();
|
79
|
+
// Registers FaultInjectionServiceConfigParser to ServiceConfigParser.
|
80
|
+
static void Register();
|
81
|
+
};
|
82
|
+
|
83
|
+
} // namespace grpc_core
|
84
|
+
|
85
|
+
#endif // GRPC_CORE_EXT_FILTERS_FAULT_INJECTION_SERVICE_CONFIG_PARSER_H
|
@@ -192,7 +192,7 @@ static bool register_workaround_cronet_compression(
|
|
192
192
|
if (a == nullptr) {
|
193
193
|
return true;
|
194
194
|
}
|
195
|
-
if (grpc_channel_arg_get_bool(a, false)
|
195
|
+
if (!grpc_channel_arg_get_bool(a, false)) {
|
196
196
|
return true;
|
197
197
|
}
|
198
198
|
return grpc_channel_stack_builder_prepend_filter(
|
@@ -178,7 +178,7 @@ void Chttp2Connector::OnHandshakeDone(void* arg, grpc_error* error) {
|
|
178
178
|
self->Ref().release(); // Ref held by OnTimeout()
|
179
179
|
grpc_chttp2_transport_start_reading(self->result_->transport,
|
180
180
|
args->read_buffer,
|
181
|
-
&self->on_receive_settings_);
|
181
|
+
&self->on_receive_settings_, nullptr);
|
182
182
|
GRPC_CLOSURE_INIT(&self->on_timeout_, OnTimeout, self,
|
183
183
|
grpc_schedule_on_exec_ctx);
|
184
184
|
grpc_timer_init(&self->timer_, self->args_.deadline, &self->on_timeout_);
|
@@ -37,10 +37,11 @@ namespace grpc_core {
|
|
37
37
|
|
38
38
|
class Chttp2InsecureClientChannelFactory : public ClientChannelFactory {
|
39
39
|
public:
|
40
|
-
Subchannel
|
40
|
+
RefCountedPtr<Subchannel> CreateSubchannel(
|
41
|
+
const grpc_channel_args* args) override {
|
41
42
|
grpc_channel_args* new_args =
|
42
43
|
grpc_default_authority_add_if_not_present(args);
|
43
|
-
Subchannel
|
44
|
+
RefCountedPtr<Subchannel> s =
|
44
45
|
Subchannel::Create(MakeOrphanable<Chttp2Connector>(), new_args);
|
45
46
|
grpc_channel_args_destroy(new_args);
|
46
47
|
return s;
|
@@ -62,7 +62,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
|
|
62
62
|
transport, nullptr, &error);
|
63
63
|
grpc_channel_args_destroy(final_args);
|
64
64
|
if (channel != nullptr) {
|
65
|
-
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
|
65
|
+
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
|
66
66
|
grpc_core::ExecCtx::Get()->Flush();
|
67
67
|
} else {
|
68
68
|
intptr_t integer;
|
@@ -43,14 +43,15 @@ namespace grpc_core {
|
|
43
43
|
|
44
44
|
class Chttp2SecureClientChannelFactory : public ClientChannelFactory {
|
45
45
|
public:
|
46
|
-
Subchannel
|
46
|
+
RefCountedPtr<Subchannel> CreateSubchannel(
|
47
|
+
const grpc_channel_args* args) override {
|
47
48
|
grpc_channel_args* new_args = GetSecureNamingChannelArgs(args);
|
48
49
|
if (new_args == nullptr) {
|
49
50
|
gpr_log(GPR_ERROR,
|
50
51
|
"Failed to create channel args during subchannel creation.");
|
51
52
|
return nullptr;
|
52
53
|
}
|
53
|
-
Subchannel
|
54
|
+
RefCountedPtr<Subchannel> s =
|
54
55
|
Subchannel::Create(MakeOrphanable<Chttp2Connector>(), new_args);
|
55
56
|
grpc_channel_args_destroy(new_args);
|
56
57
|
return s;
|
@@ -90,98 +90,209 @@ class Chttp2ServerListener : public Server::ListenerInterface {
|
|
90
90
|
class ConfigFetcherWatcher
|
91
91
|
: public grpc_server_config_fetcher::WatcherInterface {
|
92
92
|
public:
|
93
|
-
explicit ConfigFetcherWatcher(Chttp2ServerListener
|
94
|
-
: listener_(listener) {}
|
95
|
-
|
96
|
-
void
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
args = listener_->args_modifier_(args, &error);
|
102
|
-
if (error != GRPC_ERROR_NONE) {
|
103
|
-
// TODO(yashykt): Set state to close down connections immediately
|
104
|
-
// after accepting.
|
105
|
-
GPR_ASSERT(0);
|
106
|
-
}
|
107
|
-
listener_->args_ = args;
|
108
|
-
if (!listener_->shutdown_) return; // Already started listening.
|
109
|
-
}
|
110
|
-
int port_temp;
|
111
|
-
grpc_error* error = grpc_tcp_server_add_port(
|
112
|
-
listener_->tcp_server_, &listener_->resolved_address_, &port_temp);
|
113
|
-
if (error != GRPC_ERROR_NONE) {
|
114
|
-
GRPC_ERROR_UNREF(error);
|
115
|
-
gpr_log(GPR_ERROR, "Error adding port to server: %s",
|
116
|
-
grpc_error_string(error));
|
117
|
-
// TODO(yashykt): We wouldn't need to assert here if we bound to the
|
118
|
-
// port earlier during AddPort.
|
119
|
-
GPR_ASSERT(0);
|
120
|
-
}
|
121
|
-
listener_->StartListening();
|
122
|
-
}
|
93
|
+
explicit ConfigFetcherWatcher(RefCountedPtr<Chttp2ServerListener> listener)
|
94
|
+
: listener_(std::move(listener)) {}
|
95
|
+
|
96
|
+
void UpdateConnectionManager(
|
97
|
+
RefCountedPtr<grpc_server_config_fetcher::ConnectionManager>
|
98
|
+
connection_manager) override;
|
99
|
+
|
100
|
+
void StopServing() override;
|
123
101
|
|
124
102
|
private:
|
125
|
-
Chttp2ServerListener
|
103
|
+
RefCountedPtr<Chttp2ServerListener> listener_;
|
126
104
|
};
|
127
105
|
|
128
|
-
class
|
106
|
+
class ActiveConnection : public InternallyRefCounted<ActiveConnection> {
|
129
107
|
public:
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
108
|
+
class HandshakingState : public InternallyRefCounted<HandshakingState> {
|
109
|
+
public:
|
110
|
+
HandshakingState(RefCountedPtr<ActiveConnection> connection_ref,
|
111
|
+
grpc_pollset* accepting_pollset,
|
112
|
+
grpc_tcp_server_acceptor* acceptor,
|
113
|
+
grpc_channel_args* args);
|
114
|
+
|
115
|
+
~HandshakingState() override;
|
116
|
+
|
117
|
+
void Orphan() override;
|
135
118
|
|
136
|
-
|
119
|
+
void Start(grpc_endpoint* endpoint, grpc_channel_args* args);
|
120
|
+
|
121
|
+
// Needed to be able to grab an external ref in ActiveConnection::Start()
|
122
|
+
using InternallyRefCounted<HandshakingState>::Ref;
|
123
|
+
|
124
|
+
private:
|
125
|
+
static void OnTimeout(void* arg, grpc_error* error);
|
126
|
+
static void OnReceiveSettings(void* arg, grpc_error* /* error */);
|
127
|
+
static void OnHandshakeDone(void* arg, grpc_error* error);
|
128
|
+
RefCountedPtr<ActiveConnection> const connection_;
|
129
|
+
grpc_pollset* const accepting_pollset_;
|
130
|
+
grpc_tcp_server_acceptor* const acceptor_;
|
131
|
+
RefCountedPtr<HandshakeManager> handshake_mgr_
|
132
|
+
ABSL_GUARDED_BY(&connection_->mu_);
|
133
|
+
// State for enforcing handshake timeout on receiving HTTP/2 settings.
|
134
|
+
grpc_millis const deadline_;
|
135
|
+
grpc_timer timer_ ABSL_GUARDED_BY(&connection_->mu_);
|
136
|
+
grpc_closure on_timeout_ ABSL_GUARDED_BY(&connection_->mu_);
|
137
|
+
grpc_closure on_receive_settings_ ABSL_GUARDED_BY(&connection_->mu_);
|
138
|
+
grpc_pollset_set* const interested_parties_;
|
139
|
+
};
|
140
|
+
|
141
|
+
ActiveConnection(grpc_pollset* accepting_pollset,
|
142
|
+
grpc_tcp_server_acceptor* acceptor,
|
143
|
+
grpc_channel_args* args);
|
144
|
+
~ActiveConnection() override;
|
145
|
+
|
146
|
+
void Orphan() override;
|
147
|
+
|
148
|
+
void SendGoAway();
|
149
|
+
|
150
|
+
void Start(RefCountedPtr<Chttp2ServerListener> listener,
|
151
|
+
grpc_endpoint* endpoint, grpc_channel_args* args);
|
152
|
+
|
153
|
+
// Needed to be able to grab an external ref in
|
154
|
+
// Chttp2ServerListener::OnAccept()
|
155
|
+
using InternallyRefCounted<ActiveConnection>::Ref;
|
137
156
|
|
138
157
|
private:
|
139
|
-
static void
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
//
|
148
|
-
grpc_chttp2_transport* transport_ = nullptr;
|
149
|
-
|
150
|
-
|
151
|
-
grpc_closure on_timeout_;
|
152
|
-
grpc_closure on_receive_settings_;
|
153
|
-
grpc_pollset_set* const interested_parties_;
|
158
|
+
static void OnClose(void* arg, grpc_error* error);
|
159
|
+
|
160
|
+
RefCountedPtr<Chttp2ServerListener> listener_;
|
161
|
+
Mutex mu_ ABSL_ACQUIRED_AFTER(&listener_->mu_);
|
162
|
+
// Set by HandshakingState before the handshaking begins and reset when
|
163
|
+
// handshaking is done.
|
164
|
+
OrphanablePtr<HandshakingState> handshaking_state_ ABSL_GUARDED_BY(&mu_);
|
165
|
+
// Set by HandshakingState when handshaking is done and a valid transport is
|
166
|
+
// created.
|
167
|
+
grpc_chttp2_transport* transport_ ABSL_GUARDED_BY(&mu_) = nullptr;
|
168
|
+
grpc_closure on_close_;
|
169
|
+
bool shutdown_ ABSL_GUARDED_BY(&mu_) = false;
|
154
170
|
};
|
155
171
|
|
172
|
+
// To allow access to RefCounted<> like interface.
|
173
|
+
friend class RefCountedPtr<Chttp2ServerListener>;
|
174
|
+
|
175
|
+
// Should only be called once so as to start the TCP server.
|
156
176
|
void StartListening();
|
157
177
|
|
158
178
|
static void OnAccept(void* arg, grpc_endpoint* tcp,
|
159
179
|
grpc_pollset* accepting_pollset,
|
160
180
|
grpc_tcp_server_acceptor* acceptor);
|
161
181
|
|
162
|
-
RefCountedPtr<HandshakeManager> CreateHandshakeManager();
|
163
|
-
|
164
182
|
static void TcpServerShutdownComplete(void* arg, grpc_error* error);
|
165
183
|
|
166
184
|
static void DestroyListener(Server* /*server*/, void* arg,
|
167
185
|
grpc_closure* destroy_done);
|
168
186
|
|
187
|
+
// The interface required by RefCountedPtr<> has been manually implemented
|
188
|
+
// here to take a ref on tcp_server_ instead. Note that, the handshaker needs
|
189
|
+
// tcp_server_ to exist for the lifetime of the handshake since it's needed by
|
190
|
+
// acceptor. Sharing refs between the listener and tcp_server_ is just an
|
191
|
+
// optimization to avoid taking additional refs on the listener, since
|
192
|
+
// TcpServerShutdownComplete already holds a ref to the listener.
|
193
|
+
void IncrementRefCount() { grpc_tcp_server_ref(tcp_server_); }
|
194
|
+
void IncrementRefCount(const DebugLocation& /* location */,
|
195
|
+
const char* /* reason */) {
|
196
|
+
IncrementRefCount();
|
197
|
+
}
|
198
|
+
|
199
|
+
RefCountedPtr<Chttp2ServerListener> Ref() GRPC_MUST_USE_RESULT {
|
200
|
+
IncrementRefCount();
|
201
|
+
return RefCountedPtr<Chttp2ServerListener>(this);
|
202
|
+
}
|
203
|
+
RefCountedPtr<Chttp2ServerListener> Ref(const DebugLocation& /* location */,
|
204
|
+
const char* /* reason */)
|
205
|
+
GRPC_MUST_USE_RESULT {
|
206
|
+
return Ref();
|
207
|
+
}
|
208
|
+
|
209
|
+
void Unref() { grpc_tcp_server_unref(tcp_server_); }
|
210
|
+
void Unref(const DebugLocation& /* location */, const char* /* reason */) {
|
211
|
+
Unref();
|
212
|
+
}
|
213
|
+
|
169
214
|
Server* const server_;
|
170
215
|
grpc_tcp_server* tcp_server_;
|
171
216
|
grpc_resolved_address resolved_address_;
|
172
|
-
Chttp2ServerArgsModifier args_modifier_;
|
173
|
-
Mutex mu_;
|
174
|
-
grpc_channel_args* args_; // guarded by mu_
|
217
|
+
Chttp2ServerArgsModifier const args_modifier_;
|
175
218
|
ConfigFetcherWatcher* config_fetcher_watcher_ = nullptr;
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
219
|
+
Mutex channel_args_mu_;
|
220
|
+
grpc_channel_args* args_ ABSL_GUARDED_BY(channel_args_mu_);
|
221
|
+
RefCountedPtr<grpc_server_config_fetcher::ConnectionManager>
|
222
|
+
connection_manager_ ABSL_GUARDED_BY(channel_args_mu_);
|
223
|
+
Mutex mu_;
|
224
|
+
// Signals whether grpc_tcp_server_start() has been called.
|
225
|
+
bool started_ ABSL_GUARDED_BY(mu_) = false;
|
226
|
+
// Signals whether grpc_tcp_server_start() has completed.
|
227
|
+
CondVar started_cv_ ABSL_GUARDED_BY(mu_);
|
228
|
+
// Signals whether new requests/connections are to be accepted.
|
229
|
+
bool is_serving_ ABSL_GUARDED_BY(mu_) = false;
|
230
|
+
// Signals whether the application has triggered shutdown.
|
231
|
+
bool shutdown_ ABSL_GUARDED_BY(mu_) = false;
|
232
|
+
std::map<ActiveConnection*, OrphanablePtr<ActiveConnection>> connections_
|
233
|
+
ABSL_GUARDED_BY(mu_);
|
234
|
+
grpc_closure tcp_server_shutdown_complete_ ABSL_GUARDED_BY(mu_);
|
235
|
+
grpc_closure* on_destroy_done_ ABSL_GUARDED_BY(mu_) = nullptr;
|
180
236
|
RefCountedPtr<channelz::ListenSocketNode> channelz_listen_socket_;
|
181
237
|
};
|
182
238
|
|
183
239
|
//
|
184
|
-
// Chttp2ServerListener::
|
240
|
+
// Chttp2ServerListener::ConfigFetcherWatcher
|
241
|
+
//
|
242
|
+
|
243
|
+
void Chttp2ServerListener::ConfigFetcherWatcher::UpdateConnectionManager(
|
244
|
+
RefCountedPtr<grpc_server_config_fetcher::ConnectionManager>
|
245
|
+
connection_manager) {
|
246
|
+
RefCountedPtr<grpc_server_config_fetcher::ConnectionManager>
|
247
|
+
connection_manager_to_destroy;
|
248
|
+
{
|
249
|
+
MutexLock lock(&listener_->channel_args_mu_);
|
250
|
+
connection_manager_to_destroy = listener_->connection_manager_;
|
251
|
+
listener_->connection_manager_ = std::move(connection_manager);
|
252
|
+
}
|
253
|
+
{
|
254
|
+
MutexLock lock(&listener_->mu_);
|
255
|
+
if (listener_->shutdown_) {
|
256
|
+
return;
|
257
|
+
}
|
258
|
+
listener_->is_serving_ = true;
|
259
|
+
if (listener_->started_) return;
|
260
|
+
}
|
261
|
+
int port_temp;
|
262
|
+
grpc_error* error = grpc_tcp_server_add_port(
|
263
|
+
listener_->tcp_server_, &listener_->resolved_address_, &port_temp);
|
264
|
+
if (error != GRPC_ERROR_NONE) {
|
265
|
+
GRPC_ERROR_UNREF(error);
|
266
|
+
gpr_log(GPR_ERROR, "Error adding port to server: %s",
|
267
|
+
grpc_error_string(error));
|
268
|
+
// TODO(yashykt): We wouldn't need to assert here if we bound to the
|
269
|
+
// port earlier during AddPort.
|
270
|
+
GPR_ASSERT(0);
|
271
|
+
}
|
272
|
+
listener_->StartListening();
|
273
|
+
{
|
274
|
+
MutexLock lock(&listener_->mu_);
|
275
|
+
listener_->started_ = true;
|
276
|
+
listener_->started_cv_.SignalAll();
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
void Chttp2ServerListener::ConfigFetcherWatcher::StopServing() {
|
281
|
+
std::map<ActiveConnection*, OrphanablePtr<ActiveConnection>> connections;
|
282
|
+
{
|
283
|
+
MutexLock lock(&listener_->mu_);
|
284
|
+
listener_->is_serving_ = false;
|
285
|
+
connections = std::move(listener_->connections_);
|
286
|
+
}
|
287
|
+
// Send GOAWAYs on the transports so that they disconnected when existing RPCs
|
288
|
+
// finish.
|
289
|
+
for (auto& connection : connections) {
|
290
|
+
connection.first->SendGoAway();
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
//
|
295
|
+
// Chttp2ServerListener::ActiveConnection::HandshakingState
|
185
296
|
//
|
186
297
|
|
187
298
|
grpc_millis GetConnectionDeadline(const grpc_channel_args* args) {
|
@@ -191,73 +302,96 @@ grpc_millis GetConnectionDeadline(const grpc_channel_args* args) {
|
|
191
302
|
return ExecCtx::Get()->Now() + timeout_ms;
|
192
303
|
}
|
193
304
|
|
194
|
-
Chttp2ServerListener::
|
195
|
-
|
196
|
-
grpc_tcp_server_acceptor* acceptor,
|
197
|
-
|
198
|
-
|
199
|
-
: listener_(listener),
|
305
|
+
Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState(
|
306
|
+
RefCountedPtr<ActiveConnection> connection_ref,
|
307
|
+
grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor,
|
308
|
+
grpc_channel_args* args)
|
309
|
+
: connection_(std::move(connection_ref)),
|
200
310
|
accepting_pollset_(accepting_pollset),
|
201
311
|
acceptor_(acceptor),
|
202
|
-
handshake_mgr_(
|
312
|
+
handshake_mgr_(MakeRefCounted<HandshakeManager>()),
|
203
313
|
deadline_(GetConnectionDeadline(args)),
|
204
314
|
interested_parties_(grpc_pollset_set_create()) {
|
205
315
|
grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_);
|
206
316
|
HandshakerRegistry::AddHandshakers(HANDSHAKER_SERVER, args,
|
207
317
|
interested_parties_, handshake_mgr_.get());
|
208
|
-
handshake_mgr_->DoHandshake(endpoint, args, deadline_, acceptor_,
|
209
|
-
OnHandshakeDone, this);
|
210
318
|
}
|
211
319
|
|
212
|
-
Chttp2ServerListener::
|
213
|
-
if (transport_ != nullptr) {
|
214
|
-
GRPC_CHTTP2_UNREF_TRANSPORT(transport_, "receive settings timeout");
|
215
|
-
}
|
320
|
+
Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() {
|
216
321
|
grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_);
|
217
322
|
grpc_pollset_set_destroy(interested_parties_);
|
218
323
|
}
|
219
324
|
|
220
|
-
void Chttp2ServerListener::
|
221
|
-
|
222
|
-
|
325
|
+
void Chttp2ServerListener::ActiveConnection::HandshakingState::Orphan() {
|
326
|
+
{
|
327
|
+
MutexLock lock(&connection_->mu_);
|
328
|
+
if (handshake_mgr_ != nullptr) {
|
329
|
+
handshake_mgr_->Shutdown(
|
330
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Listener stopped serving."));
|
331
|
+
}
|
332
|
+
}
|
333
|
+
Unref();
|
334
|
+
}
|
335
|
+
|
336
|
+
void Chttp2ServerListener::ActiveConnection::HandshakingState::Start(
|
337
|
+
grpc_endpoint* endpoint, grpc_channel_args* args) {
|
338
|
+
Ref().release(); // Held by OnHandshakeDone
|
339
|
+
RefCountedPtr<HandshakeManager> handshake_mgr;
|
340
|
+
{
|
341
|
+
MutexLock lock(&connection_->mu_);
|
342
|
+
if (handshake_mgr_ == nullptr) return;
|
343
|
+
handshake_mgr = handshake_mgr_;
|
344
|
+
}
|
345
|
+
handshake_mgr->DoHandshake(endpoint, args, deadline_, acceptor_,
|
346
|
+
OnHandshakeDone, this);
|
347
|
+
}
|
348
|
+
|
349
|
+
void Chttp2ServerListener::ActiveConnection::HandshakingState::OnTimeout(
|
350
|
+
void* arg, grpc_error* error) {
|
351
|
+
HandshakingState* self = static_cast<HandshakingState*>(arg);
|
223
352
|
// Note that we may be called with GRPC_ERROR_NONE when the timer fires
|
224
353
|
// or with an error indicating that the timer system is being shut down.
|
225
354
|
if (error != GRPC_ERROR_CANCELLED) {
|
226
355
|
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
227
356
|
op->disconnect_with_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
228
357
|
"Did not receive HTTP/2 settings before handshake timeout");
|
229
|
-
|
358
|
+
grpc_chttp2_transport* transport = nullptr;
|
359
|
+
{
|
360
|
+
MutexLock lock(&self->connection_->mu_);
|
361
|
+
transport = self->connection_->transport_;
|
362
|
+
}
|
363
|
+
grpc_transport_perform_op(&transport->base, op);
|
230
364
|
}
|
231
365
|
self->Unref();
|
232
366
|
}
|
233
367
|
|
234
|
-
void Chttp2ServerListener::
|
235
|
-
void* arg, grpc_error* error) {
|
236
|
-
|
237
|
-
|
238
|
-
grpc_timer_cancel(&self->timer_);
|
239
|
-
}
|
368
|
+
void Chttp2ServerListener::ActiveConnection::HandshakingState::
|
369
|
+
OnReceiveSettings(void* arg, grpc_error* /* error */) {
|
370
|
+
HandshakingState* self = static_cast<HandshakingState*>(arg);
|
371
|
+
grpc_timer_cancel(&self->timer_);
|
240
372
|
self->Unref();
|
241
373
|
}
|
242
374
|
|
243
|
-
void Chttp2ServerListener::
|
244
|
-
|
375
|
+
void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone(
|
376
|
+
void* arg, grpc_error* error) {
|
245
377
|
auto* args = static_cast<HandshakerArgs*>(arg);
|
246
|
-
|
378
|
+
HandshakingState* self = static_cast<HandshakingState*>(args->user_data);
|
379
|
+
OrphanablePtr<HandshakingState> handshaking_state_ref;
|
380
|
+
RefCountedPtr<HandshakeManager> handshake_mgr;
|
381
|
+
bool cleanup_connection = false;
|
382
|
+
bool free_resource_quota = false;
|
383
|
+
grpc_resource_user* resource_user =
|
384
|
+
self->connection_->listener_->server_->default_resource_user();
|
247
385
|
{
|
248
|
-
MutexLock
|
249
|
-
|
250
|
-
self->listener_->server_->default_resource_user();
|
251
|
-
if (error != GRPC_ERROR_NONE || self->listener_->shutdown_) {
|
386
|
+
MutexLock connection_lock(&self->connection_->mu_);
|
387
|
+
if (error != GRPC_ERROR_NONE || self->connection_->shutdown_) {
|
252
388
|
const char* error_str = grpc_error_string(error);
|
253
389
|
gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
|
254
|
-
|
255
|
-
|
256
|
-
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
|
257
|
-
}
|
390
|
+
cleanup_connection = true;
|
391
|
+
free_resource_quota = true;
|
258
392
|
if (error == GRPC_ERROR_NONE && args->endpoint != nullptr) {
|
259
|
-
// We were shut down after handshaking completed
|
260
|
-
// destroy the endpoint here.
|
393
|
+
// We were shut down or stopped serving after handshaking completed
|
394
|
+
// successfully, so destroy the endpoint here.
|
261
395
|
// TODO(ctiller): It is currently necessary to shutdown endpoints
|
262
396
|
// before destroying them, even if we know that there are no
|
263
397
|
// pending read/write callbacks. This should be fixed, at which
|
@@ -275,9 +409,11 @@ void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
|
|
275
409
|
if (args->endpoint != nullptr) {
|
276
410
|
grpc_transport* transport = grpc_create_chttp2_transport(
|
277
411
|
args->args, args->endpoint, false, resource_user);
|
278
|
-
grpc_error* channel_init_err =
|
279
|
-
|
280
|
-
|
412
|
+
grpc_error* channel_init_err =
|
413
|
+
self->connection_->listener_->server_->SetupTransport(
|
414
|
+
transport, self->accepting_pollset_, args->args,
|
415
|
+
grpc_chttp2_transport_get_socket_node(transport),
|
416
|
+
resource_user);
|
281
417
|
if (channel_init_err == GRPC_ERROR_NONE) {
|
282
418
|
// Use notify_on_receive_settings callback to enforce the
|
283
419
|
// handshake deadline.
|
@@ -287,18 +423,32 @@ void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
|
|
287
423
|
// static_cast<> to a derived class.
|
288
424
|
// TODO(roth): Change to static_cast<> when we C++-ify the
|
289
425
|
// transport API.
|
290
|
-
self->transport_ =
|
426
|
+
self->connection_->transport_ =
|
291
427
|
reinterpret_cast<grpc_chttp2_transport*>(transport);
|
428
|
+
GRPC_CHTTP2_REF_TRANSPORT(self->connection_->transport_,
|
429
|
+
"ActiveConnection"); // Held by connection_
|
292
430
|
self->Ref().release(); // Held by OnReceiveSettings().
|
293
431
|
GRPC_CLOSURE_INIT(&self->on_receive_settings_, OnReceiveSettings,
|
294
432
|
self, grpc_schedule_on_exec_ctx);
|
433
|
+
// If the listener has been configured with a config fetcher, we need
|
434
|
+
// to watch on the transport being closed so that we can an updated
|
435
|
+
// list of active connections.
|
436
|
+
grpc_closure* on_close = nullptr;
|
437
|
+
if (self->connection_->listener_->config_fetcher_watcher_ !=
|
438
|
+
nullptr) {
|
439
|
+
// Refs helds by OnClose()
|
440
|
+
self->connection_->Ref().release();
|
441
|
+
on_close = &self->connection_->on_close_;
|
442
|
+
} else {
|
443
|
+
// Remove the connection from the connections_ map since OnClose()
|
444
|
+
// will not be invoked when a config fetcher is set.
|
445
|
+
cleanup_connection = true;
|
446
|
+
}
|
295
447
|
grpc_chttp2_transport_start_reading(transport, args->read_buffer,
|
296
|
-
&self->on_receive_settings_
|
448
|
+
&self->on_receive_settings_,
|
449
|
+
on_close);
|
297
450
|
grpc_channel_args_destroy(args->args);
|
298
451
|
self->Ref().release(); // Held by OnTimeout().
|
299
|
-
GRPC_CHTTP2_REF_TRANSPORT(
|
300
|
-
reinterpret_cast<grpc_chttp2_transport*>(transport),
|
301
|
-
"receive settings timeout");
|
302
452
|
GRPC_CLOSURE_INIT(&self->on_timeout_, OnTimeout, self,
|
303
453
|
grpc_schedule_on_exec_ctx);
|
304
454
|
grpc_timer_init(&self->timer_, self->deadline_, &self->on_timeout_);
|
@@ -310,25 +460,116 @@ void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
|
|
310
460
|
grpc_transport_destroy(transport);
|
311
461
|
grpc_slice_buffer_destroy_internal(args->read_buffer);
|
312
462
|
gpr_free(args->read_buffer);
|
313
|
-
|
314
|
-
|
315
|
-
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
|
316
|
-
}
|
463
|
+
cleanup_connection = true;
|
464
|
+
free_resource_quota = true;
|
317
465
|
grpc_channel_args_destroy(args->args);
|
318
466
|
}
|
319
467
|
} else {
|
320
|
-
|
321
|
-
|
322
|
-
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
|
323
|
-
}
|
468
|
+
cleanup_connection = true;
|
469
|
+
free_resource_quota = true;
|
324
470
|
}
|
325
471
|
}
|
326
|
-
|
327
|
-
|
472
|
+
// Since the handshake manager is done, the connection no longer needs to
|
473
|
+
// shutdown the handshake when the listener needs to stop serving.
|
474
|
+
// Avoid calling the destructor of HandshakeManager and HandshakingState
|
475
|
+
// from within the critical region.
|
476
|
+
handshake_mgr = std::move(self->handshake_mgr_);
|
477
|
+
handshaking_state_ref = std::move(self->connection_->handshaking_state_);
|
328
478
|
}
|
329
|
-
self->handshake_mgr_.reset();
|
330
479
|
gpr_free(self->acceptor_);
|
331
|
-
|
480
|
+
OrphanablePtr<ActiveConnection> connection;
|
481
|
+
if (free_resource_quota && resource_user != nullptr) {
|
482
|
+
grpc_resource_user_free(resource_user, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
|
483
|
+
}
|
484
|
+
if (cleanup_connection) {
|
485
|
+
MutexLock listener_lock(&self->connection_->listener_->mu_);
|
486
|
+
auto it = self->connection_->listener_->connections_.find(
|
487
|
+
self->connection_.get());
|
488
|
+
if (it != self->connection_->listener_->connections_.end()) {
|
489
|
+
connection = std::move(it->second);
|
490
|
+
self->connection_->listener_->connections_.erase(it);
|
491
|
+
}
|
492
|
+
}
|
493
|
+
self->Unref();
|
494
|
+
}
|
495
|
+
|
496
|
+
//
|
497
|
+
// Chttp2ServerListener::ActiveConnection
|
498
|
+
//
|
499
|
+
|
500
|
+
Chttp2ServerListener::ActiveConnection::ActiveConnection(
|
501
|
+
grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor,
|
502
|
+
grpc_channel_args* args)
|
503
|
+
: handshaking_state_(MakeOrphanable<HandshakingState>(
|
504
|
+
Ref(), accepting_pollset, acceptor, args)) {
|
505
|
+
GRPC_CLOSURE_INIT(&on_close_, ActiveConnection::OnClose, this,
|
506
|
+
grpc_schedule_on_exec_ctx);
|
507
|
+
}
|
508
|
+
|
509
|
+
Chttp2ServerListener::ActiveConnection::~ActiveConnection() {
|
510
|
+
if (transport_ != nullptr) {
|
511
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(transport_, "ActiveConnection");
|
512
|
+
}
|
513
|
+
}
|
514
|
+
|
515
|
+
void Chttp2ServerListener::ActiveConnection::Orphan() {
|
516
|
+
OrphanablePtr<HandshakingState> handshaking_state;
|
517
|
+
{
|
518
|
+
MutexLock lock(&mu_);
|
519
|
+
shutdown_ = true;
|
520
|
+
// Reset handshaking_state_ since we have been orphaned by the listener
|
521
|
+
// signaling that the listener has stopped serving.
|
522
|
+
handshaking_state = std::move(handshaking_state_);
|
523
|
+
}
|
524
|
+
Unref();
|
525
|
+
}
|
526
|
+
|
527
|
+
void Chttp2ServerListener::ActiveConnection::SendGoAway() {
|
528
|
+
grpc_chttp2_transport* transport = nullptr;
|
529
|
+
{
|
530
|
+
MutexLock lock(&mu_);
|
531
|
+
transport = transport_;
|
532
|
+
}
|
533
|
+
if (transport != nullptr) {
|
534
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
535
|
+
op->goaway_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
536
|
+
"Server is stopping to serve requests.");
|
537
|
+
grpc_transport_perform_op(&transport->base, op);
|
538
|
+
}
|
539
|
+
}
|
540
|
+
|
541
|
+
void Chttp2ServerListener::ActiveConnection::Start(
|
542
|
+
RefCountedPtr<Chttp2ServerListener> listener, grpc_endpoint* endpoint,
|
543
|
+
grpc_channel_args* args) {
|
544
|
+
RefCountedPtr<HandshakingState> handshaking_state_ref;
|
545
|
+
listener_ = std::move(listener);
|
546
|
+
{
|
547
|
+
MutexLock lock(&mu_);
|
548
|
+
if (shutdown_) return;
|
549
|
+
// Hold a ref to HandshakingState to allow starting the handshake outside
|
550
|
+
// the critical region.
|
551
|
+
handshaking_state_ref = handshaking_state_->Ref();
|
552
|
+
}
|
553
|
+
handshaking_state_ref->Start(endpoint, args);
|
554
|
+
}
|
555
|
+
|
556
|
+
void Chttp2ServerListener::ActiveConnection::OnClose(void* arg,
|
557
|
+
grpc_error* /* error */) {
|
558
|
+
ActiveConnection* self = static_cast<ActiveConnection*>(arg);
|
559
|
+
OrphanablePtr<ActiveConnection> connection;
|
560
|
+
{
|
561
|
+
MutexLock listener_lock(&self->listener_->mu_);
|
562
|
+
MutexLock connection_lock(&self->mu_);
|
563
|
+
// The node was already deleted from the connections_ list if the connection
|
564
|
+
// is shutdown.
|
565
|
+
if (!self->shutdown_) {
|
566
|
+
auto it = self->listener_->connections_.find(self);
|
567
|
+
if (it != self->listener_->connections_.end()) {
|
568
|
+
connection = std::move(it->second);
|
569
|
+
self->listener_->connections_.erase(it);
|
570
|
+
}
|
571
|
+
}
|
572
|
+
}
|
332
573
|
self->Unref();
|
333
574
|
}
|
334
575
|
|
@@ -361,7 +602,7 @@ grpc_error* Chttp2ServerListener::Create(Server* server,
|
|
361
602
|
// Create channelz node.
|
362
603
|
if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
|
363
604
|
GRPC_ENABLE_CHANNELZ_DEFAULT)) {
|
364
|
-
std::string string_address =
|
605
|
+
std::string string_address = grpc_sockaddr_to_uri(addr);
|
365
606
|
listener->channelz_listen_socket_ =
|
366
607
|
MakeRefCounted<channelz::ListenSocketNode>(
|
367
608
|
string_address.c_str(),
|
@@ -414,6 +655,13 @@ Chttp2ServerListener::Chttp2ServerListener(
|
|
414
655
|
}
|
415
656
|
|
416
657
|
Chttp2ServerListener::~Chttp2ServerListener() {
|
658
|
+
// Flush queued work before destroying handshaker factory, since that
|
659
|
+
// may do a synchronous unref.
|
660
|
+
ExecCtx::Get()->Flush();
|
661
|
+
if (on_destroy_done_ != nullptr) {
|
662
|
+
ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, GRPC_ERROR_NONE);
|
663
|
+
ExecCtx::Get()->Flush();
|
664
|
+
}
|
417
665
|
grpc_channel_args_destroy(args_);
|
418
666
|
}
|
419
667
|
|
@@ -422,24 +670,27 @@ void Chttp2ServerListener::Start(
|
|
422
670
|
Server* /*server*/, const std::vector<grpc_pollset*>* /* pollsets */) {
|
423
671
|
if (server_->config_fetcher() != nullptr) {
|
424
672
|
grpc_channel_args* args = nullptr;
|
425
|
-
auto watcher = absl::make_unique<ConfigFetcherWatcher>(
|
673
|
+
auto watcher = absl::make_unique<ConfigFetcherWatcher>(Ref());
|
674
|
+
config_fetcher_watcher_ = watcher.get();
|
426
675
|
{
|
427
|
-
MutexLock lock(&
|
428
|
-
config_fetcher_watcher_ = watcher.get();
|
676
|
+
MutexLock lock(&channel_args_mu_);
|
429
677
|
args = grpc_channel_args_copy(args_);
|
430
678
|
}
|
431
679
|
server_->config_fetcher()->StartWatch(
|
432
680
|
grpc_sockaddr_to_string(&resolved_address_, false), args,
|
433
681
|
std::move(watcher));
|
434
682
|
} else {
|
683
|
+
{
|
684
|
+
MutexLock lock(&mu_);
|
685
|
+
started_ = true;
|
686
|
+
is_serving_ = true;
|
687
|
+
}
|
435
688
|
StartListening();
|
436
689
|
}
|
437
690
|
}
|
438
691
|
|
439
692
|
void Chttp2ServerListener::StartListening() {
|
440
693
|
grpc_tcp_server_start(tcp_server_, &server_->pollsets(), OnAccept, this);
|
441
|
-
MutexLock lock(&mu_);
|
442
|
-
shutdown_ = false;
|
443
694
|
}
|
444
695
|
|
445
696
|
void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
|
@@ -447,67 +698,93 @@ void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
|
|
447
698
|
on_destroy_done_ = on_destroy_done;
|
448
699
|
}
|
449
700
|
|
450
|
-
RefCountedPtr<HandshakeManager> Chttp2ServerListener::CreateHandshakeManager() {
|
451
|
-
MutexLock lock(&mu_);
|
452
|
-
if (shutdown_) return nullptr;
|
453
|
-
grpc_resource_user* resource_user = server_->default_resource_user();
|
454
|
-
if (resource_user != nullptr &&
|
455
|
-
!grpc_resource_user_safe_alloc(resource_user,
|
456
|
-
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) {
|
457
|
-
gpr_log(GPR_ERROR,
|
458
|
-
"Memory quota exhausted, rejecting connection, no handshaking.");
|
459
|
-
return nullptr;
|
460
|
-
}
|
461
|
-
auto handshake_mgr = MakeRefCounted<HandshakeManager>();
|
462
|
-
handshake_mgr->AddToPendingMgrList(&pending_handshake_mgrs_);
|
463
|
-
grpc_tcp_server_ref(tcp_server_); // Ref held by ConnectionState.
|
464
|
-
return handshake_mgr;
|
465
|
-
}
|
466
|
-
|
467
701
|
void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
|
468
702
|
grpc_pollset* accepting_pollset,
|
469
703
|
grpc_tcp_server_acceptor* acceptor) {
|
470
704
|
Chttp2ServerListener* self = static_cast<Chttp2ServerListener*>(arg);
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
705
|
+
grpc_channel_args* args = nullptr;
|
706
|
+
RefCountedPtr<grpc_server_config_fetcher::ConnectionManager>
|
707
|
+
connection_manager;
|
708
|
+
{
|
709
|
+
MutexLock lock(&self->channel_args_mu_);
|
710
|
+
args = grpc_channel_args_copy(self->args_);
|
711
|
+
connection_manager = self->connection_manager_;
|
712
|
+
}
|
713
|
+
auto endpoint_cleanup = [&](grpc_error* error) {
|
714
|
+
grpc_endpoint_shutdown(tcp, error);
|
475
715
|
grpc_endpoint_destroy(tcp);
|
476
716
|
gpr_free(acceptor);
|
477
|
-
|
717
|
+
};
|
718
|
+
if (self->server_->config_fetcher() != nullptr) {
|
719
|
+
if (connection_manager == nullptr) {
|
720
|
+
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
721
|
+
"No ConnectionManager configured. Closing connection.");
|
722
|
+
endpoint_cleanup(error);
|
723
|
+
grpc_channel_args_destroy(args);
|
724
|
+
return;
|
725
|
+
}
|
726
|
+
// TODO(yashykt): Maybe combine the following two arg modifiers into a
|
727
|
+
// single one.
|
728
|
+
absl::StatusOr<grpc_channel_args*> args_result =
|
729
|
+
connection_manager->UpdateChannelArgsForConnection(args, tcp);
|
730
|
+
if (!args_result.ok()) {
|
731
|
+
gpr_log(GPR_DEBUG, "Closing connection: %s",
|
732
|
+
args_result.status().ToString().c_str());
|
733
|
+
endpoint_cleanup(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
734
|
+
args_result.status().ToString().c_str()));
|
735
|
+
return;
|
736
|
+
}
|
737
|
+
grpc_error* error = GRPC_ERROR_NONE;
|
738
|
+
args = self->args_modifier_(*args_result, &error);
|
739
|
+
if (error != GRPC_ERROR_NONE) {
|
740
|
+
gpr_log(GPR_DEBUG, "Closing connection: %s", grpc_error_string(error));
|
741
|
+
endpoint_cleanup(error);
|
742
|
+
grpc_channel_args_destroy(args);
|
743
|
+
return;
|
744
|
+
}
|
478
745
|
}
|
479
|
-
|
746
|
+
auto connection =
|
747
|
+
MakeOrphanable<ActiveConnection>(accepting_pollset, acceptor, args);
|
748
|
+
// Hold a ref to connection to allow starting handshake outside the
|
749
|
+
// critical region
|
750
|
+
RefCountedPtr<ActiveConnection> connection_ref = connection->Ref();
|
751
|
+
RefCountedPtr<Chttp2ServerListener> listener_ref;
|
480
752
|
{
|
481
753
|
MutexLock lock(&self->mu_);
|
482
|
-
|
754
|
+
// Shutdown the the connection if listener's stopped serving.
|
755
|
+
if (!self->shutdown_ && self->is_serving_) {
|
756
|
+
grpc_resource_user* resource_user =
|
757
|
+
self->server_->default_resource_user();
|
758
|
+
if (resource_user != nullptr &&
|
759
|
+
!grpc_resource_user_safe_alloc(resource_user,
|
760
|
+
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) {
|
761
|
+
gpr_log(
|
762
|
+
GPR_ERROR,
|
763
|
+
"Memory quota exhausted, rejecting connection, no handshaking.");
|
764
|
+
} else {
|
765
|
+
// This ref needs to be taken in the critical region after having made
|
766
|
+
// sure that the listener has not been Orphaned, so as to avoid
|
767
|
+
// heap-use-after-free issues where `Ref()` is invoked when the ref of
|
768
|
+
// tcp_server_ has already reached 0. (Ref() implementation of
|
769
|
+
// Chttp2ServerListener is grpc_tcp_server_ref().)
|
770
|
+
listener_ref = self->Ref();
|
771
|
+
self->connections_.emplace(connection.get(), std::move(connection));
|
772
|
+
}
|
773
|
+
}
|
774
|
+
}
|
775
|
+
if (connection != nullptr) {
|
776
|
+
endpoint_cleanup(GRPC_ERROR_NONE);
|
777
|
+
} else {
|
778
|
+
connection_ref->Start(std::move(listener_ref), tcp, args);
|
483
779
|
}
|
484
|
-
// Deletes itself when done.
|
485
|
-
new ConnectionState(self, accepting_pollset, acceptor,
|
486
|
-
std::move(handshake_mgr), args, tcp);
|
487
780
|
grpc_channel_args_destroy(args);
|
488
781
|
}
|
489
782
|
|
490
783
|
void Chttp2ServerListener::TcpServerShutdownComplete(void* arg,
|
491
784
|
grpc_error* error) {
|
492
785
|
Chttp2ServerListener* self = static_cast<Chttp2ServerListener*>(arg);
|
493
|
-
|
494
|
-
|
495
|
-
{
|
496
|
-
MutexLock lock(&self->mu_);
|
497
|
-
destroy_done = self->on_destroy_done_;
|
498
|
-
GPR_ASSERT(self->shutdown_);
|
499
|
-
if (self->pending_handshake_mgrs_ != nullptr) {
|
500
|
-
self->pending_handshake_mgrs_->ShutdownAllPending(GRPC_ERROR_REF(error));
|
501
|
-
}
|
502
|
-
self->channelz_listen_socket_.reset();
|
503
|
-
}
|
504
|
-
// Flush queued work before destroying handshaker factory, since that
|
505
|
-
// may do a synchronous unref.
|
506
|
-
ExecCtx::Get()->Flush();
|
507
|
-
if (destroy_done != nullptr) {
|
508
|
-
ExecCtx::Run(DEBUG_LOCATION, destroy_done, GRPC_ERROR_REF(error));
|
509
|
-
ExecCtx::Get()->Flush();
|
510
|
-
}
|
786
|
+
self->channelz_listen_socket_.reset();
|
787
|
+
GRPC_ERROR_UNREF(error);
|
511
788
|
delete self;
|
512
789
|
}
|
513
790
|
|
@@ -519,10 +796,20 @@ void Chttp2ServerListener::Orphan() {
|
|
519
796
|
if (config_fetcher_watcher_ != nullptr) {
|
520
797
|
server_->config_fetcher()->CancelWatch(config_fetcher_watcher_);
|
521
798
|
}
|
799
|
+
std::map<ActiveConnection*, OrphanablePtr<ActiveConnection>> connections;
|
522
800
|
grpc_tcp_server* tcp_server;
|
523
801
|
{
|
524
802
|
MutexLock lock(&mu_);
|
525
803
|
shutdown_ = true;
|
804
|
+
is_serving_ = false;
|
805
|
+
// Orphan the connections so that they can start cleaning up.
|
806
|
+
connections = std::move(connections_);
|
807
|
+
// If the listener is currently set to be serving but has not been started
|
808
|
+
// yet, it means that `grpc_tcp_server_start` is in progress. Wait for the
|
809
|
+
// operation to finish to avoid causing races.
|
810
|
+
while (is_serving_ && !started_) {
|
811
|
+
started_cv_.Wait(&mu_);
|
812
|
+
}
|
526
813
|
tcp_server = tcp_server_;
|
527
814
|
}
|
528
815
|
grpc_tcp_server_shutdown_listeners(tcp_server);
|