xDS stateful session affinity: implement C-core filter (#31788)

* stateful session affinity: implement filter

* register filter config parser

* fix unused parameter errors

* remove some FIXMEs that are not longer needed

* clang-tidy

* iwyu

* iwyu

* revert iwyu changes to observability_logging_sink.cc

* generate_projects

* shorten filter name

* don't use absl::optional for path

* fix build

* don't add cookie to trailing metadata unless it's Trailers-Only
pull/31793/head^2
Mark D. Roth 2 years ago committed by GitHub
parent 1bfc50f27e
commit 5e4d9f4bcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      BUILD
  2. 2
      CMakeLists.txt
  3. 4
      Makefile
  4. 4
      build_autogenerated.yaml
  5. 3
      config.m4
  6. 3
      config.w32
  7. 4
      gRPC-C++.podspec
  8. 6
      gRPC-Core.podspec
  9. 4
      grpc.gemspec
  10. 2
      grpc.gyp
  11. 4
      package.xml
  12. 52
      src/core/BUILD
  13. 1
      src/core/ext/filters/client_channel/config_selector.h
  14. 1
      src/core/ext/filters/client_channel/lb_policy/priority/priority.cc
  15. 1
      src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
  16. 1
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
  17. 1
      src/core/ext/filters/client_channel/subchannel.h
  18. 4
      src/core/ext/filters/http/message_compress/compression_filter.cc
  19. 3
      src/core/ext/filters/server_config_selector/server_config_selector.h
  20. 1
      src/core/ext/filters/server_config_selector/server_config_selector_filter.cc
  21. 230
      src/core/ext/filters/stateful_session/stateful_session_filter.cc
  22. 66
      src/core/ext/filters/stateful_session/stateful_session_filter.h
  23. 82
      src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc
  24. 93
      src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h
  25. 1
      src/core/ext/transport/chaotic_good/frame.cc
  26. 1
      src/core/ext/transport/chttp2/transport/flow_control.cc
  27. 1
      src/core/ext/transport/chttp2/transport/hpack_parser.cc
  28. 1
      src/core/ext/transport/chttp2/transport/parsing.cc
  29. 1
      src/core/ext/xds/xds_listener.cc
  30. 1
      src/core/ext/xds/xds_route_config.cc
  31. 2
      src/core/ext/xds/xds_server_config_fetcher.cc
  32. 4
      src/core/lib/event_engine/tcp_socket_utils.cc
  33. 8
      src/core/lib/service_config/service_config_call_data.h
  34. 11
      src/core/lib/transport/metadata_batch.h
  35. 2
      src/core/plugin_registry/grpc_plugin_registry_extra.cc
  36. 2
      src/cpp/common/core_codegen.cc
  37. 1
      src/cpp/ext/gcp/BUILD
  38. 1
      src/cpp/ext/gcp/observability_config.h
  39. 2
      src/cpp/ext/gcp/observability_logging_sink.h
  40. 2
      src/python/grpcio/grpc_core_dependencies.py
  41. 2
      test/core/client_channel/lb_policy/lb_policy_test_lib.h
  42. 7
      test/core/client_channel/lb_policy/outlier_detection_test.cc
  43. 11
      test/core/client_channel/lb_policy/pick_first_test.cc
  44. 1
      test/core/event_engine/BUILD
  45. 8
      test/core/event_engine/posix/tcp_posix_socket_utils_test.cc
  46. 4
      test/core/event_engine/posix/traced_buffer_list_test.cc
  47. 3
      test/core/event_engine/tcp_socket_utils_test.cc
  48. 1
      test/core/transport/chttp2/flow_control_test.cc
  49. 17
      test/core/xds/xds_client_fuzzer.cc
  50. 1
      test/core/xds/xds_route_config_resource_type_test.cc
  51. 4
      tools/doxygen/Doxyfile.c++.internal
  52. 4
      tools/doxygen/Doxyfile.core.internal

@ -528,6 +528,7 @@ GRPC_XDS_TARGETS = [
"//src/core:grpc_resolver_xds",
"//src/core:grpc_resolver_c2p",
"//src/core:grpc_xds_server_config_fetcher",
"//src/core:grpc_stateful_session_filter",
# Not xDS-specific but currently only used by xDS.
"//src/core:channel_creds_registry_init",
@ -3175,11 +3176,12 @@ grpc_cc_library(
"//src/core:channel_init",
"//src/core:channel_stack_type",
"//src/core:context",
"//src/core:for_each",
"//src/core:grpc_message_size_filter",
"//src/core:latch",
"//src/core:map_pipe",
"//src/core:percent_encoding",
"//src/core:pipe",
"//src/core:promise_like",
"//src/core:seq",
"//src/core:slice",
"//src/core:slice_buffer",

2
CMakeLists.txt generated

@ -1737,6 +1737,8 @@ add_library(grpc
src/core/ext/filters/rbac/rbac_filter.cc
src/core/ext/filters/rbac/rbac_service_config_parser.cc
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc
src/core/ext/filters/stateful_session/stateful_session_filter.cc
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc
src/core/ext/transport/chttp2/alpn/alpn.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
src/core/ext/transport/chttp2/server/chttp2_server.cc

4
Makefile generated

@ -1030,6 +1030,8 @@ LIBGRPC_SRC = \
src/core/ext/filters/rbac/rbac_filter.cc \
src/core/ext/filters/rbac/rbac_service_config_parser.cc \
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc \
src/core/ext/transport/chttp2/alpn/alpn.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
@ -2912,6 +2914,8 @@ src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc: $(OPENSSL_DEP)
src/core/ext/filters/rbac/rbac_filter.cc: $(OPENSSL_DEP)
src/core/ext/filters/rbac/rbac_service_config_parser.cc: $(OPENSSL_DEP)
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc: $(OPENSSL_DEP)
src/core/ext/filters/stateful_session/stateful_session_filter.cc: $(OPENSSL_DEP)
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/alpn/alpn.cc: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/admin/v3/certs.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.c: $(OPENSSL_DEP)

@ -372,6 +372,8 @@ libs:
- src/core/ext/filters/rbac/rbac_service_config_parser.h
- src/core/ext/filters/server_config_selector/server_config_selector.h
- src/core/ext/filters/server_config_selector/server_config_selector_filter.h
- src/core/ext/filters/stateful_session/stateful_session_filter.h
- src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h
- src/core/ext/transport/chttp2/alpn/alpn.h
- src/core/ext/transport/chttp2/client/chttp2_connector.h
- src/core/ext/transport/chttp2/server/chttp2_server.h
@ -1118,6 +1120,8 @@ libs:
- src/core/ext/filters/rbac/rbac_filter.cc
- src/core/ext/filters/rbac/rbac_service_config_parser.cc
- src/core/ext/filters/server_config_selector/server_config_selector_filter.cc
- src/core/ext/filters/stateful_session/stateful_session_filter.cc
- src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc
- src/core/ext/transport/chttp2/alpn/alpn.cc
- src/core/ext/transport/chttp2/client/chttp2_connector.cc
- src/core/ext/transport/chttp2/server/chttp2_server.cc

3
config.m4 generated

@ -112,6 +112,8 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/rbac/rbac_filter.cc \
src/core/ext/filters/rbac/rbac_service_config_parser.cc \
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc \
src/core/ext/transport/chttp2/alpn/alpn.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
@ -1248,6 +1250,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/message_size)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/rbac)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/server_config_selector)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/stateful_session)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/alpn)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server)

3
config.w32 generated

@ -78,6 +78,8 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\rbac\\rbac_filter.cc " +
"src\\core\\ext\\filters\\rbac\\rbac_service_config_parser.cc " +
"src\\core\\ext\\filters\\server_config_selector\\server_config_selector_filter.cc " +
"src\\core\\ext\\filters\\stateful_session\\stateful_session_filter.cc " +
"src\\core\\ext\\filters\\stateful_session\\stateful_session_service_config_parser.cc " +
"src\\core\\ext\\transport\\chttp2\\alpn\\alpn.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\chttp2_connector.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\chttp2_server.cc " +
@ -1246,6 +1248,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\rbac");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\server_config_selector");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\stateful_session");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\alpn");

4
gRPC-C++.podspec generated

@ -292,6 +292,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/rbac/rbac_service_config_parser.h',
'src/core/ext/filters/server_config_selector/server_config_selector.h',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h',
'src/core/ext/transport/binder/client/binder_connector.cc',
'src/core/ext/transport/binder/client/binder_connector.h',
'src/core/ext/transport/binder/client/channel_create.cc',
@ -1198,6 +1200,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/rbac/rbac_service_config_parser.h',
'src/core/ext/filters/server_config_selector/server_config_selector.h',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h',
'src/core/ext/transport/binder/client/binder_connector.h',
'src/core/ext/transport/binder/client/channel_create_impl.h',
'src/core/ext/transport/binder/client/connection_id_generator.h',

6
gRPC-Core.podspec generated

@ -326,6 +326,10 @@ Pod::Spec.new do |s|
'src/core/ext/filters/server_config_selector/server_config_selector.h',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.cc',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_filter.cc',
'src/core/ext/filters/stateful_session/stateful_session_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h',
'src/core/ext/transport/chttp2/alpn/alpn.cc',
'src/core/ext/transport/chttp2/alpn/alpn.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
@ -1851,6 +1855,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/rbac/rbac_service_config_parser.h',
'src/core/ext/filters/server_config_selector/server_config_selector.h',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_filter.h',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h',
'src/core/ext/transport/chttp2/alpn/alpn.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',

4
grpc.gemspec generated

@ -237,6 +237,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/server_config_selector/server_config_selector.h )
s.files += %w( src/core/ext/filters/server_config_selector/server_config_selector_filter.cc )
s.files += %w( src/core/ext/filters/server_config_selector/server_config_selector_filter.h )
s.files += %w( src/core/ext/filters/stateful_session/stateful_session_filter.cc )
s.files += %w( src/core/ext/filters/stateful_session/stateful_session_filter.h )
s.files += %w( src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc )
s.files += %w( src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h )
s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.cc )
s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.cc )

2
grpc.gyp generated

@ -442,6 +442,8 @@
'src/core/ext/filters/rbac/rbac_filter.cc',
'src/core/ext/filters/rbac/rbac_service_config_parser.cc',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.cc',
'src/core/ext/filters/stateful_session/stateful_session_filter.cc',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc',
'src/core/ext/transport/chttp2/alpn/alpn.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',

4
package.xml generated

@ -219,6 +219,10 @@
<file baseinstalldir="/" name="src/core/ext/filters/server_config_selector/server_config_selector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/server_config_selector/server_config_selector_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/server_config_selector/server_config_selector_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/stateful_session/stateful_session_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/stateful_session/stateful_session_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.cc" role="src" />

@ -1903,7 +1903,6 @@ grpc_cc_library(
"absl/types:optional",
],
deps = [
"grpc_sockaddr",
"iomgr_port",
"status_helper",
"//:event_engine_base_hdrs",
@ -2393,7 +2392,6 @@ grpc_cc_library(
language = "c++",
deps = [
"dual_ref_counted",
"error",
"grpc_service_config",
"ref_counted",
"service_config_parser",
@ -2425,7 +2423,6 @@ grpc_cc_library(
"channel_args",
"channel_fwd",
"context",
"error",
"grpc_server_config_selector",
"grpc_service_config",
"status_helper",
@ -3350,6 +3347,49 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_stateful_session_filter",
srcs = [
"ext/filters/stateful_session/stateful_session_filter.cc",
"ext/filters/stateful_session/stateful_session_service_config_parser.cc",
],
hdrs = [
"ext/filters/stateful_session/stateful_session_filter.h",
"ext/filters/stateful_session/stateful_session_service_config_parser.h",
],
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
],
language = "c++",
deps = [
"arena",
"arena_promise",
"basic_seq",
"channel_args",
"channel_fwd",
"context",
"grpc_service_config",
"json",
"json_args",
"json_object_loader",
"latch",
"seq",
"service_config_parser",
"slice",
"time",
"try_concurrently",
"unique_type_name",
"validation_errors",
"//:config",
"//:gpr",
"//:grpc_base",
"//:grpc_trace",
],
)
grpc_cc_library(
name = "grpc_lb_policy_grpclb",
srcs = [
@ -3717,7 +3757,6 @@ grpc_cc_library(
"channel_args",
"channel_args_preconditioning",
"channel_fwd",
"error",
"grpc_server_config_selector",
"grpc_server_config_selector_filter",
"grpc_service_config",
@ -3729,7 +3768,6 @@ grpc_cc_library(
"match",
"resolved_address",
"slice_refcount",
"status_helper",
"unique_type_name",
"//:config",
"//:debug_location",
@ -3963,7 +4001,6 @@ grpc_cc_library(
"lb_policy_factory",
"lb_policy_registry",
"pollset_set",
"ref_counted",
"subchannel_interface",
"time",
"validation_errors",
@ -4250,7 +4287,6 @@ grpc_cc_library(
"lb_policy_factory",
"lb_policy_registry",
"pollset_set",
"ref_counted",
"subchannel_interface",
"time",
"validation_errors",
@ -4291,7 +4327,6 @@ grpc_cc_library(
"lb_policy_factory",
"lb_policy_registry",
"pollset_set",
"ref_counted",
"subchannel_interface",
"time",
"validation_errors",
@ -4888,6 +4923,7 @@ grpc_cc_library(
"//:gpr",
"//:gpr_platform",
"//:grpc_base",
"//:grpc_public_hdrs",
"//:hpack_encoder",
"//:hpack_parser",
],

@ -31,7 +31,6 @@
#include <grpc/slice.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/ref_counted.h"

@ -45,7 +45,6 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/validation_errors.h"

@ -45,7 +45,6 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/validation_errors.h"

@ -44,7 +44,6 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/validation_errors.h"

@ -21,7 +21,6 @@
#include <stddef.h>
#include <deque>
#include <functional>
#include <map>
#include <memory>

@ -18,7 +18,6 @@
#include <inttypes.h>
#include <cstdint>
#include <functional>
#include <memory>
#include <utility>
@ -43,9 +42,10 @@
#include "src/core/lib/compression/message_compress.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/for_each.h"
#include "src/core/lib/promise/detail/promise_like.h"
#include "src/core/lib/promise/latch.h"
#include "src/core/lib/promise/map_pipe.h"
#include "src/core/lib/promise/pipe.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/try_concurrently.h"

@ -24,13 +24,10 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/dual_ref_counted.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/service_config/service_config_parser.h"
#include "src/core/lib/transport/metadata_batch.h"

@ -34,7 +34,6 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/promise/arena_promise.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/promise.h"

@ -0,0 +1,230 @@
//
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/stateful_session/stateful_session_filter.h"
#include <string.h>
#include <algorithm>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include <grpc/impl/codegen/gpr_types.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/detail/basic_seq.h"
#include "src/core/lib/promise/latch.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/try_concurrently.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/service_config/service_config_call_data.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
TraceFlag grpc_stateful_session_filter_trace(false, "stateful_session_filter");
UniqueTypeName XdsHostOverrideTypeName() {
static UniqueTypeName::Factory kFactory("xds_host_override");
return kFactory.Create();
}
const grpc_channel_filter StatefulSessionFilter::kFilter =
MakePromiseBasedFilter<StatefulSessionFilter, FilterEndpoint::kClient>(
"stateful_session_filter");
absl::StatusOr<StatefulSessionFilter> StatefulSessionFilter::Create(
const ChannelArgs&, ChannelFilter::Args filter_args) {
return StatefulSessionFilter(filter_args);
}
StatefulSessionFilter::StatefulSessionFilter(ChannelFilter::Args filter_args)
: index_(grpc_channel_stack_filter_instance_number(
filter_args.channel_stack(),
filter_args.uninitialized_channel_element())),
service_config_parser_index_(
StatefulSessionServiceConfigParser::ParserIndex()) {}
namespace {
// Adds the set-cookie header to the server initial metadata if needed.
void MaybeUpdateServerInitialMetadata(
const StatefulSessionMethodParsedConfig::CookieConfig* cookie_config,
absl::optional<absl::string_view> cookie_value,
ServerMetadata* server_initial_metadata) {
// Get peer string.
auto peer_string = server_initial_metadata->get(PeerString());
if (!peer_string.has_value()) return; // Nothing we can do.
// If there was no cookie or if the address changed, set the cookie.
if (!cookie_value.has_value() || *peer_string != *cookie_value) {
std::vector<std::string> parts = {
absl::StrCat(*cookie_config->name, "=",
absl::Base64Escape(*peer_string), "; HttpOnly")};
if (!cookie_config->path.empty()) {
parts.emplace_back(absl::StrCat("Path=", cookie_config->path));
}
if (cookie_config->ttl > Duration::Zero()) {
parts.emplace_back(
absl::StrCat("Max-Age=", cookie_config->ttl.as_timespec().tv_sec));
}
server_initial_metadata->Append(
"set-cookie", Slice::FromCopiedString(absl::StrJoin(parts, "; ")),
[](absl::string_view error, const Slice&) {
gpr_log(GPR_ERROR, "ERROR ADDING set-cookie METADATA: %s",
std::string(error).c_str());
GPR_ASSERT(false);
});
}
}
} // namespace
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> StatefulSessionFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
// Get config.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
GPR_ASSERT(service_config_call_data != nullptr);
auto* method_params = static_cast<StatefulSessionMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
service_config_parser_index_));
GPR_ASSERT(method_params != nullptr);
auto* cookie_config = method_params->GetConfig(index_);
GPR_ASSERT(cookie_config != nullptr);
if (!cookie_config->name.has_value()) {
return next_promise_factory(std::move(call_args));
}
// We have a config.
// If the config has a path, check to see if it matches the request path.
if (!cookie_config->path.empty()) {
Slice* path_slice =
call_args.client_initial_metadata->get_pointer(HttpPathMetadata());
GPR_ASSERT(path_slice != nullptr);
absl::string_view path = path_slice->as_string_view();
// Matching criteria from
// https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4.
if (!absl::StartsWith(path, cookie_config->path) ||
(path.size() != cookie_config->path.size() &&
cookie_config->path.back() != '/' &&
path[cookie_config->path.size() + 1] != '/')) {
return next_promise_factory(std::move(call_args));
}
}
// Check to see if we have a host override cookie.
auto cookie_value = GetHostOverrideFromCookie(
call_args.client_initial_metadata, *cookie_config->name);
if (cookie_value.has_value()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_stateful_session_filter_trace)) {
gpr_log(GPR_INFO,
"chand=%p: stateful session filter found cookie %s value %s",
this, cookie_config->name->c_str(),
std::string(*cookie_value).c_str());
}
// We have a valid cookie, so add the call attribute to be used by the
// xds_override_host LB policy.
service_config_call_data->SetCallAttribute(XdsHostOverrideTypeName(),
*cookie_value);
}
// Intercept server initial metadata.
auto* read_latch = GetContext<Arena>()->New<Latch<ServerMetadata*>>();
auto* write_latch =
std::exchange(call_args.server_initial_metadata, read_latch);
return TryConcurrently(
Seq(next_promise_factory(std::move(call_args)),
[cookie_config, cookie_value](ServerMetadataHandle md) {
// If we got a Trailers-Only response, then add the
// cookie to the trailing metadata instead of the
// initial metadata.
if (md->get(GrpcTrailersOnly()).value_or(false)) {
MaybeUpdateServerInitialMetadata(cookie_config,
cookie_value, md.get());
}
return md;
}))
.NecessaryPull(Seq(read_latch->Wait(),
[write_latch, cookie_config,
cookie_value](ServerMetadata** md) -> absl::Status {
if (*md != nullptr) {
// Add cookie to server initial metadata if needed.
MaybeUpdateServerInitialMetadata(
cookie_config, cookie_value, *md);
}
write_latch->Set(*md);
return absl::OkStatus();
}));
}
absl::optional<absl::string_view>
StatefulSessionFilter::GetHostOverrideFromCookie(
const ClientMetadataHandle& client_initial_metadata,
absl::string_view cookie_name) {
// Check to see if the cookie header is present.
std::string buffer;
auto header_value =
client_initial_metadata->GetStringValue("cookie", &buffer);
if (!header_value.has_value()) return absl::nullopt;
// Parse cookie header.
std::vector<absl::string_view> values;
for (absl::string_view cookie : absl::StrSplit(*header_value, "; ")) {
std::pair<absl::string_view, absl::string_view> kv =
absl::StrSplit(cookie, absl::MaxSplits('=', 1));
if (kv.first == cookie_name) values.push_back(kv.second);
}
if (values.empty()) return absl::nullopt;
// TODO(roth): Figure out the right behavior for multiple cookies.
// For now, just choose the first value.
absl::string_view value = values.front();
// Base64-decode it.
std::string decoded_value;
if (!absl::Base64Unescape(value, &decoded_value)) return absl::nullopt;
// Copy it into the arena, since it will need to persist until the LB pick.
char* arena_value =
static_cast<char*>(GetContext<Arena>()->Alloc(decoded_value.size()));
memcpy(arena_value, decoded_value.c_str(), decoded_value.size());
return absl::string_view(arena_value, decoded_value.size());
}
void StatefulSessionFilterRegister(CoreConfiguration::Builder* builder) {
StatefulSessionServiceConfigParser::Register(builder);
}
} // namespace grpc_core

@ -0,0 +1,66 @@
//
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_FILTER_H
#define GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_FILTER_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/channel/promise_based_filter.h"
#include "src/core/lib/gprpp/unique_type_name.h"
#include "src/core/lib/promise/arena_promise.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
UniqueTypeName XdsHostOverrideTypeName();
// A filter to provide cookie-based stateful session affinity.
class StatefulSessionFilter : public ChannelFilter {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<StatefulSessionFilter> Create(
const ChannelArgs& args, ChannelFilter::Args filter_args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
private:
explicit StatefulSessionFilter(ChannelFilter::Args filter_args);
absl::optional<absl::string_view> GetHostOverrideFromCookie(
const ClientMetadataHandle& initial_metadata,
absl::string_view cookie_name);
// The relative index of instances of the same filter.
const size_t index_;
// Index of the service config parser.
const size_t service_config_parser_index_;
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_FILTER_H

@ -0,0 +1,82 @@
//
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h"
#include <vector>
#include "absl/types/optional.h"
#include "src/core/lib/channel/channel_args.h"
namespace grpc_core {
const JsonLoaderInterface*
StatefulSessionMethodParsedConfig::CookieConfig::JsonLoader(const JsonArgs&) {
static const auto* loader = JsonObjectLoader<CookieConfig>()
.OptionalField("name", &CookieConfig::name)
.OptionalField("path", &CookieConfig::path)
.OptionalField("ttl", &CookieConfig::ttl)
.Finish();
return loader;
}
void StatefulSessionMethodParsedConfig::CookieConfig::JsonPostLoad(
const Json&, const JsonArgs&, ValidationErrors* errors) {
// Validate that cookie_name is non-empty.
if (name.has_value() && name->empty()) {
ValidationErrors::ScopedField field(errors, ".name");
errors->AddError("must be non-empty");
}
}
const JsonLoaderInterface* StatefulSessionMethodParsedConfig::JsonLoader(
const JsonArgs&) {
static const auto* loader =
JsonObjectLoader<StatefulSessionMethodParsedConfig>()
.OptionalField("stateful_session",
&StatefulSessionMethodParsedConfig::configs_)
.Finish();
return loader;
}
std::unique_ptr<ServiceConfigParser::ParsedConfig>
StatefulSessionServiceConfigParser::ParsePerMethodParams(
const ChannelArgs& args, const Json& json, ValidationErrors* errors) {
// Only parse config if the following channel arg is present.
if (!args.GetBool(GRPC_ARG_PARSE_STATEFUL_SESSION_METHOD_CONFIG)
.value_or(false)) {
return nullptr;
}
// Parse config from json.
return LoadFromJson<std::unique_ptr<StatefulSessionMethodParsedConfig>>(
json, JsonArgs(), errors);
}
void StatefulSessionServiceConfigParser::Register(
CoreConfiguration::Builder* builder) {
builder->service_config_parser()->RegisterParser(
std::make_unique<StatefulSessionServiceConfigParser>());
}
size_t StatefulSessionServiceConfigParser::ParserIndex() {
return CoreConfiguration::Get().service_config_parser().GetParserIndex(
parser_name());
}
} // namespace grpc_core

@ -0,0 +1,93 @@
//
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_SERVICE_CONFIG_PARSER_H
#define GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_SERVICE_CONFIG_PARSER_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/validation_errors.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/json/json_args.h"
#include "src/core/lib/json/json_object_loader.h"
#include "src/core/lib/service_config/service_config_parser.h"
// Channel arg key for enabling parsing fault injection via method config.
#define GRPC_ARG_PARSE_STATEFUL_SESSION_METHOD_CONFIG \
"grpc.internal.parse_stateful_session_method_config"
namespace grpc_core {
class StatefulSessionMethodParsedConfig
: public ServiceConfigParser::ParsedConfig {
public:
struct CookieConfig {
absl::optional<std::string> name; // Will be unset if disabled.
std::string path;
Duration ttl;
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
void JsonPostLoad(const Json&, const JsonArgs&, ValidationErrors* errors);
};
// Returns the config at the specified index. There might be multiple
// stateful session filters in the list of HTTP filters at the same time.
// The order of the list is stable, and an index is used to keep track of
// their relative positions. Each filter instance uses this method to
// access the appropriate parsed config for that instance.
const CookieConfig* GetConfig(size_t index) const {
if (index >= configs_.size()) return nullptr;
return &configs_[index];
}
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
private:
std::vector<CookieConfig> configs_;
};
class StatefulSessionServiceConfigParser final
: public ServiceConfigParser::Parser {
public:
absl::string_view name() const override { return parser_name(); }
// Parses the per-method service config for the filter.
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& args, const Json& json,
ValidationErrors* errors) override;
// Returns the parser index for the parser.
static size_t ParserIndex();
// Registers the parser.
static void Register(CoreConfiguration::Builder* builder);
private:
static absl::string_view parser_name() { return "stateful_session"; }
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_FILTERS_STATEFUL_SESSION_STATEFUL_SESSION_SERVICE_CONFIG_PARSER_H

@ -25,6 +25,7 @@
#include "absl/status/statusor.h"
#include <grpc/slice.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include "src/core/lib/gprpp/bitset.h"

@ -27,6 +27,7 @@
#include <cmath>
#include <ostream>
#include <string>
#include <tuple>
#include <vector>
#include "absl/strings/str_cat.h"

@ -26,7 +26,6 @@
#include <stdlib.h>
#include <algorithm>
#include <cinttypes>
#include <string>
#include <utility>

@ -598,6 +598,7 @@ static grpc_error_handle init_header_frame_parser(grpc_chttp2_transport* t,
*s->trailing_metadata_available = true;
}
s->parsed_trailers_only = true;
s->trailing_metadata_buffer.Set(grpc_core::GrpcTrailersOnly(), true);
incoming_metadata_buffer = &s->trailing_metadata_buffer;
frame_type = HPackParser::LogInfo::kTrailers;
} else {

@ -58,7 +58,6 @@
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/gprpp/validation_errors.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/matchers/matchers.h"
namespace grpc_core {

@ -68,6 +68,7 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/env.h"
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/load_balancing/lb_policy_registry.h"

@ -70,11 +70,9 @@
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/gprpp/unique_type_name.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr_fwd.h"
#include "src/core/lib/iomgr/resolved_address.h"

@ -24,11 +24,8 @@
#include <linux/tcp.h>
#else
#include <netinet/in.h> // IWYU pragma: keep
#include <netinet/tcp.h>
#endif
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>
#endif // GRPC_POSIX_SOCKET_UTILS_COMMON
#ifdef GRPC_HAVE_UNIX_SOCKET
@ -51,7 +48,6 @@
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_event_engine {

@ -65,6 +65,12 @@ class ServiceConfigCallData {
const CallAttributes& call_attributes() const { return call_attributes_; }
// Must be called when holding the call combiner (legacy filter) or from
// inside the activity (promise-based filter).
void SetCallAttribute(UniqueTypeName name, absl::string_view value) {
call_attributes_[name] = value;
}
private:
RefCountedPtr<ServiceConfig> service_config_;
const ServiceConfigParser::ParsedConfigVector* method_configs_;
@ -73,4 +79,4 @@ class ServiceConfigCallData {
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H */
#endif // GRPC_CORE_LIB_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H

@ -406,6 +406,15 @@ struct WaitForReady {
static std::string DisplayValue(ValueType x);
};
// Annotation added by a transport to note that server trailing metadata
// is a Trailers-Only response.
struct GrpcTrailersOnly {
static absl::string_view DebugKey() { return "GrpcTrailersOnly"; }
static constexpr bool kRepeatable = false;
using ValueType = bool;
static absl::string_view DisplayValue(bool x) { return x ? "true" : "false"; }
};
namespace metadata_detail {
// Build a key/value formatted debug string.
@ -1317,7 +1326,7 @@ using grpc_metadata_batch_base = grpc_core::MetadataMap<
// Non-encodable things
grpc_core::GrpcStreamNetworkState, grpc_core::PeerString,
grpc_core::GrpcStatusContext, grpc_core::GrpcStatusFromWire,
grpc_core::WaitForReady>;
grpc_core::WaitForReady, grpc_core::GrpcTrailersOnly>;
struct grpc_metadata_batch : public grpc_metadata_batch_base {
using grpc_metadata_batch_base::grpc_metadata_batch_base;

@ -24,6 +24,7 @@
namespace grpc_core {
#ifndef GRPC_NO_XDS
extern void RbacFilterRegister(CoreConfiguration::Builder* builder);
extern void StatefulSessionFilterRegister(CoreConfiguration::Builder* builder);
extern void RegisterXdsChannelStackModifier(
CoreConfiguration::Builder* builder);
extern void RegisterChannelDefaultCreds(CoreConfiguration::Builder* builder);
@ -48,6 +49,7 @@ void RegisterExtraFilters(CoreConfiguration::Builder* builder) {
// rbac_filter is being guarded with GRPC_NO_XDS to avoid a dependency on the
// re2 library by default
RbacFilterRegister(builder);
StatefulSessionFilterRegister(builder);
RegisterXdsChannelStackModifier(builder);
RegisterChannelDefaultCreds(builder);
RegisterXdsResolver(builder);

@ -27,9 +27,7 @@
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/status.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include <grpcpp/impl/codegen/core_codegen.h>
#include <grpcpp/support/status.h>

@ -102,6 +102,7 @@ grpc_cc_library(
"absl/strings:str_format",
"absl/types:optional",
"googleapis_logging_grpc_service",
"protobuf_headers",
],
language = "c++",
visibility = ["//test:__subpackages__"],

@ -19,6 +19,7 @@
#include <stdint.h>
#include <map>
#include <string>
#include <vector>

@ -27,6 +27,8 @@
#include <string>
#include <vector>
#include <google/protobuf/struct.pb.h>
#include "absl/strings/string_view.h"
#include "google/logging/v2/logging.grpc.pb.h"

@ -87,6 +87,8 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/rbac/rbac_filter.cc',
'src/core/ext/filters/rbac/rbac_service_config_parser.cc',
'src/core/ext/filters/server_config_selector/server_config_selector_filter.cc',
'src/core/ext/filters/stateful_session/stateful_session_filter.cc',
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc',
'src/core/ext/transport/chttp2/alpn/alpn.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',

@ -26,6 +26,7 @@
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
@ -36,6 +37,7 @@
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "absl/types/variant.h"
#include "gtest/gtest.h"

@ -19,27 +19,20 @@
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/resolved_address.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/load_balancing/lb_policy.h"
#include "src/core/lib/resolver/server_address.h"
#include "test/core/client_channel/lb_policy/lb_policy_test_lib.h"
#include "test/core/util/test_config.h"

@ -16,25 +16,16 @@
#include <stddef.h>
#include <algorithm>
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/iomgr/resolved_address.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/load_balancing/lb_policy.h"
#include "src/core/lib/resolver/server_address.h"
#include "test/core/client_channel/lb_policy/lb_policy_test_lib.h"
#include "test/core/util/test_config.h"

@ -176,6 +176,7 @@ grpc_cc_test(
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/strings",
"gtest",
],
language = "C++",

@ -16,12 +16,8 @@
#include <unistd.h>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/port.h"
@ -33,10 +29,6 @@
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
#endif
#include <grpc/support/alloc.h>

@ -19,7 +19,11 @@
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/port.h"

@ -19,6 +19,9 @@
#include <stdint.h>
#include <string.h>
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
// IWYU pragma: no_include <arpa/inet.h>
#include <string>

@ -15,6 +15,7 @@
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
#include <memory>
#include <tuple>
#include "gtest/gtest.h"

@ -14,8 +14,23 @@
// limitations under the License.
//
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_bootstrap_grpc.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_cluster.h"
@ -23,8 +38,10 @@
#include "src/core/ext/xds/xds_listener.h"
#include "src/core/ext/xds/xds_route_config.h"
#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/libfuzzer/libfuzzer_macro.h"
#include "src/proto/grpc/testing/xds/v3/discovery.pb.h"
#include "test/core/xds/xds_client_fuzzer.pb.h"
#include "test/core/xds/xds_transport_fake.h"

@ -44,7 +44,6 @@
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_bootstrap_grpc.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_route_config.h"
#include "src/core/lib/channel/status_util.h"

@ -1197,6 +1197,10 @@ src/core/ext/filters/rbac/rbac_service_config_parser.h \
src/core/ext/filters/server_config_selector/server_config_selector.h \
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc \
src/core/ext/filters/server_config_selector/server_config_selector_filter.h \
src/core/ext/filters/stateful_session/stateful_session_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_filter.h \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h \
src/core/ext/transport/binder/client/binder_connector.cc \
src/core/ext/transport/binder/client/binder_connector.h \
src/core/ext/transport/binder/client/channel_create.cc \

@ -1004,6 +1004,10 @@ src/core/ext/filters/rbac/rbac_service_config_parser.h \
src/core/ext/filters/server_config_selector/server_config_selector.h \
src/core/ext/filters/server_config_selector/server_config_selector_filter.cc \
src/core/ext/filters/server_config_selector/server_config_selector_filter.h \
src/core/ext/filters/stateful_session/stateful_session_filter.cc \
src/core/ext/filters/stateful_session/stateful_session_filter.h \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc \
src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h \
src/core/ext/transport/README.md \
src/core/ext/transport/binder/README.md \
src/core/ext/transport/chttp2/README.md \

Loading…
Cancel
Save