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
@@ -24,73 +24,33 @@
|
|
24
24
|
|
25
25
|
namespace grpc_core {
|
26
26
|
|
27
|
-
LocalSubchannelPool::
|
28
|
-
|
27
|
+
RefCountedPtr<Subchannel> LocalSubchannelPool::RegisterSubchannel(
|
28
|
+
const SubchannelKey& key, RefCountedPtr<Subchannel> constructed) {
|
29
|
+
auto it = subchannel_map_.find(key);
|
30
|
+
// Because this pool is only accessed under the client channel's work
|
31
|
+
// serializer, and because FindSubchannel is checked before invoking
|
32
|
+
// RegisterSubchannel, no such subchannel should exist in the map.
|
33
|
+
GPR_ASSERT(it == subchannel_map_.end());
|
34
|
+
subchannel_map_[key] = constructed.get();
|
35
|
+
return constructed;
|
36
|
+
}
|
37
|
+
|
38
|
+
void LocalSubchannelPool::UnregisterSubchannel(const SubchannelKey& key,
|
39
|
+
Subchannel* subchannel) {
|
40
|
+
auto it = subchannel_map_.find(key);
|
41
|
+
// Because this subchannel pool is accessed only under the client
|
42
|
+
// channel's work serializer, any subchannel created by RegisterSubchannel
|
43
|
+
// will be deleted from the map in UnregisterSubchannel.
|
44
|
+
GPR_ASSERT(it != subchannel_map_.end());
|
45
|
+
GPR_ASSERT(it->second == subchannel);
|
46
|
+
subchannel_map_.erase(it);
|
47
|
+
}
|
48
|
+
|
49
|
+
RefCountedPtr<Subchannel> LocalSubchannelPool::FindSubchannel(
|
50
|
+
const SubchannelKey& key) {
|
51
|
+
auto it = subchannel_map_.find(key);
|
52
|
+
if (it == subchannel_map_.end()) return nullptr;
|
53
|
+
return it->second->Ref();
|
29
54
|
}
|
30
55
|
|
31
|
-
LocalSubchannelPool::~LocalSubchannelPool() {
|
32
|
-
grpc_avl_unref(subchannel_map_, nullptr);
|
33
|
-
}
|
34
|
-
|
35
|
-
Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key,
|
36
|
-
Subchannel* constructed) {
|
37
|
-
// Check to see if a subchannel already exists.
|
38
|
-
Subchannel* c =
|
39
|
-
static_cast<Subchannel*>(grpc_avl_get(subchannel_map_, key, nullptr));
|
40
|
-
if (c != nullptr) {
|
41
|
-
// The subchannel already exists. Reuse it.
|
42
|
-
c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse");
|
43
|
-
GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing");
|
44
|
-
} else {
|
45
|
-
// There hasn't been such subchannel. Add one.
|
46
|
-
subchannel_map_ = grpc_avl_add(subchannel_map_, new SubchannelKey(*key),
|
47
|
-
constructed, nullptr);
|
48
|
-
c = constructed;
|
49
|
-
}
|
50
|
-
return c;
|
51
|
-
}
|
52
|
-
|
53
|
-
void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) {
|
54
|
-
subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr);
|
55
|
-
}
|
56
|
-
|
57
|
-
Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) {
|
58
|
-
Subchannel* c =
|
59
|
-
static_cast<Subchannel*>(grpc_avl_get(subchannel_map_, key, nullptr));
|
60
|
-
return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool");
|
61
|
-
}
|
62
|
-
|
63
|
-
namespace {
|
64
|
-
|
65
|
-
void sck_avl_destroy(void* p, void* /*user_data*/) {
|
66
|
-
SubchannelKey* key = static_cast<SubchannelKey*>(p);
|
67
|
-
delete key;
|
68
|
-
}
|
69
|
-
|
70
|
-
void* sck_avl_copy(void* p, void* /*unused*/) {
|
71
|
-
const SubchannelKey* key = static_cast<const SubchannelKey*>(p);
|
72
|
-
auto new_key = new SubchannelKey(*key);
|
73
|
-
return static_cast<void*>(new_key);
|
74
|
-
}
|
75
|
-
|
76
|
-
long sck_avl_compare(void* a, void* b, void* /*unused*/) {
|
77
|
-
const SubchannelKey* key_a = static_cast<const SubchannelKey*>(a);
|
78
|
-
const SubchannelKey* key_b = static_cast<const SubchannelKey*>(b);
|
79
|
-
return key_a->Cmp(*key_b);
|
80
|
-
}
|
81
|
-
|
82
|
-
void scv_avl_destroy(void* /*p*/, void* /*user_data*/) {}
|
83
|
-
|
84
|
-
void* scv_avl_copy(void* p, void* /*unused*/) { return p; }
|
85
|
-
|
86
|
-
} // namespace
|
87
|
-
|
88
|
-
const grpc_avl_vtable LocalSubchannelPool::subchannel_avl_vtable_ = {
|
89
|
-
sck_avl_destroy, // destroy_key
|
90
|
-
sck_avl_copy, // copy_key
|
91
|
-
sck_avl_compare, // compare_keys
|
92
|
-
scv_avl_destroy, // destroy_value
|
93
|
-
scv_avl_copy // copy_value
|
94
|
-
};
|
95
|
-
|
96
56
|
} // namespace grpc_core
|
@@ -21,6 +21,8 @@
|
|
21
21
|
|
22
22
|
#include <grpc/support/port_platform.h>
|
23
23
|
|
24
|
+
#include <map>
|
25
|
+
|
24
26
|
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
|
25
27
|
|
26
28
|
namespace grpc_core {
|
@@ -34,22 +36,21 @@ namespace grpc_core {
|
|
34
36
|
// Thread-unsafe.
|
35
37
|
class LocalSubchannelPool final : public SubchannelPoolInterface {
|
36
38
|
public:
|
37
|
-
LocalSubchannelPool()
|
38
|
-
~LocalSubchannelPool() override
|
39
|
+
LocalSubchannelPool() {}
|
40
|
+
~LocalSubchannelPool() override {}
|
39
41
|
|
40
42
|
// Implements interface methods.
|
41
43
|
// Thread-unsafe. Intended to be invoked within the client_channel work
|
42
44
|
// serializer.
|
43
|
-
Subchannel
|
44
|
-
|
45
|
-
void UnregisterSubchannel(SubchannelKey
|
46
|
-
|
45
|
+
RefCountedPtr<Subchannel> RegisterSubchannel(
|
46
|
+
const SubchannelKey& key, RefCountedPtr<Subchannel> constructed) override;
|
47
|
+
void UnregisterSubchannel(const SubchannelKey& key,
|
48
|
+
Subchannel* subchannel) override;
|
49
|
+
RefCountedPtr<Subchannel> FindSubchannel(const SubchannelKey& key) override;
|
47
50
|
|
48
51
|
private:
|
49
|
-
// The vtable for subchannel operations in an AVL tree.
|
50
|
-
static const grpc_avl_vtable subchannel_avl_vtable_;
|
51
52
|
// A map from subchannel key to subchannel.
|
52
|
-
|
53
|
+
std::map<SubchannelKey, Subchannel*> subchannel_map_;
|
53
54
|
};
|
54
55
|
|
55
56
|
} // namespace grpc_core
|
@@ -60,6 +60,9 @@ Resolver::Result::Result(Result&& other) noexcept {
|
|
60
60
|
}
|
61
61
|
|
62
62
|
Resolver::Result& Resolver::Result::operator=(const Result& other) {
|
63
|
+
if (&other == this) {
|
64
|
+
return *this;
|
65
|
+
}
|
63
66
|
addresses = other.addresses;
|
64
67
|
service_config = other.service_config;
|
65
68
|
GRPC_ERROR_UNREF(service_config_error);
|
@@ -54,8 +54,8 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
|
|
54
54
|
/* c-ares library will close the fd inside grpc_fd. This fd may be picked up
|
55
55
|
immediately by another thread, and should not be closed by the following
|
56
56
|
grpc_fd_orphan. */
|
57
|
-
int
|
58
|
-
grpc_fd_orphan(fd_, nullptr, &
|
57
|
+
int phony_release_fd;
|
58
|
+
grpc_fd_orphan(fd_, nullptr, &phony_release_fd, "c-ares query finished");
|
59
59
|
}
|
60
60
|
|
61
61
|
void RegisterForOnReadableLocked(grpc_closure* read_closure) override {
|
@@ -251,7 +251,7 @@ class GrpcPolledFdWindows {
|
|
251
251
|
}
|
252
252
|
}
|
253
253
|
|
254
|
-
bool IsFdStillReadableLocked() { return
|
254
|
+
bool IsFdStillReadableLocked() { return read_buf_has_data_; }
|
255
255
|
|
256
256
|
void ShutdownLocked(grpc_error* error) {
|
257
257
|
grpc_winsocket_shutdown(winsocket_);
|
@@ -362,6 +362,8 @@ class GrpcPolledFdWindows {
|
|
362
362
|
DWORD bytes_sent = 0;
|
363
363
|
int wsa_error_code = 0;
|
364
364
|
if (SendWriteBuf(&bytes_sent, nullptr, &wsa_error_code) != 0) {
|
365
|
+
grpc_slice_unref_internal(write_buf_);
|
366
|
+
write_buf_ = grpc_empty_slice();
|
365
367
|
wsa_error_ctx->SetWSAError(wsa_error_code);
|
366
368
|
char* msg = gpr_format_message(wsa_error_code);
|
367
369
|
GRPC_CARES_TRACE_LOG(
|
@@ -238,14 +238,14 @@ void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
|
|
238
238
|
// Search fd in the fd_node list head. This is an O(n) search, the max possible
|
239
239
|
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
|
240
240
|
static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
|
241
|
-
fd_node
|
242
|
-
|
243
|
-
fd_node* node = &
|
241
|
+
fd_node phony_head;
|
242
|
+
phony_head.next = *head;
|
243
|
+
fd_node* node = &phony_head;
|
244
244
|
while (node->next != nullptr) {
|
245
245
|
if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
|
246
246
|
fd_node* ret = node->next;
|
247
247
|
node->next = node->next->next;
|
248
|
-
*head =
|
248
|
+
*head = phony_head.next;
|
249
249
|
return ret;
|
250
250
|
}
|
251
251
|
node = node->next;
|
@@ -971,11 +971,7 @@ static bool target_matches_localhost_inner(const char* name, std::string* host,
|
|
971
971
|
gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name);
|
972
972
|
return false;
|
973
973
|
}
|
974
|
-
|
975
|
-
return true;
|
976
|
-
} else {
|
977
|
-
return false;
|
978
|
-
}
|
974
|
+
return gpr_stricmp(host->c_str(), "localhost") == 0;
|
979
975
|
}
|
980
976
|
|
981
977
|
static bool target_matches_localhost(const char* name) {
|
@@ -19,6 +19,7 @@
|
|
19
19
|
#include "src/core/ext/filters/client_channel/resolver_registry.h"
|
20
20
|
#include "src/core/ext/xds/xds_client.h"
|
21
21
|
#include "src/core/lib/gpr/env.h"
|
22
|
+
#include "src/core/lib/gpr/string.h"
|
22
23
|
#include "src/core/lib/http/httpcli.h"
|
23
24
|
#include "src/core/lib/iomgr/polling_entity.h"
|
24
25
|
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
|
@@ -307,17 +308,25 @@ void GoogleCloud2ProdResolver::StartXdsResolver() {
|
|
307
308
|
{"TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE", true},
|
308
309
|
};
|
309
310
|
}
|
311
|
+
// Allow the TD server uri to be overridden for testing purposes.
|
312
|
+
UniquePtr<char> override_server(
|
313
|
+
gpr_getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI"));
|
314
|
+
const char* server_uri =
|
315
|
+
override_server != nullptr && strlen(override_server.get()) > 0
|
316
|
+
? override_server.get()
|
317
|
+
: "directpath-trafficdirector.googleapis.com";
|
310
318
|
Json bootstrap = Json::Object{
|
311
319
|
{"xds_servers",
|
312
320
|
Json::Array{
|
313
321
|
Json::Object{
|
314
|
-
{"server_uri",
|
322
|
+
{"server_uri", server_uri},
|
315
323
|
{"channel_creds",
|
316
324
|
Json::Array{
|
317
325
|
Json::Object{
|
318
326
|
{"type", "google_default"},
|
319
327
|
},
|
320
328
|
}},
|
329
|
+
{"server_features", Json::Array{"xds_v3"}},
|
321
330
|
},
|
322
331
|
}},
|
323
332
|
{"node", std::move(node)},
|
@@ -353,8 +362,14 @@ class GoogleCloud2ProdResolverFactory : public ResolverFactory {
|
|
353
362
|
} // namespace
|
354
363
|
|
355
364
|
void GoogleCloud2ProdResolverInit() {
|
356
|
-
|
357
|
-
|
365
|
+
// TODO(roth): Remove env var protection once this code is proven stable.
|
366
|
+
UniquePtr<char> value(gpr_getenv("GRPC_EXPERIMENTAL_GOOGLE_C2P_RESOLVER"));
|
367
|
+
bool parsed_value;
|
368
|
+
bool parse_succeeded = gpr_parse_bool_value(value.get(), &parsed_value);
|
369
|
+
if (parse_succeeded && parsed_value) {
|
370
|
+
ResolverRegistry::Builder::RegisterResolverFactory(
|
371
|
+
absl::make_unique<GoogleCloud2ProdResolverFactory>());
|
372
|
+
}
|
358
373
|
}
|
359
374
|
|
360
375
|
void GoogleCloud2ProdResolverShutdown() {}
|
@@ -22,13 +22,18 @@
|
|
22
22
|
#include "absl/strings/str_join.h"
|
23
23
|
#include "absl/strings/str_split.h"
|
24
24
|
#include "re2/re2.h"
|
25
|
+
#define XXH_INLINE_ALL
|
26
|
+
#include "xxhash.h"
|
25
27
|
|
26
28
|
#include "src/core/ext/filters/client_channel/config_selector.h"
|
29
|
+
#include "src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h"
|
27
30
|
#include "src/core/ext/filters/client_channel/resolver_registry.h"
|
28
31
|
#include "src/core/ext/xds/xds_client.h"
|
32
|
+
#include "src/core/ext/xds/xds_http_filters.h"
|
29
33
|
#include "src/core/lib/channel/channel_args.h"
|
30
34
|
#include "src/core/lib/iomgr/closure.h"
|
31
35
|
#include "src/core/lib/iomgr/exec_ctx.h"
|
36
|
+
#include "src/core/lib/surface/lame_client.h"
|
32
37
|
#include "src/core/lib/transport/timeout_encoding.h"
|
33
38
|
|
34
39
|
namespace grpc_core {
|
@@ -135,9 +140,7 @@ class XdsResolver : public Resolver {
|
|
135
140
|
|
136
141
|
class XdsConfigSelector : public ConfigSelector {
|
137
142
|
public:
|
138
|
-
XdsConfigSelector(RefCountedPtr<XdsResolver> resolver,
|
139
|
-
const std::vector<XdsApi::Route>& routes,
|
140
|
-
grpc_error* error);
|
143
|
+
XdsConfigSelector(RefCountedPtr<XdsResolver> resolver, grpc_error** error);
|
141
144
|
~XdsConfigSelector() override;
|
142
145
|
|
143
146
|
const char* name() const override { return "XdsConfigSelector"; }
|
@@ -151,26 +154,41 @@ class XdsResolver : public Resolver {
|
|
151
154
|
|
152
155
|
CallConfig GetCallConfig(GetCallConfigArgs args) override;
|
153
156
|
|
157
|
+
std::vector<const grpc_channel_filter*> GetFilters() override {
|
158
|
+
return filters_;
|
159
|
+
}
|
160
|
+
|
161
|
+
grpc_channel_args* ModifyChannelArgs(grpc_channel_args* args) override;
|
162
|
+
|
154
163
|
private:
|
155
164
|
struct Route {
|
165
|
+
struct ClusterWeightState {
|
166
|
+
uint32_t range_end;
|
167
|
+
absl::string_view cluster;
|
168
|
+
RefCountedPtr<ServiceConfig> method_config;
|
169
|
+
|
170
|
+
bool operator==(const ClusterWeightState& other) const;
|
171
|
+
};
|
172
|
+
|
156
173
|
XdsApi::Route route;
|
157
|
-
absl::InlinedVector<std::pair<uint32_t, absl::string_view>, 2>
|
158
|
-
weighted_cluster_state;
|
159
174
|
RefCountedPtr<ServiceConfig> method_config;
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
}
|
175
|
+
absl::InlinedVector<ClusterWeightState, 2> weighted_cluster_state;
|
176
|
+
|
177
|
+
bool operator==(const Route& other) const;
|
164
178
|
};
|
165
179
|
using RouteTable = std::vector<Route>;
|
166
180
|
|
167
181
|
void MaybeAddCluster(const std::string& name);
|
168
|
-
grpc_error* CreateMethodConfig(
|
169
|
-
|
182
|
+
grpc_error* CreateMethodConfig(
|
183
|
+
const XdsApi::Route& route,
|
184
|
+
const XdsApi::Route::ClusterWeight* cluster_weight,
|
185
|
+
RefCountedPtr<ServiceConfig>* method_config);
|
170
186
|
|
171
187
|
RefCountedPtr<XdsResolver> resolver_;
|
172
188
|
RouteTable route_table_;
|
173
189
|
std::map<absl::string_view, RefCountedPtr<ClusterState>> clusters_;
|
190
|
+
std::vector<const grpc_channel_filter*> filters_;
|
191
|
+
grpc_error* filter_error_ = GRPC_ERROR_NONE;
|
174
192
|
};
|
175
193
|
|
176
194
|
void OnListenerUpdate(XdsApi::LdsUpdate listener);
|
@@ -187,13 +205,20 @@ class XdsResolver : public Resolver {
|
|
187
205
|
std::string server_name_;
|
188
206
|
const grpc_channel_args* args_;
|
189
207
|
grpc_pollset_set* interested_parties_;
|
208
|
+
|
190
209
|
RefCountedPtr<XdsClient> xds_client_;
|
210
|
+
|
191
211
|
XdsClient::ListenerWatcherInterface* listener_watcher_ = nullptr;
|
212
|
+
// This will not contain the RouteConfiguration, even if it comes with the
|
213
|
+
// LDS response; instead, the relevant VirtualHost from the
|
214
|
+
// RouteConfiguration will be saved in current_virtual_host_.
|
215
|
+
XdsApi::LdsUpdate current_listener_;
|
216
|
+
|
192
217
|
std::string route_config_name_;
|
193
218
|
XdsClient::RouteConfigWatcherInterface* route_config_watcher_ = nullptr;
|
219
|
+
XdsApi::RdsUpdate::VirtualHost current_virtual_host_;
|
220
|
+
|
194
221
|
ClusterState::ClusterStateMap cluster_state_map_;
|
195
|
-
std::vector<XdsApi::Route> current_update_;
|
196
|
-
XdsApi::Duration http_max_stream_duration_;
|
197
222
|
};
|
198
223
|
|
199
224
|
//
|
@@ -212,7 +237,7 @@ XdsResolver::Notifier::Notifier(RefCountedPtr<XdsResolver> resolver,
|
|
212
237
|
XdsResolver::Notifier::Notifier(RefCountedPtr<XdsResolver> resolver,
|
213
238
|
XdsApi::RdsUpdate update)
|
214
239
|
: resolver_(std::move(resolver)), type_(kRdsUpdate) {
|
215
|
-
update_.rds_update = std::move(update);
|
240
|
+
update_.http_connection_manager.rds_update = std::move(update);
|
216
241
|
GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
|
217
242
|
ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
|
218
243
|
}
|
@@ -248,7 +273,8 @@ void XdsResolver::Notifier::RunInWorkSerializer(grpc_error* error) {
|
|
248
273
|
resolver_->OnListenerUpdate(std::move(update_));
|
249
274
|
break;
|
250
275
|
case kRdsUpdate:
|
251
|
-
resolver_->OnRouteConfigUpdate(
|
276
|
+
resolver_->OnRouteConfigUpdate(
|
277
|
+
std::move(*update_.http_connection_manager.rds_update));
|
252
278
|
break;
|
253
279
|
case kError:
|
254
280
|
resolver_->OnError(error);
|
@@ -260,13 +286,35 @@ void XdsResolver::Notifier::RunInWorkSerializer(grpc_error* error) {
|
|
260
286
|
delete this;
|
261
287
|
}
|
262
288
|
|
289
|
+
//
|
290
|
+
// XdsResolver::XdsConfigSelector::Route
|
291
|
+
//
|
292
|
+
|
293
|
+
bool MethodConfigsEqual(const ServiceConfig* sc1, const ServiceConfig* sc2) {
|
294
|
+
if (sc1 == nullptr) return sc2 == nullptr;
|
295
|
+
if (sc2 == nullptr) return false;
|
296
|
+
return sc1->json_string() == sc2->json_string();
|
297
|
+
}
|
298
|
+
|
299
|
+
bool XdsResolver::XdsConfigSelector::Route::ClusterWeightState::operator==(
|
300
|
+
const ClusterWeightState& other) const {
|
301
|
+
return range_end == other.range_end && cluster == other.cluster &&
|
302
|
+
MethodConfigsEqual(method_config.get(), other.method_config.get());
|
303
|
+
}
|
304
|
+
|
305
|
+
bool XdsResolver::XdsConfigSelector::Route::operator==(
|
306
|
+
const Route& other) const {
|
307
|
+
return route == other.route &&
|
308
|
+
weighted_cluster_state == other.weighted_cluster_state &&
|
309
|
+
MethodConfigsEqual(method_config.get(), other.method_config.get());
|
310
|
+
}
|
311
|
+
|
263
312
|
//
|
264
313
|
// XdsResolver::XdsConfigSelector
|
265
314
|
//
|
266
315
|
|
267
316
|
XdsResolver::XdsConfigSelector::XdsConfigSelector(
|
268
|
-
RefCountedPtr<XdsResolver> resolver,
|
269
|
-
const std::vector<XdsApi::Route>& routes, grpc_error* error)
|
317
|
+
RefCountedPtr<XdsResolver> resolver, grpc_error** error)
|
270
318
|
: resolver_(std::move(resolver)) {
|
271
319
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
272
320
|
gpr_log(GPR_INFO, "[xds_resolver %p] creating XdsConfigSelector %p",
|
@@ -281,8 +329,8 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
|
|
281
329
|
// weighted_cluster_state field points to the memory in the route field, so
|
282
330
|
// moving the entry in a reallocation will cause the string_view to point to
|
283
331
|
// invalid data.
|
284
|
-
route_table_.reserve(routes.size());
|
285
|
-
for (auto& route : routes) {
|
332
|
+
route_table_.reserve(resolver_->current_virtual_host_.routes.size());
|
333
|
+
for (auto& route : resolver_->current_virtual_host_.routes) {
|
286
334
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
287
335
|
gpr_log(GPR_INFO, "[xds_resolver %p] XdsConfigSelector %p: route: %s",
|
288
336
|
resolver_.get(), this, route.ToString().c_str());
|
@@ -294,27 +342,95 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
|
|
294
342
|
// one.
|
295
343
|
if (!route.max_stream_duration.has_value()) {
|
296
344
|
route_entry.route.max_stream_duration =
|
297
|
-
resolver_->
|
345
|
+
resolver_->current_listener_.http_connection_manager
|
346
|
+
.http_max_stream_duration;
|
298
347
|
}
|
299
|
-
error = CreateMethodConfig(&route_entry.method_config, route_entry.route);
|
300
348
|
if (route.weighted_clusters.empty()) {
|
349
|
+
*error = CreateMethodConfig(route_entry.route, nullptr,
|
350
|
+
&route_entry.method_config);
|
301
351
|
MaybeAddCluster(route.cluster_name);
|
302
352
|
} else {
|
303
353
|
uint32_t end = 0;
|
304
354
|
for (const auto& weighted_cluster : route_entry.route.weighted_clusters) {
|
305
|
-
|
355
|
+
Route::ClusterWeightState cluster_weight_state;
|
356
|
+
*error = CreateMethodConfig(route_entry.route, &weighted_cluster,
|
357
|
+
&cluster_weight_state.method_config);
|
358
|
+
if (*error != GRPC_ERROR_NONE) return;
|
306
359
|
end += weighted_cluster.weight;
|
307
|
-
|
308
|
-
|
360
|
+
cluster_weight_state.range_end = end;
|
361
|
+
cluster_weight_state.cluster = weighted_cluster.name;
|
362
|
+
route_entry.weighted_cluster_state.push_back(
|
363
|
+
std::move(cluster_weight_state));
|
364
|
+
MaybeAddCluster(weighted_cluster.name);
|
309
365
|
}
|
310
366
|
}
|
311
367
|
}
|
368
|
+
// Populate filter list.
|
369
|
+
bool found_router = false;
|
370
|
+
for (const auto& http_filter :
|
371
|
+
resolver_->current_listener_.http_connection_manager.http_filters) {
|
372
|
+
// Stop at the router filter. It's a no-op for us, and we ignore
|
373
|
+
// anything that may come after it, for compatibility with Envoy.
|
374
|
+
if (http_filter.config.config_proto_type_name ==
|
375
|
+
kXdsHttpRouterFilterConfigName) {
|
376
|
+
found_router = true;
|
377
|
+
break;
|
378
|
+
}
|
379
|
+
// Find filter. This is guaranteed to succeed, because it's checked
|
380
|
+
// at config validation time in the XdsApi code.
|
381
|
+
const XdsHttpFilterImpl* filter_impl =
|
382
|
+
XdsHttpFilterRegistry::GetFilterForType(
|
383
|
+
http_filter.config.config_proto_type_name);
|
384
|
+
GPR_ASSERT(filter_impl != nullptr);
|
385
|
+
// Add C-core filter to list.
|
386
|
+
filters_.push_back(filter_impl->channel_filter());
|
387
|
+
}
|
388
|
+
// For compatibility with Envoy, if the router filter is not
|
389
|
+
// configured, we fail all RPCs.
|
390
|
+
if (!found_router) {
|
391
|
+
filter_error_ =
|
392
|
+
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
393
|
+
"no xDS HTTP router filter configured"),
|
394
|
+
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
|
395
|
+
filters_.push_back(&grpc_lame_filter);
|
396
|
+
}
|
397
|
+
}
|
398
|
+
|
399
|
+
XdsResolver::XdsConfigSelector::~XdsConfigSelector() {
|
400
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
401
|
+
gpr_log(GPR_INFO, "[xds_resolver %p] destroying XdsConfigSelector %p",
|
402
|
+
resolver_.get(), this);
|
403
|
+
}
|
404
|
+
clusters_.clear();
|
405
|
+
resolver_->MaybeRemoveUnusedClusters();
|
406
|
+
GRPC_ERROR_UNREF(filter_error_);
|
407
|
+
}
|
408
|
+
|
409
|
+
const XdsHttpFilterImpl::FilterConfig* FindFilterConfigOverride(
|
410
|
+
const std::string& instance_name,
|
411
|
+
const XdsApi::RdsUpdate::VirtualHost& vhost, const XdsApi::Route& route,
|
412
|
+
const XdsApi::Route::ClusterWeight* cluster_weight) {
|
413
|
+
// Check ClusterWeight, if any.
|
414
|
+
if (cluster_weight != nullptr) {
|
415
|
+
auto it = cluster_weight->typed_per_filter_config.find(instance_name);
|
416
|
+
if (it != cluster_weight->typed_per_filter_config.end()) return &it->second;
|
417
|
+
}
|
418
|
+
// Check Route.
|
419
|
+
auto it = route.typed_per_filter_config.find(instance_name);
|
420
|
+
if (it != route.typed_per_filter_config.end()) return &it->second;
|
421
|
+
// Check VirtualHost.
|
422
|
+
it = vhost.typed_per_filter_config.find(instance_name);
|
423
|
+
if (it != vhost.typed_per_filter_config.end()) return &it->second;
|
424
|
+
// Not found.
|
425
|
+
return nullptr;
|
312
426
|
}
|
313
427
|
|
314
428
|
grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig(
|
315
|
-
|
316
|
-
|
429
|
+
const XdsApi::Route& route,
|
430
|
+
const XdsApi::Route::ClusterWeight* cluster_weight,
|
431
|
+
RefCountedPtr<ServiceConfig>* method_config) {
|
317
432
|
std::vector<std::string> fields;
|
433
|
+
// Set timeout.
|
318
434
|
if (route.max_stream_duration.has_value() &&
|
319
435
|
(route.max_stream_duration->seconds != 0 ||
|
320
436
|
route.max_stream_duration->nanos != 0)) {
|
@@ -322,6 +438,51 @@ grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig(
|
|
322
438
|
route.max_stream_duration->seconds,
|
323
439
|
route.max_stream_duration->nanos));
|
324
440
|
}
|
441
|
+
// Handle xDS HTTP filters.
|
442
|
+
std::map<std::string, std::vector<std::string>> per_filter_configs;
|
443
|
+
grpc_channel_args* args = grpc_channel_args_copy(resolver_->args_);
|
444
|
+
for (const auto& http_filter :
|
445
|
+
resolver_->current_listener_.http_connection_manager.http_filters) {
|
446
|
+
// Stop at the router filter. It's a no-op for us, and we ignore
|
447
|
+
// anything that may come after it, for compatibility with Envoy.
|
448
|
+
if (http_filter.config.config_proto_type_name ==
|
449
|
+
kXdsHttpRouterFilterConfigName) {
|
450
|
+
break;
|
451
|
+
}
|
452
|
+
// Find filter. This is guaranteed to succeed, because it's checked
|
453
|
+
// at config validation time in the XdsApi code.
|
454
|
+
const XdsHttpFilterImpl* filter_impl =
|
455
|
+
XdsHttpFilterRegistry::GetFilterForType(
|
456
|
+
http_filter.config.config_proto_type_name);
|
457
|
+
GPR_ASSERT(filter_impl != nullptr);
|
458
|
+
// Allow filter to add channel args that may affect service config
|
459
|
+
// parsing.
|
460
|
+
args = filter_impl->ModifyChannelArgs(args);
|
461
|
+
// Find config override, if any.
|
462
|
+
const XdsHttpFilterImpl::FilterConfig* config_override =
|
463
|
+
FindFilterConfigOverride(http_filter.name,
|
464
|
+
resolver_->current_virtual_host_, route,
|
465
|
+
cluster_weight);
|
466
|
+
// Generate service config for filter.
|
467
|
+
auto method_config_field =
|
468
|
+
filter_impl->GenerateServiceConfig(http_filter.config, config_override);
|
469
|
+
if (!method_config_field.ok()) {
|
470
|
+
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
471
|
+
absl::StrCat("failed to generate method config for HTTP filter ",
|
472
|
+
http_filter.name, ": ",
|
473
|
+
method_config_field.status().ToString())
|
474
|
+
.c_str());
|
475
|
+
}
|
476
|
+
per_filter_configs[method_config_field->service_config_field_name]
|
477
|
+
.push_back(method_config_field->element);
|
478
|
+
}
|
479
|
+
for (const auto& p : per_filter_configs) {
|
480
|
+
fields.emplace_back(absl::StrCat(" \"", p.first, "\": [\n",
|
481
|
+
absl::StrJoin(p.second, ",\n"),
|
482
|
+
"\n ]"));
|
483
|
+
}
|
484
|
+
// Construct service config.
|
485
|
+
grpc_error* error = GRPC_ERROR_NONE;
|
325
486
|
if (!fields.empty()) {
|
326
487
|
std::string json = absl::StrCat(
|
327
488
|
"{\n"
|
@@ -333,19 +494,20 @@ grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig(
|
|
333
494
|
absl::StrJoin(fields, ",\n"),
|
334
495
|
"\n } ]\n"
|
335
496
|
"}");
|
336
|
-
*method_config =
|
337
|
-
ServiceConfig::Create(resolver_->args_, json.c_str(), &error);
|
497
|
+
*method_config = ServiceConfig::Create(args, json.c_str(), &error);
|
338
498
|
}
|
499
|
+
grpc_channel_args_destroy(args);
|
339
500
|
return error;
|
340
501
|
}
|
341
502
|
|
342
|
-
XdsResolver::XdsConfigSelector
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
503
|
+
grpc_channel_args* XdsResolver::XdsConfigSelector::ModifyChannelArgs(
|
504
|
+
grpc_channel_args* args) {
|
505
|
+
if (filter_error_ == GRPC_ERROR_NONE) return args;
|
506
|
+
grpc_arg error_arg = MakeLameClientErrorArg(filter_error_);
|
507
|
+
grpc_channel_args* new_args =
|
508
|
+
grpc_channel_args_copy_and_add(args, &error_arg, 1);
|
509
|
+
grpc_channel_args_destroy(args);
|
510
|
+
return new_args;
|
349
511
|
}
|
350
512
|
|
351
513
|
void XdsResolver::XdsConfigSelector::MaybeAddCluster(const std::string& name) {
|
@@ -361,56 +523,52 @@ void XdsResolver::XdsConfigSelector::MaybeAddCluster(const std::string& name) {
|
|
361
523
|
}
|
362
524
|
}
|
363
525
|
|
364
|
-
absl::optional<absl::string_view>
|
365
|
-
|
526
|
+
absl::optional<absl::string_view> GetHeaderValue(
|
527
|
+
grpc_metadata_batch* initial_metadata, absl::string_view header_name,
|
366
528
|
std::string* concatenated_value) {
|
367
|
-
// Find all values for the specified key.
|
368
|
-
GPR_DEBUG_ASSERT(initial_metadata != nullptr);
|
369
|
-
absl::InlinedVector<absl::string_view, 1> values;
|
370
|
-
for (grpc_linked_mdelem* md = initial_metadata->list.head; md != nullptr;
|
371
|
-
md = md->next) {
|
372
|
-
absl::string_view key = StringViewFromSlice(GRPC_MDKEY(md->md));
|
373
|
-
absl::string_view value = StringViewFromSlice(GRPC_MDVALUE(md->md));
|
374
|
-
if (target_key == key) values.push_back(value);
|
375
|
-
}
|
376
|
-
// If none found, no match.
|
377
|
-
if (values.empty()) return absl::nullopt;
|
378
|
-
// If exactly one found, return it as-is.
|
379
|
-
if (values.size() == 1) return values.front();
|
380
|
-
// If more than one found, concatenate the values, using
|
381
|
-
// *concatenated_values as a temporary holding place for the
|
382
|
-
// concatenated string.
|
383
|
-
*concatenated_value = absl::StrJoin(values, ",");
|
384
|
-
return *concatenated_value;
|
385
|
-
}
|
386
|
-
|
387
|
-
bool HeaderMatchHelper(const HeaderMatcher& header_matcher,
|
388
|
-
grpc_metadata_batch* initial_metadata) {
|
389
|
-
std::string concatenated_value;
|
390
|
-
absl::optional<absl::string_view> value;
|
391
529
|
// Note: If we ever allow binary headers here, we still need to
|
392
530
|
// special-case ignore "grpc-tags-bin" and "grpc-trace-bin", since
|
393
531
|
// they are not visible to the LB policy in grpc-go.
|
394
|
-
if (absl::EndsWith(
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
value = "application/grpc";
|
399
|
-
} else {
|
400
|
-
value = GetMetadataValue(header_matcher.name(), initial_metadata,
|
401
|
-
&concatenated_value);
|
532
|
+
if (absl::EndsWith(header_name, "-bin")) {
|
533
|
+
return absl::nullopt;
|
534
|
+
} else if (header_name == "content-type") {
|
535
|
+
return "application/grpc";
|
402
536
|
}
|
403
|
-
return
|
537
|
+
return grpc_metadata_batch_get_value(initial_metadata, header_name,
|
538
|
+
concatenated_value);
|
404
539
|
}
|
405
540
|
|
406
541
|
bool HeadersMatch(const std::vector<HeaderMatcher>& header_matchers,
|
407
542
|
grpc_metadata_batch* initial_metadata) {
|
408
543
|
for (const auto& header_matcher : header_matchers) {
|
409
|
-
|
544
|
+
std::string concatenated_value;
|
545
|
+
if (!header_matcher.Match(GetHeaderValue(
|
546
|
+
initial_metadata, header_matcher.name(), &concatenated_value))) {
|
547
|
+
return false;
|
548
|
+
}
|
410
549
|
}
|
411
550
|
return true;
|
412
551
|
}
|
413
552
|
|
553
|
+
absl::optional<uint64_t> HeaderHashHelper(
|
554
|
+
const XdsApi::Route::HashPolicy& policy,
|
555
|
+
grpc_metadata_batch* initial_metadata) {
|
556
|
+
GPR_ASSERT(policy.type == XdsApi::Route::HashPolicy::HEADER);
|
557
|
+
std::string value_buffer;
|
558
|
+
absl::optional<absl::string_view> header_value =
|
559
|
+
GetHeaderValue(initial_metadata, policy.header_name, &value_buffer);
|
560
|
+
if (policy.regex != nullptr) {
|
561
|
+
// If GetHeaderValue() did not already store the value in
|
562
|
+
// value_buffer, copy it there now, so we can modify it.
|
563
|
+
if (header_value->data() != value_buffer.data()) {
|
564
|
+
value_buffer = std::string(*header_value);
|
565
|
+
}
|
566
|
+
RE2::GlobalReplace(&value_buffer, *policy.regex, policy.regex_substitution);
|
567
|
+
header_value = value_buffer;
|
568
|
+
}
|
569
|
+
return XXH64(header_value->data(), header_value->size(), 0);
|
570
|
+
}
|
571
|
+
|
414
572
|
bool UnderFraction(const uint32_t fraction_per_million) {
|
415
573
|
// Generate a random number in [0, 1000000).
|
416
574
|
const uint32_t random_number = rand() % 1000000;
|
@@ -437,13 +595,15 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
|
|
437
595
|
}
|
438
596
|
// Found a route match
|
439
597
|
absl::string_view cluster_name;
|
598
|
+
RefCountedPtr<ServiceConfig> method_config;
|
440
599
|
if (entry.route.weighted_clusters.empty()) {
|
441
600
|
cluster_name = entry.route.cluster_name;
|
601
|
+
method_config = entry.method_config;
|
442
602
|
} else {
|
443
603
|
const uint32_t key =
|
444
604
|
rand() %
|
445
605
|
entry.weighted_cluster_state[entry.weighted_cluster_state.size() - 1]
|
446
|
-
.
|
606
|
+
.range_end;
|
447
607
|
// Find the index in weighted clusters corresponding to key.
|
448
608
|
size_t mid = 0;
|
449
609
|
size_t start_index = 0;
|
@@ -451,9 +611,9 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
|
|
451
611
|
size_t index = 0;
|
452
612
|
while (end_index > start_index) {
|
453
613
|
mid = (start_index + end_index) / 2;
|
454
|
-
if (entry.weighted_cluster_state[mid].
|
614
|
+
if (entry.weighted_cluster_state[mid].range_end > key) {
|
455
615
|
end_index = mid;
|
456
|
-
} else if (entry.weighted_cluster_state[mid].
|
616
|
+
} else if (entry.weighted_cluster_state[mid].range_end < key) {
|
457
617
|
start_index = mid + 1;
|
458
618
|
} else {
|
459
619
|
index = mid + 1;
|
@@ -461,21 +621,56 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
|
|
461
621
|
}
|
462
622
|
}
|
463
623
|
if (index == 0) index = start_index;
|
464
|
-
GPR_ASSERT(entry.weighted_cluster_state[index].
|
465
|
-
cluster_name = entry.weighted_cluster_state[index].
|
624
|
+
GPR_ASSERT(entry.weighted_cluster_state[index].range_end > key);
|
625
|
+
cluster_name = entry.weighted_cluster_state[index].cluster;
|
626
|
+
method_config = entry.weighted_cluster_state[index].method_config;
|
466
627
|
}
|
467
628
|
auto it = clusters_.find(cluster_name);
|
468
629
|
GPR_ASSERT(it != clusters_.end());
|
469
630
|
XdsResolver* resolver =
|
470
631
|
static_cast<XdsResolver*>(resolver_->Ref().release());
|
471
632
|
ClusterState* cluster_state = it->second->Ref().release();
|
633
|
+
// Generate a hash
|
634
|
+
absl::optional<uint64_t> hash;
|
635
|
+
for (const auto& hash_policy : entry.route.hash_policies) {
|
636
|
+
absl::optional<uint64_t> new_hash;
|
637
|
+
switch (hash_policy.type) {
|
638
|
+
case XdsApi::Route::HashPolicy::HEADER:
|
639
|
+
new_hash = HeaderHashHelper(hash_policy, args.initial_metadata);
|
640
|
+
break;
|
641
|
+
case XdsApi::Route::HashPolicy::CHANNEL_ID:
|
642
|
+
new_hash =
|
643
|
+
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(resolver));
|
644
|
+
break;
|
645
|
+
default:
|
646
|
+
GPR_ASSERT(0);
|
647
|
+
}
|
648
|
+
if (new_hash.has_value()) {
|
649
|
+
// Rotating the old value prevents duplicate hash rules from cancelling
|
650
|
+
// each other out and preserves all of the entropy
|
651
|
+
const uint64_t old_value =
|
652
|
+
hash.has_value() ? ((hash.value() << 1) | (hash.value() >> 63)) : 0;
|
653
|
+
hash = old_value ^ new_hash.value();
|
654
|
+
}
|
655
|
+
// If the policy is a terminal policy and a hash has been generated,
|
656
|
+
// ignore the rest of the hash policies.
|
657
|
+
if (hash_policy.terminal && hash.has_value()) {
|
658
|
+
break;
|
659
|
+
}
|
660
|
+
}
|
661
|
+
if (!hash.has_value()) {
|
662
|
+
// If there is no hash, we just choose a random value as a default.
|
663
|
+
hash = rand();
|
664
|
+
}
|
472
665
|
CallConfig call_config;
|
473
|
-
if (
|
474
|
-
call_config.service_config = entry.method_config;
|
666
|
+
if (method_config != nullptr) {
|
475
667
|
call_config.method_configs =
|
476
|
-
|
668
|
+
method_config->GetMethodParsedConfigVector(grpc_empty_slice());
|
669
|
+
call_config.service_config = std::move(method_config);
|
477
670
|
}
|
478
671
|
call_config.call_attributes[kXdsClusterAttribute] = it->first;
|
672
|
+
call_config.call_attributes[kRequestRingHashAttribute] =
|
673
|
+
absl::StrFormat("%" PRIu64, hash.value());
|
479
674
|
call_config.on_call_committed = [resolver, cluster_state]() {
|
480
675
|
cluster_state->Unref();
|
481
676
|
ExecCtx::Run(
|
@@ -563,24 +758,34 @@ void XdsResolver::OnListenerUpdate(XdsApi::LdsUpdate listener) {
|
|
563
758
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
564
759
|
gpr_log(GPR_INFO, "[xds_resolver %p] received updated listener data", this);
|
565
760
|
}
|
566
|
-
if (listener.route_config_name !=
|
761
|
+
if (listener.http_connection_manager.route_config_name !=
|
762
|
+
route_config_name_) {
|
567
763
|
if (route_config_watcher_ != nullptr) {
|
568
764
|
xds_client_->CancelRouteConfigDataWatch(
|
569
765
|
route_config_name_, route_config_watcher_,
|
570
|
-
/*delay_unsubscription
|
766
|
+
/*delay_unsubscription=*/
|
767
|
+
!listener.http_connection_manager.route_config_name.empty());
|
571
768
|
route_config_watcher_ = nullptr;
|
572
769
|
}
|
573
|
-
route_config_name_ =
|
770
|
+
route_config_name_ =
|
771
|
+
std::move(listener.http_connection_manager.route_config_name);
|
574
772
|
if (!route_config_name_.empty()) {
|
773
|
+
current_virtual_host_.routes.clear();
|
575
774
|
auto watcher = absl::make_unique<RouteConfigWatcher>(Ref());
|
576
775
|
route_config_watcher_ = watcher.get();
|
577
776
|
xds_client_->WatchRouteConfigData(route_config_name_, std::move(watcher));
|
578
777
|
}
|
579
778
|
}
|
580
|
-
|
779
|
+
current_listener_ = std::move(listener);
|
581
780
|
if (route_config_name_.empty()) {
|
582
|
-
GPR_ASSERT(
|
583
|
-
|
781
|
+
GPR_ASSERT(
|
782
|
+
current_listener_.http_connection_manager.rds_update.has_value());
|
783
|
+
OnRouteConfigUpdate(
|
784
|
+
std::move(*current_listener_.http_connection_manager.rds_update));
|
785
|
+
} else {
|
786
|
+
// HCM may contain newer filter config. We need to propagate the update as
|
787
|
+
// config selector to the channel
|
788
|
+
GenerateResult();
|
584
789
|
}
|
585
790
|
}
|
586
791
|
|
@@ -598,8 +803,8 @@ void XdsResolver::OnRouteConfigUpdate(XdsApi::RdsUpdate rds_update) {
|
|
598
803
|
.c_str()));
|
599
804
|
return;
|
600
805
|
}
|
601
|
-
// Save the
|
602
|
-
|
806
|
+
// Save the virtual host in the resolver.
|
807
|
+
current_virtual_host_ = std::move(*vhost);
|
603
808
|
// Send a new result to the channel.
|
604
809
|
GenerateResult();
|
605
810
|
}
|
@@ -618,7 +823,7 @@ void XdsResolver::OnResourceDoesNotExist() {
|
|
618
823
|
"[xds_resolver %p] LDS/RDS resource does not exist -- clearing "
|
619
824
|
"update and returning empty service config",
|
620
825
|
this);
|
621
|
-
|
826
|
+
current_virtual_host_.routes.clear();
|
622
827
|
Result result;
|
623
828
|
result.service_config =
|
624
829
|
ServiceConfig::Create(args_, "{}", &result.service_config_error);
|
@@ -660,12 +865,11 @@ grpc_error* XdsResolver::CreateServiceConfig(
|
|
660
865
|
}
|
661
866
|
|
662
867
|
void XdsResolver::GenerateResult() {
|
663
|
-
if (
|
868
|
+
if (current_virtual_host_.routes.empty()) return;
|
664
869
|
// First create XdsConfigSelector, which may add new entries to the cluster
|
665
870
|
// state map, and then CreateServiceConfig for LB policies.
|
666
871
|
grpc_error* error = GRPC_ERROR_NONE;
|
667
|
-
auto config_selector =
|
668
|
-
MakeRefCounted<XdsConfigSelector>(Ref(), current_update_, error);
|
872
|
+
auto config_selector = MakeRefCounted<XdsConfigSelector>(Ref(), &error);
|
669
873
|
if (error != GRPC_ERROR_NONE) {
|
670
874
|
OnError(error);
|
671
875
|
return;
|