[EventEngine] Implement the EventEngine-driven client channel resolver. (#32632)

This PR also centralizes the client channel resolver selection. Resolver
selection is still done using the plugin system, but when the Ares and
native client channel resolvers go away, we can consider bootstrapping
this differently.
pull/32766/head
AJ Heller 2 years ago committed by GitHub
parent b94d55bd20
commit 7dec55de5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      BUILD
  2. 6
      CMakeLists.txt
  3. 6
      Makefile
  4. 16
      build_autogenerated.yaml
  5. 5
      config.m4
  6. 4
      config.w32
  7. 10
      gRPC-C++.podspec
  8. 13
      gRPC-Core.podspec
  9. 8
      grpc.gemspec
  10. 6
      grpc.gyp
  11. 8
      package.xml
  12. 86
      src/core/BUILD
  13. 139
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  14. 30
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h
  15. 60
      src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc
  16. 27
      src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h
  17. 524
      src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
  18. 35
      src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h
  19. 97
      src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc
  20. 32
      src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h
  21. 15
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  22. 24
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h
  23. 1
      src/core/lib/event_engine/trace.cc
  24. 6
      src/core/lib/event_engine/trace.h
  25. 3
      src/core/lib/experiments/experiments.cc
  26. 5
      src/core/lib/experiments/experiments.h
  27. 7
      src/core/lib/experiments/experiments.yaml
  28. 6
      src/core/plugin_registry/grpc_plugin_registry.cc
  29. 3
      src/python/grpcio/grpc_core_dependencies.py
  30. 3
      test/cpp/naming/resolver_component_test.cc
  31. 4
      test/cpp/naming/resolver_component_tests_runner.py
  32. 6
      test/cpp/naming/resolver_test_record_groups.yaml
  33. 8
      tools/doxygen/Doxyfile.c++.internal
  34. 8
      tools/doxygen/Doxyfile.core.internal

@ -783,6 +783,7 @@ grpc_cc_library(
"//src/core:grpc_transport_chttp2_server",
"//src/core:grpc_transport_inproc",
"//src/core:grpc_fault_injection_filter",
"//src/core:grpc_resolver_dns_plugin",
],
)
@ -2952,6 +2953,7 @@ grpc_cc_library(
"//src/core:ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
],
hdrs = [
"//src/core:ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h",
"//src/core:ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
"//src/core:ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
],
@ -2994,12 +2996,10 @@ grpc_cc_library(
"//src/core:grpc_sockaddr",
"//src/core:iomgr_fwd",
"//src/core:iomgr_port",
"//src/core:json",
"//src/core:json_reader",
"//src/core:json_writer",
"//src/core:polling_resolver",
"//src/core:pollset_set",
"//src/core:resolved_address",
"//src/core:service_config_helper",
"//src/core:slice",
"//src/core:status_helper",
"//src/core:time",

6
CMakeLists.txt generated

@ -1775,6 +1775,9 @@ add_library(grpc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc
@ -2790,6 +2793,9 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
src/core/ext/filters/client_channel/resolver/polling_resolver.cc

6
Makefile generated

@ -1010,6 +1010,9 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc \
@ -1879,6 +1882,9 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/resolver/polling_resolver.cc \

@ -371,8 +371,13 @@ libs:
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h
- src/core/ext/filters/client_channel/local_subchannel_pool.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h
- src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h
- src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
- src/core/ext/filters/client_channel/resolver/polling_resolver.h
- src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h
@ -1165,6 +1170,9 @@ libs:
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc
- src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
- src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc
@ -2048,8 +2056,13 @@ libs:
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
- src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/static_stride_scheduler.h
- src/core/ext/filters/client_channel/local_subchannel_pool.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h
- src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h
- src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
- src/core/ext/filters/client_channel/resolver/polling_resolver.h
- src/core/ext/filters/client_channel/retry_filter.h
@ -2452,6 +2465,9 @@ libs:
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc
- src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
- src/core/ext/filters/client_channel/resolver/polling_resolver.cc

5
config.m4 generated

@ -89,6 +89,9 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc \
@ -1297,7 +1300,9 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/binder)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/event_engine)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/google_c2p)

4
config.w32 generated

@ -55,6 +55,9 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_plugin.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\event_engine\\event_engine_client_channel_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\event_engine\\service_config_helper.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\google_c2p\\google_c2p_resolver.cc " +
@ -1297,6 +1300,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\binder");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\event_engine");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\fake");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\google_c2p");

10
gRPC-C++.podspec generated

@ -276,8 +276,13 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/resolver/polling_resolver.h',
'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h',
@ -1234,8 +1239,13 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/resolver/polling_resolver.h',
'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h',

13
gRPC-Core.podspec generated

@ -287,6 +287,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
'src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
@ -294,7 +295,14 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc',
@ -1944,8 +1952,13 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/resolver/polling_resolver.h',
'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h',

8
grpc.gemspec generated

@ -194,6 +194,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc )
@ -201,7 +202,14 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc )

6
grpc.gyp generated

@ -425,6 +425,9 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc',
@ -1235,6 +1238,9 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/resolver/polling_resolver.cc',

8
package.xml generated

@ -176,6 +176,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/local_subchannel_pool.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc" role="src" />
@ -183,7 +184,14 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc" role="src" />

@ -4890,11 +4890,96 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "service_config_helper",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h"],
external_deps = [
"absl/status:statusor",
"absl/strings",
],
language = "c++",
deps = [
"json",
"json_args",
"json_object_loader",
"json_reader",
"json_writer",
"status_helper",
"//:gpr_platform",
"//:grpc_base",
],
)
grpc_cc_library(
name = "grpc_resolver_dns_event_engine",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h"],
external_deps = [
"absl/base:core_headers",
"absl/cleanup",
"absl/container:flat_hash_set",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
],
language = "c++",
deps = [
"channel_args",
"event_engine_common",
"event_engine_utils",
"grpc_service_config",
"polling_resolver",
"service_config_helper",
"time",
"validation_errors",
"//:backoff",
"//:debug_location",
"//:gpr",
"//:gpr_platform",
"//:grpc_base",
"//:grpc_grpclb_balancer_addresses",
"//:grpc_resolver",
"//:grpc_service_config_impl",
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:uri_parser",
],
)
grpc_cc_library(
name = "grpc_resolver_dns_plugin",
srcs = [
"ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h",
],
external_deps = ["absl/strings"],
language = "c++",
deps = [
"experiments",
"grpc_resolver_dns_event_engine",
"grpc_resolver_dns_native",
"//:config",
"//:config_vars",
"//:gpr",
"//:grpc_resolver",
"//:grpc_resolver_dns_ares",
],
)
grpc_cc_library(
name = "grpc_resolver_dns_native",
srcs = [
"ext/filters/client_channel/resolver/dns/native/dns_resolver.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/native/dns_resolver.h",
],
external_deps = [
"absl/functional:bind_front",
"absl/status",
@ -4910,7 +4995,6 @@ grpc_cc_library(
"time",
"//:backoff",
"//:config",
"//:config_vars",
"//:debug_location",
"//:gpr",
"//:grpc_base",

@ -17,11 +17,9 @@
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <stdlib.h>
#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <utility>
@ -40,6 +38,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
@ -60,8 +59,6 @@
#if GRPC_ARES == 1
#include <stdio.h>
#include <address_sorting/address_sorting.h>
#include "absl/container/flat_hash_set.h"
@ -74,11 +71,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/config_vars.h"
#include "src/core/lib/event_engine/handle_containers.h"
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/json/json_reader.h"
#include "src/core/lib/json/json_writer.h"
#include "src/core/lib/resolver/server_address.h"
#include "src/core/lib/service_config/service_config_impl.h"
#include "src/core/lib/transport/error_utils.h"
@ -237,97 +230,6 @@ OrphanablePtr<Orphanable> AresClientChannelDNSResolver::StartRequest() {
Ref(DEBUG_LOCATION, "dns-resolving"));
}
bool ValueInJsonArray(const Json::Array& array, const char* value) {
for (const Json& entry : array) {
if (entry.type() == Json::Type::kString && entry.string() == value) {
return true;
}
}
return false;
}
std::string ChooseServiceConfig(char* service_config_choice_json,
grpc_error_handle* error) {
auto json = JsonParse(service_config_choice_json);
if (!json.ok()) {
*error = absl_status_to_grpc_error(json.status());
return "";
}
if (json->type() != Json::Type::kArray) {
*error = GRPC_ERROR_CREATE(
"Service Config Choices, error: should be of type array");
return "";
}
const Json* service_config = nullptr;
std::vector<grpc_error_handle> error_list;
for (const Json& choice : json->array()) {
if (choice.type() != Json::Type::kObject) {
error_list.push_back(GRPC_ERROR_CREATE(
"Service Config Choice, error: should be of type object"));
continue;
}
// Check client language, if specified.
auto it = choice.object().find("clientLanguage");
if (it != choice.object().end()) {
if (it->second.type() != Json::Type::kArray) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:clientLanguage error:should be of type array"));
} else if (!ValueInJsonArray(it->second.array(), "c++")) {
continue;
}
}
// Check client hostname, if specified.
it = choice.object().find("clientHostname");
if (it != choice.object().end()) {
if (it->second.type() != Json::Type::kArray) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:clientHostname error:should be of type array"));
} else {
char* hostname = grpc_gethostname();
if (hostname == nullptr ||
!ValueInJsonArray(it->second.array(), hostname)) {
continue;
}
}
}
// Check percentage, if specified.
it = choice.object().find("percentage");
if (it != choice.object().end()) {
if (it->second.type() != Json::Type::kNumber) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:percentage error:should be of type number"));
} else {
int random_pct = rand() % 100;
int percentage;
if (sscanf(it->second.string().c_str(), "%d", &percentage) != 1) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:percentage error:should be of type integer"));
} else if (random_pct > percentage || percentage == 0) {
continue;
}
}
}
// Found service config.
it = choice.object().find("serviceConfig");
if (it == choice.object().end()) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:serviceConfig error:required field missing"));
} else if (it->second.type() != Json::Type::kObject) {
error_list.push_back(GRPC_ERROR_CREATE(
"field:serviceConfig error:should be of type object"));
} else if (service_config == nullptr) {
service_config = &it->second;
}
}
if (!error_list.empty()) {
service_config = nullptr;
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Service Config Choices Parser",
&error_list);
}
if (service_config == nullptr) return "";
return JsonDump(*service_config);
}
void AresClientChannelDNSResolver::AresRequestWrapper::OnHostnameResolved(
void* arg, grpc_error_handle error) {
auto* self = static_cast<AresRequestWrapper*>(arg);
@ -402,18 +304,16 @@ AresClientChannelDNSResolver::AresRequestWrapper::OnResolvedLocked(
result.addresses = ServerAddressList();
}
if (service_config_json_ != nullptr) {
grpc_error_handle service_config_error;
std::string service_config_string =
ChooseServiceConfig(service_config_json_, &service_config_error);
if (!service_config_error.ok()) {
auto service_config_string = ChooseServiceConfig(service_config_json_);
if (!service_config_string.ok()) {
result.service_config = absl::UnavailableError(
absl::StrCat("failed to parse service config: ",
StatusToString(service_config_error)));
} else if (!service_config_string.empty()) {
StatusToString(service_config_string.status())));
} else if (!service_config_string->empty()) {
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
this, service_config_string.c_str());
this, service_config_string->c_str());
result.service_config = ServiceConfigImpl::Create(
resolver_->channel_args(), service_config_string);
resolver_->channel_args(), *service_config_string);
if (!result.service_config.ok()) {
result.service_config = absl::UnavailableError(
absl::StrCat("failed to parse service config: ",
@ -811,27 +711,22 @@ class AresDNSResolver : public DNSResolver {
intptr_t aba_token_ ABSL_GUARDED_BY(mu_) = 0;
};
bool ShouldUseAres(absl::string_view resolver_env) {
return resolver_env.empty() || absl::EqualsIgnoreCase(resolver_env, "ares");
}
} // namespace
bool UseAresDnsResolver() {
return ShouldUseAres(ConfigVars::Get().DnsResolver());
bool ShouldUseAresDnsResolver(absl::string_view resolver_env) {
return resolver_env.empty() || absl::EqualsIgnoreCase(resolver_env, "ares");
}
} // namespace
void RegisterAresDnsResolver(CoreConfiguration::Builder* builder) {
if (UseAresDnsResolver()) {
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<AresClientChannelDNSResolverFactory>());
}
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<AresClientChannelDNSResolverFactory>());
}
} // namespace grpc_core
void grpc_resolver_dns_ares_init() {
if (grpc_core::UseAresDnsResolver()) {
if (grpc_core::ShouldUseAresDnsResolver(
grpc_core::ConfigVars::Get().DnsResolver())) {
address_sorting_init();
grpc_error_handle error = grpc_ares_init();
if (!error.ok()) {
@ -843,7 +738,8 @@ void grpc_resolver_dns_ares_init() {
}
void grpc_resolver_dns_ares_shutdown() {
if (grpc_core::UseAresDnsResolver()) {
if (grpc_core::ShouldUseAresDnsResolver(
grpc_core::ConfigVars::Get().DnsResolver())) {
address_sorting_shutdown();
grpc_ares_cleanup();
}
@ -852,6 +748,9 @@ void grpc_resolver_dns_ares_shutdown() {
#else // GRPC_ARES == 1
namespace grpc_core {
bool ShouldUseAresDnsResolver(absl::string_view /* resolver_env */) {
return false;
}
void RegisterAresDnsResolver(CoreConfiguration::Builder*) {}
} // namespace grpc_core

@ -0,0 +1,30 @@
// Copyright 2022 The 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_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_DNS_RESOLVER_ARES_H
#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_DNS_RESOLVER_ARES_H
#include <grpc/support/port_platform.h>
#include "absl/strings/string_view.h"
#include "src/core/lib/config/core_configuration.h"
namespace grpc_core {
bool ShouldUseAresDnsResolver(absl::string_view resolver_env);
void RegisterAresDnsResolver(CoreConfiguration::Builder*);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_DNS_RESOLVER_ARES_H

@ -0,0 +1,60 @@
// Copyright 2022 The 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/client_channel/resolver/dns/dns_resolver_plugin.h"
#include <memory>
#include "absl/strings/match.h"
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h"
#include "src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h"
#include "src/core/lib/config/config_vars.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/resolver/resolver_factory.h"
namespace grpc_core {
void RegisterDnsResolver(CoreConfiguration::Builder* builder) {
if (IsEventEngineDnsEnabled()) {
gpr_log(GPR_DEBUG, "Using EventEngine dns resolver");
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<EventEngineClientChannelDNSResolverFactory>());
return;
}
auto resolver = ConfigVars::Get().DnsResolver();
// ---- Ares resolver ----
if (ShouldUseAresDnsResolver(resolver)) {
gpr_log(GPR_DEBUG, "Using ares dns resolver");
RegisterAresDnsResolver(builder);
return;
}
// ---- Native resolver ----
if (absl::EqualsIgnoreCase(resolver, "native") ||
!builder->resolver_registry()->HasResolverFactory("dns")) {
gpr_log(GPR_DEBUG, "Using native dns resolver");
RegisterNativeDnsResolver(builder);
return;
}
Crash(
"Unable to set DNS resolver! Likely a logic error in gRPC-core, "
"please file a bug.");
}
} // namespace grpc_core

@ -0,0 +1,27 @@
// Copyright 2022 The 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_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_PLUGIN_H
#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_PLUGIN_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/config/core_configuration.h"
namespace grpc_core {
// Centralized decision logic about which client channel DNS resolver to enable.
void RegisterDnsResolver(CoreConfiguration::Builder* builder);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_PLUGIN_H

@ -0,0 +1,524 @@
// Copyright 2023 The 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/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h"
#include <inttypes.h>
#include <stddef.h>
#include <algorithm>
#include <chrono>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/cleanup/cleanup.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/strip.h"
#include "absl/types/optional.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h"
#include "src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h"
#include "src/core/ext/filters/client_channel/resolver/polling_resolver.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/event_engine/handle_containers.h"
#include "src/core/lib/event_engine/resolved_address_internal.h"
#include "src/core/lib/event_engine/utils.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/validation_errors.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/resolver/resolver.h"
#include "src/core/lib/resolver/resolver_factory.h"
#include "src/core/lib/resolver/server_address.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/service_config/service_config_impl.h"
// IWYU pragma: no_include <ratio>
namespace grpc_core {
namespace {
#define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
#define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
#define GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS 120
#define GRPC_DNS_RECONNECT_JITTER 0.2
#define GRPC_DNS_DEFAULT_QUERY_TIMEOUT_MS 120000
using grpc_event_engine::experimental::EventEngine;
using grpc_event_engine::experimental::HandleToString;
using grpc_event_engine::experimental::LookupTaskHandleSet;
// TODO(hork): Investigate adding a resolver test scenario where the first
// balancer hostname lookup result is an error, and the second contains valid
// addresses.
// TODO(hork): Add a test that checks for proper authority from balancer
// addresses.
// TODO(hork): replace this with `dns_resolver` when all other resolver
// implementations are removed.
TraceFlag grpc_event_engine_client_channel_resolver_trace(
false, "event_engine_client_channel_resolver");
#define GRPC_EVENT_ENGINE_RESOLVER_TRACE(format, ...) \
if (GRPC_TRACE_FLAG_ENABLED( \
grpc_event_engine_client_channel_resolver_trace)) { \
gpr_log(GPR_DEBUG, "(event_engine client channel resolver) " format, \
__VA_ARGS__); \
}
// ----------------------------------------------------------------------------
// EventEngineClientChannelDNSResolver
// ----------------------------------------------------------------------------
class EventEngineClientChannelDNSResolver : public PollingResolver {
public:
EventEngineClientChannelDNSResolver(ResolverArgs args,
Duration min_time_between_resolutions);
OrphanablePtr<Orphanable> StartRequest() override;
private:
// ----------------------------------------------------------------------------
// EventEngineDNSRequestWrapper declaration
// ----------------------------------------------------------------------------
class EventEngineDNSRequestWrapper
: public InternallyRefCounted<EventEngineDNSRequestWrapper> {
public:
EventEngineDNSRequestWrapper(
RefCountedPtr<EventEngineClientChannelDNSResolver> resolver,
std::unique_ptr<EventEngine::DNSResolver> event_engine_resolver);
~EventEngineDNSRequestWrapper() override;
// Note that thread safety cannot be analyzed due to this being invoked from
// OrphanablePtr<>, and there's no way to pass the lock annotation through
// there.
void Orphan() override ABSL_NO_THREAD_SAFETY_ANALYSIS;
private:
void OnHostnameResolved(
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>> addresses);
void OnSRVResolved(
absl::StatusOr<std::vector<EventEngine::DNSResolver::SRVRecord>>
srv_records);
void OnBalancerHostnamesResolved(
std::string authority,
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>> addresses);
void OnTXTResolved(absl::StatusOr<std::string> service_config);
// Returns a Result if resolution is complete.
// callers must release the lock and call OnRequestComplete if a Result is
// returned. This is because OnRequestComplete may Orphan the resolver,
// which requires taking the lock.
absl::optional<Resolver::Result> OnResolvedLocked()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(on_resolved_mu_);
// Helper method to populate server addresses on resolver result.
void MaybePopulateAddressesLocked(Resolver::Result* result)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(on_resolved_mu_);
// Helper method to populate balancer addresses on resolver result.
void MaybePopulateBalancerAddressesLocked(Resolver::Result* result)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(on_resolved_mu_);
// Helper method to populate service config on resolver result.
void MaybePopulateServiceConfigLocked(Resolver::Result* result)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(on_resolved_mu_);
RefCountedPtr<EventEngineClientChannelDNSResolver> resolver_;
Mutex on_resolved_mu_;
// Lookup callbacks
absl::optional<EventEngine::DNSResolver::LookupTaskHandle> hostname_handle_
ABSL_GUARDED_BY(on_resolved_mu_);
absl::optional<EventEngine::DNSResolver::LookupTaskHandle> srv_handle_
ABSL_GUARDED_BY(on_resolved_mu_);
absl::optional<EventEngine::DNSResolver::LookupTaskHandle> txt_handle_
ABSL_GUARDED_BY(on_resolved_mu_);
LookupTaskHandleSet balancer_hostname_handles_
ABSL_GUARDED_BY(on_resolved_mu_);
// Output fields from requests.
ServerAddressList addresses_ ABSL_GUARDED_BY(on_resolved_mu_);
ServerAddressList balancer_addresses_ ABSL_GUARDED_BY(on_resolved_mu_);
ValidationErrors errors_ ABSL_GUARDED_BY(on_resolved_mu_);
absl::StatusOr<std::string> service_config_json_
ABSL_GUARDED_BY(on_resolved_mu_);
// Other internal state
size_t number_of_balancer_hostnames_resolved_
ABSL_GUARDED_BY(on_resolved_mu_) = 0;
bool orphaned_ ABSL_GUARDED_BY(on_resolved_mu_) = false;
std::unique_ptr<EventEngine::DNSResolver> event_engine_resolver_;
};
/// whether to request the service config
const bool request_service_config_;
// whether or not to enable SRV DNS queries
const bool enable_srv_queries_;
// timeout in milliseconds for active DNS queries
EventEngine::Duration query_timeout_ms_;
std::shared_ptr<EventEngine> event_engine_;
};
EventEngineClientChannelDNSResolver::EventEngineClientChannelDNSResolver(
ResolverArgs args, Duration min_time_between_resolutions)
: PollingResolver(std::move(args), min_time_between_resolutions,
BackOff::Options()
.set_initial_backoff(Duration::Milliseconds(
GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * 1000))
.set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER)
.set_jitter(GRPC_DNS_RECONNECT_JITTER)
.set_max_backoff(Duration::Milliseconds(
GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)),
&grpc_event_engine_client_channel_resolver_trace),
request_service_config_(
!channel_args()
.GetBool(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION)
.value_or(true)),
enable_srv_queries_(channel_args()
.GetBool(GRPC_ARG_DNS_ENABLE_SRV_QUERIES)
.value_or(false)),
// TODO(yijiem): decide if the ares channel arg timeout should be reused.
query_timeout_ms_(std::chrono::milliseconds(
std::max(0, channel_args()
.GetInt(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS)
.value_or(GRPC_DNS_DEFAULT_QUERY_TIMEOUT_MS)))),
event_engine_(channel_args().GetObjectRef<EventEngine>()) {}
OrphanablePtr<Orphanable> EventEngineClientChannelDNSResolver::StartRequest() {
return MakeOrphanable<EventEngineDNSRequestWrapper>(
Ref(DEBUG_LOCATION, "dns-resolving"),
event_engine_->GetDNSResolver({/*dns_server=*/authority()}));
}
// ----------------------------------------------------------------------------
// EventEngineDNSRequestWrapper definition
// ----------------------------------------------------------------------------
EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
EventEngineDNSRequestWrapper(
RefCountedPtr<EventEngineClientChannelDNSResolver> resolver,
std::unique_ptr<EventEngine::DNSResolver> event_engine_resolver)
: resolver_(std::move(resolver)),
event_engine_resolver_(std::move(event_engine_resolver)) {
// Locking to prevent completion before all records are queried
MutexLock lock(&on_resolved_mu_);
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p Starting hostname resolution for %s", resolver_.get(),
resolver_->name_to_resolve().c_str());
hostname_handle_ = event_engine_resolver_->LookupHostname(
[self = Ref(DEBUG_LOCATION, "OnHostnameResolved")](
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>> addresses) {
self->OnHostnameResolved(std::move(addresses));
},
resolver_->name_to_resolve(), kDefaultSecurePort,
resolver_->query_timeout_ms_);
GRPC_EVENT_ENGINE_RESOLVER_TRACE("hostname lookup handle: %s",
HandleToString(*hostname_handle_).c_str());
if (resolver_->enable_srv_queries_) {
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p Starting SRV record resolution for %s",
resolver_.get(), resolver_->name_to_resolve().c_str());
srv_handle_ = event_engine_resolver_->LookupSRV(
[self = Ref(DEBUG_LOCATION, "OnSRVResolved")](
absl::StatusOr<std::vector<EventEngine::DNSResolver::SRVRecord>>
srv_records) { self->OnSRVResolved(std::move(srv_records)); },
resolver_->name_to_resolve(), resolver_->query_timeout_ms_);
GRPC_EVENT_ENGINE_RESOLVER_TRACE("srv lookup handle: %s",
HandleToString(*srv_handle_).c_str());
}
if (resolver_->request_service_config_) {
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p Starting TXT record resolution for %s",
resolver_.get(), resolver_->name_to_resolve().c_str());
txt_handle_ = event_engine_resolver_->LookupTXT(
[self = Ref(DEBUG_LOCATION, "OnTXTResolved")](
absl::StatusOr<std::string> service_config) {
self->OnTXTResolved(std::move(service_config));
},
absl::StrCat("_grpc_config.", resolver_->name_to_resolve()),
resolver_->query_timeout_ms_);
GRPC_EVENT_ENGINE_RESOLVER_TRACE("txt lookup handle: %s",
HandleToString(*txt_handle_).c_str());
}
}
EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
~EventEngineDNSRequestWrapper() {
resolver_.reset(DEBUG_LOCATION, "dns-resolving");
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
Orphan() {
{
MutexLock lock(&on_resolved_mu_);
orphaned_ = true;
// Event if cancellation fails here, OnResolvedLocked will return early, and
// the resolver will never see a completed request.
if (hostname_handle_.has_value()) {
event_engine_resolver_->CancelLookup(*hostname_handle_);
}
if (srv_handle_.has_value()) {
event_engine_resolver_->CancelLookup(*srv_handle_);
}
for (const auto& handle : balancer_hostname_handles_) {
event_engine_resolver_->CancelLookup(handle);
}
if (txt_handle_.has_value()) {
event_engine_resolver_->CancelLookup(*txt_handle_);
}
}
Unref(DEBUG_LOCATION, "Orphan");
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
OnHostnameResolved(absl::StatusOr<std::vector<EventEngine::ResolvedAddress>>
new_addresses) {
ValidationErrors::ScopedField field(&errors_, "hostname lookup");
absl::optional<Resolver::Result> result;
{
MutexLock lock(&on_resolved_mu_);
if (orphaned_) return;
hostname_handle_.reset();
if (!new_addresses.ok()) {
errors_.AddError(new_addresses.status().message());
} else {
addresses_.reserve(addresses_.size() + new_addresses->size());
for (const auto& addr : *new_addresses) {
addresses_.emplace_back(CreateGRPCResolvedAddress(addr), ChannelArgs());
}
}
result = OnResolvedLocked();
}
if (result.has_value()) {
resolver_->OnRequestComplete(std::move(*result));
}
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
OnSRVResolved(
absl::StatusOr<std::vector<EventEngine::DNSResolver::SRVRecord>>
srv_records) {
ValidationErrors::ScopedField field(&errors_, "srv lookup");
absl::optional<Resolver::Result> result;
auto cleanup = absl::MakeCleanup([&]() {
if (result.has_value()) {
resolver_->OnRequestComplete(std::move(*result));
}
});
MutexLock lock(&on_resolved_mu_);
if (orphaned_) return;
srv_handle_.reset();
if (!srv_records.ok()) {
// An error has occurred, finish resolving.
errors_.AddError(srv_records.status().message());
result = OnResolvedLocked();
return;
}
// Do a subsequent hostname query since SRV records were returned
for (auto& srv_record : *srv_records) {
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p Starting balancer hostname resolution for %s:%d",
resolver_.get(), srv_record.host.c_str(), srv_record.port);
auto handle = event_engine_resolver_->LookupHostname(
[host = std::move(srv_record.host),
self = Ref(DEBUG_LOCATION, "OnBalancerHostnamesResolved")](
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>>
new_balancer_addresses) mutable {
self->OnBalancerHostnamesResolved(std::move(host),
std::move(new_balancer_addresses));
},
srv_record.host, std::to_string(srv_record.port),
resolver_->query_timeout_ms_);
GRPC_EVENT_ENGINE_RESOLVER_TRACE("balancer hostname lookup handle: %s",
HandleToString(handle).c_str());
balancer_hostname_handles_.insert(handle);
}
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
OnBalancerHostnamesResolved(
std::string authority,
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>>
new_balancer_addresses) {
ValidationErrors::ScopedField field(
&errors_, absl::StrCat("balancer lookup for ", authority));
absl::optional<Resolver::Result> result;
auto cleanup = absl::MakeCleanup([&]() {
if (result.has_value()) {
resolver_->OnRequestComplete(std::move(*result));
}
});
MutexLock lock(&on_resolved_mu_);
if (orphaned_) return;
++number_of_balancer_hostnames_resolved_;
if (!new_balancer_addresses.ok()) {
// An error has occurred, finish resolving.
errors_.AddError(new_balancer_addresses.status().message());
} else {
// Capture the addresses and finish resolving.
balancer_addresses_.reserve(balancer_addresses_.size() +
new_balancer_addresses->size());
auto srv_channel_args =
ChannelArgs().Set(GRPC_ARG_DEFAULT_AUTHORITY, authority);
for (const auto& addr : *new_balancer_addresses) {
balancer_addresses_.emplace_back(CreateGRPCResolvedAddress(addr),
srv_channel_args);
}
}
result = OnResolvedLocked();
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
OnTXTResolved(absl::StatusOr<std::string> service_config) {
ValidationErrors::ScopedField field(&errors_, "txt lookup");
absl::optional<Resolver::Result> result;
{
MutexLock lock(&on_resolved_mu_);
if (orphaned_) return;
GPR_ASSERT(txt_handle_.has_value());
txt_handle_.reset();
if (!service_config.ok()) {
errors_.AddError(service_config.status().message());
service_config_json_ = service_config.status();
} else {
service_config_json_ = absl::StrCat("grpc_config=", *service_config);
}
result = OnResolvedLocked();
}
if (result.has_value()) {
resolver_->OnRequestComplete(std::move(*result));
}
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
MaybePopulateAddressesLocked(Resolver::Result* result) {
if (addresses_.empty()) return;
result->addresses = std::move(addresses_);
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
MaybePopulateBalancerAddressesLocked(Resolver::Result* result) {
if (!balancer_addresses_.empty()) {
result->args =
SetGrpcLbBalancerAddresses(result->args, balancer_addresses_);
}
}
void EventEngineClientChannelDNSResolver::EventEngineDNSRequestWrapper::
MaybePopulateServiceConfigLocked(Resolver::Result* result) {
// This function is called only if we are returning addresses. In that case,
// we currently ignore TXT lookup failures.
// TODO(roth): Consider differentiating between NXDOMAIN and other failures,
// so that we can return an error in the non-NXDOMAIN case.
if (!service_config_json_.ok()) return;
// TXT lookup succeeded, so parse the config.
auto service_config = ChooseServiceConfig(*service_config_json_);
if (!service_config.ok()) {
result->service_config = absl::UnavailableError(absl::StrCat(
"failed to parse service config: ", service_config.status().message()));
return;
}
if (service_config->empty()) return;
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p selected service config choice: %s",
event_engine_resolver_.get(), service_config->c_str());
result->service_config =
ServiceConfigImpl::Create(resolver_->channel_args(), *service_config);
if (!result->service_config.ok()) {
result->service_config = absl::UnavailableError(
absl::StrCat("failed to parse service config: ",
result->service_config.status().message()));
}
}
absl::optional<Resolver::Result> EventEngineClientChannelDNSResolver::
EventEngineDNSRequestWrapper::OnResolvedLocked() {
if (orphaned_) return absl::nullopt;
// Wait for all requested queries to return.
if (hostname_handle_.has_value() || srv_handle_.has_value() ||
txt_handle_.has_value() ||
number_of_balancer_hostnames_resolved_ !=
balancer_hostname_handles_.size()) {
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p OnResolved() waiting for results (hostname: %s, "
"srv: %s, "
"txt: %s, "
"balancer addresses: %" PRIuPTR "/%" PRIuPTR " complete",
this, hostname_handle_.has_value() ? "waiting" : "done",
srv_handle_.has_value() ? "waiting" : "done",
txt_handle_.has_value() ? "waiting" : "done",
number_of_balancer_hostnames_resolved_,
balancer_hostname_handles_.size());
return absl::nullopt;
}
GRPC_EVENT_ENGINE_RESOLVER_TRACE(
"DNSResolver::%p OnResolvedLocked() proceeding", this);
Resolver::Result result;
result.args = resolver_->channel_args();
// If both addresses and balancer addresses failed, return an error for both
// addresses and service config.
if (addresses_.empty() && balancer_addresses_.empty()) {
absl::Status status = errors_.status(
absl::StatusCode::kUnavailable,
absl::StrCat("errors resolving ", resolver_->name_to_resolve()));
GRPC_EVENT_ENGINE_RESOLVER_TRACE("%s", status.message().data());
result.addresses = status;
result.service_config = status;
return std::move(result);
}
if (!errors_.ok()) {
result.resolution_note = errors_.message(
absl::StrCat("errors resolving ", resolver_->name_to_resolve()));
}
// We have at least one of addresses or balancer addresses, so we're going to
// return a non-error for addresses.
result.addresses.emplace();
MaybePopulateAddressesLocked(&result);
MaybePopulateServiceConfigLocked(&result);
MaybePopulateBalancerAddressesLocked(&result);
return std::move(result);
}
} // namespace
bool EventEngineClientChannelDNSResolverFactory::IsValidUri(
const URI& uri) const {
if (absl::StripPrefix(uri.path(), "/").empty()) {
gpr_log(GPR_ERROR, "no server name supplied in dns URI");
return false;
}
return true;
}
OrphanablePtr<Resolver>
EventEngineClientChannelDNSResolverFactory::CreateResolver(
ResolverArgs args) const {
Duration min_time_between_resolutions = std::max(
Duration::Zero(), args.args
.GetDurationFromIntMillis(
GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS)
.value_or(Duration::Seconds(30)));
return MakeOrphanable<EventEngineClientChannelDNSResolver>(
std::move(args), min_time_between_resolutions);
}
} // namespace grpc_core

@ -0,0 +1,35 @@
// Copyright 2023 The 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_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_EVENT_ENGINE_CLIENT_CHANNEL_RESOLVER_H
#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_EVENT_ENGINE_CLIENT_CHANNEL_RESOLVER_H
#include <grpc/support/port_platform.h>
#include "absl/strings/string_view.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/resolver/resolver.h"
#include "src/core/lib/resolver/resolver_factory.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_core {
class EventEngineClientChannelDNSResolverFactory : public ResolverFactory {
public:
absl::string_view scheme() const override { return "dns"; }
bool IsValidUri(const URI& uri) const override;
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_EVENT_ENGINE_CLIENT_CHANNEL_RESOLVER_H

@ -0,0 +1,97 @@
// Copyright 2023 The 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/client_channel/resolver/dns/event_engine/service_config_helper.h"
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/iomgr/gethostname.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/json/json_reader.h"
#include "src/core/lib/json/json_writer.h"
namespace grpc_core {
namespace {
struct ServiceConfigChoice {
std::vector<std::string> client_language;
int percentage = -1;
std::vector<std::string> client_hostname;
Json::Object service_config;
static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
static const auto* loader =
JsonObjectLoader<ServiceConfigChoice>()
.OptionalField("clientLanguage",
&ServiceConfigChoice::client_language)
.OptionalField("percentage", &ServiceConfigChoice::percentage)
.OptionalField("clientHostname",
&ServiceConfigChoice::client_hostname)
.Field("serviceConfig", &ServiceConfigChoice::service_config)
.Finish();
return loader;
}
};
bool vector_contains(const std::vector<std::string>& v,
const std::string& value) {
return std::find(v.begin(), v.end(), value) != v.end();
}
} // namespace
absl::StatusOr<std::string> ChooseServiceConfig(
absl::string_view service_config_json) {
auto json = JsonParse(service_config_json);
GRPC_RETURN_IF_ERROR(json.status());
auto choices = LoadFromJson<std::vector<ServiceConfigChoice>>(*json);
GRPC_RETURN_IF_ERROR(choices.status());
for (const ServiceConfigChoice& choice : *choices) {
// Check client language, if specified.
if (!choice.client_language.empty() &&
!vector_contains(choice.client_language, "c++")) {
continue;
}
// Check client hostname, if specified.
if (!choice.client_hostname.empty()) {
const char* hostname = grpc_gethostname();
if (!vector_contains(choice.client_hostname, hostname)) {
continue;
}
}
// Check percentage, if specified.
if (choice.percentage != -1) {
int random_pct = rand() % 100;
if (random_pct > choice.percentage || choice.percentage == 0) {
continue;
}
}
return JsonDump(choice.service_config);
}
// No matching service config was found
return "";
}
} // namespace grpc_core

@ -0,0 +1,32 @@
// Copyright 2023 The 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_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_SERVICE_CONFIG_HELPER_H
#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_SERVICE_CONFIG_HELPER_H
#include <grpc/support/port_platform.h>
#include <string>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
namespace grpc_core {
absl::StatusOr<std::string> ChooseServiceConfig(
absl::string_view service_config_json);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_EVENT_ENGINE_SERVICE_CONFIG_HELPER_H

@ -25,7 +25,6 @@
#include "absl/functional/bind_front.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
@ -37,7 +36,6 @@
#include "src/core/ext/filters/client_channel/resolver/polling_resolver.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/config_vars.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
@ -179,17 +177,8 @@ class NativeClientChannelDNSResolverFactory : public ResolverFactory {
} // namespace
void RegisterNativeDnsResolver(CoreConfiguration::Builder* builder) {
if (absl::EqualsIgnoreCase(ConfigVars::Get().DnsResolver(), "native")) {
gpr_log(GPR_DEBUG, "Using native dns resolver");
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<NativeClientChannelDNSResolverFactory>());
} else {
if (!builder->resolver_registry()->HasResolverFactory("dns")) {
gpr_log(GPR_DEBUG, "Using native dns resolver");
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<NativeClientChannelDNSResolverFactory>());
}
}
builder->resolver_registry()->RegisterResolverFactory(
std::make_unique<NativeClientChannelDNSResolverFactory>());
}
} // namespace grpc_core

@ -0,0 +1,24 @@
// Copyright 2022 The 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_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_NATIVE_DNS_RESOLVER_H
#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_NATIVE_DNS_RESOLVER_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/config/core_configuration.h"
namespace grpc_core {
void RegisterNativeDnsResolver(CoreConfiguration::Builder* builder);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_NATIVE_DNS_RESOLVER_H

@ -16,6 +16,7 @@
#include "src/core/lib/debug/trace.h"
grpc_core::TraceFlag grpc_event_engine_trace(false, "event_engine");
grpc_core::TraceFlag grpc_event_engine_dns_trace(false, "event_engine_dns");
grpc_core::TraceFlag grpc_event_engine_endpoint_trace(false,
"event_engine_endpoint");
grpc_core::TraceFlag grpc_event_engine_endpoint_data_trace(

@ -21,6 +21,7 @@
#include "src/core/lib/debug/trace.h"
extern grpc_core::TraceFlag grpc_event_engine_trace;
extern grpc_core::TraceFlag grpc_event_engine_dns_trace;
extern grpc_core::TraceFlag grpc_event_engine_endpoint_data_trace;
extern grpc_core::TraceFlag grpc_event_engine_poller_trace;
extern grpc_core::TraceFlag grpc_event_engine_endpoint_trace;
@ -40,4 +41,9 @@ extern grpc_core::TraceFlag grpc_event_engine_endpoint_trace;
gpr_log(GPR_DEBUG, "(event_engine poller) " format, __VA_ARGS__); \
}
#define GRPC_EVENT_ENGINE_DNS_TRACE(format, ...) \
if (GRPC_TRACE_FLAG_ENABLED(grpc_event_engine_dns_trace)) { \
gpr_log(GPR_DEBUG, "(event_engine dns) " format, __VA_ARGS__); \
}
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_TRACE_H

@ -58,6 +58,8 @@ const char* const description_schedule_cancellation_over_write =
"Allow cancellation op to be scheduled over a write";
const char* const description_trace_record_callops =
"Enables tracing of call batch initiation and completion.";
const char* const description_event_engine_dns =
"If set, use EventEngine DNSResolver for client channel resolution";
} // namespace
namespace grpc_core {
@ -82,6 +84,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"schedule_cancellation_over_write",
description_schedule_cancellation_over_write, false},
{"trace_record_callops", description_trace_record_callops, false},
{"event_engine_dns", description_event_engine_dns, false},
};
} // namespace grpc_core

@ -74,6 +74,7 @@ inline bool IsTransportSuppliesClientLatencyEnabled() { return false; }
inline bool IsEventEngineListenerEnabled() { return false; }
inline bool IsScheduleCancellationOverWriteEnabled() { return false; }
inline bool IsTraceRecordCallopsEnabled() { return false; }
inline bool IsEventEngineDnsEnabled() { return false; }
#else
#define GRPC_EXPERIMENT_IS_INCLUDED_TCP_FRAME_SIZE_TUNING
inline bool IsTcpFrameSizeTuningEnabled() { return IsExperimentEnabled(0); }
@ -115,8 +116,10 @@ inline bool IsScheduleCancellationOverWriteEnabled() {
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() { return IsExperimentEnabled(14); }
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_DNS
inline bool IsEventEngineDnsEnabled() { return IsExperimentEnabled(15); }
constexpr const size_t kNumExperiments = 15;
constexpr const size_t kNumExperiments = 16;
extern const ExperimentMetadata g_experiment_metadata[kNumExperiments];
#endif

@ -148,3 +148,10 @@
expiry: 2023/07/01
owner: vigneshbabu@google.com
test_tags: []
- name: event_engine_dns
description:
If set, use EventEngine DNSResolver for client channel resolution
default: false
expiry: 2023/06/01
owner: yijiem@google.com
test_tags: []

@ -50,9 +50,8 @@ extern void RegisterServiceConfigChannelArgFilter(
extern void RegisterExtraFilters(CoreConfiguration::Builder* builder);
extern void RegisterResourceQuota(CoreConfiguration::Builder* builder);
extern void FaultInjectionFilterRegister(CoreConfiguration::Builder* builder);
extern void RegisterDnsResolver(CoreConfiguration::Builder* builder);
extern void RegisterBackendMetricFilter(CoreConfiguration::Builder* builder);
extern void RegisterNativeDnsResolver(CoreConfiguration::Builder* builder);
extern void RegisterAresDnsResolver(CoreConfiguration::Builder* builder);
extern void RegisterSockaddrResolver(CoreConfiguration::Builder* builder);
extern void RegisterFakeResolver(CoreConfiguration::Builder* builder);
extern void RegisterPriorityLbPolicy(CoreConfiguration::Builder* builder);
@ -98,8 +97,7 @@ void BuildCoreConfiguration(CoreConfiguration::Builder* builder) {
RegisterServiceConfigChannelArgFilter(builder);
RegisterResourceQuota(builder);
FaultInjectionFilterRegister(builder);
RegisterAresDnsResolver(builder);
RegisterNativeDnsResolver(builder);
RegisterDnsResolver(builder);
RegisterSockaddrResolver(builder);
RegisterFakeResolver(builder);
RegisterHttpProxyMapper(builder);

@ -64,6 +64,9 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc',

@ -272,7 +272,8 @@ void CheckServiceConfigResultLocked(const char* service_config_json,
EXPECT_EQ(service_config_json, args->expected_service_config_string);
}
if (args->expected_service_config_error.empty()) {
EXPECT_TRUE(service_config_error.ok());
EXPECT_TRUE(service_config_error.ok())
<< "Actual error: " << service_config_error.ToString();
} else {
EXPECT_THAT(service_config_error.ToString(),
testing::HasSubstr(args->expected_service_config_error));

@ -541,7 +541,7 @@ current_test_subprocess = subprocess.Popen([
'--do_ordered_address_comparison', 'False',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '',
'--expected_service_config_error', 'field:clientLanguage error:should be of type array',
'--expected_service_config_error', 'clientLanguage error:is not an array',
'--expected_lb_policy', '',
'--enable_srv_queries', 'True',
'--enable_txt_queries', 'True',
@ -559,7 +559,7 @@ current_test_subprocess = subprocess.Popen([
'--do_ordered_address_comparison', 'False',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '',
'--expected_service_config_error', 'field:percentage error:should be of type number',
'--expected_service_config_error', 'percentage error:failed to parse number',
'--expected_lb_policy', '',
'--enable_srv_queries', 'True',
'--enable_txt_queries', 'True',

@ -403,7 +403,7 @@ resolver_component_tests:
- {address: '1.2.3.4:443', is_balancer: false}
do_ordered_address_comparison: false
expected_chosen_service_config: null
expected_service_config_error: 'field:clientLanguage error:should be of type array'
expected_service_config_error: 'clientLanguage error:is not an array'
expected_lb_policy: null
enable_srv_queries: true
enable_txt_queries: true
@ -419,7 +419,7 @@ resolver_component_tests:
- {address: '1.2.3.4:443', is_balancer: false}
do_ordered_address_comparison: false
expected_chosen_service_config: null
expected_service_config_error: 'field:percentage error:should be of type number'
expected_service_config_error: 'percentage error:failed to parse number'
expected_lb_policy: null
enable_srv_queries: true
enable_txt_queries: true
@ -429,7 +429,7 @@ resolver_component_tests:
ipv4-svc_cfg_bad_percentage:
- {TTL: '2100', data: 1.2.3.4, type: A}
_grpc_config.ipv4-svc_cfg_bad_percentage:
- {TTL: '2100', data: 'grpc_config=[{"percentage":"0","serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]',
- {TTL: '2100', data: 'grpc_config=[{"percentage":"arst","serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]',
type: TXT}
- expected_addrs:
- {address: '1.2.3.4:443', is_balancer: false}

@ -1151,6 +1151,7 @@ src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/local_subchannel_pool.h \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
@ -1158,7 +1159,14 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h \
src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc \

@ -959,6 +959,7 @@ src/core/ext/filters/client_channel/resolver/README.md \
src/core/ext/filters/client_channel/resolver/binder/README.md \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
@ -966,8 +967,15 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_plugin.h \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc \
src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h \
src/core/ext/filters/client_channel/resolver/dns/native/README.md \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.h \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h \
src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc \

Loading…
Cancel
Save