From 5e4d9f4bcf6a33d3d43c850f40c8c34815f94d3d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 5 Dec 2022 16:32:04 -0800 Subject: [PATCH] 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 --- BUILD | 4 +- CMakeLists.txt | 2 + Makefile | 4 + build_autogenerated.yaml | 4 + config.m4 | 3 + config.w32 | 3 + gRPC-C++.podspec | 4 + gRPC-Core.podspec | 6 + grpc.gemspec | 4 + grpc.gyp | 2 + package.xml | 4 + src/core/BUILD | 52 +++- .../filters/client_channel/config_selector.h | 1 - .../lb_policy/priority/priority.cc | 1 - .../weighted_target/weighted_target.cc | 1 - .../lb_policy/xds/xds_cluster_manager.cc | 1 - .../ext/filters/client_channel/subchannel.h | 1 - .../message_compress/compression_filter.cc | 4 +- .../server_config_selector.h | 3 - .../server_config_selector_filter.cc | 1 - .../stateful_session_filter.cc | 230 ++++++++++++++++++ .../stateful_session_filter.h | 66 +++++ .../stateful_session_service_config_parser.cc | 82 +++++++ .../stateful_session_service_config_parser.h | 93 +++++++ src/core/ext/transport/chaotic_good/frame.cc | 1 + .../chttp2/transport/flow_control.cc | 1 + .../chttp2/transport/hpack_parser.cc | 1 - .../ext/transport/chttp2/transport/parsing.cc | 1 + src/core/ext/xds/xds_listener.cc | 1 - src/core/ext/xds/xds_route_config.cc | 1 + src/core/ext/xds/xds_server_config_fetcher.cc | 2 - src/core/lib/event_engine/tcp_socket_utils.cc | 4 - .../service_config/service_config_call_data.h | 8 +- src/core/lib/transport/metadata_batch.h | 11 +- .../grpc_plugin_registry_extra.cc | 2 + src/cpp/common/core_codegen.cc | 2 - src/cpp/ext/gcp/BUILD | 1 + src/cpp/ext/gcp/observability_config.h | 1 + src/cpp/ext/gcp/observability_logging_sink.h | 2 + src/python/grpcio/grpc_core_dependencies.py | 2 + .../lb_policy/lb_policy_test_lib.h | 2 + .../lb_policy/outlier_detection_test.cc | 7 - .../lb_policy/pick_first_test.cc | 11 +- test/core/event_engine/BUILD | 1 + .../posix/tcp_posix_socket_utils_test.cc | 8 - .../posix/traced_buffer_list_test.cc | 4 + .../event_engine/tcp_socket_utils_test.cc | 3 + .../transport/chttp2/flow_control_test.cc | 1 + test/core/xds/xds_client_fuzzer.cc | 17 ++ .../xds_route_config_resource_type_test.cc | 1 - tools/doxygen/Doxyfile.c++.internal | 4 + tools/doxygen/Doxyfile.core.internal | 4 + 52 files changed, 622 insertions(+), 58 deletions(-) create mode 100644 src/core/ext/filters/stateful_session/stateful_session_filter.cc create mode 100644 src/core/ext/filters/stateful_session/stateful_session_filter.h create mode 100644 src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc create mode 100644 src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h diff --git a/BUILD b/BUILD index 8a279fae625..d644ecd0b80 100644 --- a/BUILD +++ b/BUILD @@ -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", diff --git a/CMakeLists.txt b/CMakeLists.txt index e2b237d9499..0b76f470e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/Makefile b/Makefile index 79bd679cde3..2281ca677b7 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 3233fda672c..7935bcad7be 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -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 diff --git a/config.m4 b/config.m4 index 3a0ebfb6faa..be56c6d24f9 100644 --- a/config.m4 +++ b/config.m4 @@ -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) diff --git a/config.w32 b/config.w32 index 63a1e6795b4..dc38be5b9b7 100644 --- a/config.w32 +++ b/config.w32 @@ -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"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e76cdb438ca..06e4d6f03a4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 664116e0db6..962d3a7a94b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -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', diff --git a/grpc.gemspec b/grpc.gemspec index 5cabc734dbc..db657352cd0 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -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 ) diff --git a/grpc.gyp b/grpc.gyp index f231ecb5353..a358e00870a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -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', diff --git a/package.xml b/package.xml index f0325e19bf5..612217edee2 100644 --- a/package.xml +++ b/package.xml @@ -219,6 +219,10 @@ + + + + diff --git a/src/core/BUILD b/src/core/BUILD index 7606378df28..374df712f5c 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -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", ], diff --git a/src/core/ext/filters/client_channel/config_selector.h b/src/core/ext/filters/client_channel/config_selector.h index 5112a5a466f..85e711609ca 100644 --- a/src/core/ext/filters/client_channel/config_selector.h +++ b/src/core/ext/filters/client_channel/config_selector.h @@ -31,7 +31,6 @@ #include #include -#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" diff --git a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc index 4cbf45ac089..7aa2ee43fb8 100644 --- a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +++ b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc index eb1ce62d792..1484385f1e0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +++ b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc index d80b0441d82..6daee327668 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 99b7153b7a0..05e80c71ea1 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -21,7 +21,6 @@ #include -#include #include #include #include diff --git a/src/core/ext/filters/http/message_compress/compression_filter.cc b/src/core/ext/filters/http/message_compress/compression_filter.cc index 1deae30bc15..5e56c519f6f 100644 --- a/src/core/ext/filters/http/message_compress/compression_filter.cc +++ b/src/core/ext/filters/http/message_compress/compression_filter.cc @@ -18,7 +18,6 @@ #include -#include #include #include #include @@ -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" diff --git a/src/core/ext/filters/server_config_selector/server_config_selector.h b/src/core/ext/filters/server_config_selector/server_config_selector.h index d68ee2e0a3e..69713e87bbb 100644 --- a/src/core/ext/filters/server_config_selector/server_config_selector.h +++ b/src/core/ext/filters/server_config_selector/server_config_selector.h @@ -24,13 +24,10 @@ #include "absl/status/statusor.h" #include "absl/strings/string_view.h" -#include - #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" diff --git a/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc b/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc index 0f17ff9fdcf..357da392cf1 100644 --- a/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +++ b/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc @@ -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" diff --git a/src/core/ext/filters/stateful_session/stateful_session_filter.cc b/src/core/ext/filters/stateful_session/stateful_session_filter.cc new file mode 100644 index 00000000000..b536f3c064c --- /dev/null +++ b/src/core/ext/filters/stateful_session/stateful_session_filter.cc @@ -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 + +#include "src/core/ext/filters/stateful_session/stateful_session_filter.h" + +#include + +#include +#include +#include +#include +#include +#include + +#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 +#include + +#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( + "stateful_session_filter"); + +absl::StatusOr 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 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 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 StatefulSessionFilter::MakeCallPromise( + CallArgs call_args, NextPromiseFactory next_promise_factory) { + // Get config. + auto* service_config_call_data = static_cast( + GetContext< + grpc_call_context_element>()[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA] + .value); + GPR_ASSERT(service_config_call_data != nullptr); + auto* method_params = static_cast( + 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()->New>(); + 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 +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 values; + for (absl::string_view cookie : absl::StrSplit(*header_value, "; ")) { + std::pair 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(GetContext()->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 diff --git a/src/core/ext/filters/stateful_session/stateful_session_filter.h b/src/core/ext/filters/stateful_session/stateful_session_filter.h new file mode 100644 index 00000000000..058fd65d04b --- /dev/null +++ b/src/core/ext/filters/stateful_session/stateful_session_filter.h @@ -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 + +#include + +#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 Create( + const ChannelArgs& args, ChannelFilter::Args filter_args); + + // Construct a promise for one call. + ArenaPromise MakeCallPromise( + CallArgs call_args, NextPromiseFactory next_promise_factory) override; + + private: + explicit StatefulSessionFilter(ChannelFilter::Args filter_args); + + absl::optional 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 diff --git a/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc b/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc new file mode 100644 index 00000000000..3be9785ac7c --- /dev/null +++ b/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc @@ -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 + +#include "src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h" + +#include + +#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() + .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() + .OptionalField("stateful_session", + &StatefulSessionMethodParsedConfig::configs_) + .Finish(); + return loader; +} + +std::unique_ptr +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>( + json, JsonArgs(), errors); +} + +void StatefulSessionServiceConfigParser::Register( + CoreConfiguration::Builder* builder) { + builder->service_config_parser()->RegisterParser( + std::make_unique()); +} + +size_t StatefulSessionServiceConfigParser::ParserIndex() { + return CoreConfiguration::Get().service_config_parser().GetParserIndex( + parser_name()); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h b/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h new file mode 100644 index 00000000000..cab5565239c --- /dev/null +++ b/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h @@ -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 + +#include + +#include +#include +#include + +#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 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 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 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 diff --git a/src/core/ext/transport/chaotic_good/frame.cc b/src/core/ext/transport/chaotic_good/frame.cc index ad260793d72..cb473636d39 100644 --- a/src/core/ext/transport/chaotic_good/frame.cc +++ b/src/core/ext/transport/chaotic_good/frame.cc @@ -25,6 +25,7 @@ #include "absl/status/statusor.h" #include +#include #include #include "src/core/lib/gprpp/bitset.h" diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index 48eae6e67b6..e1c26124bc5 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "absl/strings/str_cat.h" diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index a62602c8f2b..c3d762e0bda 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 95ebb29e776..144907773fa 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -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 { diff --git a/src/core/ext/xds/xds_listener.cc b/src/core/ext/xds/xds_listener.cc index febeeacbef6..4da36a9d592 100644 --- a/src/core/ext/xds/xds_listener.cc +++ b/src/core/ext/xds/xds_listener.cc @@ -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 { diff --git a/src/core/ext/xds/xds_route_config.cc b/src/core/ext/xds/xds_route_config.cc index c7d35cfc1d4..25478580839 100644 --- a/src/core/ext/xds/xds_route_config.cc +++ b/src/core/ext/xds/xds_route_config.cc @@ -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" diff --git a/src/core/ext/xds/xds_server_config_fetcher.cc b/src/core/ext/xds/xds_server_config_fetcher.cc index 2712254a2eb..08428d0928d 100644 --- a/src/core/ext/xds/xds_server_config_fetcher.cc +++ b/src/core/ext/xds/xds_server_config_fetcher.cc @@ -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" diff --git a/src/core/lib/event_engine/tcp_socket_utils.cc b/src/core/lib/event_engine/tcp_socket_utils.cc index e517ae57f59..25dc3d5e41a 100644 --- a/src/core/lib/event_engine/tcp_socket_utils.cc +++ b/src/core/lib/event_engine/tcp_socket_utils.cc @@ -24,11 +24,8 @@ #include #else #include // IWYU pragma: keep -#include #endif -#include #include -#include #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 { diff --git a/src/core/lib/service_config/service_config_call_data.h b/src/core/lib/service_config/service_config_call_data.h index f222846d742..10671f19612 100644 --- a/src/core/lib/service_config/service_config_call_data.h +++ b/src/core/lib/service_config/service_config_call_data.h @@ -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 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 diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 668ef31143f..d06d0f3e6f0 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.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; diff --git a/src/core/plugin_registry/grpc_plugin_registry_extra.cc b/src/core/plugin_registry/grpc_plugin_registry_extra.cc index 6fdc2d52a69..ce94a2809bc 100644 --- a/src/core/plugin_registry/grpc_plugin_registry_extra.cc +++ b/src/core/plugin_registry/grpc_plugin_registry_extra.cc @@ -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); diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index 87f72a7c438..e4960b73063 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -27,9 +27,7 @@ #include #include #include -#include #include -#include #include #include #include diff --git a/src/cpp/ext/gcp/BUILD b/src/cpp/ext/gcp/BUILD index 517862b8b2d..f75b9aa62a8 100644 --- a/src/cpp/ext/gcp/BUILD +++ b/src/cpp/ext/gcp/BUILD @@ -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__"], diff --git a/src/cpp/ext/gcp/observability_config.h b/src/cpp/ext/gcp/observability_config.h index a9ab6f0b4d9..0d5cc69c53f 100644 --- a/src/cpp/ext/gcp/observability_config.h +++ b/src/cpp/ext/gcp/observability_config.h @@ -19,6 +19,7 @@ #include +#include #include #include diff --git a/src/cpp/ext/gcp/observability_logging_sink.h b/src/cpp/ext/gcp/observability_logging_sink.h index 36d676f261c..5144c15c62c 100644 --- a/src/cpp/ext/gcp/observability_logging_sink.h +++ b/src/cpp/ext/gcp/observability_logging_sink.h @@ -27,6 +27,8 @@ #include #include +#include + #include "absl/strings/string_view.h" #include "google/logging/v2/logging.grpc.pb.h" diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index cdab9772b88..2a90435c5b2 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -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', diff --git a/test/core/client_channel/lb_policy/lb_policy_test_lib.h b/test/core/client_channel/lb_policy/lb_policy_test_lib.h index 6b7430bc6ac..e864b8bd954 100644 --- a/test/core/client_channel/lb_policy/lb_policy_test_lib.h +++ b/test/core/client_channel/lb_policy/lb_policy_test_lib.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -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" diff --git a/test/core/client_channel/lb_policy/outlier_detection_test.cc b/test/core/client_channel/lb_policy/outlier_detection_test.cc index 3a368f6c4a8..80870826079 100644 --- a/test/core/client_channel/lb_policy/outlier_detection_test.cc +++ b/test/core/client_channel/lb_policy/outlier_detection_test.cc @@ -19,27 +19,20 @@ #include #include -#include #include #include -#include #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "gtest/gtest.h" #include -#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" diff --git a/test/core/client_channel/lb_policy/pick_first_test.cc b/test/core/client_channel/lb_policy/pick_first_test.cc index 4578648726c..fd9ace9de89 100644 --- a/test/core/client_channel/lb_policy/pick_first_test.cc +++ b/test/core/client_channel/lb_policy/pick_first_test.cc @@ -16,25 +16,16 @@ #include -#include -#include -#include -#include -#include - #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "gtest/gtest.h" #include -#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" diff --git a/test/core/event_engine/BUILD b/test/core/event_engine/BUILD index 932e4f48f93..1e2e7d0fd8d 100644 --- a/test/core/event_engine/BUILD +++ b/test/core/event_engine/BUILD @@ -176,6 +176,7 @@ grpc_cc_test( external_deps = [ "absl/status", "absl/status:statusor", + "absl/strings", "gtest", ], language = "C++", diff --git a/test/core/event_engine/posix/tcp_posix_socket_utils_test.cc b/test/core/event_engine/posix/tcp_posix_socket_utils_test.cc index 4ea8c1e41bb..da5f3fb84dc 100644 --- a/test/core/event_engine/posix/tcp_posix_socket_utils_test.cc +++ b/test/core/event_engine/posix/tcp_posix_socket_utils_test.cc @@ -16,12 +16,8 @@ #include #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 #include #include "src/core/lib/iomgr/port.h" @@ -33,10 +29,6 @@ #include #include -#include -#ifdef GRPC_HAVE_UNIX_SOCKET -#include -#endif #include diff --git a/test/core/event_engine/posix/traced_buffer_list_test.cc b/test/core/event_engine/posix/traced_buffer_list_test.cc index fbd635b2630..7bb62475bd2 100644 --- a/test/core/event_engine/posix/traced_buffer_list_test.cc +++ b/test/core/event_engine/posix/traced_buffer_list_test.cc @@ -19,7 +19,11 @@ #include "gtest/gtest.h" #include +#include +#include +#include +#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" diff --git a/test/core/event_engine/tcp_socket_utils_test.cc b/test/core/event_engine/tcp_socket_utils_test.cc index 4a2a9bf2cbe..9215f44c991 100644 --- a/test/core/event_engine/tcp_socket_utils_test.cc +++ b/test/core/event_engine/tcp_socket_utils_test.cc @@ -19,6 +19,9 @@ #include #include +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + // IWYU pragma: no_include #include diff --git a/test/core/transport/chttp2/flow_control_test.cc b/test/core/transport/chttp2/flow_control_test.cc index fe7a972385a..4a53c611e02 100644 --- a/test/core/transport/chttp2/flow_control_test.cc +++ b/test/core/transport/chttp2/flow_control_test.cc @@ -15,6 +15,7 @@ #include "src/core/ext/transport/chttp2/transport/flow_control.h" #include +#include #include "gtest/gtest.h" diff --git a/test/core/xds/xds_client_fuzzer.cc b/test/core/xds/xds_client_fuzzer.cc index dd41d220e80..9fee1133a0a 100644 --- a/test/core/xds/xds_client_fuzzer.cc +++ b/test/core/xds/xds_client_fuzzer.cc @@ -14,8 +14,23 @@ // limitations under the License. // +#include +#include +#include +#include +#include + +#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 #include +#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" diff --git a/test/core/xds/xds_route_config_resource_type_test.cc b/test/core/xds/xds_route_config_resource_type_test.cc index 27400f554d8..077c12fdeba 100644 --- a/test/core/xds/xds_route_config_resource_type_test.cc +++ b/test/core/xds/xds_route_config_resource_type_test.cc @@ -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" diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 4f9608eccce..a8fcbbc279e 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -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 \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index dfc07b57004..793fc2107d4 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -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 \