Browse Source

Merge branch 'master' into minor-timer-fix

Sree Kuchibhotla 7 years ago
parent
commit
8b6fdca7c5
100 changed files with 2910 additions and 476 deletions
  1. 12 0
      BUILD
  2. 3 1
      BUILDING.md
  3. 104 0
      CMakeLists.txt
  4. 3 3
      CONTRIBUTING.md
  5. 120 1
      Makefile
  6. 4 0
      README.md
  7. 43 0
      TROUBLESHOOTING.md
  8. 25 1
      build.yaml
  9. 5 0
      config.m4
  10. 5 0
      config.w32
  11. 19 1
      gRPC-C++.podspec
  12. 18 2
      gRPC-Core.podspec
  13. 9 7
      grpc.def
  14. 11 0
      grpc.gemspec
  15. 7 0
      grpc.gyp
  16. 30 0
      include/grpc/grpc_security.h
  17. 112 0
      include/grpc/impl/codegen/log.h
  18. 2 0
      include/grpc/module.modulemap
  19. 2 88
      include/grpc/support/log.h
  20. 2 56
      include/grpcpp/generic/async_generic_service.h
  21. 81 0
      include/grpcpp/impl/codegen/async_generic_service.h
  22. 6 5
      include/grpcpp/impl/codegen/method_handler_impl.h
  23. 42 2
      include/grpcpp/impl/codegen/rpc_service_method.h
  24. 19 2
      include/grpcpp/impl/codegen/service_type.h
  25. 3 2
      include/grpcpp/impl/server_builder_plugin.h
  26. 11 0
      package.xml
  27. 1 1
      requirements.txt
  28. 89 38
      src/compiler/cpp_generator.cc
  29. 80 0
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  30. 58 0
      src/core/ext/filters/client_channel/client_channel_channelz.h
  31. 9 0
      src/core/ext/filters/client_channel/client_channel_plugin.cc
  32. 8 2
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
  33. 6 5
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  34. 4 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
  35. 22 21
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  36. 4 0
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  37. 19 6
      src/core/ext/filters/client_channel/subchannel.cc
  38. 3 0
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  39. 22 24
      src/core/lib/channel/channel_stack.cc
  40. 8 21
      src/core/lib/channel/channelz.cc
  41. 25 6
      src/core/lib/channel/channelz.h
  42. 7 24
      src/core/lib/channel/channelz_registry.cc
  43. 12 8
      src/core/lib/channel/channelz_registry.h
  44. 28 0
      src/core/lib/gpr/alloc.h
  45. 8 8
      src/core/lib/gpr/arena.cc
  46. 2 2
      src/core/lib/gprpp/memory.h
  47. 5 0
      src/core/lib/gprpp/ref_counted_ptr.h
  48. 1 1
      src/core/lib/gprpp/thd_posix.cc
  49. 2 0
      src/core/lib/iomgr/iomgr.cc
  50. 5 0
      src/core/lib/iomgr/iomgr.h
  51. 0 1
      src/core/lib/iomgr/timer_manager.cc
  52. 4 4
      src/core/lib/security/context/security_context.cc
  53. 2 1
      src/core/lib/security/context/security_context.h
  54. 77 0
      src/core/lib/security/credentials/local/local_credentials.cc
  55. 40 0
      src/core/lib/security/credentials/local/local_credentials.h
  56. 245 0
      src/core/lib/security/security_connector/local_security_connector.cc
  57. 58 0
      src/core/lib/security/security_connector/local_security_connector.h
  58. 5 1
      src/core/lib/security/transport/client_auth_filter.cc
  59. 3 4
      src/core/lib/security/transport/server_auth_filter.cc
  60. 4 7
      src/core/lib/surface/call.cc
  61. 15 3
      src/core/lib/surface/channel.cc
  62. 2 1
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  63. 47 1
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
  64. 3 1
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
  65. 12 11
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
  66. 7 2
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
  67. 209 0
      src/core/tsi/local_transport_security.cc
  68. 51 0
      src/core/tsi/local_transport_security.h
  69. 5 1
      src/cpp/README.md
  70. 1 4
      src/cpp/server/server_builder.cc
  71. 15 0
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
  72. 15 0
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
  73. 5 0
      src/objective-c/GRPCClient/private/GRPCHost.h
  74. 15 0
      src/objective-c/GRPCClient/private/GRPCHost.m
  75. 92 0
      src/objective-c/NetworkTransitionBehavior.md
  76. 32 0
      src/objective-c/README-CFSTREAM.md
  77. 43 0
      src/objective-c/tests/GRPCClientTests.m
  78. 28 13
      src/php/lib/Grpc/BaseStub.php
  79. 33 0
      src/php/lib/Grpc/CallInvoker.php
  80. 47 0
      src/php/lib/Grpc/DefaultCallInvoker.php
  81. 227 0
      src/php/tests/unit_tests/CallInvokerTest.php
  82. 1 0
      src/php/tests/unit_tests/InterceptorTest.php
  83. 4 0
      src/python/grpcio/grpc_core_dependencies.py
  84. 18 14
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  85. 28 22
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  86. 1 1
      templates/Makefile.template
  87. 9 1
      templates/gRPC-C++.podspec.template
  88. 3 0
      templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template
  89. 19 0
      test/build/no-maybe-uninitialized.c
  90. 9 0
      test/core/channel/channelz_registry_test.cc
  91. 154 0
      test/core/end2end/fixtures/h2_local.cc
  92. 4 0
      test/core/end2end/gen_build_yaml.py
  93. 1 0
      test/core/end2end/generate_tests.bzl
  94. 2 0
      test/core/security/check_gcp_environment_linux_test.cc
  95. 2 0
      test/core/security/check_gcp_environment_windows_test.cc
  96. 10 7
      test/core/surface/public_headers_must_be_c89.c
  97. 17 9
      test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
  98. 26 15
      test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
  99. 114 13
      test/cpp/codegen/compiler_test_golden
  100. 20 0
      test/cpp/end2end/BUILD

+ 12 - 0
BUILD

@@ -540,6 +540,7 @@ grpc_cc_library(
         "src/core/lib/profiling/stap_timers.cc",
         "src/core/lib/profiling/stap_timers.cc",
     ],
     ],
     hdrs = [
     hdrs = [
+        "src/core/lib/gpr/alloc.h",
         "src/core/lib/gpr/arena.h",
         "src/core/lib/gpr/arena.h",
         "src/core/lib/gpr/env.h",
         "src/core/lib/gpr/env.h",
         "src/core/lib/gpr/host_port.h",
         "src/core/lib/gpr/host_port.h",
@@ -580,6 +581,7 @@ grpc_cc_library(
         "include/grpc/impl/codegen/fork.h",
         "include/grpc/impl/codegen/fork.h",
         "include/grpc/impl/codegen/gpr_slice.h",
         "include/grpc/impl/codegen/gpr_slice.h",
         "include/grpc/impl/codegen/gpr_types.h",
         "include/grpc/impl/codegen/gpr_types.h",
+        "include/grpc/impl/codegen/log.h",
         "include/grpc/impl/codegen/port_platform.h",
         "include/grpc/impl/codegen/port_platform.h",
         "include/grpc/impl/codegen/sync.h",
         "include/grpc/impl/codegen/sync.h",
         "include/grpc/impl/codegen/sync_custom.h",
         "include/grpc/impl/codegen/sync_custom.h",
@@ -858,6 +860,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/exec_ctx.h",
         "src/core/lib/iomgr/exec_ctx.h",
         "src/core/lib/iomgr/executor.h",
         "src/core/lib/iomgr/executor.h",
         "src/core/lib/iomgr/gethostname.h",
         "src/core/lib/iomgr/gethostname.h",
+        "src/core/lib/iomgr/gevent_util.h",
         "src/core/lib/iomgr/iocp_windows.h",
         "src/core/lib/iomgr/iocp_windows.h",
         "src/core/lib/iomgr/iomgr.h",
         "src/core/lib/iomgr/iomgr.h",
         "src/core/lib/iomgr/iomgr_custom.h",
         "src/core/lib/iomgr/iomgr_custom.h",
@@ -1026,6 +1029,7 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/backup_poller.cc",
         "src/core/ext/filters/client_channel/backup_poller.cc",
         "src/core/ext/filters/client_channel/channel_connectivity.cc",
         "src/core/ext/filters/client_channel/channel_connectivity.cc",
         "src/core/ext/filters/client_channel/client_channel.cc",
         "src/core/ext/filters/client_channel/client_channel.cc",
+        "src/core/ext/filters/client_channel/client_channel_channelz.cc",
         "src/core/ext/filters/client_channel/client_channel_factory.cc",
         "src/core/ext/filters/client_channel/client_channel_factory.cc",
         "src/core/ext/filters/client_channel/client_channel_plugin.cc",
         "src/core/ext/filters/client_channel/client_channel_plugin.cc",
         "src/core/ext/filters/client_channel/connector.cc",
         "src/core/ext/filters/client_channel/connector.cc",
@@ -1048,6 +1052,7 @@ grpc_cc_library(
     hdrs = [
     hdrs = [
         "src/core/ext/filters/client_channel/backup_poller.h",
         "src/core/ext/filters/client_channel/backup_poller.h",
         "src/core/ext/filters/client_channel/client_channel.h",
         "src/core/ext/filters/client_channel/client_channel.h",
+        "src/core/ext/filters/client_channel/client_channel_channelz.h",
         "src/core/ext/filters/client_channel/client_channel_factory.h",
         "src/core/ext/filters/client_channel/client_channel_factory.h",
         "src/core/ext/filters/client_channel/connector.h",
         "src/core/ext/filters/client_channel/connector.h",
         "src/core/ext/filters/client_channel/http_connect_handshaker.h",
         "src/core/ext/filters/client_channel/http_connect_handshaker.h",
@@ -1441,10 +1446,12 @@ grpc_cc_library(
         "src/core/lib/security/credentials/jwt/json_token.cc",
         "src/core/lib/security/credentials/jwt/json_token.cc",
         "src/core/lib/security/credentials/jwt/jwt_credentials.cc",
         "src/core/lib/security/credentials/jwt/jwt_credentials.cc",
         "src/core/lib/security/credentials/jwt/jwt_verifier.cc",
         "src/core/lib/security/credentials/jwt/jwt_verifier.cc",
+        "src/core/lib/security/credentials/local/local_credentials.cc",
         "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
         "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
         "src/core/lib/security/credentials/plugin/plugin_credentials.cc",
         "src/core/lib/security/credentials/plugin/plugin_credentials.cc",
         "src/core/lib/security/credentials/ssl/ssl_credentials.cc",
         "src/core/lib/security/credentials/ssl/ssl_credentials.cc",
         "src/core/lib/security/security_connector/alts_security_connector.cc",
         "src/core/lib/security/security_connector/alts_security_connector.cc",
+        "src/core/lib/security/security_connector/local_security_connector.cc",
         "src/core/lib/security/security_connector/security_connector.cc",
         "src/core/lib/security/security_connector/security_connector.cc",
         "src/core/lib/security/transport/client_auth_filter.cc",
         "src/core/lib/security/transport/client_auth_filter.cc",
         "src/core/lib/security/transport/secure_endpoint.cc",
         "src/core/lib/security/transport/secure_endpoint.cc",
@@ -1467,10 +1474,12 @@ grpc_cc_library(
         "src/core/lib/security/credentials/jwt/json_token.h",
         "src/core/lib/security/credentials/jwt/json_token.h",
         "src/core/lib/security/credentials/jwt/jwt_credentials.h",
         "src/core/lib/security/credentials/jwt/jwt_credentials.h",
         "src/core/lib/security/credentials/jwt/jwt_verifier.h",
         "src/core/lib/security/credentials/jwt/jwt_verifier.h",
+        "src/core/lib/security/credentials/local/local_credentials.h",
         "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
         "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
         "src/core/lib/security/credentials/plugin/plugin_credentials.h",
         "src/core/lib/security/credentials/plugin/plugin_credentials.h",
         "src/core/lib/security/credentials/ssl/ssl_credentials.h",
         "src/core/lib/security/credentials/ssl/ssl_credentials.h",
         "src/core/lib/security/security_connector/alts_security_connector.h",
         "src/core/lib/security/security_connector/alts_security_connector.h",
+        "src/core/lib/security/security_connector/local_security_connector.h",
         "src/core/lib/security/security_connector/security_connector.h",
         "src/core/lib/security/security_connector/security_connector.h",
         "src/core/lib/security/transport/auth_filters.h",
         "src/core/lib/security/transport/auth_filters.h",
         "src/core/lib/security/transport/secure_endpoint.h",
         "src/core/lib/security/transport/secure_endpoint.h",
@@ -1809,6 +1818,7 @@ grpc_cc_library(
         "src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
         "src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
         "src/core/tsi/alts_transport_security.cc",
         "src/core/tsi/alts_transport_security.cc",
         "src/core/tsi/fake_transport_security.cc",
         "src/core/tsi/fake_transport_security.cc",
+        "src/core/tsi/local_transport_security.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_cache.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_cache.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc",
         "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc",
@@ -1822,6 +1832,7 @@ grpc_cc_library(
         "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h",
         "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h",
         "src/core/tsi/alts/handshaker/alts_tsi_utils.h",
         "src/core/tsi/alts/handshaker/alts_tsi_utils.h",
         "src/core/tsi/alts_transport_security.h",
         "src/core/tsi/alts_transport_security.h",
+        "src/core/tsi/local_transport_security.h",
         "src/core/tsi/fake_transport_security.h",
         "src/core/tsi/fake_transport_security.h",
         "src/core/tsi/ssl/session_cache/ssl_session.h",
         "src/core/tsi/ssl/session_cache/ssl_session.h",
         "src/core/tsi/ssl/session_cache/ssl_session_cache.h",
         "src/core/tsi/ssl/session_cache/ssl_session_cache.h",
@@ -1901,6 +1912,7 @@ grpc_cc_library(
         "include/grpc++/impl/codegen/stub_options.h",
         "include/grpc++/impl/codegen/stub_options.h",
         "include/grpc++/impl/codegen/sync_stream.h",
         "include/grpc++/impl/codegen/sync_stream.h",
         "include/grpc++/impl/codegen/time.h",
         "include/grpc++/impl/codegen/time.h",
+        "include/grpcpp/impl/codegen/async_generic_service.h",
         "include/grpcpp/impl/codegen/async_stream.h",
         "include/grpcpp/impl/codegen/async_stream.h",
         "include/grpcpp/impl/codegen/async_unary_call.h",
         "include/grpcpp/impl/codegen/async_unary_call.h",
         "include/grpcpp/impl/codegen/byte_buffer.h",
         "include/grpcpp/impl/codegen/byte_buffer.h",

+ 3 - 1
BUILDING.md

@@ -112,9 +112,11 @@ From the grpc repository root
 
 
 ## bazel
 ## bazel
 
 
+See [Installing Bazel](https://docs.bazel.build/versions/master/install.html) for instructions how to install bazel on your system.
+
 From the grpc repository root
 From the grpc repository root
 ```
 ```
-bazel build :all
+$ bazel build :all
 ```
 ```
 
 
 ## cmake: Windows, Using Visual Studio 2015 or 2017 (can only build with OPENSSL_NO_ASM).
 ## cmake: Windows, Using Visual Studio 2015 or 2017 (can only build with OPENSSL_NO_ASM).

+ 104 - 0
CMakeLists.txt

@@ -433,6 +433,9 @@ endif()
 add_dependencies(buildtests_c h2_full+trace_test)
 add_dependencies(buildtests_c h2_full+trace_test)
 add_dependencies(buildtests_c h2_full+workarounds_test)
 add_dependencies(buildtests_c h2_full+workarounds_test)
 add_dependencies(buildtests_c h2_http_proxy_test)
 add_dependencies(buildtests_c h2_http_proxy_test)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_c h2_local_test)
+endif()
 add_dependencies(buildtests_c h2_oauth2_test)
 add_dependencies(buildtests_c h2_oauth2_test)
 add_dependencies(buildtests_c h2_proxy_test)
 add_dependencies(buildtests_c h2_proxy_test)
 add_dependencies(buildtests_c h2_sockpair_test)
 add_dependencies(buildtests_c h2_sockpair_test)
@@ -616,6 +619,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx qps_openloop_test)
 add_dependencies(buildtests_cxx qps_openloop_test)
 endif()
 endif()
 add_dependencies(buildtests_cxx qps_worker)
 add_dependencies(buildtests_cxx qps_worker)
+add_dependencies(buildtests_cxx raw_end2end_test)
 add_dependencies(buildtests_cxx reconnect_interop_client)
 add_dependencies(buildtests_cxx reconnect_interop_client)
 add_dependencies(buildtests_cxx reconnect_interop_server)
 add_dependencies(buildtests_cxx reconnect_interop_server)
 add_dependencies(buildtests_cxx ref_counted_ptr_test)
 add_dependencies(buildtests_cxx ref_counted_ptr_test)
@@ -870,6 +874,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -1125,10 +1130,12 @@ add_library(grpc
   src/core/lib/security/credentials/jwt/json_token.cc
   src/core/lib/security/credentials/jwt/json_token.cc
   src/core/lib/security/credentials/jwt/jwt_credentials.cc
   src/core/lib/security/credentials/jwt/jwt_credentials.cc
   src/core/lib/security/credentials/jwt/jwt_verifier.cc
   src/core/lib/security/credentials/jwt/jwt_verifier.cc
+  src/core/lib/security/credentials/local/local_credentials.cc
   src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   src/core/lib/security/credentials/plugin/plugin_credentials.cc
   src/core/lib/security/credentials/plugin/plugin_credentials.cc
   src/core/lib/security/credentials/ssl/ssl_credentials.cc
   src/core/lib/security/credentials/ssl/ssl_credentials.cc
   src/core/lib/security/security_connector/alts_security_connector.cc
   src/core/lib/security/security_connector/alts_security_connector.cc
+  src/core/lib/security/security_connector/local_security_connector.cc
   src/core/lib/security/security_connector/security_connector.cc
   src/core/lib/security/security_connector/security_connector.cc
   src/core/lib/security/transport/client_auth_filter.cc
   src/core/lib/security/transport/client_auth_filter.cc
   src/core/lib/security/transport/secure_endpoint.cc
   src/core/lib/security/transport/secure_endpoint.cc
@@ -1180,6 +1187,7 @@ add_library(grpc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -1201,6 +1209,7 @@ add_library(grpc
   src/core/ext/filters/deadline/deadline_filter.cc
   src/core/ext/filters/deadline/deadline_filter.cc
   src/core/tsi/alts_transport_security.cc
   src/core/tsi/alts_transport_security.cc
   src/core/tsi/fake_transport_security.cc
   src/core/tsi/fake_transport_security.cc
+  src/core/tsi/local_transport_security.cc
   src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
@@ -1290,6 +1299,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -1514,6 +1524,7 @@ add_library(grpc_cronet
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -1546,10 +1557,12 @@ add_library(grpc_cronet
   src/core/lib/security/credentials/jwt/json_token.cc
   src/core/lib/security/credentials/jwt/json_token.cc
   src/core/lib/security/credentials/jwt/jwt_credentials.cc
   src/core/lib/security/credentials/jwt/jwt_credentials.cc
   src/core/lib/security/credentials/jwt/jwt_verifier.cc
   src/core/lib/security/credentials/jwt/jwt_verifier.cc
+  src/core/lib/security/credentials/local/local_credentials.cc
   src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   src/core/lib/security/credentials/plugin/plugin_credentials.cc
   src/core/lib/security/credentials/plugin/plugin_credentials.cc
   src/core/lib/security/credentials/ssl/ssl_credentials.cc
   src/core/lib/security/credentials/ssl/ssl_credentials.cc
   src/core/lib/security/security_connector/alts_security_connector.cc
   src/core/lib/security/security_connector/alts_security_connector.cc
+  src/core/lib/security/security_connector/local_security_connector.cc
   src/core/lib/security/security_connector/security_connector.cc
   src/core/lib/security/security_connector/security_connector.cc
   src/core/lib/security/transport/client_auth_filter.cc
   src/core/lib/security/transport/client_auth_filter.cc
   src/core/lib/security/transport/secure_endpoint.cc
   src/core/lib/security/transport/secure_endpoint.cc
@@ -1600,6 +1613,7 @@ add_library(grpc_cronet
   src/core/ext/transport/chttp2/client/chttp2_connector.cc
   src/core/ext/transport/chttp2/client/chttp2_connector.cc
   src/core/tsi/alts_transport_security.cc
   src/core/tsi/alts_transport_security.cc
   src/core/tsi/fake_transport_security.cc
   src/core/tsi/fake_transport_security.cc
+  src/core/tsi/local_transport_security.cc
   src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
   src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
@@ -1659,6 +1673,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -1868,6 +1883,7 @@ add_library(grpc_test_util
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -1973,6 +1989,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -2174,6 +2191,7 @@ add_library(grpc_test_util_unsecure
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -2279,6 +2297,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -2493,6 +2512,7 @@ add_library(grpc_unsecure
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -2594,6 +2614,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -2911,6 +2932,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -2967,6 +2989,7 @@ foreach(_hdr
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/time.h
   include/grpc++/impl/codegen/time.h
+  include/grpcpp/impl/codegen/async_generic_service.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/byte_buffer.h
   include/grpcpp/impl/codegen/byte_buffer.h
@@ -3297,6 +3320,7 @@ add_library(grpc++_cronet
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/backup_poller.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/channel_connectivity.cc
   src/core/ext/filters/client_channel/client_channel.cc
   src/core/ext/filters/client_channel/client_channel.cc
+  src/core/ext/filters/client_channel/client_channel_channelz.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/connector.cc
   src/core/ext/filters/client_channel/connector.cc
@@ -3475,6 +3499,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -3531,6 +3556,7 @@ foreach(_hdr
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/time.h
   include/grpc++/impl/codegen/time.h
+  include/grpcpp/impl/codegen/async_generic_service.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/byte_buffer.h
   include/grpcpp/impl/codegen/byte_buffer.h
@@ -3940,6 +3966,7 @@ foreach(_hdr
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/time.h
   include/grpc++/impl/codegen/time.h
+  include/grpcpp/impl/codegen/async_generic_service.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/byte_buffer.h
   include/grpcpp/impl/codegen/byte_buffer.h
@@ -3985,6 +4012,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -4116,6 +4144,7 @@ foreach(_hdr
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/time.h
   include/grpc++/impl/codegen/time.h
+  include/grpcpp/impl/codegen/async_generic_service.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/byte_buffer.h
   include/grpcpp/impl/codegen/byte_buffer.h
@@ -4161,6 +4190,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -4375,6 +4405,7 @@ foreach(_hdr
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/fork.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/log.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_custom.h
   include/grpc/impl/codegen/sync_custom.h
@@ -4431,6 +4462,7 @@ foreach(_hdr
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/sync_stream.h
   include/grpc++/impl/codegen/time.h
   include/grpc++/impl/codegen/time.h
+  include/grpcpp/impl/codegen/async_generic_service.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_stream.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/async_unary_call.h
   include/grpcpp/impl/codegen/byte_buffer.h
   include/grpcpp/impl/codegen/byte_buffer.h
@@ -13257,6 +13289,46 @@ target_link_libraries(qps_worker
 endif (gRPC_BUILD_TESTS)
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
 
+add_executable(raw_end2end_test
+  test/cpp/end2end/raw_end2end_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(raw_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+  PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+  PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+  PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+  PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+  PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(raw_end2end_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(reconnect_interop_client
 add_executable(reconnect_interop_client
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
@@ -15258,6 +15330,38 @@ target_link_libraries(h2_http_proxy_test
   gpr
   gpr
 )
 )
 
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(h2_local_test
+  test/core/end2end/fixtures/h2_local.cc
+)
+
+
+target_include_directories(h2_local_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+  PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+  PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+  PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+  PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+  PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
+)
+
+target_link_libraries(h2_local_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif()
 endif (gRPC_BUILD_TESTS)
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
 

+ 3 - 3
CONTRIBUTING.md

@@ -24,9 +24,9 @@ script that unifies the experience of building and testing gRPC in different
 languages and on different platforms is provided.
 languages and on different platforms is provided.
 
 
 To build gRPC in the language of choice (e.g. `c++`, `csharp`, `php`, `python`, `ruby`, ...)
 To build gRPC in the language of choice (e.g. `c++`, `csharp`, `php`, `python`, `ruby`, ...)
-- Prepare you development environment based on language-specific instructions in `src/YOUR-LANGUAGE` directory.
+- Prepare your development environment based on language-specific instructions in `src/YOUR-LANGUAGE` directory.
 - The language-specific instructions might involve installing C/C++ prerequisites listed in
 - The language-specific instructions might involve installing C/C++ prerequisites listed in
-  [Building gRPC C++: Prerequisites](BUILDING.md#pre-requisites) as gRPC implementations
+  [Building gRPC C++: Prerequisites](BUILDING.md#pre-requisites). This is because gRPC implementations
   in this repository are using the native gRPC "core" library internally.
   in this repository are using the native gRPC "core" library internally.
 - Run
 - Run
   ```
   ```
@@ -38,7 +38,7 @@ To build gRPC in the language of choice (e.g. `c++`, `csharp`, `php`, `python`,
   ```
   ```
 
 
 You can also run `python tools/run_tests/run_tests.py --help` to discover useful command line flags supported. For more details,
 You can also run `python tools/run_tests/run_tests.py --help` to discover useful command line flags supported. For more details,
-see [tools/run_tests](tools/run_tests) where you will also find guidance on how to run various other test suites (e.g. interop tests, benchmarks)
+see [tools/run_tests](tools/run_tests) where you will also find guidance on how to run various other test suites (e.g. interop tests, benchmarks).
 
 
 ## Generated project files
 ## Generated project files
 
 

+ 120 - 1
Makefile

@@ -330,6 +330,12 @@ ifeq ($(HAS_WORKING_NO_UNUSED_BUT_SET_VARIABLE),true)
 W_NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
 W_NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
 NO_W_NO_UNUSED_BUT_SET_VARIABLE=-Wunused-but-set-variable
 NO_W_NO_UNUSED_BUT_SET_VARIABLE=-Wunused-but-set-variable
 endif
 endif
+CHECK_NO_MAYBE_UNINITIALIZED_WORKS_CMD = $(CC) -std=c99 -Werror -Wno-maybe-uninitialized -o $(TMPOUT) -c test/build/no-maybe-uninitialized.c
+HAS_WORKING_NO_MAYBE_UNINITIALIZED = $(shell $(CHECK_NO_MAYBE_UNINITIALIZED_WORKS_CMD) 2> /dev/null && echo true || echo false)
+ifeq ($(HAS_WORKING_NO_MAYBE_UNINITIALIZED),true)
+W_NO_MAYBE_UNINITIALIZED=-Wno-maybe-uninitialized
+NO_W_NO_MAYBE_UNINITIALIZED=-Wmaybe-uninitialized
+endif
 
 
 # The HOST compiler settings are used to compile the protoc plugins.
 # The HOST compiler settings are used to compile the protoc plugins.
 # In most cases, you won't have to change anything, but if you are
 # In most cases, you won't have to change anything, but if you are
@@ -1193,6 +1199,7 @@ qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
 qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
 qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
 qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
 qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
 qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
 qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
+raw_end2end_test: $(BINDIR)/$(CONFIG)/raw_end2end_test
 reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client
 reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client
 reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
 reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
 ref_counted_ptr_test: $(BINDIR)/$(CONFIG)/ref_counted_ptr_test
 ref_counted_ptr_test: $(BINDIR)/$(CONFIG)/ref_counted_ptr_test
@@ -1298,6 +1305,7 @@ h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test
 h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
 h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
 h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test
 h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test
 h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test
 h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test
+h2_local_test: $(BINDIR)/$(CONFIG)/h2_local_test
 h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
 h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
 h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
 h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
 h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test
 h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test
@@ -1552,6 +1560,7 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/h2_full+trace_test \
   $(BINDIR)/$(CONFIG)/h2_full+trace_test \
   $(BINDIR)/$(CONFIG)/h2_full+workarounds_test \
   $(BINDIR)/$(CONFIG)/h2_full+workarounds_test \
   $(BINDIR)/$(CONFIG)/h2_http_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_http_proxy_test \
+  $(BINDIR)/$(CONFIG)/h2_local_test \
   $(BINDIR)/$(CONFIG)/h2_oauth2_test \
   $(BINDIR)/$(CONFIG)/h2_oauth2_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_test \
@@ -1681,6 +1690,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/qps_json_driver \
   $(BINDIR)/$(CONFIG)/qps_json_driver \
   $(BINDIR)/$(CONFIG)/qps_openloop_test \
   $(BINDIR)/$(CONFIG)/qps_openloop_test \
   $(BINDIR)/$(CONFIG)/qps_worker \
   $(BINDIR)/$(CONFIG)/qps_worker \
+  $(BINDIR)/$(CONFIG)/raw_end2end_test \
   $(BINDIR)/$(CONFIG)/reconnect_interop_client \
   $(BINDIR)/$(CONFIG)/reconnect_interop_client \
   $(BINDIR)/$(CONFIG)/reconnect_interop_server \
   $(BINDIR)/$(CONFIG)/reconnect_interop_server \
   $(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
   $(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
@@ -1858,6 +1868,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/qps_json_driver \
   $(BINDIR)/$(CONFIG)/qps_json_driver \
   $(BINDIR)/$(CONFIG)/qps_openloop_test \
   $(BINDIR)/$(CONFIG)/qps_openloop_test \
   $(BINDIR)/$(CONFIG)/qps_worker \
   $(BINDIR)/$(CONFIG)/qps_worker \
+  $(BINDIR)/$(CONFIG)/raw_end2end_test \
   $(BINDIR)/$(CONFIG)/reconnect_interop_client \
   $(BINDIR)/$(CONFIG)/reconnect_interop_client \
   $(BINDIR)/$(CONFIG)/reconnect_interop_server \
   $(BINDIR)/$(CONFIG)/reconnect_interop_server \
   $(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
   $(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
@@ -2328,6 +2339,8 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/proto_utils_test || ( echo test proto_utils_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/proto_utils_test || ( echo test proto_utils_test failed ; exit 1 )
 	$(E) "[RUN]     Testing qps_openloop_test"
 	$(E) "[RUN]     Testing qps_openloop_test"
 	$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
+	$(E) "[RUN]     Testing raw_end2end_test"
+	$(Q) $(BINDIR)/$(CONFIG)/raw_end2end_test || ( echo test raw_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing ref_counted_ptr_test"
 	$(E) "[RUN]     Testing ref_counted_ptr_test"
 	$(Q) $(BINDIR)/$(CONFIG)/ref_counted_ptr_test || ( echo test ref_counted_ptr_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/ref_counted_ptr_test || ( echo test ref_counted_ptr_test failed ; exit 1 )
 	$(E) "[RUN]     Testing ref_counted_test"
 	$(E) "[RUN]     Testing ref_counted_test"
@@ -3214,7 +3227,7 @@ PUBLIC_HEADERS_C += \
 
 
 LIBCXXABI_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCXXABI_SRC))))
 LIBCXXABI_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCXXABI_SRC))))
 
 
-$(LIBCXXABI_OBJS): CPPFLAGS += -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS -Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE) -fvisibility=hidden
+$(LIBCXXABI_OBJS): CPPFLAGS += -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS -Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE) $(W_NO_MAYBE_UNINITIALIZED) -fvisibility=hidden
 $(LIBCXXABI_OBJS): CXXFLAGS += $(W_NO_CXX14_COMPAT)
 $(LIBCXXABI_OBJS): CXXFLAGS += $(W_NO_CXX14_COMPAT)
 
 
 $(LIBDIR)/$(CONFIG)/libcxxabi.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP)  $(LIBCXXABI_OBJS) 
 $(LIBDIR)/$(CONFIG)/libcxxabi.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP)  $(LIBCXXABI_OBJS) 
@@ -3300,6 +3313,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -3562,10 +3576,12 @@ LIBGRPC_SRC = \
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
+    src/core/lib/security/credentials/local/local_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
+    src/core/lib/security/security_connector/local_security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
@@ -3617,6 +3633,7 @@ LIBGRPC_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -3638,6 +3655,7 @@ LIBGRPC_SRC = \
     src/core/ext/filters/deadline/deadline_filter.cc \
     src/core/ext/filters/deadline/deadline_filter.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
+    src/core/tsi/local_transport_security.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
@@ -3691,6 +3709,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -3950,6 +3969,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -3982,10 +4002,12 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
+    src/core/lib/security/credentials/local/local_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
+    src/core/lib/security/security_connector/local_security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
@@ -4036,6 +4058,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/transport/chttp2/client/chttp2_connector.cc \
     src/core/ext/transport/chttp2/client/chttp2_connector.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
+    src/core/tsi/local_transport_security.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
@@ -4059,6 +4082,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -4302,6 +4326,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -4374,6 +4399,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -4599,6 +4625,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -4671,6 +4698,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -4896,6 +4924,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -4962,6 +4991,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -5258,6 +5288,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -5314,6 +5345,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/time.h \
     include/grpc++/impl/codegen/time.h \
+    include/grpcpp/impl/codegen/async_generic_service.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
@@ -5688,6 +5720,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -5829,6 +5862,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -5885,6 +5919,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/time.h \
     include/grpc++/impl/codegen/time.h \
+    include/grpcpp/impl/codegen/async_generic_service.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
@@ -6274,6 +6309,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/time.h \
     include/grpc++/impl/codegen/time.h \
+    include/grpcpp/impl/codegen/async_generic_service.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
@@ -6319,6 +6355,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -6426,6 +6463,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/time.h \
     include/grpc++/impl/codegen/time.h \
+    include/grpcpp/impl/codegen/async_generic_service.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
@@ -6471,6 +6509,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -6689,6 +6728,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/fork.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_custom.h \
     include/grpc/impl/codegen/sync_custom.h \
@@ -6745,6 +6785,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/sync_stream.h \
     include/grpc++/impl/codegen/time.h \
     include/grpc++/impl/codegen/time.h \
+    include/grpcpp/impl/codegen/async_generic_service.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_stream.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/async_unary_call.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
     include/grpcpp/impl/codegen/byte_buffer.h \
@@ -18936,6 +18977,49 @@ endif
 endif
 endif
 
 
 
 
+RAW_END2END_TEST_SRC = \
+    test/cpp/end2end/raw_end2end_test.cc \
+
+RAW_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RAW_END2END_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/raw_end2end_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/raw_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_raw_end2end_test: $(RAW_END2END_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(RAW_END2END_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 RECONNECT_INTEROP_CLIENT_SRC = \
 RECONNECT_INTEROP_CLIENT_SRC = \
     $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
@@ -22950,6 +23034,38 @@ endif
 endif
 endif
 
 
 
 
+H2_LOCAL_TEST_SRC = \
+    test/core/end2end/fixtures/h2_local.cc \
+
+H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_LOCAL_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 H2_OAUTH2_TEST_SRC = \
 H2_OAUTH2_TEST_SRC = \
     test/core/end2end/fixtures/h2_oauth2.cc \
     test/core/end2end/fixtures/h2_oauth2.cc \
 
 
@@ -24343,10 +24459,12 @@ src/core/lib/security/credentials/iam/iam_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/json_token.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/json_token.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/jwt_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/jwt_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/jwt_verifier.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/jwt_verifier.cc: $(OPENSSL_DEP)
+src/core/lib/security/credentials/local/local_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/alts_security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/alts_security_connector.cc: $(OPENSSL_DEP)
+src/core/lib/security/security_connector/local_security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP)
 src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP)
 src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP)
 src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP)
@@ -24384,6 +24502,7 @@ src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc: $(OPE
 src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc: $(OPENSSL_DEP)
 src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc: $(OPENSSL_DEP)
 src/core/tsi/alts_transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/alts_transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/fake_transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/fake_transport_security.cc: $(OPENSSL_DEP)
+src/core/tsi/local_transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_cache.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_cache.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_openssl.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl/session_cache/ssl_session_openssl.cc: $(OPENSSL_DEP)

+ 4 - 0
README.md

@@ -45,6 +45,10 @@ Please read [How to contribute](CONTRIBUTING.md) which will guide you through th
 the gRPC codebase.
 the gRPC codebase.
 The document also contains info on how the contributing process works and contains best practices for creating contributions.
 The document also contains info on how the contributing process works and contains best practices for creating contributions.
 
 
+# Troubleshooting
+
+Sometimes things go wrong. Please check out the [Troubleshooting guide](TROUBLESHOOTING.md) if you are experiencing issues with gRPC.
+
 # Performance 
 # Performance 
 
 
 See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for the performance numbers for the latest released version.
 See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for the performance numbers for the latest released version.

+ 43 - 0
TROUBLESHOOTING.md

@@ -0,0 +1,43 @@
+# Troubleshooting gRPC
+
+This guide is for troubleshooting gRPC implementations based on C core library (sources for most of them are living in the `grpc/grpc` repository).
+
+## Enabling extra logging and tracing
+
+Extra logging can be very useful for diagnosing problems. All gRPC implementations based on C core library support
+the `GRPC_VERBOSITY` and `GRPC_TRACE` environment variables that can be used to increase the amount of information
+that gets printed to stderr.
+
+## GRPC_VERBOSITY
+
+`GRPC_VERBOSITY` is used to set the minimum level of log messages printed by gRPC (supported values are `DEBUG`, `INFO` and `ERROR`). If this environment variable is unset, only `ERROR` logs will be printed.
+
+## GRPC_TRACE
+
+`GRPC_TRACE` can be used to enable extra logging for some internal gRPC components. Enabling the right traces can be invaluable
+for diagnosing for what is going wrong when things aren't working as intended. Possible values for `GRPC_TRACE` are listed in [Environment Variables Overview](doc/environment_variables.md).
+Multiple traces can be enable at once (use comma as separator).
+
+```
+# Enable debug logs for an application
+GRPC_VERBOSITY=debug ./helloworld_application_using_grpc
+```
+
+```
+# Print information about invocations of low-level C core API.
+# Note that trace logs of log level DEBUG won't be displayed.
+# Also note that most tracers user log level INFO, so without setting
+# GPRC_VERBOSITY accordingly, no traces will be printed.
+GRPC_VERBOSITY=info GRPC_TRACE=api ./helloworld_application_using_grpc
+```
+
+```
+# Print info from 3 different tracers, including tracing logs with log level DEBUG
+GRPC_VERBOSITY=debug GRPC_TRACE=tcp,http,api ./helloworld_application_using_grpc
+```
+
+Known limitations: `GPRC_TRACE=tcp` is currently not implemented for Windows (you won't see any tcp traces).
+
+Please note that the `GRPC_TRACE` environment variable has nothing to do with gRPC's "tracing" feature (= tracing RPCs in
+microservice environment to gain insight about how requests are processed by deployment), it is merely used to enable printing
+of extra logs.

+ 25 - 1
build.yaml

@@ -173,6 +173,7 @@ filegroups:
   - include/grpc/support/thd_id.h
   - include/grpc/support/thd_id.h
   - include/grpc/support/time.h
   - include/grpc/support/time.h
   headers:
   headers:
+  - src/core/lib/gpr/alloc.h
   - src/core/lib/gpr/arena.h
   - src/core/lib/gpr/arena.h
   - src/core/lib/gpr/env.h
   - src/core/lib/gpr/env.h
   - src/core/lib/gpr/host_port.h
   - src/core/lib/gpr/host_port.h
@@ -208,6 +209,7 @@ filegroups:
   - include/grpc/impl/codegen/fork.h
   - include/grpc/impl/codegen/fork.h
   - include/grpc/impl/codegen/gpr_slice.h
   - include/grpc/impl/codegen/gpr_slice.h
   - include/grpc/impl/codegen/gpr_types.h
   - include/grpc/impl/codegen/gpr_types.h
+  - include/grpc/impl/codegen/log.h
   - include/grpc/impl/codegen/port_platform.h
   - include/grpc/impl/codegen/port_platform.h
   - include/grpc/impl/codegen/sync.h
   - include/grpc/impl/codegen/sync.h
   - include/grpc/impl/codegen/sync_custom.h
   - include/grpc/impl/codegen/sync_custom.h
@@ -562,6 +564,7 @@ filegroups:
   headers:
   headers:
   - src/core/ext/filters/client_channel/backup_poller.h
   - src/core/ext/filters/client_channel/backup_poller.h
   - src/core/ext/filters/client_channel/client_channel.h
   - src/core/ext/filters/client_channel/client_channel.h
+  - src/core/ext/filters/client_channel/client_channel_channelz.h
   - src/core/ext/filters/client_channel/client_channel_factory.h
   - src/core/ext/filters/client_channel/client_channel_factory.h
   - src/core/ext/filters/client_channel/connector.h
   - src/core/ext/filters/client_channel/connector.h
   - src/core/ext/filters/client_channel/http_connect_handshaker.h
   - src/core/ext/filters/client_channel/http_connect_handshaker.h
@@ -584,6 +587,7 @@ filegroups:
   - src/core/ext/filters/client_channel/backup_poller.cc
   - src/core/ext/filters/client_channel/backup_poller.cc
   - src/core/ext/filters/client_channel/channel_connectivity.cc
   - src/core/ext/filters/client_channel/channel_connectivity.cc
   - src/core/ext/filters/client_channel/client_channel.cc
   - src/core/ext/filters/client_channel/client_channel.cc
+  - src/core/ext/filters/client_channel/client_channel_channelz.cc
   - src/core/ext/filters/client_channel/client_channel_factory.cc
   - src/core/ext/filters/client_channel/client_channel_factory.cc
   - src/core/ext/filters/client_channel/client_channel_plugin.cc
   - src/core/ext/filters/client_channel/client_channel_plugin.cc
   - src/core/ext/filters/client_channel/connector.cc
   - src/core/ext/filters/client_channel/connector.cc
@@ -780,10 +784,12 @@ filegroups:
   - src/core/lib/security/credentials/jwt/json_token.h
   - src/core/lib/security/credentials/jwt/json_token.h
   - src/core/lib/security/credentials/jwt/jwt_credentials.h
   - src/core/lib/security/credentials/jwt/jwt_credentials.h
   - src/core/lib/security/credentials/jwt/jwt_verifier.h
   - src/core/lib/security/credentials/jwt/jwt_verifier.h
+  - src/core/lib/security/credentials/local/local_credentials.h
   - src/core/lib/security/credentials/oauth2/oauth2_credentials.h
   - src/core/lib/security/credentials/oauth2/oauth2_credentials.h
   - src/core/lib/security/credentials/plugin/plugin_credentials.h
   - src/core/lib/security/credentials/plugin/plugin_credentials.h
   - src/core/lib/security/credentials/ssl/ssl_credentials.h
   - src/core/lib/security/credentials/ssl/ssl_credentials.h
   - src/core/lib/security/security_connector/alts_security_connector.h
   - src/core/lib/security/security_connector/alts_security_connector.h
+  - src/core/lib/security/security_connector/local_security_connector.h
   - src/core/lib/security/security_connector/security_connector.h
   - src/core/lib/security/security_connector/security_connector.h
   - src/core/lib/security/transport/auth_filters.h
   - src/core/lib/security/transport/auth_filters.h
   - src/core/lib/security/transport/secure_endpoint.h
   - src/core/lib/security/transport/secure_endpoint.h
@@ -805,10 +811,12 @@ filegroups:
   - src/core/lib/security/credentials/jwt/json_token.cc
   - src/core/lib/security/credentials/jwt/json_token.cc
   - src/core/lib/security/credentials/jwt/jwt_credentials.cc
   - src/core/lib/security/credentials/jwt/jwt_credentials.cc
   - src/core/lib/security/credentials/jwt/jwt_verifier.cc
   - src/core/lib/security/credentials/jwt/jwt_verifier.cc
+  - src/core/lib/security/credentials/local/local_credentials.cc
   - src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   - src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
   - src/core/lib/security/credentials/plugin/plugin_credentials.cc
   - src/core/lib/security/credentials/plugin/plugin_credentials.cc
   - src/core/lib/security/credentials/ssl/ssl_credentials.cc
   - src/core/lib/security/credentials/ssl/ssl_credentials.cc
   - src/core/lib/security/security_connector/alts_security_connector.cc
   - src/core/lib/security/security_connector/alts_security_connector.cc
+  - src/core/lib/security/security_connector/local_security_connector.cc
   - src/core/lib/security/security_connector/security_connector.cc
   - src/core/lib/security/security_connector/security_connector.cc
   - src/core/lib/security/transport/client_auth_filter.cc
   - src/core/lib/security/transport/client_auth_filter.cc
   - src/core/lib/security/transport/secure_endpoint.cc
   - src/core/lib/security/transport/secure_endpoint.cc
@@ -1069,6 +1077,7 @@ filegroups:
   headers:
   headers:
   - src/core/tsi/alts_transport_security.h
   - src/core/tsi/alts_transport_security.h
   - src/core/tsi/fake_transport_security.h
   - src/core/tsi/fake_transport_security.h
+  - src/core/tsi/local_transport_security.h
   - src/core/tsi/ssl/session_cache/ssl_session.h
   - src/core/tsi/ssl/session_cache/ssl_session.h
   - src/core/tsi/ssl/session_cache/ssl_session_cache.h
   - src/core/tsi/ssl/session_cache/ssl_session_cache.h
   - src/core/tsi/ssl_transport_security.h
   - src/core/tsi/ssl_transport_security.h
@@ -1077,6 +1086,7 @@ filegroups:
   src:
   src:
   - src/core/tsi/alts_transport_security.cc
   - src/core/tsi/alts_transport_security.cc
   - src/core/tsi/fake_transport_security.cc
   - src/core/tsi/fake_transport_security.cc
+  - src/core/tsi/local_transport_security.cc
   - src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   - src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
   - src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   - src/core/tsi/ssl/session_cache/ssl_session_cache.cc
   - src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
   - src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
@@ -1138,6 +1148,7 @@ filegroups:
   - include/grpc++/impl/codegen/stub_options.h
   - include/grpc++/impl/codegen/stub_options.h
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/time.h
   - include/grpc++/impl/codegen/time.h
+  - include/grpcpp/impl/codegen/async_generic_service.h
   - include/grpcpp/impl/codegen/async_stream.h
   - include/grpcpp/impl/codegen/async_stream.h
   - include/grpcpp/impl/codegen/async_unary_call.h
   - include/grpcpp/impl/codegen/async_unary_call.h
   - include/grpcpp/impl/codegen/byte_buffer.h
   - include/grpcpp/impl/codegen/byte_buffer.h
@@ -5096,6 +5107,19 @@ targets:
   - gpr_test_util
   - gpr_test_util
   - gpr
   - gpr
   - grpc++_test_config
   - grpc++_test_config
+- name: raw_end2end_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - test/cpp/end2end/raw_end2end_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: reconnect_interop_client
 - name: reconnect_interop_client
   build: test
   build: test
   run: false
   run: false
@@ -5694,7 +5718,7 @@ defaults:
   cxxabi:
   cxxabi:
     CPPFLAGS: -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS
     CPPFLAGS: -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS
       -Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE)
       -Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE)
-      -fvisibility=hidden
+      $(W_NO_MAYBE_UNINITIALIZED) -fvisibility=hidden
     CXXFLAGS: $(W_NO_CXX14_COMPAT)
     CXXFLAGS: $(W_NO_CXX14_COMPAT)
   global:
   global:
     COREFLAGS: -fno-rtti -fno-exceptions
     COREFLAGS: -fno-rtti -fno-exceptions

+ 5 - 0
config.m4

@@ -275,10 +275,12 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/json_token.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_credentials.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
     src/core/lib/security/credentials/jwt/jwt_verifier.cc \
+    src/core/lib/security/credentials/local/local_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/plugin/plugin_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/credentials/ssl/ssl_credentials.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
     src/core/lib/security/security_connector/alts_security_connector.cc \
+    src/core/lib/security/security_connector/local_security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/security_connector/security_connector.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/client_auth_filter.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
     src/core/lib/security/transport/secure_endpoint.cc \
@@ -330,6 +332,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/channel_connectivity.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
     src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/connector.cc \
     src/core/ext/filters/client_channel/connector.cc \
@@ -351,6 +354,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/deadline/deadline_filter.cc \
     src/core/ext/filters/deadline/deadline_filter.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/alts_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
     src/core/tsi/fake_transport_security.cc \
+    src/core/tsi/local_transport_security.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
     src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
@@ -697,6 +701,7 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/google_default)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/google_default)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/iam)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/iam)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/jwt)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/jwt)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/local)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl)

+ 5 - 0
config.w32

@@ -250,10 +250,12 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\security\\credentials\\jwt\\json_token.cc " +
     "src\\core\\lib\\security\\credentials\\jwt\\json_token.cc " +
     "src\\core\\lib\\security\\credentials\\jwt\\jwt_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\jwt\\jwt_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\jwt\\jwt_verifier.cc " +
     "src\\core\\lib\\security\\credentials\\jwt\\jwt_verifier.cc " +
+    "src\\core\\lib\\security\\credentials\\local\\local_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
     "src\\core\\lib\\security\\security_connector\\alts_security_connector.cc " +
     "src\\core\\lib\\security\\security_connector\\alts_security_connector.cc " +
+    "src\\core\\lib\\security\\security_connector\\local_security_connector.cc " +
     "src\\core\\lib\\security\\security_connector\\security_connector.cc " +
     "src\\core\\lib\\security\\security_connector\\security_connector.cc " +
     "src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
     "src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
     "src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
     "src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
@@ -305,6 +307,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\backup_poller.cc " +
     "src\\core\\ext\\filters\\client_channel\\backup_poller.cc " +
     "src\\core\\ext\\filters\\client_channel\\channel_connectivity.cc " +
     "src\\core\\ext\\filters\\client_channel\\channel_connectivity.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel.cc " +
+    "src\\core\\ext\\filters\\client_channel\\client_channel_channelz.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " +
     "src\\core\\ext\\filters\\client_channel\\connector.cc " +
     "src\\core\\ext\\filters\\client_channel\\connector.cc " +
@@ -326,6 +329,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
     "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
     "src\\core\\tsi\\alts_transport_security.cc " +
     "src\\core\\tsi\\alts_transport_security.cc " +
     "src\\core\\tsi\\fake_transport_security.cc " +
     "src\\core\\tsi\\fake_transport_security.cc " +
+    "src\\core\\tsi\\local_transport_security.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_boringssl.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_boringssl.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_cache.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_cache.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_openssl.cc " +
     "src\\core\\tsi\\ssl\\session_cache\\ssl_session_openssl.cc " +
@@ -713,6 +717,7 @@ if (PHP_GRPC != "no") {
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\iam");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\iam");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\jwt");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\jwt");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\local");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl");

+ 19 - 1
gRPC-C++.podspec

@@ -24,7 +24,7 @@ Pod::Spec.new do |s|
   s.name     = 'gRPC-C++'
   s.name     = 'gRPC-C++'
   # TODO (mxyan): use version that match gRPC version when pod is stabilized
   # TODO (mxyan): use version that match gRPC version when pod is stabilized
   # version = '1.14.0-dev'
   # version = '1.14.0-dev'
-  version = '0.0.2'
+  version = '0.0.3'
   s.version  = version
   s.version  = version
   s.summary  = 'gRPC C++ library'
   s.summary  = 'gRPC C++ library'
   s.homepage = 'https://grpc.io'
   s.homepage = 'https://grpc.io'
@@ -121,6 +121,7 @@ Pod::Spec.new do |s|
                       'include/grpcpp/support/stub_options.h',
                       'include/grpcpp/support/stub_options.h',
                       'include/grpcpp/support/sync_stream.h',
                       'include/grpcpp/support/sync_stream.h',
                       'include/grpcpp/support/time.h',
                       'include/grpcpp/support/time.h',
+                      'include/grpcpp/impl/codegen/async_generic_service.h',
                       'include/grpcpp/impl/codegen/async_stream.h',
                       'include/grpcpp/impl/codegen/async_stream.h',
                       'include/grpcpp/impl/codegen/async_unary_call.h',
                       'include/grpcpp/impl/codegen/async_unary_call.h',
                       'include/grpcpp/impl/codegen/byte_buffer.h',
                       'include/grpcpp/impl/codegen/byte_buffer.h',
@@ -212,6 +213,7 @@ Pod::Spec.new do |s|
                       'src/cpp/util/string_ref.cc',
                       'src/cpp/util/string_ref.cc',
                       'src/cpp/util/time_cc.cc',
                       'src/cpp/util/time_cc.cc',
                       'src/cpp/codegen/codegen_init.cc',
                       'src/cpp/codegen/codegen_init.cc',
+                      'src/core/lib/gpr/alloc.h',
                       'src/core/lib/gpr/arena.h',
                       'src/core/lib/gpr/arena.h',
                       'src/core/lib/gpr/env.h',
                       'src/core/lib/gpr/env.h',
                       'src/core/lib/gpr/host_port.h',
                       'src/core/lib/gpr/host_port.h',
@@ -271,10 +273,12 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/jwt/json_token.h',
                       'src/core/lib/security/credentials/jwt/json_token.h',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.h',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.h',
+                      'src/core/lib/security/credentials/local/local_credentials.h',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                       'src/core/lib/security/security_connector/alts_security_connector.h',
                       'src/core/lib/security/security_connector/alts_security_connector.h',
+                      'src/core/lib/security/security_connector/local_security_connector.h',
                       'src/core/lib/security/security_connector/security_connector.h',
                       'src/core/lib/security/security_connector/security_connector.h',
                       'src/core/lib/security/transport/auth_filters.h',
                       'src/core/lib/security/transport/auth_filters.h',
                       'src/core/lib/security/transport/secure_endpoint.h',
                       'src/core/lib/security/transport/secure_endpoint.h',
@@ -313,6 +317,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                       'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                       'src/core/ext/filters/client_channel/backup_poller.h',
                       'src/core/ext/filters/client_channel/backup_poller.h',
                       'src/core/ext/filters/client_channel/client_channel.h',
                       'src/core/ext/filters/client_channel/client_channel.h',
+                      'src/core/ext/filters/client_channel/client_channel_channelz.h',
                       'src/core/ext/filters/client_channel/client_channel_factory.h',
                       'src/core/ext/filters/client_channel/client_channel_factory.h',
                       'src/core/ext/filters/client_channel/connector.h',
                       'src/core/ext/filters/client_channel/connector.h',
                       'src/core/ext/filters/client_channel/http_connect_handshaker.h',
                       'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -334,6 +339,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/deadline/deadline_filter.h',
                       'src/core/ext/filters/deadline/deadline_filter.h',
                       'src/core/tsi/alts_transport_security.h',
                       'src/core/tsi/alts_transport_security.h',
                       'src/core/tsi/fake_transport_security.h',
                       'src/core/tsi/fake_transport_security.h',
+                      'src/core/tsi/local_transport_security.h',
                       'src/core/tsi/ssl/session_cache/ssl_session.h',
                       'src/core/tsi/ssl/session_cache/ssl_session.h',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                       'src/core/tsi/ssl_transport_security.h',
                       'src/core/tsi/ssl_transport_security.h',
@@ -503,6 +509,7 @@ Pod::Spec.new do |s|
                               'src/cpp/server/health/health.pb.h',
                               'src/cpp/server/health/health.pb.h',
                               'src/cpp/server/thread_pool_interface.h',
                               'src/cpp/server/thread_pool_interface.h',
                               'src/cpp/thread_manager/thread_manager.h',
                               'src/cpp/thread_manager/thread_manager.h',
+                              'src/core/lib/gpr/alloc.h',
                               'src/core/lib/gpr/arena.h',
                               'src/core/lib/gpr/arena.h',
                               'src/core/lib/gpr/env.h',
                               'src/core/lib/gpr/env.h',
                               'src/core/lib/gpr/host_port.h',
                               'src/core/lib/gpr/host_port.h',
@@ -664,6 +671,17 @@ Pod::Spec.new do |s|
                               'src/core/ext/transport/inproc/inproc_transport.h'
                               'src/core/ext/transport/inproc/inproc_transport.h'
   end
   end
 
 
+  s.subspec 'Protobuf' do |ss|
+    ss.header_mappings_dir = 'include/grpcpp'
+    ss.dependency "#{s.name}/Interface", version
+
+    ss.source_files = 'include/grpcpp/impl/codegen/proto_buffer_reader.h',
+                      'include/grpcpp/impl/codegen/proto_buffer_writer.h',
+                      'include/grpcpp/impl/codegen/proto_utils.h',
+                      'include/grpcpp/impl/codegen/config_protobuf.h',
+                      'include/grpcpp/impl/codegen/config_protobuf.h'
+  end
+
   s.prepare_command = <<-END_OF_COMMAND
   s.prepare_command = <<-END_OF_COMMAND
     find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
     find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
     find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm
     find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm

+ 18 - 2
gRPC-Core.podspec

@@ -133,6 +133,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/fork.h',
                       'include/grpc/impl/codegen/fork.h',
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/gpr_types.h',
+                      'include/grpc/impl/codegen/log.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_custom.h',
                       'include/grpc/impl/codegen/sync_custom.h',
@@ -154,6 +155,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/fork.h',
                       'include/grpc/impl/codegen/fork.h',
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/gpr_types.h',
+                      'include/grpc/impl/codegen/log.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_custom.h',
                       'include/grpc/impl/codegen/sync_custom.h',
@@ -183,7 +185,8 @@ Pod::Spec.new do |s|
     ss.dependency 'nanopb', '~> 0.3'
     ss.dependency 'nanopb', '~> 0.3'
 
 
     # To save you from scrolling, this is the last part of the podspec.
     # To save you from scrolling, this is the last part of the podspec.
-    ss.source_files = 'src/core/lib/gpr/arena.h',
+    ss.source_files = 'src/core/lib/gpr/alloc.h',
+                      'src/core/lib/gpr/arena.h',
                       'src/core/lib/gpr/env.h',
                       'src/core/lib/gpr/env.h',
                       'src/core/lib/gpr/host_port.h',
                       'src/core/lib/gpr/host_port.h',
                       'src/core/lib/gpr/mpscq.h',
                       'src/core/lib/gpr/mpscq.h',
@@ -281,10 +284,12 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/jwt/json_token.h',
                       'src/core/lib/security/credentials/jwt/json_token.h',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.h',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.h',
+                      'src/core/lib/security/credentials/local/local_credentials.h',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                       'src/core/lib/security/security_connector/alts_security_connector.h',
                       'src/core/lib/security/security_connector/alts_security_connector.h',
+                      'src/core/lib/security/security_connector/local_security_connector.h',
                       'src/core/lib/security/security_connector/security_connector.h',
                       'src/core/lib/security/security_connector/security_connector.h',
                       'src/core/lib/security/transport/auth_filters.h',
                       'src/core/lib/security/transport/auth_filters.h',
                       'src/core/lib/security/transport/secure_endpoint.h',
                       'src/core/lib/security/transport/secure_endpoint.h',
@@ -323,6 +328,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                       'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                       'src/core/ext/filters/client_channel/backup_poller.h',
                       'src/core/ext/filters/client_channel/backup_poller.h',
                       'src/core/ext/filters/client_channel/client_channel.h',
                       'src/core/ext/filters/client_channel/client_channel.h',
+                      'src/core/ext/filters/client_channel/client_channel_channelz.h',
                       'src/core/ext/filters/client_channel/client_channel_factory.h',
                       'src/core/ext/filters/client_channel/client_channel_factory.h',
                       'src/core/ext/filters/client_channel/connector.h',
                       'src/core/ext/filters/client_channel/connector.h',
                       'src/core/ext/filters/client_channel/http_connect_handshaker.h',
                       'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -344,6 +350,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/deadline/deadline_filter.h',
                       'src/core/ext/filters/deadline/deadline_filter.h',
                       'src/core/tsi/alts_transport_security.h',
                       'src/core/tsi/alts_transport_security.h',
                       'src/core/tsi/fake_transport_security.h',
                       'src/core/tsi/fake_transport_security.h',
+                      'src/core/tsi/local_transport_security.h',
                       'src/core/tsi/ssl/session_cache/ssl_session.h',
                       'src/core/tsi/ssl/session_cache/ssl_session.h',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                       'src/core/tsi/ssl_transport_security.h',
                       'src/core/tsi/ssl_transport_security.h',
@@ -693,10 +700,12 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/jwt/json_token.cc',
                       'src/core/lib/security/credentials/jwt/json_token.cc',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
                       'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
                       'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
+                      'src/core/lib/security/credentials/local/local_credentials.cc',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
                       'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
                       'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
                       'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
                       'src/core/lib/security/security_connector/alts_security_connector.cc',
                       'src/core/lib/security/security_connector/alts_security_connector.cc',
+                      'src/core/lib/security/security_connector/local_security_connector.cc',
                       'src/core/lib/security/security_connector/security_connector.cc',
                       'src/core/lib/security/security_connector/security_connector.cc',
                       'src/core/lib/security/transport/client_auth_filter.cc',
                       'src/core/lib/security/transport/client_auth_filter.cc',
                       'src/core/lib/security/transport/secure_endpoint.cc',
                       'src/core/lib/security/transport/secure_endpoint.cc',
@@ -745,6 +754,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/backup_poller.cc',
                       'src/core/ext/filters/client_channel/backup_poller.cc',
                       'src/core/ext/filters/client_channel/channel_connectivity.cc',
                       'src/core/ext/filters/client_channel/channel_connectivity.cc',
                       'src/core/ext/filters/client_channel/client_channel.cc',
                       'src/core/ext/filters/client_channel/client_channel.cc',
+                      'src/core/ext/filters/client_channel/client_channel_channelz.cc',
                       'src/core/ext/filters/client_channel/client_channel_factory.cc',
                       'src/core/ext/filters/client_channel/client_channel_factory.cc',
                       'src/core/ext/filters/client_channel/client_channel_plugin.cc',
                       'src/core/ext/filters/client_channel/client_channel_plugin.cc',
                       'src/core/ext/filters/client_channel/connector.cc',
                       'src/core/ext/filters/client_channel/connector.cc',
@@ -766,6 +776,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/deadline/deadline_filter.cc',
                       'src/core/ext/filters/deadline/deadline_filter.cc',
                       'src/core/tsi/alts_transport_security.cc',
                       'src/core/tsi/alts_transport_security.cc',
                       'src/core/tsi/fake_transport_security.cc',
                       'src/core/tsi/fake_transport_security.cc',
+                      'src/core/tsi/local_transport_security.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
                       'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
@@ -803,7 +814,8 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/workarounds/workaround_utils.cc',
                       'src/core/ext/filters/workarounds/workaround_utils.cc',
                       'src/core/plugin_registry/grpc_plugin_registry.cc'
                       'src/core/plugin_registry/grpc_plugin_registry.cc'
 
 
-    ss.private_header_files = 'src/core/lib/gpr/arena.h',
+    ss.private_header_files = 'src/core/lib/gpr/alloc.h',
+                              'src/core/lib/gpr/arena.h',
                               'src/core/lib/gpr/env.h',
                               'src/core/lib/gpr/env.h',
                               'src/core/lib/gpr/host_port.h',
                               'src/core/lib/gpr/host_port.h',
                               'src/core/lib/gpr/mpscq.h',
                               'src/core/lib/gpr/mpscq.h',
@@ -862,10 +874,12 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/credentials/jwt/json_token.h',
                               'src/core/lib/security/credentials/jwt/json_token.h',
                               'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                               'src/core/lib/security/credentials/jwt/jwt_credentials.h',
                               'src/core/lib/security/credentials/jwt/jwt_verifier.h',
                               'src/core/lib/security/credentials/jwt/jwt_verifier.h',
+                              'src/core/lib/security/credentials/local/local_credentials.h',
                               'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                               'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
                               'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                               'src/core/lib/security/credentials/plugin/plugin_credentials.h',
                               'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                               'src/core/lib/security/credentials/ssl/ssl_credentials.h',
                               'src/core/lib/security/security_connector/alts_security_connector.h',
                               'src/core/lib/security/security_connector/alts_security_connector.h',
+                              'src/core/lib/security/security_connector/local_security_connector.h',
                               'src/core/lib/security/security_connector/security_connector.h',
                               'src/core/lib/security/security_connector/security_connector.h',
                               'src/core/lib/security/transport/auth_filters.h',
                               'src/core/lib/security/transport/auth_filters.h',
                               'src/core/lib/security/transport/secure_endpoint.h',
                               'src/core/lib/security/transport/secure_endpoint.h',
@@ -904,6 +918,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                               'src/core/ext/transport/chttp2/client/chttp2_connector.h',
                               'src/core/ext/filters/client_channel/backup_poller.h',
                               'src/core/ext/filters/client_channel/backup_poller.h',
                               'src/core/ext/filters/client_channel/client_channel.h',
                               'src/core/ext/filters/client_channel/client_channel.h',
+                              'src/core/ext/filters/client_channel/client_channel_channelz.h',
                               'src/core/ext/filters/client_channel/client_channel_factory.h',
                               'src/core/ext/filters/client_channel/client_channel_factory.h',
                               'src/core/ext/filters/client_channel/connector.h',
                               'src/core/ext/filters/client_channel/connector.h',
                               'src/core/ext/filters/client_channel/http_connect_handshaker.h',
                               'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -925,6 +940,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/deadline/deadline_filter.h',
                               'src/core/ext/filters/deadline/deadline_filter.h',
                               'src/core/tsi/alts_transport_security.h',
                               'src/core/tsi/alts_transport_security.h',
                               'src/core/tsi/fake_transport_security.h',
                               'src/core/tsi/fake_transport_security.h',
+                              'src/core/tsi/local_transport_security.h',
                               'src/core/tsi/ssl/session_cache/ssl_session.h',
                               'src/core/tsi/ssl/session_cache/ssl_session.h',
                               'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                               'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
                               'src/core/tsi/ssl_transport_security.h',
                               'src/core/tsi/ssl_transport_security.h',

+ 9 - 7
grpc.def

@@ -119,6 +119,8 @@ EXPORTS
     grpc_alts_credentials_options_destroy
     grpc_alts_credentials_options_destroy
     grpc_alts_credentials_create
     grpc_alts_credentials_create
     grpc_alts_server_credentials_create
     grpc_alts_server_credentials_create
+    grpc_local_credentials_create
+    grpc_local_server_credentials_create
     grpc_raw_byte_buffer_create
     grpc_raw_byte_buffer_create
     grpc_raw_compressed_byte_buffer_create
     grpc_raw_compressed_byte_buffer_create
     grpc_byte_buffer_copy
     grpc_byte_buffer_copy
@@ -129,6 +131,13 @@ EXPORTS
     grpc_byte_buffer_reader_next
     grpc_byte_buffer_reader_next
     grpc_byte_buffer_reader_readall
     grpc_byte_buffer_reader_readall
     grpc_raw_byte_buffer_from_reader
     grpc_raw_byte_buffer_from_reader
+    gpr_log_severity_string
+    gpr_log
+    gpr_should_log
+    gpr_log_message
+    gpr_set_log_verbosity
+    gpr_log_verbosity_init
+    gpr_set_log_function
     grpc_slice_ref
     grpc_slice_ref
     grpc_slice_unref
     grpc_slice_unref
     grpc_slice_copy
     grpc_slice_copy
@@ -187,13 +196,6 @@ EXPORTS
     gpr_get_allocation_functions
     gpr_get_allocation_functions
     gpr_cpu_num_cores
     gpr_cpu_num_cores
     gpr_cpu_current_cpu
     gpr_cpu_current_cpu
-    gpr_log_severity_string
-    gpr_log
-    gpr_should_log
-    gpr_log_message
-    gpr_set_log_verbosity
-    gpr_log_verbosity_init
-    gpr_set_log_function
     gpr_format_message
     gpr_format_message
     gpr_strdup
     gpr_strdup
     gpr_asprintf
     gpr_asprintf

+ 11 - 0
grpc.gemspec

@@ -75,12 +75,14 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/fork.h )
   s.files += %w( include/grpc/impl/codegen/fork.h )
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
+  s.files += %w( include/grpc/impl/codegen/log.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_custom.h )
   s.files += %w( include/grpc/impl/codegen/sync_custom.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
+  s.files += %w( src/core/lib/gpr/alloc.h )
   s.files += %w( src/core/lib/gpr/arena.h )
   s.files += %w( src/core/lib/gpr/arena.h )
   s.files += %w( src/core/lib/gpr/env.h )
   s.files += %w( src/core/lib/gpr/env.h )
   s.files += %w( src/core/lib/gpr/host_port.h )
   s.files += %w( src/core/lib/gpr/host_port.h )
@@ -159,6 +161,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/fork.h )
   s.files += %w( include/grpc/impl/codegen/fork.h )
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
+  s.files += %w( include/grpc/impl/codegen/log.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_custom.h )
   s.files += %w( include/grpc/impl/codegen/sync_custom.h )
@@ -214,10 +217,12 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/credentials/jwt/json_token.h )
   s.files += %w( src/core/lib/security/credentials/jwt/json_token.h )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.h )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.h )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.h )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.h )
+  s.files += %w( src/core/lib/security/credentials/local/local_credentials.h )
   s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h )
   s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h )
   s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
   s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
   s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
   s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
   s.files += %w( src/core/lib/security/security_connector/alts_security_connector.h )
   s.files += %w( src/core/lib/security/security_connector/alts_security_connector.h )
+  s.files += %w( src/core/lib/security/security_connector/local_security_connector.h )
   s.files += %w( src/core/lib/security/security_connector/security_connector.h )
   s.files += %w( src/core/lib/security/security_connector/security_connector.h )
   s.files += %w( src/core/lib/security/transport/auth_filters.h )
   s.files += %w( src/core/lib/security/transport/auth_filters.h )
   s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
   s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
@@ -260,6 +265,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
   s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
   s.files += %w( src/core/ext/filters/client_channel/backup_poller.h )
   s.files += %w( src/core/ext/filters/client_channel/backup_poller.h )
   s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
   s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
   s.files += %w( src/core/ext/filters/client_channel/connector.h )
   s.files += %w( src/core/ext/filters/client_channel/connector.h )
   s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h )
   s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h )
@@ -281,6 +287,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
   s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
   s.files += %w( src/core/tsi/alts_transport_security.h )
   s.files += %w( src/core/tsi/alts_transport_security.h )
   s.files += %w( src/core/tsi/fake_transport_security.h )
   s.files += %w( src/core/tsi/fake_transport_security.h )
+  s.files += %w( src/core/tsi/local_transport_security.h )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session.h )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session.h )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_cache.h )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_cache.h )
   s.files += %w( src/core/tsi/ssl_transport_security.h )
   s.files += %w( src/core/tsi/ssl_transport_security.h )
@@ -630,10 +637,12 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/credentials/jwt/json_token.cc )
   s.files += %w( src/core/lib/security/credentials/jwt/json_token.cc )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.cc )
   s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.cc )
+  s.files += %w( src/core/lib/security/credentials/local/local_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc )
   s.files += %w( src/core/lib/security/security_connector/alts_security_connector.cc )
   s.files += %w( src/core/lib/security/security_connector/alts_security_connector.cc )
+  s.files += %w( src/core/lib/security/security_connector/local_security_connector.cc )
   s.files += %w( src/core/lib/security/security_connector/security_connector.cc )
   s.files += %w( src/core/lib/security/security_connector/security_connector.cc )
   s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
   s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
   s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
   s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
@@ -685,6 +694,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/backup_poller.cc )
   s.files += %w( src/core/ext/filters/client_channel/backup_poller.cc )
   s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.cc )
   s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel.cc )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc )
   s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc )
   s.files += %w( src/core/ext/filters/client_channel/connector.cc )
   s.files += %w( src/core/ext/filters/client_channel/connector.cc )
@@ -706,6 +716,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
   s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
   s.files += %w( src/core/tsi/alts_transport_security.cc )
   s.files += %w( src/core/tsi/alts_transport_security.cc )
   s.files += %w( src/core/tsi/fake_transport_security.cc )
   s.files += %w( src/core/tsi/fake_transport_security.cc )
+  s.files += %w( src/core/tsi/local_transport_security.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_cache.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_cache.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_openssl.cc )
   s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_openssl.cc )

+ 7 - 0
grpc.gyp

@@ -467,10 +467,12 @@
         'src/core/lib/security/credentials/jwt/json_token.cc',
         'src/core/lib/security/credentials/jwt/json_token.cc',
         'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
         'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
         'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
         'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
+        'src/core/lib/security/credentials/local/local_credentials.cc',
         'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
         'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
         'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
         'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
         'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
         'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
         'src/core/lib/security/security_connector/alts_security_connector.cc',
         'src/core/lib/security/security_connector/alts_security_connector.cc',
+        'src/core/lib/security/security_connector/local_security_connector.cc',
         'src/core/lib/security/security_connector/security_connector.cc',
         'src/core/lib/security/security_connector/security_connector.cc',
         'src/core/lib/security/transport/client_auth_filter.cc',
         'src/core/lib/security/transport/client_auth_filter.cc',
         'src/core/lib/security/transport/secure_endpoint.cc',
         'src/core/lib/security/transport/secure_endpoint.cc',
@@ -522,6 +524,7 @@
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
+        'src/core/ext/filters/client_channel/client_channel_channelz.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/connector.cc',
         'src/core/ext/filters/client_channel/connector.cc',
@@ -543,6 +546,7 @@
         'src/core/ext/filters/deadline/deadline_filter.cc',
         'src/core/ext/filters/deadline/deadline_filter.cc',
         'src/core/tsi/alts_transport_security.cc',
         'src/core/tsi/alts_transport_security.cc',
         'src/core/tsi/fake_transport_security.cc',
         'src/core/tsi/fake_transport_security.cc',
+        'src/core/tsi/local_transport_security.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
         'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
@@ -780,6 +784,7 @@
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
+        'src/core/ext/filters/client_channel/client_channel_channelz.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/connector.cc',
         'src/core/ext/filters/client_channel/connector.cc',
@@ -1012,6 +1017,7 @@
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
+        'src/core/ext/filters/client_channel/client_channel_channelz.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/connector.cc',
         'src/core/ext/filters/client_channel/connector.cc',
@@ -1256,6 +1262,7 @@
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/backup_poller.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/channel_connectivity.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
         'src/core/ext/filters/client_channel/client_channel.cc',
+        'src/core/ext/filters/client_channel/client_channel_channelz.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/connector.cc',
         'src/core/ext/filters/client_channel/connector.cc',

+ 30 - 0
include/grpc/grpc_security.h

@@ -585,6 +585,36 @@ GRPCAPI grpc_channel_credentials* grpc_alts_credentials_create(
 GRPCAPI grpc_server_credentials* grpc_alts_server_credentials_create(
 GRPCAPI grpc_server_credentials* grpc_alts_server_credentials_create(
     const grpc_alts_credentials_options* options);
     const grpc_alts_credentials_options* options);
 
 
+/** --- Local channel/server credentials --- **/
+
+/**
+ * Type of local connection for which local channel/server credentials will be
+ * applied. It only supports UDS for now.
+ */
+typedef enum { UDS = 0 } grpc_local_connect_type;
+
+/**
+ * This method creates a local channel credential object. It is used for
+ * experimental purpose for now and subject to change.
+ *
+ * - type: local connection type
+ *
+ * It returns the created local channel credential object.
+ */
+GRPCAPI grpc_channel_credentials* grpc_local_credentials_create(
+    grpc_local_connect_type type);
+
+/**
+ * This method creates a local server credential object. It is used for
+ * experimental purpose for now and subject to change.
+ *
+ * - type: local connection type
+ *
+ * It returns the created local server credential object.
+ */
+GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create(
+    grpc_local_connect_type type);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 112 - 0
include/grpc/impl/codegen/log.h

@@ -0,0 +1,112 @@
+/*
+ *
+ * Copyright 2015 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_IMPL_CODEGEN_LOG_H
+#define GRPC_IMPL_CODEGEN_LOG_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <stdarg.h>
+#include <stdlib.h> /* for abort() */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** GPR log API.
+
+   Usage (within grpc):
+
+   int argument1 = 3;
+   char* argument2 = "hello";
+   gpr_log(GPR_DEBUG, "format string %d", argument1);
+   gpr_log(GPR_INFO, "hello world");
+   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
+
+/** The severity of a log message - use the #defines below when calling into
+   gpr_log to additionally supply file and line data */
+typedef enum gpr_log_severity {
+  GPR_LOG_SEVERITY_DEBUG,
+  GPR_LOG_SEVERITY_INFO,
+  GPR_LOG_SEVERITY_ERROR
+} gpr_log_severity;
+
+#define GPR_LOG_VERBOSITY_UNSET -1
+
+/** Returns a string representation of the log severity */
+GPRAPI const char* gpr_log_severity_string(gpr_log_severity severity);
+
+/** Macros to build log contexts at various severity levels */
+#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
+#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
+#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
+
+/** Log a message. It's advised to use GPR_xxx above to generate the context
+ * for each message */
+GPRAPI void gpr_log(const char* file, int line, gpr_log_severity severity,
+                    const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
+
+GPRAPI int gpr_should_log(gpr_log_severity severity);
+
+GPRAPI void gpr_log_message(const char* file, int line,
+                            gpr_log_severity severity, const char* message);
+
+/** Set global log verbosity */
+GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
+
+GPRAPI void gpr_log_verbosity_init(void);
+
+/** Log overrides: applications can use this API to intercept logging calls
+   and use their own implementations */
+
+struct gpr_log_func_args {
+  const char* file;
+  int line;
+  gpr_log_severity severity;
+  const char* message;
+};
+
+typedef struct gpr_log_func_args gpr_log_func_args;
+
+typedef void (*gpr_log_func)(gpr_log_func_args* args);
+GPRAPI void gpr_set_log_function(gpr_log_func func);
+
+/** abort() the process if x is zero, having written a line to the log.
+
+   Intended for internal invariants.  If the error can be recovered from,
+   without the possibility of corruption, or might best be reflected via
+   an exception in a higher-level language, consider returning error code.  */
+#define GPR_ASSERT(x)                                 \
+  do {                                                \
+    if (GPR_UNLIKELY(!(x))) {                         \
+      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
+      abort();                                        \
+    }                                                 \
+  } while (0)
+
+#ifndef NDEBUG
+#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x)
+#else
+#define GPR_DEBUG_ASSERT(x)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_LOG_H */

+ 2 - 0
include/grpc/module.modulemap

@@ -17,6 +17,7 @@ framework module grpc {
   header "impl/codegen/fork.h"
   header "impl/codegen/fork.h"
   header "impl/codegen/gpr_slice.h"
   header "impl/codegen/gpr_slice.h"
   header "impl/codegen/gpr_types.h"
   header "impl/codegen/gpr_types.h"
+  header "impl/codegen/log.h"
   header "impl/codegen/port_platform.h"
   header "impl/codegen/port_platform.h"
   header "impl/codegen/sync.h"
   header "impl/codegen/sync.h"
   header "impl/codegen/sync_generic.h"
   header "impl/codegen/sync_generic.h"
@@ -32,6 +33,7 @@ framework module grpc {
   header "impl/codegen/fork.h"
   header "impl/codegen/fork.h"
   header "impl/codegen/gpr_slice.h"
   header "impl/codegen/gpr_slice.h"
   header "impl/codegen/gpr_types.h"
   header "impl/codegen/gpr_types.h"
+  header "impl/codegen/log.h"
   header "impl/codegen/port_platform.h"
   header "impl/codegen/port_platform.h"
   header "impl/codegen/sync.h"
   header "impl/codegen/sync.h"
   header "impl/codegen/sync_generic.h"
   header "impl/codegen/sync_generic.h"

+ 2 - 88
include/grpc/support/log.h

@@ -19,94 +19,8 @@
 #ifndef GRPC_SUPPORT_LOG_H
 #ifndef GRPC_SUPPORT_LOG_H
 #define GRPC_SUPPORT_LOG_H
 #define GRPC_SUPPORT_LOG_H
 
 
-#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/support/port_platform.h>
 
 
-#include <stdarg.h>
-#include <stdlib.h> /* for abort() */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** GPR log API.
-
-   Usage (within grpc):
-
-   int argument1 = 3;
-   char* argument2 = "hello";
-   gpr_log(GPR_DEBUG, "format string %d", argument1);
-   gpr_log(GPR_INFO, "hello world");
-   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
-
-/** The severity of a log message - use the #defines below when calling into
-   gpr_log to additionally supply file and line data */
-typedef enum gpr_log_severity {
-  GPR_LOG_SEVERITY_DEBUG,
-  GPR_LOG_SEVERITY_INFO,
-  GPR_LOG_SEVERITY_ERROR
-} gpr_log_severity;
-
-#define GPR_LOG_VERBOSITY_UNSET -1
-
-/** Returns a string representation of the log severity */
-GPRAPI const char* gpr_log_severity_string(gpr_log_severity severity);
-
-/** Macros to build log contexts at various severity levels */
-#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
-#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
-#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
-
-/** Log a message. It's advised to use GPR_xxx above to generate the context
- * for each message */
-GPRAPI void gpr_log(const char* file, int line, gpr_log_severity severity,
-                    const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
-
-GPRAPI int gpr_should_log(gpr_log_severity severity);
-
-GPRAPI void gpr_log_message(const char* file, int line,
-                            gpr_log_severity severity, const char* message);
-
-/** Set global log verbosity */
-GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
-
-GPRAPI void gpr_log_verbosity_init(void);
-
-/** Log overrides: applications can use this API to intercept logging calls
-   and use their own implementations */
-
-struct gpr_log_func_args {
-  const char* file;
-  int line;
-  gpr_log_severity severity;
-  const char* message;
-};
-
-typedef struct gpr_log_func_args gpr_log_func_args;
-
-typedef void (*gpr_log_func)(gpr_log_func_args* args);
-GPRAPI void gpr_set_log_function(gpr_log_func func);
-
-/** abort() the process if x is zero, having written a line to the log.
-
-   Intended for internal invariants.  If the error can be recovered from,
-   without the possibility of corruption, or might best be reflected via
-   an exception in a higher-level language, consider returning error code.  */
-#define GPR_ASSERT(x)                                 \
-  do {                                                \
-    if (GPR_UNLIKELY(!(x))) {                         \
-      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
-      abort();                                        \
-    }                                                 \
-  } while (0)
-
-#ifndef NDEBUG
-#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x)
-#else
-#define GPR_DEBUG_ASSERT(x)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/log.h>
 
 
 #endif /* GRPC_SUPPORT_LOG_H */
 #endif /* GRPC_SUPPORT_LOG_H */

+ 2 - 56
include/grpcpp/generic/async_generic_service.h

@@ -1,6 +1,6 @@
 /*
 /*
  *
  *
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
@@ -19,60 +19,6 @@
 #ifndef GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
 #ifndef GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
 #define GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
 #define GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
 
 
-#include <grpcpp/support/async_stream.h>
-#include <grpcpp/support/byte_buffer.h>
-
-struct grpc_server;
-
-namespace grpc {
-
-typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
-    GenericServerAsyncReaderWriter;
-
-class GenericServerContext final : public ServerContext {
- public:
-  const grpc::string& method() const { return method_; }
-  const grpc::string& host() const { return host_; }
-
- private:
-  friend class Server;
-  friend class ServerInterface;
-
-  grpc::string method_;
-  grpc::string host_;
-};
-
-// A generic service at the server side accepts all RPC methods and hosts. It is
-// typically used in proxies. The generic service can be registered to a server
-// which also has other services.
-// Sample usage:
-//   ServerBuilder builder;
-//   auto cq = builder.AddCompletionQueue();
-//   AsyncGenericService generic_service;
-//   builder.RegisterAsyncGeneicService(&generic_service);
-//   auto server = builder.BuildAndStart();
-//
-//   // request a new call
-//   GenericServerContext context;
-//   GenericAsyncReaderWriter stream;
-//   generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
-//
-// When tag is retrieved from cq->Next(), context.method() can be used to look
-// at the method and the RPC can be handled accordingly.
-class AsyncGenericService final {
- public:
-  AsyncGenericService() : server_(nullptr) {}
-
-  void RequestCall(GenericServerContext* ctx,
-                   GenericServerAsyncReaderWriter* reader_writer,
-                   CompletionQueue* call_cq,
-                   ServerCompletionQueue* notification_cq, void* tag);
-
- private:
-  friend class Server;
-  Server* server_;
-};
-
-}  // namespace grpc
+#include <grpcpp/impl/codegen/async_generic_service.h>
 
 
 #endif  // GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
 #endif  // GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H

+ 81 - 0
include/grpcpp/impl/codegen/async_generic_service.h

@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2015 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 GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H
+#define GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H
+
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
+
+struct grpc_server;
+
+namespace grpc {
+
+typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
+    GenericServerAsyncReaderWriter;
+typedef ServerAsyncResponseWriter<ByteBuffer> GenericServerAsyncResponseWriter;
+typedef ServerAsyncReader<ByteBuffer, ByteBuffer> GenericServerAsyncReader;
+typedef ServerAsyncWriter<ByteBuffer> GenericServerAsyncWriter;
+
+class GenericServerContext final : public ServerContext {
+ public:
+  const grpc::string& method() const { return method_; }
+  const grpc::string& host() const { return host_; }
+
+ private:
+  friend class Server;
+  friend class ServerInterface;
+
+  grpc::string method_;
+  grpc::string host_;
+};
+
+// A generic service at the server side accepts all RPC methods and hosts. It is
+// typically used in proxies. The generic service can be registered to a server
+// which also has other services.
+// Sample usage:
+//   ServerBuilder builder;
+//   auto cq = builder.AddCompletionQueue();
+//   AsyncGenericService generic_service;
+//   builder.RegisterAsyncGeneicService(&generic_service);
+//   auto server = builder.BuildAndStart();
+//
+//   // request a new call
+//   GenericServerContext context;
+//   GenericAsyncReaderWriter stream;
+//   generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
+//
+// When tag is retrieved from cq->Next(), context.method() can be used to look
+// at the method and the RPC can be handled accordingly.
+class AsyncGenericService final {
+ public:
+  AsyncGenericService() : server_(nullptr) {}
+
+  void RequestCall(GenericServerContext* ctx,
+                   GenericServerAsyncReaderWriter* reader_writer,
+                   CompletionQueue* call_cq,
+                   ServerCompletionQueue* notification_cq, void* tag);
+
+ private:
+  friend class Server;
+  Server* server_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H

+ 6 - 5
include/grpcpp/impl/codegen/method_handler_impl.h

@@ -113,14 +113,15 @@ class ClientStreamingHandler : public MethodHandler {
       return func_(service_, param.server_context, &reader, &rsp);
       return func_(service_, param.server_context, &reader, &rsp);
     });
     });
 
 
-    GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
               CallOpServerSendStatus>
               CallOpServerSendStatus>
         ops;
         ops;
-    ops.SendInitialMetadata(param.server_context->initial_metadata_,
-                            param.server_context->initial_metadata_flags());
-    if (param.server_context->compression_level_set()) {
-      ops.set_compression_level(param.server_context->compression_level());
+    if (!param.server_context->sent_initial_metadata_) {
+      ops.SendInitialMetadata(param.server_context->initial_metadata_,
+                              param.server_context->initial_metadata_flags());
+      if (param.server_context->compression_level_set()) {
+        ops.set_compression_level(param.server_context->compression_level());
+      }
     }
     }
     if (status.ok()) {
     if (status.ok()) {
       status = ops.SendMessage(rsp);
       status = ops.SendMessage(rsp);

+ 42 - 2
include/grpcpp/impl/codegen/rpc_service_method.h

@@ -25,6 +25,7 @@
 #include <memory>
 #include <memory>
 #include <vector>
 #include <vector>
 
 
+#include <grpc/impl/codegen/log.h>
 #include <grpcpp/impl/codegen/byte_buffer.h>
 #include <grpcpp/impl/codegen/byte_buffer.h>
 #include <grpcpp/impl/codegen/config.h>
 #include <grpcpp/impl/codegen/config.h>
 #include <grpcpp/impl/codegen/rpc_method.h>
 #include <grpcpp/impl/codegen/rpc_method.h>
@@ -58,18 +59,57 @@ class RpcServiceMethod : public RpcMethod {
   /// Takes ownership of the handler
   /// Takes ownership of the handler
   RpcServiceMethod(const char* name, RpcMethod::RpcType type,
   RpcServiceMethod(const char* name, RpcMethod::RpcType type,
                    MethodHandler* handler)
                    MethodHandler* handler)
-      : RpcMethod(name, type), server_tag_(nullptr), handler_(handler) {}
+      : RpcMethod(name, type),
+        server_tag_(nullptr),
+        async_type_(AsyncType::UNSET),
+        handler_(handler) {}
+
+  enum class AsyncType {
+    UNSET,
+    ASYNC,
+    RAW,
+  };
 
 
   void set_server_tag(void* tag) { server_tag_ = tag; }
   void set_server_tag(void* tag) { server_tag_ = tag; }
   void* server_tag() const { return server_tag_; }
   void* server_tag() const { return server_tag_; }
   /// if MethodHandler is nullptr, then this is an async method
   /// if MethodHandler is nullptr, then this is an async method
   MethodHandler* handler() const { return handler_.get(); }
   MethodHandler* handler() const { return handler_.get(); }
-  void ResetHandler() { handler_.reset(); }
   void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
   void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
+  void SetServerAsyncType(RpcServiceMethod::AsyncType type) {
+    if (async_type_ == AsyncType::UNSET) {
+      // this marks this method as async
+      handler_.reset();
+    } else {
+      // this is not an error condition, as it allows users to declare a server
+      // like WithRawMethod_foo<AsyncService>. However since it
+      // overwrites behavior, it should be logged.
+      gpr_log(
+          GPR_INFO,
+          "You are marking method %s as '%s', even though it was "
+          "previously marked '%s'. This behavior will overwrite the original "
+          "behavior. If you expected this then ignore this message.",
+          name(), TypeToString(async_type_), TypeToString(type));
+    }
+    async_type_ = type;
+  }
 
 
  private:
  private:
   void* server_tag_;
   void* server_tag_;
+  AsyncType async_type_;
   std::unique_ptr<MethodHandler> handler_;
   std::unique_ptr<MethodHandler> handler_;
+
+  const char* TypeToString(RpcServiceMethod::AsyncType type) {
+    switch (type) {
+      case AsyncType::UNSET:
+        return "unset";
+      case AsyncType::ASYNC:
+        return "async";
+      case AsyncType::RAW:
+        return "raw";
+      default:
+        GPR_UNREACHABLE_CODE(return "unknown");
+    }
+  }
 };
 };
 }  // namespace internal
 }  // namespace internal
 
 

+ 19 - 2
include/grpcpp/impl/codegen/service_type.h

@@ -124,22 +124,39 @@ class Service {
   }
   }
 
 
   void MarkMethodAsync(int index) {
   void MarkMethodAsync(int index) {
+    // This does not have to be a hard error, however no one has approached us
+    // with a use case yet. Please file an issue if you believe you have one.
     GPR_CODEGEN_ASSERT(
     GPR_CODEGEN_ASSERT(
         methods_[index].get() != nullptr &&
         methods_[index].get() != nullptr &&
         "Cannot mark the method as 'async' because it has already been "
         "Cannot mark the method as 'async' because it has already been "
         "marked as 'generic'.");
         "marked as 'generic'.");
-    methods_[index]->ResetHandler();
+    methods_[index]->SetServerAsyncType(
+        internal::RpcServiceMethod::AsyncType::ASYNC);
+  }
+
+  void MarkMethodRaw(int index) {
+    // This does not have to be a hard error, however no one has approached us
+    // with a use case yet. Please file an issue if you believe you have one.
+    GPR_CODEGEN_ASSERT(methods_[index].get() != nullptr &&
+                       "Cannot mark the method as 'raw' because it has already "
+                       "been marked as 'generic'.");
+    methods_[index]->SetServerAsyncType(
+        internal::RpcServiceMethod::AsyncType::RAW);
   }
   }
 
 
   void MarkMethodGeneric(int index) {
   void MarkMethodGeneric(int index) {
+    // This does not have to be a hard error, however no one has approached us
+    // with a use case yet. Please file an issue if you believe you have one.
     GPR_CODEGEN_ASSERT(
     GPR_CODEGEN_ASSERT(
         methods_[index]->handler() != nullptr &&
         methods_[index]->handler() != nullptr &&
         "Cannot mark the method as 'generic' because it has already been "
         "Cannot mark the method as 'generic' because it has already been "
-        "marked as 'async'.");
+        "marked as 'async' or 'raw'.");
     methods_[index].reset();
     methods_[index].reset();
   }
   }
 
 
   void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
   void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
+    // This does not have to be a hard error, however no one has approached us
+    // with a use case yet. Please file an issue if you believe you have one.
     GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
     GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
                        "Cannot mark an async or generic method Streamed");
                        "Cannot mark an async or generic method Streamed");
     methods_[index]->SetHandler(streamed_method);
     methods_[index]->SetHandler(streamed_method);

+ 3 - 2
include/grpcpp/impl/server_builder_plugin.h

@@ -37,8 +37,9 @@ class ServerBuilderPlugin {
   virtual ~ServerBuilderPlugin() {}
   virtual ~ServerBuilderPlugin() {}
   virtual grpc::string name() = 0;
   virtual grpc::string name() = 0;
 
 
-  /// UpdateServerBuilder will be called at the beginning of
-  /// \a ServerBuilder::BuildAndStart().
+  /// UpdateServerBuilder will be called at an early stage in
+  /// ServerBuilder::BuildAndStart(), right after the ServerBuilderOptions have
+  /// done their updates.
   virtual void UpdateServerBuilder(ServerBuilder* builder) {}
   virtual void UpdateServerBuilder(ServerBuilder* builder) {}
 
 
   /// InitServer will be called in ServerBuilder::BuildAndStart(), after the
   /// InitServer will be called in ServerBuilder::BuildAndStart(), after the

+ 11 - 0
package.xml

@@ -80,12 +80,14 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/fork.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/fork.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_custom.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_custom.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/alloc.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
@@ -164,6 +166,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/fork.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/fork.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_custom.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_custom.h" role="src" />
@@ -219,10 +222,12 @@
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/local/local_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
@@ -265,6 +270,7 @@
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_channelz.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" />
@@ -286,6 +292,7 @@
     <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/local_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_cache.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_cache.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
@@ -635,10 +642,12 @@
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/local/local_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" />
@@ -690,6 +699,7 @@
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_channelz.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" />
@@ -711,6 +721,7 @@
     <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/local_transport_security.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_cache.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_cache.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_openssl.cc" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_openssl.cc" role="src" />

+ 1 - 1
requirements.txt

@@ -1,6 +1,6 @@
 # GRPC Python setup requirements
 # GRPC Python setup requirements
 coverage>=4.0
 coverage>=4.0
-cython>=0.27
+cython==0.28.3
 enum34>=1.0.4
 enum34>=1.0.4
 protobuf>=3.5.0.post1
 protobuf>=3.5.0.post1
 six>=1.10
 six>=1.10

+ 89 - 38
src/compiler/cpp_generator.cc

@@ -128,6 +128,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
                     "");
                     "");
     }
     }
     static const char* headers_strs[] = {
     static const char* headers_strs[] = {
+        "grpcpp/impl/codegen/async_generic_service.h",
         "grpcpp/impl/codegen/async_stream.h",
         "grpcpp/impl/codegen/async_stream.h",
         "grpcpp/impl/codegen/async_unary_call.h",
         "grpcpp/impl/codegen/async_unary_call.h",
         "grpcpp/impl/codegen/method_handler_impl.h",
         "grpcpp/impl/codegen/method_handler_impl.h",
@@ -588,43 +589,27 @@ void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
   printer->Print(method->GetTrailingComments("//").c_str());
   printer->Print(method->GetTrailingComments("//").c_str());
 }
 }
 
 
-void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
-                                  const grpc_generator::Method* method,
-                                  std::map<grpc::string, grpc::string>* vars) {
-  (*vars)["Method"] = method->name();
-  (*vars)["Request"] = method->input_type_name();
-  (*vars)["Response"] = method->output_type_name();
-  printer->Print(*vars, "template <class BaseClass>\n");
-  printer->Print(*vars,
-                 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
-  printer->Print(
-      " private:\n"
-      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
-  printer->Print(" public:\n");
-  printer->Indent();
-  printer->Print(*vars,
-                 "WithAsyncMethod_$Method$() {\n"
-                 "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
-                 "}\n");
-  printer->Print(*vars,
-                 "~WithAsyncMethod_$Method$() override {\n"
-                 "  BaseClassMustBeDerivedFromService(this);\n"
-                 "}\n");
+// Helper generator. Disabled the sync API for Request and Response, then adds
+// in an async API for RealRequest and RealResponse types. This is to be used
+// to generate async and raw APIs.
+void PrintHeaderServerAsyncMethodsHelper(
+    grpc_generator::Printer* printer, const grpc_generator::Method* method,
+    std::map<grpc::string, grpc::string>* vars) {
   if (method->NoStreaming()) {
   if (method->NoStreaming()) {
     printer->Print(
     printer->Print(
         *vars,
         *vars,
         "// disable synchronous version of this method\n"
         "// disable synchronous version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "$Response$* response) final override {\n"
+        "$Response$* response) override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
     printer->Print(
     printer->Print(
         *vars,
         *vars,
         "void Request$Method$("
         "void Request$Method$("
-        "::grpc::ServerContext* context, $Request$* request, "
-        "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
+        "::grpc::ServerContext* context, $RealRequest$* request, "
+        "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     printer->Print(*vars,
     printer->Print(*vars,
@@ -638,7 +623,7 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
         "::grpc::ServerReader< $Request$>* reader, "
         "::grpc::ServerReader< $Request$>* reader, "
-        "$Response$* response) final override {\n"
+        "$Response$* response) override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -646,7 +631,7 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
         *vars,
         *vars,
         "void Request$Method$("
         "void Request$Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
-        "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
+        "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     printer->Print(*vars,
     printer->Print(*vars,
@@ -659,7 +644,7 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
         "// disable synchronous version of this method\n"
         "// disable synchronous version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "::grpc::ServerWriter< $Response$>* writer) override "
         "{\n"
         "{\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
@@ -667,8 +652,8 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
     printer->Print(
     printer->Print(
         *vars,
         *vars,
         "void Request$Method$("
         "void Request$Method$("
-        "::grpc::ServerContext* context, $Request$* request, "
-        "::grpc::ServerAsyncWriter< $Response$>* writer, "
+        "::grpc::ServerContext* context, $RealRequest$* request, "
+        "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     printer->Print(
     printer->Print(
@@ -683,7 +668,7 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
-        "final override {\n"
+        " override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -691,7 +676,8 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
         *vars,
         *vars,
         "void Request$Method$("
         "void Request$Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
-        "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
+        "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
+        "stream, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::CompletionQueue* new_call_cq, "
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     printer->Print(*vars,
     printer->Print(*vars,
@@ -699,6 +685,35 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
                    "context, stream, new_call_cq, notification_cq, tag);\n");
                    "context, stream, new_call_cq, notification_cq, tag);\n");
     printer->Print("}\n");
     printer->Print("}\n");
   }
   }
+}
+
+void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
+                                  const grpc_generator::Method* method,
+                                  std::map<grpc::string, grpc::string>* vars) {
+  (*vars)["Method"] = method->name();
+  // These will be disabled
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  // These will be used for the async API
+  (*vars)["RealRequest"] = method->input_type_name();
+  (*vars)["RealResponse"] = method->output_type_name();
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars,
+                 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithAsyncMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithAsyncMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
   printer->Outdent();
   printer->Outdent();
   printer->Print(*vars, "};\n");
   printer->Print(*vars, "};\n");
 }
 }
@@ -738,7 +753,7 @@ void PrintHeaderServerMethodStreamedUnary(
         "// disable regular version of this method\n"
         "// disable regular version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "$Response$* response) final override {\n"
+        "$Response$* response) override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -790,7 +805,7 @@ void PrintHeaderServerMethodSplitStreaming(
         "// disable regular version of this method\n"
         "// disable regular version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "::grpc::ServerWriter< $Response$>* writer) override "
         "{\n"
         "{\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
@@ -835,7 +850,7 @@ void PrintHeaderServerMethodGeneric(
         "// disable synchronous version of this method\n"
         "// disable synchronous version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "$Response$* response) final override {\n"
+        "$Response$* response) override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -846,7 +861,7 @@ void PrintHeaderServerMethodGeneric(
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
         "::grpc::ServerReader< $Request$>* reader, "
         "::grpc::ServerReader< $Request$>* reader, "
-        "$Response$* response) final override {\n"
+        "$Response$* response) override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -856,7 +871,7 @@ void PrintHeaderServerMethodGeneric(
         "// disable synchronous version of this method\n"
         "// disable synchronous version of this method\n"
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, const $Request$* request, "
         "::grpc::ServerContext* context, const $Request$* request, "
-        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "::grpc::ServerWriter< $Response$>* writer) override "
         "{\n"
         "{\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
@@ -868,7 +883,7 @@ void PrintHeaderServerMethodGeneric(
         "::grpc::Status $Method$("
         "::grpc::Status $Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerContext* context, "
         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
-        "final override {\n"
+        " override {\n"
         "  abort();\n"
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
         "}\n");
@@ -877,6 +892,36 @@ void PrintHeaderServerMethodGeneric(
   printer->Print(*vars, "};\n");
   printer->Print(*vars, "};\n");
 }
 }
 
 
+void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
+                                const grpc_generator::Method* method,
+                                std::map<grpc::string, grpc::string>* vars) {
+  (*vars)["Method"] = method->name();
+  // These will be disabled
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  // These will be used for raw API
+  (*vars)["RealRequest"] = "::grpc::ByteBuffer";
+  (*vars)["RealResponse"] = "::grpc::ByteBuffer";
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithRawMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodRaw($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithRawMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
+  printer->Outdent();
+  printer->Print(*vars, "};\n");
+}
+
 void PrintHeaderService(grpc_generator::Printer* printer,
 void PrintHeaderService(grpc_generator::Printer* printer,
                         const grpc_generator::Service* service,
                         const grpc_generator::Service* service,
                         std::map<grpc::string, grpc::string>* vars) {
                         std::map<grpc::string, grpc::string>* vars) {
@@ -981,6 +1026,12 @@ void PrintHeaderService(grpc_generator::Printer* printer,
     PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
     PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
   }
   }
 
 
+  // Server side - Raw
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodRaw(printer, service->method(i).get(), vars);
+  }
+
   // Server side - Streamed Unary
   // Server side - Streamed Unary
   for (int i = 0; i < service->method_count(); ++i) {
   for (int i = 0; i < service->method_count(); ++i) {
     (*vars)["Idx"] = as_string(i);
     (*vars)["Idx"] = as_string(i);

+ 80 - 0
src/core/ext/filters/client_channel/client_channel_channelz.cc

@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2018 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/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/connectivity_state.h"
+
+namespace grpc_core {
+namespace channelz {
+namespace {
+
+void* client_channel_channelz_copy(void* p) { return p; }
+
+void client_channel_channelz_destroy(void* p) {}
+
+int client_channel_channelz_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
+
+}  // namespace
+
+static const grpc_arg_pointer_vtable client_channel_channelz_vtable = {
+    client_channel_channelz_copy, client_channel_channelz_destroy,
+    client_channel_channelz_cmp};
+
+ClientChannelNode::ClientChannelNode(grpc_channel* channel,
+                                     size_t channel_tracer_max_nodes)
+    : ChannelNode(channel, channel_tracer_max_nodes) {
+  client_channel_ =
+      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
+  GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
+}
+
+void ClientChannelNode::PopulateConnectivityState(grpc_json* json) {
+  grpc_connectivity_state state;
+  if (ChannelIsDestroyed()) {
+    state = GRPC_CHANNEL_SHUTDOWN;
+  } else {
+    state =
+        grpc_client_channel_check_connectivity_state(client_channel_, false);
+  }
+  json = grpc_json_create_child(nullptr, json, "state", nullptr,
+                                GRPC_JSON_OBJECT, false);
+  grpc_json_create_child(nullptr, json, "state",
+                         grpc_connectivity_state_name(state), GRPC_JSON_STRING,
+                         false);
+}
+
+grpc_arg ClientChannelNode::CreateChannelArg() {
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC),
+      reinterpret_cast<void*>(MakeClientChannelNode),
+      &client_channel_channelz_vtable);
+}
+
+RefCountedPtr<ChannelNode> ClientChannelNode::MakeClientChannelNode(
+    grpc_channel* channel, size_t channel_tracer_max_nodes) {
+  return MakePolymorphicRefCounted<ChannelNode, ClientChannelNode>(
+      channel, channel_tracer_max_nodes);
+}
+
+}  // namespace channelz
+}  // namespace grpc_core

+ 58 - 0
src/core/ext/filters/client_channel/client_channel_channelz.h

@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2018 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_CLIENT_CHANNEL_CLIENT_CHANNEL_CHANNELZ_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_CHANNELZ_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/channelz.h"
+
+namespace grpc_core {
+namespace channelz {
+
+// Subtype of ChannelNode that overrides and provides client_channel specific
+// functionality like querying for connectivity_state and subchannel data.
+class ClientChannelNode : public ChannelNode {
+ public:
+  static RefCountedPtr<ChannelNode> MakeClientChannelNode(
+      grpc_channel* channel, size_t channel_tracer_max_nodes);
+
+  // Override this functionality since client_channels have a notion of
+  // channel connectivity.
+  void PopulateConnectivityState(grpc_json* json) override;
+
+  // Helper to create a channel arg to ensure this type of ChannelNode is
+  // created.
+  static grpc_arg CreateChannelArg();
+
+ protected:
+  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+  ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
+  virtual ~ClientChannelNode() {}
+
+ private:
+  grpc_channel_element* client_channel_;
+};
+
+}  // namespace channelz
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_CHANNELZ_H */

+ 9 - 0
src/core/ext/filters/client_channel/client_channel_plugin.cc

@@ -25,6 +25,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 
 
 #include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
 #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
 #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
 #include "src/core/ext/filters/client_channel/http_proxy.h"
 #include "src/core/ext/filters/client_channel/http_proxy.h"
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
@@ -35,6 +36,14 @@
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/surface/channel_init.h"
 
 
 static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
 static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
+  const grpc_channel_args* args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  grpc_arg args_to_add[] = {
+      grpc_core::channelz::ClientChannelNode::CreateChannelArg()};
+  grpc_channel_args* new_args = grpc_channel_args_copy_and_add(
+      args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
+  grpc_channel_stack_builder_set_channel_arguments(builder, new_args);
+  grpc_channel_args_destroy(new_args);
   return grpc_channel_stack_builder_append_filter(
   return grpc_channel_stack_builder_append_filter(
       builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
       builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
 }
 }

+ 8 - 2
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc

@@ -74,6 +74,8 @@ struct grpc_ares_ev_driver {
   bool working;
   bool working;
   /** is this event driver being shut down */
   /** is this event driver being shut down */
   bool shutting_down;
   bool shutting_down;
+  /** request object that's using this ev driver */
+  grpc_ares_request* request;
 };
 };
 
 
 static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
 static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
@@ -92,6 +94,7 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
     GPR_ASSERT(ev_driver->fds == nullptr);
     GPR_ASSERT(ev_driver->fds == nullptr);
     GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver");
     GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver");
     ares_destroy(ev_driver->channel);
     ares_destroy(ev_driver->channel);
+    grpc_ares_complete_request_locked(ev_driver->request);
     gpr_free(ev_driver);
     gpr_free(ev_driver);
   }
   }
 }
 }
@@ -115,7 +118,8 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
 
 
 grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
 grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
                                               grpc_pollset_set* pollset_set,
                                               grpc_pollset_set* pollset_set,
-                                              grpc_combiner* combiner) {
+                                              grpc_combiner* combiner,
+                                              grpc_ares_request* request) {
   *ev_driver = static_cast<grpc_ares_ev_driver*>(
   *ev_driver = static_cast<grpc_ares_ev_driver*>(
       gpr_malloc(sizeof(grpc_ares_ev_driver)));
       gpr_malloc(sizeof(grpc_ares_ev_driver)));
   ares_options opts;
   ares_options opts;
@@ -139,10 +143,12 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
   (*ev_driver)->fds = nullptr;
   (*ev_driver)->fds = nullptr;
   (*ev_driver)->working = false;
   (*ev_driver)->working = false;
   (*ev_driver)->shutting_down = false;
   (*ev_driver)->shutting_down = false;
+  (*ev_driver)->request = request;
   return GRPC_ERROR_NONE;
   return GRPC_ERROR_NONE;
 }
 }
 
 
-void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver) {
+void grpc_ares_ev_driver_on_queries_complete_locked(
+    grpc_ares_ev_driver* ev_driver) {
   // We mark the event driver as being shut down. If the event driver
   // We mark the event driver as being shut down. If the event driver
   // is working, grpc_ares_notify_on_event_locked will shut down the
   // is working, grpc_ares_notify_on_event_locked will shut down the
   // fds; if it's not working, there are no fds to shut down.
   // fds; if it's not working, there are no fds to shut down.

+ 6 - 5
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h

@@ -22,6 +22,7 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
 
 
 #include <ares.h>
 #include <ares.h>
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
 #include "src/core/lib/gprpp/abstract.h"
 #include "src/core/lib/gprpp/abstract.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 
 
@@ -42,12 +43,12 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked(
    created successfully. */
    created successfully. */
 grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
 grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
                                               grpc_pollset_set* pollset_set,
                                               grpc_pollset_set* pollset_set,
-                                              grpc_combiner* combiner);
+                                              grpc_combiner* combiner,
+                                              grpc_ares_request* request);
 
 
-/* Destroys \a ev_driver asynchronously. Pending lookups made on \a ev_driver
-   will be cancelled and their on_done callbacks will be invoked with a status
-   of ARES_ECANCELLED. */
-void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver);
+/* Called back when all DNS lookups have completed. */
+void grpc_ares_ev_driver_on_queries_complete_locked(
+    grpc_ares_ev_driver* ev_driver);
 
 
 /* Shutdown all the grpc_fds used by \a ev_driver */
 /* Shutdown all the grpc_fds used by \a ev_driver */
 void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);
 void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);

+ 4 - 1
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc

@@ -44,11 +44,13 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
       : as_(as) {
       : as_(as) {
     gpr_asprintf(&name_, "c-ares fd: %d", (int)as);
     gpr_asprintf(&name_, "c-ares fd: %d", (int)as);
     fd_ = grpc_fd_create((int)as, name_, false);
     fd_ = grpc_fd_create((int)as, name_, false);
-    grpc_pollset_set_add_fd(driver_pollset_set, fd_);
+    driver_pollset_set_ = driver_pollset_set;
+    grpc_pollset_set_add_fd(driver_pollset_set_, fd_);
   }
   }
 
 
   ~GrpcPolledFdPosix() {
   ~GrpcPolledFdPosix() {
     gpr_free(name_);
     gpr_free(name_);
+    grpc_pollset_set_del_fd(driver_pollset_set_, fd_);
     /* c-ares library will close the fd inside grpc_fd. This fd may be picked up
     /* c-ares library will close the fd inside grpc_fd. This fd may be picked up
        immediately by another thread, and should not be closed by the following
        immediately by another thread, and should not be closed by the following
        grpc_fd_orphan. */
        grpc_fd_orphan. */
@@ -81,6 +83,7 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
   char* name_;
   char* name_;
   ares_socket_t as_;
   ares_socket_t as_;
   grpc_fd* fd_;
   grpc_fd* fd_;
+  grpc_pollset_set* driver_pollset_set_;
 };
 };
 
 
 GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as,
 GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as,

+ 22 - 21
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc

@@ -63,7 +63,7 @@ struct grpc_ares_request {
   /** the evernt driver used by this request */
   /** the evernt driver used by this request */
   grpc_ares_ev_driver* ev_driver;
   grpc_ares_ev_driver* ev_driver;
   /** number of ongoing queries */
   /** number of ongoing queries */
-  gpr_refcount pending_queries;
+  size_t pending_queries;
 
 
   /** is there at least one successful query, set in on_done_cb */
   /** is there at least one successful query, set in on_done_cb */
   bool success;
   bool success;
@@ -145,21 +145,25 @@ void grpc_cares_wrapper_test_only_address_sorting_sort(
 }
 }
 
 
 static void grpc_ares_request_ref_locked(grpc_ares_request* r) {
 static void grpc_ares_request_ref_locked(grpc_ares_request* r) {
-  gpr_ref(&r->pending_queries);
+  r->pending_queries++;
 }
 }
 
 
 static void grpc_ares_request_unref_locked(grpc_ares_request* r) {
 static void grpc_ares_request_unref_locked(grpc_ares_request* r) {
-  /* If there are no pending queries, invoke on_done callback and destroy the
+  r->pending_queries--;
+  if (r->pending_queries == 0u) {
+    grpc_ares_ev_driver_on_queries_complete_locked(r->ev_driver);
+  }
+}
+
+void grpc_ares_complete_request_locked(grpc_ares_request* r) {
+  /* Invoke on_done callback and destroy the
      request */
      request */
-  if (gpr_unref(&r->pending_queries)) {
-    grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
-    if (lb_addrs != nullptr) {
-      grpc_cares_wrapper_address_sorting_sort(lb_addrs);
-    }
-    GRPC_CLOSURE_SCHED(r->on_done, r->error);
-    grpc_ares_ev_driver_destroy_locked(r->ev_driver);
-    gpr_free(r);
+  grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
+  if (lb_addrs != nullptr) {
+    grpc_cares_wrapper_address_sorting_sort(lb_addrs);
   }
   }
+  GRPC_CLOSURE_SCHED(r->on_done, r->error);
+  gpr_free(r);
 }
 }
 
 
 static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
 static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
@@ -399,20 +403,18 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
     }
     }
     port = gpr_strdup(default_port);
     port = gpr_strdup(default_port);
   }
   }
-  grpc_ares_ev_driver* ev_driver;
-  error = grpc_ares_ev_driver_create_locked(&ev_driver, interested_parties,
-                                            combiner);
-  if (error != GRPC_ERROR_NONE) goto error_cleanup;
-
   r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
   r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
-  r->ev_driver = ev_driver;
+  r->ev_driver = nullptr;
   r->on_done = on_done;
   r->on_done = on_done;
   r->lb_addrs_out = addrs;
   r->lb_addrs_out = addrs;
   r->service_config_json_out = service_config_json;
   r->service_config_json_out = service_config_json;
   r->success = false;
   r->success = false;
   r->error = GRPC_ERROR_NONE;
   r->error = GRPC_ERROR_NONE;
+  r->pending_queries = 0;
+  error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
+                                            combiner, r);
+  if (error != GRPC_ERROR_NONE) goto error_cleanup;
   channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
   channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
-
   // If dns_server is specified, use it.
   // If dns_server is specified, use it.
   if (dns_server != nullptr) {
   if (dns_server != nullptr) {
     gpr_log(GPR_INFO, "Using DNS server %s", dns_server);
     gpr_log(GPR_INFO, "Using DNS server %s", dns_server);
@@ -437,7 +439,6 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
       error = grpc_error_set_str(
       error = grpc_error_set_str(
           GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
           GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
           GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
           GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
-      gpr_free(r);
       goto error_cleanup;
       goto error_cleanup;
     }
     }
     int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
     int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
@@ -447,11 +448,10 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
                    ares_strerror(status));
                    ares_strerror(status));
       error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
       error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
       gpr_free(error_msg);
       gpr_free(error_msg);
-      gpr_free(r);
       goto error_cleanup;
       goto error_cleanup;
     }
     }
   }
   }
-  gpr_ref_init(&r->pending_queries, 1);
+  r->pending_queries = 1;
   if (grpc_ipv6_loopback_available()) {
   if (grpc_ipv6_loopback_available()) {
     hr = create_hostbyname_request_locked(r, host, strhtons(port),
     hr = create_hostbyname_request_locked(r, host, strhtons(port),
                                           false /* is_balancer */);
                                           false /* is_balancer */);
@@ -487,6 +487,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
 
 
 error_cleanup:
 error_cleanup:
   GRPC_CLOSURE_SCHED(on_done, error);
   GRPC_CLOSURE_SCHED(on_done, error);
+  gpr_free(r);
   gpr_free(host);
   gpr_free(host);
   gpr_free(port);
   gpr_free(port);
   return nullptr;
   return nullptr;

+ 4 - 0
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h

@@ -66,6 +66,10 @@ grpc_error* grpc_ares_init(void);
    it has been called the same number of times as grpc_ares_init(). */
    it has been called the same number of times as grpc_ares_init(). */
 void grpc_ares_cleanup(void);
 void grpc_ares_cleanup(void);
 
 
+/** Schedules the desired callback for request completion
+ * and destroys the grpc_ares_request */
+void grpc_ares_complete_request_locked(grpc_ares_request* request);
+
 /* Exposed only for testing */
 /* Exposed only for testing */
 void grpc_cares_wrapper_test_only_address_sorting_sort(
 void grpc_cares_wrapper_test_only_address_sorting_sort(
     grpc_lb_addresses* lb_addrs);
     grpc_lb_addresses* lb_addrs);

+ 19 - 6
src/core/ext/filters/client_channel/subchannel.cc

@@ -38,6 +38,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/alloc.h"
 #include "src/core/lib/gprpp/debug_location.h"
 #include "src/core/lib/gprpp/debug_location.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
@@ -140,9 +141,13 @@ struct grpc_subchannel_call {
   grpc_closure* schedule_closure_after_destroy;
   grpc_closure* schedule_closure_after_destroy;
 };
 };
 
 
-#define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack*)((call) + 1))
-#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
-  (((grpc_subchannel_call*)(callstack)) - 1)
+#define SUBCHANNEL_CALL_TO_CALL_STACK(call)                          \
+  (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
+                                         sizeof(grpc_subchannel_call)))
+#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack)           \
+  (grpc_subchannel_call*)(((char*)(call_stack)) -         \
+                          GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
+                              sizeof(grpc_subchannel_call)))
 
 
 static void on_subchannel_connected(void* subchannel, grpc_error* error);
 static void on_subchannel_connected(void* subchannel, grpc_error* error);
 
 
@@ -783,9 +788,17 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
 
 
 grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
 grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
                                             grpc_subchannel_call** call) {
                                             grpc_subchannel_call** call) {
-  *call = static_cast<grpc_subchannel_call*>(gpr_arena_alloc(
-      args.arena, sizeof(grpc_subchannel_call) +
-                      channel_stack_->call_stack_size + args.parent_data_size));
+  size_t allocation_size =
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call));
+  if (args.parent_data_size > 0) {
+    allocation_size +=
+        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
+        args.parent_data_size;
+  } else {
+    allocation_size += channel_stack_->call_stack_size;
+  }
+  *call = static_cast<grpc_subchannel_call*>(
+      gpr_arena_alloc(args.arena, allocation_size));
   grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
   grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
   RefCountedPtr<ConnectedSubchannel> connection =
   RefCountedPtr<ConnectedSubchannel> connection =
       Ref(DEBUG_LOCATION, "subchannel_call");
       Ref(DEBUG_LOCATION, "subchannel_call");

+ 3 - 0
src/core/ext/transport/chttp2/transport/chttp2_transport.cc

@@ -2663,6 +2663,9 @@ static void init_keepalive_ping_locked(void* arg, grpc_error* error) {
 
 
 static void start_keepalive_ping_locked(void* arg, grpc_error* error) {
 static void start_keepalive_ping_locked(void* arg, grpc_error* error) {
   grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg);
   grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg);
+  if (error != GRPC_ERROR_NONE) {
+    return;
+  }
   GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog");
   GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog");
   grpc_timer_init(&t->keepalive_watchdog_timer,
   grpc_timer_init(&t->keepalive_watchdog_timer,
                   grpc_core::ExecCtx::Get()->Now() + t->keepalive_timeout,
                   grpc_core::ExecCtx::Get()->Now() + t->keepalive_timeout,

+ 22 - 24
src/core/lib/channel/channel_stack.cc

@@ -21,6 +21,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr/alloc.h"
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
@@ -43,16 +44,12 @@ grpc_core::TraceFlag grpc_trace_channel(false, "channel");
      per-filter memory, aligned to GPR_MAX_ALIGNMENT
      per-filter memory, aligned to GPR_MAX_ALIGNMENT
    } */
    } */
 
 
-/* Given a size, round up to the next multiple of sizeof(void*) */
-#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
-  (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
-
 size_t grpc_channel_stack_size(const grpc_channel_filter** filters,
 size_t grpc_channel_stack_size(const grpc_channel_filter** filters,
                                size_t filter_count) {
                                size_t filter_count) {
   /* always need the header, and size for the channel elements */
   /* always need the header, and size for the channel elements */
-  size_t size =
-      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) +
-      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
+  size_t size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) +
+                GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count *
+                                               sizeof(grpc_channel_element));
   size_t i;
   size_t i;
 
 
   GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 &&
   GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 &&
@@ -60,19 +57,19 @@ size_t grpc_channel_stack_size(const grpc_channel_filter** filters,
 
 
   /* add the size for each filter */
   /* add the size for each filter */
   for (i = 0; i < filter_count; i++) {
   for (i = 0; i < filter_count; i++) {
-    size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
+    size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
   }
   }
 
 
   return size;
   return size;
 }
 }
 
 
-#define CHANNEL_ELEMS_FROM_STACK(stk)                                 \
-  ((grpc_channel_element*)((char*)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \
+#define CHANNEL_ELEMS_FROM_STACK(stk)                                     \
+  ((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
                                               sizeof(grpc_channel_stack))))
                                               sizeof(grpc_channel_stack))))
 
 
-#define CALL_ELEMS_FROM_STACK(stk)     \
-  ((grpc_call_element*)((char*)(stk) + \
-                        ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack))))
+#define CALL_ELEMS_FROM_STACK(stk)                                     \
+  ((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
+                                           sizeof(grpc_call_stack))))
 
 
 grpc_channel_element* grpc_channel_stack_element(
 grpc_channel_element* grpc_channel_stack_element(
     grpc_channel_stack* channel_stack, size_t index) {
     grpc_channel_stack* channel_stack, size_t index) {
@@ -95,8 +92,8 @@ grpc_error* grpc_channel_stack_init(
     const grpc_channel_args* channel_args, grpc_transport* optional_transport,
     const grpc_channel_args* channel_args, grpc_transport* optional_transport,
     const char* name, grpc_channel_stack* stack) {
     const char* name, grpc_channel_stack* stack) {
   size_t call_size =
   size_t call_size =
-      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
-      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
   grpc_channel_element* elems;
   grpc_channel_element* elems;
   grpc_channel_element_args args;
   grpc_channel_element_args args;
   char* user_data;
   char* user_data;
@@ -106,9 +103,9 @@ grpc_error* grpc_channel_stack_init(
   GRPC_STREAM_REF_INIT(&stack->refcount, initial_refs, destroy, destroy_arg,
   GRPC_STREAM_REF_INIT(&stack->refcount, initial_refs, destroy, destroy_arg,
                        name);
                        name);
   elems = CHANNEL_ELEMS_FROM_STACK(stack);
   elems = CHANNEL_ELEMS_FROM_STACK(stack);
-  user_data =
-      (reinterpret_cast<char*>(elems)) +
-      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
+  user_data = (reinterpret_cast<char*>(elems)) +
+              GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count *
+                                             sizeof(grpc_channel_element));
 
 
   /* init per-filter data */
   /* init per-filter data */
   grpc_error* first_error = GRPC_ERROR_NONE;
   grpc_error* first_error = GRPC_ERROR_NONE;
@@ -128,8 +125,9 @@ grpc_error* grpc_channel_stack_init(
         GRPC_ERROR_UNREF(error);
         GRPC_ERROR_UNREF(error);
       }
       }
     }
     }
-    user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
-    call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
+    user_data +=
+        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
+    call_size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
   }
   }
 
 
   GPR_ASSERT(user_data > (char*)stack);
   GPR_ASSERT(user_data > (char*)stack);
@@ -166,7 +164,7 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack,
                        destroy_arg, "CALL_STACK");
                        destroy_arg, "CALL_STACK");
   call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack);
   call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack);
   user_data = (reinterpret_cast<char*>(call_elems)) +
   user_data = (reinterpret_cast<char*>(call_elems)) +
-              ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
+              GPR_ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
 
 
   /* init per-filter data */
   /* init per-filter data */
   grpc_error* first_error = GRPC_ERROR_NONE;
   grpc_error* first_error = GRPC_ERROR_NONE;
@@ -184,7 +182,7 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack,
       }
       }
     }
     }
     user_data +=
     user_data +=
-        ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
+        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
   }
   }
   return first_error;
   return first_error;
 }
 }
@@ -243,11 +241,11 @@ grpc_channel_stack* grpc_channel_stack_from_top_element(
     grpc_channel_element* elem) {
     grpc_channel_element* elem) {
   return reinterpret_cast<grpc_channel_stack*>(
   return reinterpret_cast<grpc_channel_stack*>(
       reinterpret_cast<char*>(elem) -
       reinterpret_cast<char*>(elem) -
-      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)));
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)));
 }
 }
 
 
 grpc_call_stack* grpc_call_stack_from_top_element(grpc_call_element* elem) {
 grpc_call_stack* grpc_call_stack_from_top_element(grpc_call_element* elem) {
   return reinterpret_cast<grpc_call_stack*>(
   return reinterpret_cast<grpc_call_stack*>(
       reinterpret_cast<char*>(elem) -
       reinterpret_cast<char*>(elem) -
-      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)));
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)));
 }
 }

+ 8 - 21
src/core/lib/channel/channelz.cc

@@ -36,7 +36,6 @@
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel.h"
-#include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/error_utils.h"
 #include "src/core/lib/transport/error_utils.h"
 
 
 namespace grpc_core {
 namespace grpc_core {
@@ -109,16 +108,7 @@ void ChannelNode::RecordCallStarted() {
                            (gpr_atm)ExecCtx::Get()->Now());
                            (gpr_atm)ExecCtx::Get()->Now());
 }
 }
 
 
-grpc_connectivity_state ChannelNode::GetConnectivityState() {
-  if (channel_ == nullptr) {
-    return GRPC_CHANNEL_SHUTDOWN;
-  } else {
-    // TODO(ncteisen): re-enable this once we have cleaned up all of the
-    // internal dependency issues.
-    // return grpc_channel_check_connectivity_state(channel_, false);
-    return GRPC_CHANNEL_IDLE;
-  }
-}
+void ChannelNode::PopulateConnectivityState(grpc_json* json) {}
 
 
 char* ChannelNode::RenderJSON() {
 char* ChannelNode::RenderJSON() {
   // We need to track these three json objects to build our object
   // We need to track these three json objects to build our object
@@ -139,16 +129,7 @@ char* ChannelNode::RenderJSON() {
                                            GRPC_JSON_OBJECT, false);
                                            GRPC_JSON_OBJECT, false);
   json = data;
   json = data;
   json_iterator = nullptr;
   json_iterator = nullptr;
-  // create and fill the connectivity state child.
-  grpc_connectivity_state connectivity_state = GetConnectivityState();
-  json_iterator = grpc_json_create_child(json_iterator, json, "state", nullptr,
-                                         GRPC_JSON_OBJECT, false);
-  json = json_iterator;
-  grpc_json_create_child(nullptr, json, "state",
-                         grpc_connectivity_state_name(connectivity_state),
-                         GRPC_JSON_STRING, false);
-  // reset the parent to be the data object.
-  json = data;
+  PopulateConnectivityState(json);
   json_iterator = grpc_json_create_child(
   json_iterator = grpc_json_create_child(
       json_iterator, json, "target", target_.get(), GRPC_JSON_STRING, false);
       json_iterator, json, "target", target_.get(), GRPC_JSON_STRING, false);
   // fill in the channel trace if applicable
   // fill in the channel trace if applicable
@@ -184,5 +165,11 @@ char* ChannelNode::RenderJSON() {
   return json_str;
   return json_str;
 }
 }
 
 
+RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
+    grpc_channel* channel, size_t channel_tracer_max_nodes) {
+  return MakeRefCounted<grpc_core::channelz::ChannelNode>(
+      channel, channel_tracer_max_nodes);
+}
+
 }  // namespace channelz
 }  // namespace channelz
 }  // namespace grpc_core
 }  // namespace grpc_core

+ 25 - 6
src/core/lib/channel/channelz.h

@@ -31,6 +31,10 @@
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/json/json.h"
 #include "src/core/lib/json/json.h"
 
 
+// Channel arg key for client channel factory.
+#define GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC \
+  "grpc.channelz_channel_node_creation_func"
+
 namespace grpc_core {
 namespace grpc_core {
 namespace channelz {
 namespace channelz {
 
 
@@ -40,8 +44,8 @@ class ChannelNodePeer;
 
 
 class ChannelNode : public RefCounted<ChannelNode> {
 class ChannelNode : public RefCounted<ChannelNode> {
  public:
  public:
-  ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
-  ~ChannelNode();
+  static RefCountedPtr<ChannelNode> MakeChannelNode(
+      grpc_channel* channel, size_t channel_tracer_max_nodes);
 
 
   void RecordCallStarted();
   void RecordCallStarted();
   void RecordCallFailed() {
   void RecordCallFailed() {
@@ -53,22 +57,32 @@ class ChannelNode : public RefCounted<ChannelNode> {
 
 
   char* RenderJSON();
   char* RenderJSON();
 
 
+  // helper for getting and populating connectivity state. It is virtual
+  // because it allows the client_channel specific code to live in ext/
+  // instead of lib/
+  virtual void PopulateConnectivityState(grpc_json* json);
+
   ChannelTrace* trace() { return trace_.get(); }
   ChannelTrace* trace() { return trace_.get(); }
 
 
-  void set_channel_destroyed() {
+  void MarkChannelDestroyed() {
     GPR_ASSERT(channel_ != nullptr);
     GPR_ASSERT(channel_ != nullptr);
     channel_ = nullptr;
     channel_ = nullptr;
   }
   }
 
 
+  bool ChannelIsDestroyed() { return channel_ == nullptr; }
+
   intptr_t channel_uuid() { return channel_uuid_; }
   intptr_t channel_uuid() { return channel_uuid_; }
 
 
+ protected:
+  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+  ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
+  virtual ~ChannelNode();
+
  private:
  private:
   // testing peer friend.
   // testing peer friend.
   friend class testing::ChannelNodePeer;
   friend class testing::ChannelNodePeer;
 
 
-  // helper for getting connectivity state.
-  grpc_connectivity_state GetConnectivityState();
-
   grpc_channel* channel_ = nullptr;
   grpc_channel* channel_ = nullptr;
   UniquePtr<char> target_;
   UniquePtr<char> target_;
   gpr_atm calls_started_ = 0;
   gpr_atm calls_started_ = 0;
@@ -79,6 +93,11 @@ class ChannelNode : public RefCounted<ChannelNode> {
   ManualConstructor<ChannelTrace> trace_;
   ManualConstructor<ChannelTrace> trace_;
 };
 };
 
 
+// Creation functions
+
+typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,
+                                                              size_t);
+
 }  // namespace channelz
 }  // namespace channelz
 }  // namespace grpc_core
 }  // namespace grpc_core
 
 

+ 7 - 24
src/core/lib/channel/channelz_registry.cc

@@ -26,27 +26,14 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 
 
+#include <cstring>
+
 namespace grpc_core {
 namespace grpc_core {
 namespace {
 namespace {
 
 
 // singleton instance of the registry.
 // singleton instance of the registry.
 ChannelzRegistry* g_channelz_registry = nullptr;
 ChannelzRegistry* g_channelz_registry = nullptr;
 
 
-// avl vtable for uuid (intptr_t) -> channelz_obj (void*)
-// this table is only looking, it does not own anything.
-void destroy_intptr(void* not_used, void* user_data) {}
-void* copy_intptr(void* key, void* user_data) { return key; }
-long compare_intptr(void* key1, void* key2, void* user_data) {
-  return GPR_ICMP(key1, key2);
-}
-
-void destroy_channelz_obj(void* channelz_obj, void* user_data) {}
-void* copy_channelz_obj(void* channelz_obj, void* user_data) {
-  return channelz_obj;
-}
-const grpc_avl_vtable avl_vtable = {destroy_intptr, copy_intptr, compare_intptr,
-                                    destroy_channelz_obj, copy_channelz_obj};
-
 }  // anonymous namespace
 }  // anonymous namespace
 
 
 void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }
 void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }
@@ -58,19 +45,15 @@ ChannelzRegistry* ChannelzRegistry::Default() {
   return g_channelz_registry;
   return g_channelz_registry;
 }
 }
 
 
-ChannelzRegistry::ChannelzRegistry() : uuid_(1) {
-  gpr_mu_init(&mu_);
-  avl_ = grpc_avl_create(&avl_vtable);
-}
+ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
 
 
-ChannelzRegistry::~ChannelzRegistry() {
-  grpc_avl_unref(avl_, nullptr);
-  gpr_mu_destroy(&mu_);
-}
+ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
 
 
 void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
 void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
+  GPR_ASSERT(uuid >= 1);
   gpr_mu_lock(&mu_);
   gpr_mu_lock(&mu_);
-  avl_ = grpc_avl_remove(avl_, (void*)uuid, nullptr);
+  GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
+  entities_[uuid - 1] = nullptr;
   gpr_mu_unlock(&mu_);
   gpr_mu_unlock(&mu_);
 }
 }
 
 

+ 12 - 8
src/core/lib/channel/channelz_registry.h

@@ -21,8 +21,8 @@
 
 
 #include <grpc/impl/codegen/port_platform.h>
 #include <grpc/impl/codegen/port_platform.h>
 
 
-#include "src/core/lib/avl/avl.h"
 #include "src/core/lib/channel/channel_trace.h"
 #include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
 
 
 #include <stdint.h>
 #include <stdint.h>
 
 
@@ -67,11 +67,11 @@ class ChannelzRegistry {
   // globally registers a channelz Object. Returns its unique uuid
   // globally registers a channelz Object. Returns its unique uuid
   template <typename Object>
   template <typename Object>
   intptr_t InternalRegister(Object* object) {
   intptr_t InternalRegister(Object* object) {
-    intptr_t prior = gpr_atm_no_barrier_fetch_add(&uuid_, 1);
     gpr_mu_lock(&mu_);
     gpr_mu_lock(&mu_);
-    avl_ = grpc_avl_add(avl_, (void*)prior, object, nullptr);
+    entities_.push_back(static_cast<void*>(object));
+    intptr_t uuid = entities_.size();
     gpr_mu_unlock(&mu_);
     gpr_mu_unlock(&mu_);
-    return prior;
+    return uuid;
   }
   }
 
 
   // globally unregisters the object that is associated to uuid.
   // globally unregisters the object that is associated to uuid.
@@ -82,16 +82,20 @@ class ChannelzRegistry {
   template <typename Object>
   template <typename Object>
   Object* InternalGet(intptr_t uuid) {
   Object* InternalGet(intptr_t uuid) {
     gpr_mu_lock(&mu_);
     gpr_mu_lock(&mu_);
-    Object* ret =
-        static_cast<Object*>(grpc_avl_get(avl_, (void*)uuid, nullptr));
+    if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
+      gpr_mu_unlock(&mu_);
+      return nullptr;
+    }
+    Object* ret = static_cast<Object*>(entities_[uuid - 1]);
     gpr_mu_unlock(&mu_);
     gpr_mu_unlock(&mu_);
     return ret;
     return ret;
   }
   }
 
 
   // private members
   // private members
+
+  // protects entities_ and uuid_
   gpr_mu mu_;
   gpr_mu mu_;
-  grpc_avl avl_;
-  gpr_atm uuid_;
+  InlinedVector<void*, 20> entities_;
 };
 };
 
 
 }  // namespace grpc_core
 }  // namespace grpc_core

+ 28 - 0
src/core/lib/gpr/alloc.h

@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright 2018 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_LIB_GPR_ALLOC_H
+#define GRPC_CORE_LIB_GPR_ALLOC_H
+
+#include <grpc/support/port_platform.h>
+
+/// Given a size, round up to the next multiple of sizeof(void*).
+#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \
+  (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
+
+#endif /* GRPC_CORE_LIB_GPR_ALLOC_H */

+ 8 - 8
src/core/lib/gpr/arena.cc

@@ -26,6 +26,8 @@
 #include <grpc/support/atm.h>
 #include <grpc/support/atm.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 
 
+#include "src/core/lib/gpr/alloc.h"
+
 // Uncomment this to use a simple arena that simply allocates the
 // Uncomment this to use a simple arena that simply allocates the
 // requested amount of memory for each call to gpr_arena_alloc().  This
 // requested amount of memory for each call to gpr_arena_alloc().  This
 // effectively eliminates the efficiency gain of using an arena, but it
 // effectively eliminates the efficiency gain of using an arena, but it
@@ -74,8 +76,6 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
 // arena API to C++, we should consider replacing gpr_arena_alloc() with a
 // arena API to C++, we should consider replacing gpr_arena_alloc() with a
 // template that takes the type of the value being allocated, which
 // template that takes the type of the value being allocated, which
 // would allow us to use the alignment actually needed by the caller.
 // would allow us to use the alignment actually needed by the caller.
-#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
-  (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
 
 
 typedef struct zone {
 typedef struct zone {
   size_t size_begin;
   size_t size_begin;
@@ -95,9 +95,9 @@ static void* zalloc_aligned(size_t size) {
 }
 }
 
 
 gpr_arena* gpr_arena_create(size_t initial_size) {
 gpr_arena* gpr_arena_create(size_t initial_size) {
-  initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
+  initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
   gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
   gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
-      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
   a->initial_zone.size_end = initial_size;
   a->initial_zone.size_end = initial_size;
   return a;
   return a;
 }
 }
@@ -115,7 +115,7 @@ size_t gpr_arena_destroy(gpr_arena* arena) {
 }
 }
 
 
 void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
 void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
-  size = ROUND_UP_TO_ALIGNMENT_SIZE(size);
+  size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
   size_t start = static_cast<size_t>(
   size_t start = static_cast<size_t>(
       gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
       gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
   zone* z = &arena->initial_zone;
   zone* z = &arena->initial_zone;
@@ -125,7 +125,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
       size_t next_z_size =
       size_t next_z_size =
           static_cast<size_t>(gpr_atm_no_barrier_load(&arena->size_so_far));
           static_cast<size_t>(gpr_atm_no_barrier_load(&arena->size_so_far));
       next_z = static_cast<zone*>(zalloc_aligned(
       next_z = static_cast<zone*>(zalloc_aligned(
-          ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
+          GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
       next_z->size_begin = z->size_end;
       next_z->size_begin = z->size_end;
       next_z->size_end = z->size_end + next_z_size;
       next_z->size_end = z->size_end + next_z_size;
       if (!gpr_atm_rel_cas(&z->next_atm, static_cast<gpr_atm>(NULL),
       if (!gpr_atm_rel_cas(&z->next_atm, static_cast<gpr_atm>(NULL),
@@ -143,9 +143,9 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
   GPR_ASSERT(start + size <= z->size_end);
   GPR_ASSERT(start + size <= z->size_end);
   char* ptr = (z == &arena->initial_zone)
   char* ptr = (z == &arena->initial_zone)
                   ? reinterpret_cast<char*>(arena) +
                   ? reinterpret_cast<char*>(arena) +
-                        ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
+                        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
                   : reinterpret_cast<char*>(z) +
                   : reinterpret_cast<char*>(z) +
-                        ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
+                        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
   return ptr + start - z->size_begin;
   return ptr + start - z->size_begin;
 }
 }
 
 

+ 2 - 2
src/core/lib/gprpp/memory.h

@@ -31,12 +31,12 @@
 // protected destructor.
 // protected destructor.
 #define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \
 #define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \
   template <typename T>                           \
   template <typename T>                           \
-  friend void Delete(T*);
+  friend void grpc_core::Delete(T*);
 // Add this to a class that want to use New(), but has a private or
 // Add this to a class that want to use New(), but has a private or
 // protected constructor.
 // protected constructor.
 #define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \
 #define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \
   template <typename T, typename... Args>      \
   template <typename T, typename... Args>      \
-  friend T* New(Args&&...);
+  friend T* grpc_core::New(Args&&...);
 
 
 namespace grpc_core {
 namespace grpc_core {
 
 

+ 5 - 0
src/core/lib/gprpp/ref_counted_ptr.h

@@ -107,6 +107,11 @@ inline RefCountedPtr<T> MakeRefCounted(Args&&... args) {
   return RefCountedPtr<T>(New<T>(std::forward<Args>(args)...));
   return RefCountedPtr<T>(New<T>(std::forward<Args>(args)...));
 }
 }
 
 
+template <typename Parent, typename Child, typename... Args>
+inline RefCountedPtr<Parent> MakePolymorphicRefCounted(Args&&... args) {
+  return RefCountedPtr<Parent>(New<Child>(std::forward<Args>(args)...));
+}
+
 }  // namespace grpc_core
 }  // namespace grpc_core
 
 
 #endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */
 #endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */

+ 1 - 1
src/core/lib/gprpp/thd_posix.cc

@@ -105,7 +105,7 @@ class ThreadInternalsPosix
 
 
     GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
     GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
 
 
-    if (!success) {
+    if (!(*success)) {
       /* don't use gpr_free, as this was allocated using malloc (see above) */
       /* don't use gpr_free, as this was allocated using malloc (see above) */
       free(info);
       free(info);
       grpc_core::Fork::DecThreadCount();
       grpc_core::Fork::DecThreadCount();

+ 2 - 0
src/core/lib/iomgr/iomgr.cc

@@ -70,6 +70,8 @@ static size_t count_objects(void) {
   return n;
   return n;
 }
 }
 
 
+size_t grpc_iomgr_count_objects_for_testing(void) { return count_objects(); }
+
 static void dump_objects(const char* kind) {
 static void dump_objects(const char* kind) {
   grpc_iomgr_object* obj;
   grpc_iomgr_object* obj;
   for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {
   for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {

+ 5 - 0
src/core/lib/iomgr/iomgr.h

@@ -23,6 +23,8 @@
 
 
 #include "src/core/lib/iomgr/port.h"
 #include "src/core/lib/iomgr/port.h"
 
 
+#include <stdlib.h>
+
 /** Initializes the iomgr. */
 /** Initializes the iomgr. */
 void grpc_iomgr_init();
 void grpc_iomgr_init();
 
 
@@ -33,4 +35,7 @@ void grpc_iomgr_start();
  * exec_ctx. */
  * exec_ctx. */
 void grpc_iomgr_shutdown();
 void grpc_iomgr_shutdown();
 
 
+/* Exposed only for testing */
+size_t grpc_iomgr_count_objects_for_testing();
+
 #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */
 #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */

+ 0 - 1
src/core/lib/iomgr/timer_manager.cc

@@ -277,7 +277,6 @@ static void start_threads(void) {
     g_threaded = true;
     g_threaded = true;
     start_timer_thread_and_unlock();
     start_timer_thread_and_unlock();
   } else {
   } else {
-    g_threaded = false;
     gpr_mu_unlock(&g_mu);
     gpr_mu_unlock(&g_mu);
   }
   }
 }
 }

+ 4 - 4
src/core/lib/security/context/security_context.cc

@@ -50,7 +50,7 @@ grpc_call_error grpc_call_set_credentials(grpc_call* call,
   ctx = static_cast<grpc_client_security_context*>(
   ctx = static_cast<grpc_client_security_context*>(
       grpc_call_context_get(call, GRPC_CONTEXT_SECURITY));
       grpc_call_context_get(call, GRPC_CONTEXT_SECURITY));
   if (ctx == nullptr) {
   if (ctx == nullptr) {
-    ctx = grpc_client_security_context_create();
+    ctx = grpc_client_security_context_create(grpc_call_get_arena(call));
     ctx->creds = grpc_call_credentials_ref(creds);
     ctx->creds = grpc_call_credentials_ref(creds);
     grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
     grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
                           grpc_client_security_context_destroy);
                           grpc_client_security_context_destroy);
@@ -82,9 +82,10 @@ void grpc_auth_context_release(grpc_auth_context* context) {
 
 
 /* --- grpc_client_security_context --- */
 /* --- grpc_client_security_context --- */
 
 
-grpc_client_security_context* grpc_client_security_context_create(void) {
+grpc_client_security_context* grpc_client_security_context_create(
+    gpr_arena* arena) {
   return static_cast<grpc_client_security_context*>(
   return static_cast<grpc_client_security_context*>(
-      gpr_zalloc(sizeof(grpc_client_security_context)));
+      gpr_arena_alloc(arena, sizeof(grpc_client_security_context)));
 }
 }
 
 
 void grpc_client_security_context_destroy(void* ctx) {
 void grpc_client_security_context_destroy(void* ctx) {
@@ -96,7 +97,6 @@ void grpc_client_security_context_destroy(void* ctx) {
   if (c->extension.instance != nullptr && c->extension.destroy != nullptr) {
   if (c->extension.instance != nullptr && c->extension.destroy != nullptr) {
     c->extension.destroy(c->extension.instance);
     c->extension.destroy(c->extension.instance);
   }
   }
-  gpr_free(ctx);
 }
 }
 
 
 /* --- grpc_server_security_context --- */
 /* --- grpc_server_security_context --- */

+ 2 - 1
src/core/lib/security/context/security_context.h

@@ -91,7 +91,8 @@ typedef struct {
   grpc_security_context_extension extension;
   grpc_security_context_extension extension;
 } grpc_client_security_context;
 } grpc_client_security_context;
 
 
-grpc_client_security_context* grpc_client_security_context_create(void);
+grpc_client_security_context* grpc_client_security_context_create(
+    gpr_arena* arena);
 void grpc_client_security_context_destroy(void* ctx);
 void grpc_client_security_context_destroy(void* ctx);
 
 
 /* --- grpc_server_security_context ---
 /* --- grpc_server_security_context ---

+ 77 - 0
src/core/lib/security/credentials/local/local_credentials.cc

@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright 2018 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/lib/security/credentials/local/local_credentials.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/security_connector/local_security_connector.h"
+
+#define GRPC_CREDENTIALS_TYPE_LOCAL "Local"
+
+static void local_credentials_destruct(grpc_channel_credentials* creds) {}
+
+static void local_server_credentials_destruct(grpc_server_credentials* creds) {}
+
+static grpc_security_status local_create_security_connector(
+    grpc_channel_credentials* creds,
+    grpc_call_credentials* request_metadata_creds, const char* target_name,
+    const grpc_channel_args* args, grpc_channel_security_connector** sc,
+    grpc_channel_args** new_args) {
+  return grpc_local_channel_security_connector_create(
+      creds, request_metadata_creds, args, target_name, sc);
+}
+
+static grpc_security_status local_server_create_security_connector(
+    grpc_server_credentials* creds, grpc_server_security_connector** sc) {
+  return grpc_local_server_security_connector_create(creds, sc);
+}
+
+static const grpc_channel_credentials_vtable local_credentials_vtable = {
+    local_credentials_destruct, local_create_security_connector,
+    /*duplicate_without_call_credentials=*/nullptr};
+
+static const grpc_server_credentials_vtable local_server_credentials_vtable = {
+    local_server_credentials_destruct, local_server_create_security_connector};
+
+grpc_channel_credentials* grpc_local_credentials_create(
+    grpc_local_connect_type connect_type) {
+  auto creds = static_cast<grpc_local_credentials*>(
+      gpr_zalloc(sizeof(grpc_local_credentials)));
+  creds->connect_type = connect_type;
+  creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL;
+  creds->base.vtable = &local_credentials_vtable;
+  gpr_ref_init(&creds->base.refcount, 1);
+  return &creds->base;
+}
+
+grpc_server_credentials* grpc_local_server_credentials_create(
+    grpc_local_connect_type connect_type) {
+  auto creds = static_cast<grpc_local_server_credentials*>(
+      gpr_zalloc(sizeof(grpc_local_server_credentials)));
+  creds->connect_type = connect_type;
+  creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL;
+  creds->base.vtable = &local_server_credentials_vtable;
+  gpr_ref_init(&creds->base.refcount, 1);
+  return &creds->base;
+}

+ 40 - 0
src/core/lib/security/credentials/local/local_credentials.h

@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2018 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_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H
+#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/grpc_security.h>
+
+#include "src/core/lib/security/credentials/credentials.h"
+
+/* Main struct for grpc local channel credential. */
+typedef struct grpc_local_credentials {
+  grpc_channel_credentials base;
+  grpc_local_connect_type connect_type;
+} grpc_local_credentials;
+
+/* Main struct for grpc local server credential. */
+typedef struct grpc_local_server_credentials {
+  grpc_server_credentials base;
+  grpc_local_connect_type connect_type;
+} grpc_local_server_credentials;
+
+#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */

+ 245 - 0
src/core/lib/security/security_connector/local_security_connector.cc

@@ -0,0 +1,245 @@
+/*
+ *
+ * Copyright 2018 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/lib/security/security_connector/local_security_connector.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/credentials/local/local_credentials.h"
+#include "src/core/lib/security/transport/security_handshaker.h"
+#include "src/core/tsi/local_transport_security.h"
+
+#define GRPC_UDS_URI_PATTERN "unix:"
+#define GRPC_UDS_URL_SCHEME "unix"
+#define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local"
+
+typedef struct {
+  grpc_channel_security_connector base;
+  char* target_name;
+} grpc_local_channel_security_connector;
+
+typedef struct {
+  grpc_server_security_connector base;
+} grpc_local_server_security_connector;
+
+static void local_channel_destroy(grpc_security_connector* sc) {
+  if (sc == nullptr) {
+    return;
+  }
+  auto c = reinterpret_cast<grpc_local_channel_security_connector*>(sc);
+  grpc_call_credentials_unref(c->base.request_metadata_creds);
+  grpc_channel_credentials_unref(c->base.channel_creds);
+  gpr_free(c->target_name);
+  gpr_free(sc);
+}
+
+static void local_server_destroy(grpc_security_connector* sc) {
+  if (sc == nullptr) {
+    return;
+  }
+  auto c = reinterpret_cast<grpc_local_server_security_connector*>(sc);
+  grpc_server_credentials_unref(c->base.server_creds);
+  gpr_free(sc);
+}
+
+static void local_channel_add_handshakers(
+    grpc_channel_security_connector* sc,
+    grpc_handshake_manager* handshake_manager) {
+  tsi_handshaker* handshaker = nullptr;
+  GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) ==
+             TSI_OK);
+  grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
+                                                    handshaker, &sc->base));
+}
+
+static void local_server_add_handshakers(
+    grpc_server_security_connector* sc,
+    grpc_handshake_manager* handshake_manager) {
+  tsi_handshaker* handshaker = nullptr;
+  GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) ==
+             TSI_OK);
+  grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
+                                                    handshaker, &sc->base));
+}
+
+static int local_channel_cmp(grpc_security_connector* sc1,
+                             grpc_security_connector* sc2) {
+  grpc_local_channel_security_connector* c1 =
+      reinterpret_cast<grpc_local_channel_security_connector*>(sc1);
+  grpc_local_channel_security_connector* c2 =
+      reinterpret_cast<grpc_local_channel_security_connector*>(sc2);
+  int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
+  if (c != 0) return c;
+  return strcmp(c1->target_name, c2->target_name);
+}
+
+static int local_server_cmp(grpc_security_connector* sc1,
+                            grpc_security_connector* sc2) {
+  grpc_local_server_security_connector* c1 =
+      reinterpret_cast<grpc_local_server_security_connector*>(sc1);
+  grpc_local_server_security_connector* c2 =
+      reinterpret_cast<grpc_local_server_security_connector*>(sc2);
+  return grpc_server_security_connector_cmp(&c1->base, &c2->base);
+}
+
+static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) {
+  if (ctx == nullptr) {
+    gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  /* Create auth context. */
+  *ctx = grpc_auth_context_create(nullptr);
+  grpc_auth_context_add_cstring_property(
+      *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+      GRPC_LOCAL_TRANSPORT_SECURITY_TYPE);
+  GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
+                 *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1);
+  return GRPC_SECURITY_OK;
+}
+
+static void local_check_peer(grpc_security_connector* sc, tsi_peer peer,
+                             grpc_auth_context** auth_context,
+                             grpc_closure* on_peer_checked) {
+  grpc_security_status status;
+  /* Create an auth context which is necessary to pass the santiy check in
+   * {client, server}_auth_filter that verifies if the peer's auth context is
+   * obtained during handshakes. The auth context is only checked for its
+   * existence and not actually used.
+   */
+  status = local_auth_context_create(auth_context);
+  grpc_error* error = status == GRPC_SECURITY_OK
+                          ? GRPC_ERROR_NONE
+                          : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                "Could not create local auth context");
+  GRPC_CLOSURE_SCHED(on_peer_checked, error);
+}
+
+static grpc_security_connector_vtable local_channel_vtable = {
+    local_channel_destroy, local_check_peer, local_channel_cmp};
+
+static grpc_security_connector_vtable local_server_vtable = {
+    local_server_destroy, local_check_peer, local_server_cmp};
+
+static bool local_check_call_host(grpc_channel_security_connector* sc,
+                                  const char* host,
+                                  grpc_auth_context* auth_context,
+                                  grpc_closure* on_call_host_checked,
+                                  grpc_error** error) {
+  grpc_local_channel_security_connector* local_sc =
+      reinterpret_cast<grpc_local_channel_security_connector*>(sc);
+  if (host == nullptr || local_sc == nullptr ||
+      strcmp(host, local_sc->target_name) != 0) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "local call host does not match target name");
+  }
+  return true;
+}
+
+static void local_cancel_check_call_host(grpc_channel_security_connector* sc,
+                                         grpc_closure* on_call_host_checked,
+                                         grpc_error* error) {
+  GRPC_ERROR_UNREF(error);
+}
+
+grpc_security_status grpc_local_channel_security_connector_create(
+    grpc_channel_credentials* channel_creds,
+    grpc_call_credentials* request_metadata_creds,
+    const grpc_channel_args* args, const char* target_name,
+    grpc_channel_security_connector** sc) {
+  if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) {
+    gpr_log(
+        GPR_ERROR,
+        "Invalid arguments to grpc_local_channel_security_connector_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  // Check if local_connect_type is UDS. Only UDS is supported for now.
+  grpc_local_credentials* creds =
+      reinterpret_cast<grpc_local_credentials*>(channel_creds);
+  if (creds->connect_type != UDS) {
+    gpr_log(GPR_ERROR,
+            "Invalid local channel type to "
+            "grpc_local_channel_security_connector_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  // Check if target_name is a valid UDS address.
+  const grpc_arg* server_uri_arg =
+      grpc_channel_args_find(args, GRPC_ARG_SERVER_URI);
+  const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
+  if (strncmp(GRPC_UDS_URI_PATTERN, server_uri_str,
+              strlen(GRPC_UDS_URI_PATTERN)) != 0) {
+    gpr_log(GPR_ERROR,
+            "Invalid target_name to "
+            "grpc_local_channel_security_connector_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  auto c = static_cast<grpc_local_channel_security_connector*>(
+      gpr_zalloc(sizeof(grpc_local_channel_security_connector)));
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.vtable = &local_channel_vtable;
+  c->base.add_handshakers = local_channel_add_handshakers;
+  c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
+  c->base.request_metadata_creds =
+      grpc_call_credentials_ref(request_metadata_creds);
+  c->base.check_call_host = local_check_call_host;
+  c->base.cancel_check_call_host = local_cancel_check_call_host;
+  c->base.base.url_scheme =
+      creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr;
+  c->target_name = gpr_strdup(target_name);
+  *sc = &c->base;
+  return GRPC_SECURITY_OK;
+}
+
+grpc_security_status grpc_local_server_security_connector_create(
+    grpc_server_credentials* server_creds,
+    grpc_server_security_connector** sc) {
+  if (server_creds == nullptr || sc == nullptr) {
+    gpr_log(
+        GPR_ERROR,
+        "Invalid arguments to grpc_local_server_security_connector_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  // Check if local_connect_type is UDS. Only UDS is supported for now.
+  grpc_local_server_credentials* creds =
+      reinterpret_cast<grpc_local_server_credentials*>(server_creds);
+  if (creds->connect_type != UDS) {
+    gpr_log(GPR_ERROR,
+            "Invalid local server type to "
+            "grpc_local_server_security_connector_create()");
+    return GRPC_SECURITY_ERROR;
+  }
+  auto c = static_cast<grpc_local_server_security_connector*>(
+      gpr_zalloc(sizeof(grpc_local_server_security_connector)));
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.vtable = &local_server_vtable;
+  c->base.server_creds = grpc_server_credentials_ref(server_creds);
+  c->base.base.url_scheme =
+      creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr;
+  c->base.add_handshakers = local_server_add_handshakers;
+  *sc = &c->base;
+  return GRPC_SECURITY_OK;
+}

+ 58 - 0
src/core/lib/security/security_connector/local_security_connector.h

@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2018 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_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H
+#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/security/context/security_context.h"
+
+/**
+ * This method creates a local channel security connector.
+ *
+ * - channel_creds: channel credential instance.
+ * - request_metadata_creds: credential object which will be sent with each
+ *   request. This parameter can be nullptr.
+ * - target_name: the name of the endpoint that the channel is connecting to.
+ * - args: channel args passed from the caller.
+ * - sc: address of local channel security connector instance to be returned
+ *   from the method.
+ *
+ * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure.
+ */
+grpc_security_status grpc_local_channel_security_connector_create(
+    grpc_channel_credentials* channel_creds,
+    grpc_call_credentials* request_metadata_creds,
+    const grpc_channel_args* args, const char* target_name,
+    grpc_channel_security_connector** sc);
+
+/**
+ * This method creates a local server security connector.
+ *
+ * - server_creds: server credential instance.
+ * - sc: address of local server security connector instance to be returned from
+ *   the method.
+ *
+ * It returns GRPC_SECURITY_OK on success, and an error status code on failure.
+ */
+grpc_security_status grpc_local_server_security_connector_create(
+    grpc_server_credentials* server_creds, grpc_server_security_connector** sc);
+
+#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H \
+        */

+ 5 - 1
src/core/lib/security/transport/client_auth_filter.cc

@@ -42,6 +42,7 @@
 namespace {
 namespace {
 /* We can have a per-call credentials. */
 /* We can have a per-call credentials. */
 struct call_data {
 struct call_data {
+  gpr_arena* arena;
   grpc_call_stack* owning_call;
   grpc_call_stack* owning_call;
   grpc_call_combiner* call_combiner;
   grpc_call_combiner* call_combiner;
   grpc_call_credentials* creds;
   grpc_call_credentials* creds;
@@ -276,10 +277,12 @@ static void auth_start_transport_stream_op_batch(
   channel_data* chand = static_cast<channel_data*>(elem->channel_data);
   channel_data* chand = static_cast<channel_data*>(elem->channel_data);
 
 
   if (!batch->cancel_stream) {
   if (!batch->cancel_stream) {
+    // TODO(hcaseyal): move this to init_call_elem once issue #15927 is
+    // resolved.
     GPR_ASSERT(batch->payload->context != nullptr);
     GPR_ASSERT(batch->payload->context != nullptr);
     if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) {
     if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) {
       batch->payload->context[GRPC_CONTEXT_SECURITY].value =
       batch->payload->context[GRPC_CONTEXT_SECURITY].value =
-          grpc_client_security_context_create();
+          grpc_client_security_context_create(calld->arena);
       batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
       batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
           grpc_client_security_context_destroy;
           grpc_client_security_context_destroy;
     }
     }
@@ -335,6 +338,7 @@ static void auth_start_transport_stream_op_batch(
 static grpc_error* init_call_elem(grpc_call_element* elem,
 static grpc_error* init_call_elem(grpc_call_element* elem,
                                   const grpc_call_element_args* args) {
                                   const grpc_call_element_args* args) {
   call_data* calld = static_cast<call_data*>(elem->call_data);
   call_data* calld = static_cast<call_data*>(elem->call_data);
+  calld->arena = args->arena;
   calld->owning_call = args->call_stack;
   calld->owning_call = args->call_stack;
   calld->call_combiner = args->call_combiner;
   calld->call_combiner = args->call_combiner;
   calld->host = grpc_empty_slice();
   calld->host = grpc_empty_slice();

+ 3 - 4
src/core/lib/security/transport/server_auth_filter.cc

@@ -44,7 +44,6 @@ struct call_data {
   grpc_metadata_array md;
   grpc_metadata_array md;
   const grpc_metadata* consumed_md;
   const grpc_metadata* consumed_md;
   size_t num_consumed_md;
   size_t num_consumed_md;
-  grpc_auth_context* auth_context;
   grpc_closure cancel_closure;
   grpc_closure cancel_closure;
   gpr_atm state;  // async_state
   gpr_atm state;  // async_state
 };
 };
@@ -178,7 +177,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
       calld->md = metadata_batch_to_md_array(
       calld->md = metadata_batch_to_md_array(
           batch->payload->recv_initial_metadata.recv_initial_metadata);
           batch->payload->recv_initial_metadata.recv_initial_metadata);
       chand->creds->processor.process(
       chand->creds->processor.process(
-          chand->creds->processor.state, calld->auth_context,
+          chand->creds->processor.state, chand->auth_context,
           calld->md.metadata, calld->md.count, on_md_processing_done, elem);
           calld->md.metadata, calld->md.count, on_md_processing_done, elem);
       return;
       return;
     }
     }
@@ -215,8 +214,8 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
   // data and save it in the call context.
   // data and save it in the call context.
   grpc_server_security_context* server_ctx =
   grpc_server_security_context* server_ctx =
       grpc_server_security_context_create(args->arena);
       grpc_server_security_context_create(args->arena);
-  server_ctx->auth_context = grpc_auth_context_create(chand->auth_context);
-  calld->auth_context = server_ctx->auth_context;
+  server_ctx->auth_context =
+      GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter");
   if (args->context[GRPC_CONTEXT_SECURITY].value != nullptr) {
   if (args->context[GRPC_CONTEXT_SECURITY].value != nullptr) {
     args->context[GRPC_CONTEXT_SECURITY].destroy(
     args->context[GRPC_CONTEXT_SECURITY].destroy(
         args->context[GRPC_CONTEXT_SECURITY].value);
         args->context[GRPC_CONTEXT_SECURITY].value);

+ 4 - 7
src/core/lib/surface/call.cc

@@ -34,6 +34,7 @@
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/alloc.h"
 #include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/useful.h"
 #include "src/core/lib/gpr/useful.h"
@@ -271,16 +272,12 @@ struct grpc_call {
 grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
 grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
 grpc_core::TraceFlag grpc_compression_trace(false, "compression");
 grpc_core::TraceFlag grpc_compression_trace(false, "compression");
 
 
-/* Given a size, round up to the next multiple of sizeof(void*) */
-#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
-  (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
-
 #define CALL_STACK_FROM_CALL(call)   \
 #define CALL_STACK_FROM_CALL(call)   \
   (grpc_call_stack*)((char*)(call) + \
   (grpc_call_stack*)((char*)(call) + \
-                     ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
+                     GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
 #define CALL_FROM_CALL_STACK(call_stack) \
 #define CALL_FROM_CALL_STACK(call_stack) \
   (grpc_call*)(((char*)(call_stack)) -   \
   (grpc_call*)(((char*)(call_stack)) -   \
-               ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
+               GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
 
 
 #define CALL_ELEM_FROM_CALL(call, idx) \
 #define CALL_ELEM_FROM_CALL(call, idx) \
   grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
   grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
@@ -353,7 +350,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
   GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
   GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
   gpr_arena* arena = gpr_arena_create(initial_size);
   gpr_arena* arena = gpr_arena_create(initial_size);
   call = static_cast<grpc_call*>(
   call = static_cast<grpc_call*>(
-      gpr_arena_alloc(arena, ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
+      gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
                                  channel_stack->call_stack_size));
                                  channel_stack->call_stack_size));
   gpr_ref_init(&call->ext_ref, 1);
   gpr_ref_init(&call->ext_ref, 1);
   call->arena = arena;
   call->arena = arena;

+ 15 - 3
src/core/lib/surface/channel.cc

@@ -105,6 +105,10 @@ grpc_channel* grpc_channel_create_with_builder(
   channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
   channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
   size_t channel_tracer_max_nodes = 0;  // default to off
   size_t channel_tracer_max_nodes = 0;  // default to off
   bool channelz_enabled = false;
   bool channelz_enabled = false;
+  // this creates the default ChannelNode. Different types of channels may
+  // override this to ensure a correct ChannelNode is created.
+  grpc_core::channelz::ChannelNodeCreationFunc channel_node_create_func =
+      grpc_core::channelz::ChannelNode::MakeChannelNode;
   gpr_mu_init(&channel->registered_call_mu);
   gpr_mu_init(&channel->registered_call_mu);
   channel->registered_calls = nullptr;
   channel->registered_calls = nullptr;
 
 
@@ -144,15 +148,23 @@ grpc_channel* grpc_channel_create_with_builder(
       channel_tracer_max_nodes =
       channel_tracer_max_nodes =
           (size_t)grpc_channel_arg_get_integer(&args->args[i], options);
           (size_t)grpc_channel_arg_get_integer(&args->args[i], options);
     } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) {
     } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) {
+      // channelz will not be enabled by default until all concerns in
+      // https://github.com/grpc/grpc/issues/15986 are addressed.
       channelz_enabled = grpc_channel_arg_get_bool(&args->args[i], false);
       channelz_enabled = grpc_channel_arg_get_bool(&args->args[i], false);
+    } else if (0 == strcmp(args->args[i].key,
+                           GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC)) {
+      GPR_ASSERT(args->args[i].type == GRPC_ARG_POINTER);
+      GPR_ASSERT(args->args[i].value.pointer.p != nullptr);
+      channel_node_create_func =
+          reinterpret_cast<grpc_core::channelz::ChannelNodeCreationFunc>(
+              args->args[i].value.pointer.p);
     }
     }
   }
   }
 
 
   grpc_channel_args_destroy(args);
   grpc_channel_args_destroy(args);
   if (channelz_enabled) {
   if (channelz_enabled) {
     channel->channelz_channel =
     channel->channelz_channel =
-        grpc_core::MakeRefCounted<grpc_core::channelz::ChannelNode>(
-            channel, channel_tracer_max_nodes);
+        channel_node_create_func(channel, channel_tracer_max_nodes);
     channel->channelz_channel->trace()->AddTraceEvent(
     channel->channelz_channel->trace()->AddTraceEvent(
         grpc_core::channelz::ChannelTrace::Severity::Info,
         grpc_core::channelz::ChannelTrace::Severity::Info,
         grpc_slice_from_static_string("Channel created"));
         grpc_slice_from_static_string("Channel created"));
@@ -400,7 +412,7 @@ void grpc_channel_internal_unref(grpc_channel* c REF_ARG) {
 static void destroy_channel(void* arg, grpc_error* error) {
 static void destroy_channel(void* arg, grpc_error* error) {
   grpc_channel* channel = static_cast<grpc_channel*>(arg);
   grpc_channel* channel = static_cast<grpc_channel*>(arg);
   if (channel->channelz_channel != nullptr) {
   if (channel->channelz_channel != nullptr) {
-    channel->channelz_channel->set_channel_destroyed();
+    channel->channelz_channel->MarkChannelDestroyed();
     channel->channelz_channel.reset();
     channel->channelz_channel.reset();
   }
   }
   grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
   grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));

+ 2 - 1
src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc

@@ -127,7 +127,8 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector(
   tsi_result ok = alts_zero_copy_grpc_protector_create(
   tsi_result ok = alts_zero_copy_grpc_protector_create(
       reinterpret_cast<const uint8_t*>(result->key_data),
       reinterpret_cast<const uint8_t*>(result->key_data),
       kAltsAes128GcmRekeyKeyLength, /*is_rekey=*/true, result->is_client,
       kAltsAes128GcmRekeyKeyLength, /*is_rekey=*/true, result->is_client,
-      /*is_integrity_only=*/false, max_output_protected_frame_size, protector);
+      /*is_integrity_only=*/false, /*enable_extra_copy=*/false,
+      max_output_protected_frame_size, protector);
   if (ok != TSI_OK) {
   if (ok != TSI_OK) {
     gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
     gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
   }
   }

+ 47 - 1
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc

@@ -23,6 +23,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 
 
+#include <string.h>
+
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
@@ -30,12 +32,49 @@
 /* Main struct for alts_grpc_integrity_only_record_protocol.  */
 /* Main struct for alts_grpc_integrity_only_record_protocol.  */
 typedef struct alts_grpc_integrity_only_record_protocol {
 typedef struct alts_grpc_integrity_only_record_protocol {
   alts_grpc_record_protocol base;
   alts_grpc_record_protocol base;
+  bool enable_extra_copy;
   grpc_slice_buffer data_sb;
   grpc_slice_buffer data_sb;
   unsigned char* tag_buf;
   unsigned char* tag_buf;
 } alts_grpc_integrity_only_record_protocol;
 } alts_grpc_integrity_only_record_protocol;
 
 
 /* --- alts_grpc_record_protocol methods implementation. --- */
 /* --- alts_grpc_record_protocol methods implementation. --- */
 
 
+static tsi_result alts_grpc_integrity_only_extra_copy_protect(
+    alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
+    grpc_slice_buffer* protected_slices) {
+  /* Allocates memory for protected frame and copies data.  */
+  size_t data_length = unprotected_slices->length;
+  size_t protected_frame_size =
+      unprotected_slices->length + rp->header_length + rp->tag_length;
+  grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
+  uint8_t* data = GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
+  for (size_t i = 0; i < unprotected_slices->count; i++) {
+    memcpy(data, GRPC_SLICE_START_PTR(unprotected_slices->slices[i]),
+           GRPC_SLICE_LENGTH(unprotected_slices->slices[i]));
+    data += GRPC_SLICE_LENGTH(unprotected_slices->slices[i]);
+  }
+  /* Calls alts_iovec_record_protocol protect.  */
+  char* error_details = nullptr;
+  iovec_t header_iovec = {GRPC_SLICE_START_PTR(protected_slice),
+                          rp->header_length};
+  iovec_t tag_iovec = {
+      GRPC_SLICE_START_PTR(protected_slice) + rp->header_length + data_length,
+      rp->tag_length};
+  rp->iovec_buf[0].iov_base =
+      GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
+  rp->iovec_buf[0].iov_len = data_length;
+  grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
+      rp->iovec_rp, rp->iovec_buf, 1, header_iovec, tag_iovec, &error_details);
+  if (status != GRPC_STATUS_OK) {
+    gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
+    gpr_free(error_details);
+    return TSI_INTERNAL_ERROR;
+  }
+  grpc_slice_buffer_add(protected_slices, protected_slice);
+  grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
+  return TSI_OK;
+}
+
 static tsi_result alts_grpc_integrity_only_protect(
 static tsi_result alts_grpc_integrity_only_protect(
     alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
     alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
     grpc_slice_buffer* protected_slices) {
     grpc_slice_buffer* protected_slices) {
@@ -46,6 +85,12 @@ static tsi_result alts_grpc_integrity_only_protect(
             "Invalid nullptr arguments to alts_grpc_record_protocol protect.");
             "Invalid nullptr arguments to alts_grpc_record_protocol protect.");
     return TSI_INVALID_ARGUMENT;
     return TSI_INVALID_ARGUMENT;
   }
   }
+  alts_grpc_integrity_only_record_protocol* integrity_only_record_protocol =
+      reinterpret_cast<alts_grpc_integrity_only_record_protocol*>(rp);
+  if (integrity_only_record_protocol->enable_extra_copy) {
+    return alts_grpc_integrity_only_extra_copy_protect(rp, unprotected_slices,
+                                                       protected_slices);
+  }
   /* Allocates memory for header and tag slices.  */
   /* Allocates memory for header and tag slices.  */
   grpc_slice header_slice = GRPC_SLICE_MALLOC(rp->header_length);
   grpc_slice header_slice = GRPC_SLICE_MALLOC(rp->header_length);
   grpc_slice tag_slice = GRPC_SLICE_MALLOC(rp->tag_length);
   grpc_slice tag_slice = GRPC_SLICE_MALLOC(rp->tag_length);
@@ -152,7 +197,7 @@ static const alts_grpc_record_protocol_vtable
 
 
 tsi_result alts_grpc_integrity_only_record_protocol_create(
 tsi_result alts_grpc_integrity_only_record_protocol_create(
     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
-    bool is_protect, alts_grpc_record_protocol** rp) {
+    bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp) {
   if (crypter == nullptr || rp == nullptr) {
   if (crypter == nullptr || rp == nullptr) {
     gpr_log(GPR_ERROR,
     gpr_log(GPR_ERROR,
             "Invalid nullptr arguments to alts_grpc_record_protocol create.");
             "Invalid nullptr arguments to alts_grpc_record_protocol create.");
@@ -169,6 +214,7 @@ tsi_result alts_grpc_integrity_only_record_protocol_create(
     gpr_free(impl);
     gpr_free(impl);
     return result;
     return result;
   }
   }
+  impl->enable_extra_copy = enable_extra_copy;
   /* Initializes slice buffer for data_sb.  */
   /* Initializes slice buffer for data_sb.  */
   grpc_slice_buffer_init(&impl->data_sb);
   grpc_slice_buffer_init(&impl->data_sb);
   /* Allocates tag buffer.  */
   /* Allocates tag buffer.  */

+ 3 - 1
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h

@@ -38,6 +38,8 @@
  *   be used at the client or server side.
  *   be used at the client or server side.
  * - is_protect: a flag indicating if the alts_grpc_record_protocol instance
  * - is_protect: a flag indicating if the alts_grpc_record_protocol instance
  *   will be used for protect or unprotect.
  *   will be used for protect or unprotect.
+ *-  enable_extra_copy: a flag indicating if the instance uses one-copy instead
+ *   of zero-copy in the protect operation.
  * - rp: an alts_grpc_record_protocol instance to be returned from
  * - rp: an alts_grpc_record_protocol instance to be returned from
  *   the method.
  *   the method.
  *
  *
@@ -46,7 +48,7 @@
  */
  */
 tsi_result alts_grpc_integrity_only_record_protocol_create(
 tsi_result alts_grpc_integrity_only_record_protocol_create(
     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
-    bool is_protect, alts_grpc_record_protocol** rp);
+    bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp);
 
 
 #endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H \
 #endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H \
         */
         */

+ 12 - 11
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc

@@ -110,7 +110,7 @@ static bool read_frame_size(const grpc_slice_buffer* sb,
  */
  */
 static tsi_result create_alts_grpc_record_protocol(
 static tsi_result create_alts_grpc_record_protocol(
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
-    bool is_integrity_only, bool is_protect,
+    bool is_integrity_only, bool is_protect, bool enable_extra_copy,
     alts_grpc_record_protocol** record_protocol) {
     alts_grpc_record_protocol** record_protocol) {
   if (key == nullptr || record_protocol == nullptr) {
   if (key == nullptr || record_protocol == nullptr) {
     return TSI_INVALID_ARGUMENT;
     return TSI_INVALID_ARGUMENT;
@@ -130,13 +130,13 @@ static tsi_result create_alts_grpc_record_protocol(
                                    : kAltsRecordProtocolFrameLimit;
                                    : kAltsRecordProtocolFrameLimit;
   /* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
   /* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
    */
    */
-  tsi_result result =
-      is_integrity_only
-          ? alts_grpc_integrity_only_record_protocol_create(
-                crypter, overflow_limit, is_client, is_protect, record_protocol)
-          : alts_grpc_privacy_integrity_record_protocol_create(
-                crypter, overflow_limit, is_client, is_protect,
-                record_protocol);
+  tsi_result result = is_integrity_only
+                          ? alts_grpc_integrity_only_record_protocol_create(
+                                crypter, overflow_limit, is_client, is_protect,
+                                enable_extra_copy, record_protocol)
+                          : alts_grpc_privacy_integrity_record_protocol_create(
+                                crypter, overflow_limit, is_client, is_protect,
+                                record_protocol);
   if (result != TSI_OK) {
   if (result != TSI_OK) {
     gsec_aead_crypter_destroy(crypter);
     gsec_aead_crypter_destroy(crypter);
     return result;
     return result;
@@ -241,7 +241,8 @@ static const tsi_zero_copy_grpc_protector_vtable
 
 
 tsi_result alts_zero_copy_grpc_protector_create(
 tsi_result alts_zero_copy_grpc_protector_create(
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
-    bool is_integrity_only, size_t* max_protected_frame_size,
+    bool is_integrity_only, bool enable_extra_copy,
+    size_t* max_protected_frame_size,
     tsi_zero_copy_grpc_protector** protector) {
     tsi_zero_copy_grpc_protector** protector) {
   if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
   if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
       protector == nullptr) {
       protector == nullptr) {
@@ -257,11 +258,11 @@ tsi_result alts_zero_copy_grpc_protector_create(
   /* Creates alts_grpc_record_protocol objects.  */
   /* Creates alts_grpc_record_protocol objects.  */
   tsi_result status = create_alts_grpc_record_protocol(
   tsi_result status = create_alts_grpc_record_protocol(
       key, key_size, is_rekey, is_client, is_integrity_only,
       key, key_size, is_rekey, is_client, is_integrity_only,
-      /*is_protect=*/true, &impl->record_protocol);
+      /*is_protect=*/true, enable_extra_copy, &impl->record_protocol);
   if (status == TSI_OK) {
   if (status == TSI_OK) {
     status = create_alts_grpc_record_protocol(
     status = create_alts_grpc_record_protocol(
         key, key_size, is_rekey, is_client, is_integrity_only,
         key, key_size, is_rekey, is_client, is_integrity_only,
-        /*is_protect=*/false, &impl->unrecord_protocol);
+        /*is_protect=*/false, enable_extra_copy, &impl->unrecord_protocol);
     if (status == TSI_OK) {
     if (status == TSI_OK) {
       /* Sets maximum frame size.  */
       /* Sets maximum frame size.  */
       size_t max_protected_frame_size_to_set = kDefaultFrameLength;
       size_t max_protected_frame_size_to_set = kDefaultFrameLength;

+ 7 - 2
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h

@@ -35,6 +35,11 @@
  *   server side.
  *   server side.
  * - is_integrity_only: a flag indicating if the protector instance will be
  * - is_integrity_only: a flag indicating if the protector instance will be
  *   used for integrity-only or privacy-integrity mode.
  *   used for integrity-only or privacy-integrity mode.
+ * - enable_extra_copy: a flag indicating if the protector instance does one
+ *   extra memory copy during the protect operation for integrity_only mode.
+ *   For the unprotect operation, it is still zero-copy. If application intends
+ *   to modify the data buffer after the protect operation, we can turn on this
+ *   mode to avoid integrity check failure.
  * - max_protected_frame_size: an in/out parameter indicating max frame size
  * - max_protected_frame_size: an in/out parameter indicating max frame size
  *   to be used by the protector. If it is nullptr, the default frame size will
  *   to be used by the protector. If it is nullptr, the default frame size will
  *   be used. Otherwise, the provided frame size will be adjusted (if not
  *   be used. Otherwise, the provided frame size will be adjusted (if not
@@ -45,8 +50,8 @@
  */
  */
 tsi_result alts_zero_copy_grpc_protector_create(
 tsi_result alts_zero_copy_grpc_protector_create(
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
     const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
-    bool is_integrity_only, size_t* max_protected_frame_size,
-    tsi_zero_copy_grpc_protector** protector);
+    bool is_integrity_only, bool enable_extra_copy,
+    size_t* max_protected_frame_size, tsi_zero_copy_grpc_protector** protector);
 
 
 #endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H \
 #endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H \
         */
         */

+ 209 - 0
src/core/tsi/local_transport_security.cc

@@ -0,0 +1,209 @@
+/*
+ *
+ * Copyright 2018 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/tsi/local_transport_security.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/tsi/transport_security_grpc.h"
+
+/* Main struct for local TSI zero-copy frame protector. */
+typedef struct local_zero_copy_grpc_protector {
+  tsi_zero_copy_grpc_protector base;
+} local_zero_copy_grpc_protector;
+
+/* Main struct for local TSI handshaker result. */
+typedef struct local_tsi_handshaker_result {
+  tsi_handshaker_result base;
+  bool is_client;
+} local_tsi_handshaker_result;
+
+/* Main struct for local TSI handshaker. */
+typedef struct local_tsi_handshaker {
+  tsi_handshaker base;
+  bool is_client;
+} local_tsi_handshaker;
+
+/* --- tsi_zero_copy_grpc_protector methods implementation. --- */
+
+static tsi_result local_zero_copy_grpc_protector_protect(
+    tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
+    grpc_slice_buffer* protected_slices) {
+  if (self == nullptr || unprotected_slices == nullptr ||
+      protected_slices == nullptr) {
+    gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
+    return TSI_INVALID_ARGUMENT;
+  }
+  grpc_slice_buffer_move_into(unprotected_slices, protected_slices);
+  return TSI_OK;
+}
+
+static tsi_result local_zero_copy_grpc_protector_unprotect(
+    tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
+    grpc_slice_buffer* unprotected_slices) {
+  if (self == nullptr || unprotected_slices == nullptr ||
+      protected_slices == nullptr) {
+    gpr_log(GPR_ERROR,
+            "Invalid nullptr arguments to zero-copy grpc unprotect.");
+    return TSI_INVALID_ARGUMENT;
+  }
+  grpc_slice_buffer_move_into(protected_slices, unprotected_slices);
+  return TSI_OK;
+}
+
+static void local_zero_copy_grpc_protector_destroy(
+    tsi_zero_copy_grpc_protector* self) {
+  gpr_free(self);
+}
+
+static const tsi_zero_copy_grpc_protector_vtable
+    local_zero_copy_grpc_protector_vtable = {
+        local_zero_copy_grpc_protector_protect,
+        local_zero_copy_grpc_protector_unprotect,
+        local_zero_copy_grpc_protector_destroy};
+
+tsi_result local_zero_copy_grpc_protector_create(
+    tsi_zero_copy_grpc_protector** protector) {
+  if (grpc_core::ExecCtx::Get() == nullptr || protector == nullptr) {
+    gpr_log(
+        GPR_ERROR,
+        "Invalid nullptr arguments to local_zero_copy_grpc_protector create.");
+    return TSI_INVALID_ARGUMENT;
+  }
+  local_zero_copy_grpc_protector* impl =
+      static_cast<local_zero_copy_grpc_protector*>(gpr_zalloc(sizeof(*impl)));
+  impl->base.vtable = &local_zero_copy_grpc_protector_vtable;
+  *protector = &impl->base;
+  return TSI_OK;
+}
+
+/* --- tsi_handshaker_result methods implementation. --- */
+
+static tsi_result handshaker_result_extract_peer(
+    const tsi_handshaker_result* self, tsi_peer* peer) {
+  return TSI_OK;
+}
+
+static tsi_result handshaker_result_create_zero_copy_grpc_protector(
+    const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
+    tsi_zero_copy_grpc_protector** protector) {
+  if (self == nullptr || protector == nullptr) {
+    gpr_log(GPR_ERROR,
+            "Invalid arguments to create_zero_copy_grpc_protector()");
+    return TSI_INVALID_ARGUMENT;
+  }
+  tsi_result ok = local_zero_copy_grpc_protector_create(protector);
+  if (ok != TSI_OK) {
+    gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
+  }
+  return ok;
+}
+
+static void handshaker_result_destroy(tsi_handshaker_result* self) {
+  if (self == nullptr) {
+    return;
+  }
+  local_tsi_handshaker_result* result =
+      reinterpret_cast<local_tsi_handshaker_result*>(
+          const_cast<tsi_handshaker_result*>(self));
+  gpr_free(result);
+}
+
+static const tsi_handshaker_result_vtable result_vtable = {
+    handshaker_result_extract_peer,
+    handshaker_result_create_zero_copy_grpc_protector,
+    nullptr, /* handshaker_result_create_frame_protector */
+    nullptr, /* handshaker_result_get_unused_bytes */
+    handshaker_result_destroy};
+
+static tsi_result create_handshaker_result(bool is_client,
+                                           tsi_handshaker_result** self) {
+  if (self == nullptr) {
+    gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
+    return TSI_INVALID_ARGUMENT;
+  }
+  local_tsi_handshaker_result* result =
+      static_cast<local_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
+  result->is_client = is_client;
+  result->base.vtable = &result_vtable;
+  *self = &result->base;
+  return TSI_OK;
+}
+
+/* --- tsi_handshaker methods implementation. --- */
+
+static tsi_result handshaker_next(
+    tsi_handshaker* self, const unsigned char* received_bytes,
+    size_t received_bytes_size, const unsigned char** bytes_to_send,
+    size_t* bytes_to_send_size, tsi_handshaker_result** result,
+    tsi_handshaker_on_next_done_cb cb, void* user_data) {
+  if (self == nullptr) {
+    gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
+    return TSI_INVALID_ARGUMENT;
+  }
+  /* Note that there is no interaction between TSI peers, and all operations are
+   * local.
+   */
+  local_tsi_handshaker* handshaker =
+      reinterpret_cast<local_tsi_handshaker*>(self);
+  *bytes_to_send_size = 0;
+  create_handshaker_result(handshaker->is_client, result);
+  return TSI_OK;
+}
+
+static void handshaker_destroy(tsi_handshaker* self) {
+  if (self == nullptr) {
+    return;
+  }
+  local_tsi_handshaker* handshaker =
+      reinterpret_cast<local_tsi_handshaker*>(self);
+  gpr_free(handshaker);
+}
+
+static const tsi_handshaker_vtable handshaker_vtable = {
+    nullptr, /* get_bytes_to_send_to_peer -- deprecated */
+    nullptr, /* process_bytes_from_peer   -- deprecated */
+    nullptr, /* get_result                -- deprecated */
+    nullptr, /* extract_peer              -- deprecated */
+    nullptr, /* create_frame_protector    -- deprecated */
+    handshaker_destroy,
+    handshaker_next,
+    nullptr, /* shutdown */
+};
+
+tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self) {
+  if (self == nullptr) {
+    gpr_log(GPR_ERROR, "Invalid arguments to local_tsi_handshaker_create()");
+    return TSI_INVALID_ARGUMENT;
+  }
+  local_tsi_handshaker* handshaker =
+      static_cast<local_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
+  handshaker->is_client = is_client;
+  handshaker->base.vtable = &handshaker_vtable;
+  *self = &handshaker->base;
+  return TSI_OK;
+}

+ 51 - 0
src/core/tsi/local_transport_security.h

@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2018 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_TSI_LOCAL_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_LOCAL_TRANSPORT_SECURITY_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/grpc.h>
+
+#include "src/core/tsi/transport_security.h"
+#include "src/core/tsi/transport_security_interface.h"
+
+#define TSI_LOCAL_NUM_OF_PEER_PROPERTIES 1
+#define TSI_LOCAL_PROCESS_ID_PEER_PROPERTY "process_id"
+
+/**
+ * Main struct for local TSI handshaker. All APIs in the header are
+ * thread-comptabile.
+ */
+typedef struct local_tsi_handshaker local_tsi_handshaker;
+
+/**
+ * This method creates a local TSI handshaker instance.
+ *
+ * - is_client: boolean value indicating if the handshaker is used at the client
+ *   (is_client = true) or server (is_client = false) side. The parameter is
+ *   added for future extension.
+ * - self: address of local TSI handshaker instance to be returned from the
+ *   method.
+ *
+ * It returns TSI_OK on success and an error status code on failure.
+ */
+tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self);
+
+#endif /* GRPC_CORE_TSI_LOCAL_TRANSPORT_SECURITY_H */

+ 5 - 1
src/cpp/README.md

@@ -18,12 +18,16 @@ To add gRPC as a dependency in bazel:
 2. Use the [http_archive](https://docs.bazel.build/versions/master/be/workspace.html#http_archive) bazel rule to include gRPC source
 2. Use the [http_archive](https://docs.bazel.build/versions/master/be/workspace.html#http_archive) bazel rule to include gRPC source
   ```
   ```
   http_archive(
   http_archive(
-      name = "grpc",
+      name = "com_github_grpc_grpc",
       urls = [
       urls = [
           "https://github.com/grpc/grpc/archive/YOUR_GRPC_COMMIT_SHA.tar.gz",
           "https://github.com/grpc/grpc/archive/YOUR_GRPC_COMMIT_SHA.tar.gz",
       ],
       ],
       strip_prefix = "grpc-YOUR_GRPC_COMMIT_SHA",
       strip_prefix = "grpc-YOUR_GRPC_COMMIT_SHA",
   )
   )
+
+  load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
+
+  grpc_deps()
   ```
   ```
 
 
 NOTE: currently bazel is only supported for building gRPC on Linux.
 NOTE: currently bazel is only supported for building gRPC on Linux.

+ 1 - 4
src/cpp/server/server_builder.cc

@@ -174,10 +174,6 @@ ServerBuilder& ServerBuilder::AddListeningPort(
 }
 }
 
 
 std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
 std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
-  for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
-    (*plugin)->UpdateServerBuilder(this);
-  }
-
   ChannelArguments args;
   ChannelArguments args;
   for (auto option = options_.begin(); option != options_.end(); ++option) {
   for (auto option = options_.begin(); option != options_.end(); ++option) {
     (*option)->UpdateArguments(&args);
     (*option)->UpdateArguments(&args);
@@ -185,6 +181,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
   }
   }
 
 
   for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
   for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
+    (*plugin)->UpdateServerBuilder(this);
     (*plugin)->UpdateChannelArguments(&args);
     (*plugin)->UpdateChannelArguments(&args);
   }
   }
 
 

+ 15 - 0
src/objective-c/GRPCClient/GRPCCall+ChannelArg.h

@@ -55,4 +55,19 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) {
                          timeout:(int)timeout
                          timeout:(int)timeout
                          forHost:(nonnull NSString *)host;
                          forHost:(nonnull NSString *)host;
 
 
+/** Enable/Disable automatic retry of gRPC calls on the channel. If automatic retry is enabled, the
+ * retry is controlled by server's service config. If automatic retry is disabled, failed calls are
+ * immediately returned to the application layer. */
++ (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host;
+
+/** Set channel connection timeout and backoff parameters. All parameters are positive integers in
+ * milliseconds. Set a parameter to 0 to make gRPC use default value for that parameter.
+ *
+ * Refer to gRPC's doc at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md for the
+ * details of each parameter. */
++ (void)setMinConnectTimeout:(unsigned int)timeout
+              initialBackoff:(unsigned int)initialBackoff
+                  maxBackoff:(unsigned int)maxBackoff
+                     forHost:(nonnull NSString *)host;
+
 @end
 @end

+ 15 - 0
src/objective-c/GRPCClient/GRPCCall+ChannelArg.m

@@ -64,4 +64,19 @@
   hostConfig.keepaliveTimeout = timeout;
   hostConfig.keepaliveTimeout = timeout;
 }
 }
 
 
++ (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host {
+  GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
+  hostConfig.retryEnabled = enabled;
+}
+
++ (void)setMinConnectTimeout:(unsigned int)timeout
+              initialBackoff:(unsigned int)initialBackoff
+                  maxBackoff:(unsigned int)maxBackoff
+                     forHost:(nonnull NSString *)host {
+  GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
+  hostConfig.minConnectTimeout = timeout;
+  hostConfig.initialConnectBackoff = initialBackoff;
+  hostConfig.maxConnectBackoff = maxBackoff;
+}
+
 @end
 @end

+ 5 - 0
src/objective-c/GRPCClient/private/GRPCHost.h

@@ -38,6 +38,11 @@ struct grpc_channel_credentials;
 @property(nonatomic) int keepaliveInterval;
 @property(nonatomic) int keepaliveInterval;
 @property(nonatomic) int keepaliveTimeout;
 @property(nonatomic) int keepaliveTimeout;
 @property(nonatomic) id logContext;
 @property(nonatomic) id logContext;
+@property(nonatomic) BOOL retryEnabled;
+
+@property(nonatomic) unsigned int minConnectTimeout;
+@property(nonatomic) unsigned int initialConnectBackoff;
+@property(nonatomic) unsigned int maxConnectBackoff;
 
 
 /** The following properties should only be modified for testing: */
 /** The following properties should only be modified for testing: */
 
 

+ 15 - 0
src/objective-c/GRPCClient/private/GRPCHost.m

@@ -85,6 +85,7 @@ static NSMutableDictionary *kHostCache;
       _secure = YES;
       _secure = YES;
       kHostCache[address] = self;
       kHostCache[address] = self;
       _compressAlgorithm = GRPC_COMPRESS_NONE;
       _compressAlgorithm = GRPC_COMPRESS_NONE;
+      _retryEnabled = YES;
     }
     }
 #ifndef GRPC_CFSTREAM
 #ifndef GRPC_CFSTREAM
     [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
     [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
@@ -240,6 +241,20 @@ static NSMutableDictionary *kHostCache;
     args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1];
     args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1];
   }
   }
 
 
+  if (_retryEnabled == NO) {
+    args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:0];
+  }
+
+  if (_minConnectTimeout > 0) {
+    args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_minConnectTimeout];
+  }
+  if (_initialConnectBackoff > 0) {
+    args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_initialConnectBackoff];
+  }
+  if (_maxConnectBackoff > 0) {
+    args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_maxConnectBackoff];
+  }
+
   return args;
   return args;
 }
 }
 
 

+ 92 - 0
src/objective-c/NetworkTransitionBehavior.md

@@ -0,0 +1,92 @@
+
+# gRPC iOS Network Transition Behaviors
+Network connectivity on an iOS device may transition between cellular, WIFI, or
+no network connectivity. This document describes how these network changes
+should be handled by gRPC and current known issues.
+
+## Expected Network Transition Behaviors
+The expected gRPC iOS channel and network transition behaviors are:
+* Channel connection to a particular host is established at the time of
+  starting the first call to the channel and remains connected for future calls
+  to the same host.
+* If the underlying connection to the remote host is broken, the channel is
+  disconnected and enters TRANSIENT\_FAILURE state.
+* A channel is broken if the channel connection is no longer viable. This
+  happens when
+    * The network interface is no longer available, e.g. WiFi or cellular
+      interface is turned off or goes offline, airplane mode turned on, etc;
+    * The underlying TCP connection is no longer valid, e.g. WiFi connects to
+      another hotspot, cellular data switched from LTE to 4G, etc;
+    * A network interface more preferable by the OS is valid, e.g. WiFi gets
+      connected when the channel is already connected via cellular.
+* A channel in TRANSIENT\_FAILURE state attempts reconnection on start of the
+  next call to the same host, but only after a certain backoff period (see
+  corresponding
+  [doc](https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md)).
+  During the backoff period, any call to the same host will wait until the
+  first of the following events occur:
+    * Connection succeeded; calls will be made using this channel;
+    * Conncetion failed; calls will be failed and return UNAVAILABLE status code;
+    * The call's deadline is reached; the call will fail and return
+      DEADLINE\_EXCEEDED status code.
+  The length of backoff period of a channel is reset whenever a connection
+  attempt is successful.
+
+## Implementations
+### gRPC iOS with TCP Sockets
+gRPC's default implementation is to use TCP sockets for networking. It turns
+out that although Apple supports this type of usage, it is [not recommended by
+Apple](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html)
+and has some issues described below.
+
+#### Issues with TCP Sockets
+The TCP sockets on iOS is flawed in that it does not reflect the viability of
+the channel connection. Particularly, we observed the following issues when
+using TCP sockets:
+* When a TCP socket connection is established on cellular data and WiFi
+  becomes available, the TCP socket neither return an error event nor continue
+  sending/receiving data on it, but still accepts write on it.
+* A TCP socket does not report certain events that happen in the
+  background. When a TCP connection breaks in the background for the reason
+  like WiFi connects to another hotspot, the socket neither return an error nor
+  continue sending/receiving data on it, but still accepts write on it.
+In both situations, the user will see the call hang for an extended period of
+time before the TCP socket times out.
+
+#### gRPC iOS library's resolution to TCP socket issues
+We introduced
+[`ConnectivityMonitor`](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html)
+in gRPC iOS library v0.14.0 to alleviate these issues in TCP sockets,
+which changes the network transition behaviors a bit.
+
+We classify network connectivity state of the device into three categories
+based on flags obtained from `SCNetworkReachability` API:
+
+| Reachable | ConnectionRequired | IsWWAN | **Category** |
+|:---------:|:------------------:|:------:|:------------:|
+|     0     |          X         |   X    |     None     |
+|     X     |          1         |   X    |     None     |
+|     1     |          0         |   0    |     WiFi     |
+|     1     |          0         |   1    |   Cellular   |
+
+Whenever there is a transition of network between two of these categories, all
+previously existing channels are assumed to be broken and are actively
+destroyed. If there is an unfinished call, the call should return with status
+code `UNAVAILABLE`.
+
+`ConnectivityMonitor` is able to detect the scenario of the first issue above
+and actively destroy the channels. However, the second issue is not resolvable.
+To solve that issue the best solution is to switch to CFStream implementation
+which eliminates all of them.
+
+### gRPC iOS with CFStream
+gRPC iOS with CFStream implementation (introduced in v1.13.0) uses Apple's
+networking API to make connections. It resolves the issues with TCP sockets
+mentioned above. Users are recommended to use this implementation rather than
+TCP socket implementation. The detailed behavior of streams in CFStream is not
+documented by Apple, but our experiments show that it accords to the expected
+behaviors.  With CFStream implementation, an event is always received when the
+underlying connection is no longer viable. For more detailed information and
+usages of CFStream implementation, refer to the
+[user guide](https://github.com/grpc/grpc/blob/master/src/objective-c/README-CFSTREAM.md).
+

+ 32 - 0
src/objective-c/README-CFSTREAM.md

@@ -0,0 +1,32 @@
+[![Cocoapods](https://img.shields.io/cocoapods/v/gRPC.svg)](https://cocoapods.org/pods/gRPC)
+# gRPC Objective-C with CFStream
+
+gRPC Objective-C library now provides the option to use Apple's CFStream API (rather than TCP
+sockets) for networking. Using CFStream resolves a bunch of network connectivity transition issues
+(see the [doc](https://github.com/grpc/grpc/blob/master/src/objective-c/NetworkTransitionBehavior.md)
+for more information).
+
+CFStream integration is now in experimental state. You will need explicit opt-in to use it to get
+the benefits of resolving the issues above. We expect to make CFStream the default networking
+interface that gRPC uses when it is ready for production.
+
+## Usage
+If you use gRPC following the instructions in
+[README.md](https://github.com/grpc/grpc/blob/master/src/objective-c/README.md):
+- Simply replace the
+dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. The build system will take care of
+everything else and switch networking to CFStream.
+
+If your project directly depends on podspecs other than `gRPC-ProtoRPC` (e.g. `gRPC` or
+`gRPC-Core`):
+
+- Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. For
+  `gRPC-Core`, you will need to make sure that the completion queue you create is of type
+  `GRPC_CQ_NON_POLLING`. This is expected to be fixed soon so that you do not have to modify the
+  completion queue type.
+
+## Notes
+
+- Currently we do not support platforms other than iOS, although it is likely that this integration
+  can run on MacOS targets with Apple's compiler.
+- Let us know if you meet any issue by filing issue and ping @muxi.

+ 43 - 0
src/objective-c/tests/GRPCClientTests.m

@@ -548,4 +548,47 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 }
 
 
+- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff {
+  const double maxConnectTime = timeout > backoff ? timeout : backoff;
+  const double kMargin = 0.1;
+
+  __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."];
+  NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"];
+  GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress
+                                             path:@""
+                                   requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
+  [GRPCCall setMinConnectTimeout:timeout * 1000
+                  initialBackoff:backoff * 1000
+                      maxBackoff:0
+                         forHost:kDummyAddress];
+  NSDate *startTime = [NSDate date];
+  id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) {
+    XCTAssert(NO, @"Received message. Should not reach here");
+  }
+      completionHandler:^(NSError *errorOrNil) {
+        XCTAssertNotNil(errorOrNil, @"Finished with no error");
+        // The call must fail before maxConnectTime. However there is no lower bound on the time
+        // taken for connection. A shorter time happens when connection is actively refused
+        // by 8.8.8.8:1 before maxConnectTime elapsed.
+        XCTAssertLessThan([[NSDate date] timeIntervalSinceDate:startTime],
+                          maxConnectTime + kMargin);
+        [completion fulfill];
+      }];
+
+  [call startWithWriteable:responsesWriteable];
+
+  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+}
+
+// The numbers of the following three tests are selected to be smaller than the default values of
+// initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default
+// values fail to be overridden by the channel args.
+- (void)testTimeoutBackoff2 {
+  [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3];
+}
+
+- (void)testTimeoutBackoff3 {
+  [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7];
+}
+
 @end
 @end

+ 28 - 13
src/php/lib/Grpc/BaseStub.php

@@ -28,6 +28,7 @@ class BaseStub
     private $hostname;
     private $hostname;
     private $hostname_override;
     private $hostname_override;
     private $channel;
     private $channel;
+    private $call_invoker;
 
 
     // a callback function
     // a callback function
     private $update_metadata;
     private $update_metadata;
@@ -58,6 +59,15 @@ class BaseStub
         if (!empty($opts['grpc.ssl_target_name_override'])) {
         if (!empty($opts['grpc.ssl_target_name_override'])) {
             $this->hostname_override = $opts['grpc.ssl_target_name_override'];
             $this->hostname_override = $opts['grpc.ssl_target_name_override'];
         }
         }
+        if (isset($opts['grpc_call_invoker'])) {
+            $this->call_invoker = $opts['grpc_call_invoker'];
+            unset($opts['grpc_call_invoker']);
+            $channel_opts = $this->updateOpts($opts);
+            // If the grpc_call_invoker is defined, use the channel created by the call invoker.
+            $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts);
+            return;
+        }
+        $this->call_invoker = new DefaultCallInvoker();
         if ($channel) {
         if ($channel) {
             if (!is_a($channel, 'Grpc\Channel') &&
             if (!is_a($channel, 'Grpc\Channel') &&
                 !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
                 !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
@@ -72,15 +82,7 @@ class BaseStub
         $this->channel = static::getDefaultChannel($hostname, $opts);
         $this->channel = static::getDefaultChannel($hostname, $opts);
     }
     }
 
 
-    /**
-     * Creates and returns the default Channel
-     *
-     * @param array $opts Channel constructor options
-     *
-     * @return Channel The channel
-     */
-    public static function getDefaultChannel($hostname, array $opts)
-    {
+    private static function updateOpts($opts) {
         $package_config = json_decode(
         $package_config = json_decode(
             file_get_contents(dirname(__FILE__).'/../../composer.json'),
             file_get_contents(dirname(__FILE__).'/../../composer.json'),
             true
             true
@@ -97,6 +99,19 @@ class BaseStub
                 'required. Please see one of the '.
                 'required. Please see one of the '.
                 'ChannelCredentials::create methods');
                 'ChannelCredentials::create methods');
         }
         }
+        return $opts;
+    }
+
+    /**
+     * Creates and returns the default Channel
+     *
+     * @param array $opts Channel constructor options
+     *
+     * @return Channel The channel
+     */
+    public static function getDefaultChannel($hostname, array $opts)
+    {
+        $channel_opts = self::updateOpts($opts);
         return new Channel($hostname, $opts);
         return new Channel($hostname, $opts);
     }
     }
 
 
@@ -239,7 +254,7 @@ class BaseStub
                          $deserialize,
                          $deserialize,
                          array $metadata = [],
                          array $metadata = [],
                          array $options = []) use ($channel) {
                          array $options = []) use ($channel) {
-            $call = new UnaryCall(
+            $call = $this->call_invoker->UnaryCall(
                 $channel,
                 $channel,
                 $method,
                 $method,
                 $deserialize,
                 $deserialize,
@@ -275,7 +290,7 @@ class BaseStub
                          $deserialize,
                          $deserialize,
                          array $metadata = [],
                          array $metadata = [],
                          array $options = []) use ($channel) {
                          array $options = []) use ($channel) {
-            $call = new ClientStreamingCall(
+            $call = $this->call_invoker->ClientStreamingCall(
                 $channel,
                 $channel,
                 $method,
                 $method,
                 $deserialize,
                 $deserialize,
@@ -312,7 +327,7 @@ class BaseStub
                          $deserialize,
                          $deserialize,
                          array $metadata = [],
                          array $metadata = [],
                          array $options = []) use ($channel) {
                          array $options = []) use ($channel) {
-            $call = new ServerStreamingCall(
+            $call = $this->call_invoker->ServerStreamingCall(
                 $channel,
                 $channel,
                 $method,
                 $method,
                 $deserialize,
                 $deserialize,
@@ -348,7 +363,7 @@ class BaseStub
                          $deserialize,
                          $deserialize,
                          array $metadata = [],
                          array $metadata = [],
                          array $options = []) use ($channel) {
                          array $options = []) use ($channel) {
-            $call = new BidiStreamingCall(
+            $call = $this->call_invoker->BidiStreamingCall(
                 $channel,
                 $channel,
                 $method,
                 $method,
                 $deserialize,
                 $deserialize,

+ 33 - 0
src/php/lib/Grpc/CallInvoker.php

@@ -0,0 +1,33 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+namespace Grpc;
+
+/**
+ * CallInvoker is used to pass the self defined channel into the stub,
+ * while intercept each RPC with the channel accessible.
+ * THIS IS AN EXPERIMENTAL API.
+ */
+interface CallInvoker
+{
+    public function createChannelFactory($hostname, $opts);
+    public function UnaryCall($channel, $method, $deserialize, $options);
+    public function ClientStreamingCall($channel, $method, $deserialize, $options);
+    public function ServerStreamingCall($channel, $method, $deserialize, $options);
+    public function BidiStreamingCall($channel, $method, $deserialize, $options);
+}

+ 47 - 0
src/php/lib/Grpc/DefaultCallInvoker.php

@@ -0,0 +1,47 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+namespace Grpc;
+
+/**
+ * Default call invoker in the gRPC stub.
+ * THIS IS AN EXPERIMENTAL API.
+ */
+class DefaultCallInvoker implements CallInvoker
+{
+    public function createChannelFactory($hostname, $opts) {
+        return new Channel($hostname, $opts);
+    }
+
+    public function UnaryCall($channel, $method, $deserialize, $options) {
+        return new UnaryCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ClientStreamingCall($channel, $method, $deserialize, $options) {
+        return new ClientStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ServerStreamingCall($channel, $method, $deserialize, $options) {
+        return new ServerStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function BidiStreamingCall($channel, $method, $deserialize, $options) {
+        return new BidiStreamingCall($channel, $method, $deserialize, $options);
+    }
+}
+

+ 227 - 0
src/php/tests/unit_tests/CallInvokerTest.php

@@ -0,0 +1,227 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+/**
+ * Interface exported by the server.
+ */
+require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');
+
+class CallInvokerSimpleRequest
+{
+    private $data;
+    public function __construct($data)
+    {
+        $this->data = $data;
+    }
+    public function setData($data)
+    {
+        $this->data = $data;
+    }
+    public function serializeToString()
+    {
+        return $this->data;
+    }
+}
+
+class CallInvokerClient extends Grpc\BaseStub
+{
+
+  /**
+   * @param string $hostname hostname
+   * @param array $opts channel options
+   * @param Channel|InterceptorChannel $channel (optional) re-use channel object
+   */
+  public function __construct($hostname, $opts, $channel = null)
+  {
+    parent::__construct($hostname, $opts, $channel);
+  }
+
+  /**
+   * A simple RPC.
+   * @param SimpleRequest $argument input argument
+   * @param array $metadata metadata
+   * @param array $options call options
+   */
+  public function UnaryCall(
+    CallInvokerSimpleRequest $argument,
+    $metadata = [],
+    $options = []
+  ) {
+    return $this->_simpleRequest(
+      '/dummy_method',
+      $argument,
+      [],
+      $metadata,
+      $options
+    );
+  }
+}
+
+class CallInvokerUpdateChannel implements \Grpc\CallInvoker
+{
+    private $channel;
+
+    public function getChannel() {
+        return $this->channel;
+    }
+
+    public function createChannelFactory($hostname, $opts) {
+        $this->channel = new \Grpc\Channel('localhost:50050', $opts);
+        return $this->channel;
+    }
+
+    public function UnaryCall($channel, $method, $deserialize, $options) {
+        return new UnaryCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ClientStreamingCall($channel, $method, $deserialize, $options) {
+        return new ClientStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ServerStreamingCall($channel, $method, $deserialize, $options) {
+        return new ServerStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function BidiStreamingCall($channel, $method, $deserialize, $options) {
+        return new BidiStreamingCall($channel, $method, $deserialize, $options);
+    }
+}
+
+
+class CallInvokerChangeRequest implements \Grpc\CallInvoker
+{
+    private $channel;
+
+    public function getChannel() {
+        return $this->channel;
+    }
+    public function createChannelFactory($hostname, $opts) {
+        $this->channel = new \Grpc\Channel($hostname, $opts);
+        return $this->channel;
+    }
+
+    public function UnaryCall($channel, $method, $deserialize, $options) {
+        return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ClientStreamingCall($channel, $method, $deserialize, $options) {
+        return new ClientStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function ServerStreamingCall($channel, $method, $deserialize, $options) {
+        return new ServerStreamingCall($channel, $method, $deserialize, $options);
+    }
+
+    public function BidiStreamingCall($channel, $method, $deserialize, $options) {
+        return new BidiStreamingCall($channel, $method, $deserialize, $options);
+    }
+}
+
+class CallInvokerChangeRequestCall
+{
+    private $call;
+
+    public function __construct($channel, $method, $deserialize, $options)
+    {
+        $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options);
+    }
+
+    public function start($argument, $metadata, $options) {
+        $argument->setData('intercepted_unary_request');
+        $this->call->start($argument, $metadata, $options);
+    }
+
+    public function wait()
+    {
+        return $this->call->wait();
+    }
+}
+
+class CallInvokerTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        $this->server = new Grpc\Server([]);
+        $this->port = $this->server->addHttp2Port('0.0.0.0:0');
+        $this->server->start();
+    }
+
+    public function tearDown()
+    {
+        unset($this->server);
+    }
+
+    public function testCreateDefaultCallInvoker()
+    {
+        $call_invoker = new \Grpc\DefaultCallInvoker();
+    }
+
+    public function testCreateCallInvoker()
+    {
+        $call_invoker = new CallInvokerUpdateChannel();
+    }
+
+    public function testCallInvokerAccessChannel()
+    {
+        $call_invoker = new CallInvokerUpdateChannel();
+        $stub = new \Grpc\BaseStub('localhost:50051',
+          ['credentials' => \Grpc\ChannelCredentials::createInsecure(),
+            'grpc_call_invoker' => $call_invoker]);
+        $this->assertEquals($call_invoker->getChannel()->getTarget(), 'localhost:50050');
+        $call_invoker->getChannel()->close();
+    }
+
+    public function testClientChangeRequestCallInvoker()
+    {
+        $req_text = 'client_request';
+        $call_invoker = new CallInvokerChangeRequest();
+        $client = new CallInvokerClient('localhost:'.$this->port, [
+            'force_new' => true,
+            'credentials' => Grpc\ChannelCredentials::createInsecure(),
+            'grpc_call_invoker' => $call_invoker,
+        ]);
+
+        $req = new CallInvokerSimpleRequest($req_text);
+        $unary_call = $client->UnaryCall($req);
+
+        $event = $this->server->requestCall();
+        $this->assertSame('/dummy_method', $event->method);
+        $server_call = $event->call;
+        $event = $server_call->startBatch([
+            Grpc\OP_SEND_INITIAL_METADATA => [],
+            Grpc\OP_SEND_STATUS_FROM_SERVER => [
+                'metadata' => [],
+                'code' => Grpc\STATUS_OK,
+                'details' => '',
+            ],
+            Grpc\OP_RECV_MESSAGE => true,
+            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+        ]);
+        $this->assertSame('intercepted_unary_request', $event->message);
+        $call_invoker->getChannel()->close();
+        unset($unary_call);
+        unset($server_call);
+    }
+}

+ 1 - 0
src/php/tests/unit_tests/InterceptorTest.php

@@ -24,6 +24,7 @@ require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');
 require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');
 
 
 class SimpleRequest
 class SimpleRequest

+ 4 - 0
src/python/grpcio/grpc_core_dependencies.py

@@ -249,10 +249,12 @@ CORE_SOURCE_FILES = [
     'src/core/lib/security/credentials/jwt/json_token.cc',
     'src/core/lib/security/credentials/jwt/json_token.cc',
     'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
     'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
     'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
     'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
+    'src/core/lib/security/credentials/local/local_credentials.cc',
     'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
     'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
     'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
     'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
     'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
     'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
     'src/core/lib/security/security_connector/alts_security_connector.cc',
     'src/core/lib/security/security_connector/alts_security_connector.cc',
+    'src/core/lib/security/security_connector/local_security_connector.cc',
     'src/core/lib/security/security_connector/security_connector.cc',
     'src/core/lib/security/security_connector/security_connector.cc',
     'src/core/lib/security/transport/client_auth_filter.cc',
     'src/core/lib/security/transport/client_auth_filter.cc',
     'src/core/lib/security/transport/secure_endpoint.cc',
     'src/core/lib/security/transport/secure_endpoint.cc',
@@ -304,6 +306,7 @@ CORE_SOURCE_FILES = [
     'src/core/ext/filters/client_channel/backup_poller.cc',
     'src/core/ext/filters/client_channel/backup_poller.cc',
     'src/core/ext/filters/client_channel/channel_connectivity.cc',
     'src/core/ext/filters/client_channel/channel_connectivity.cc',
     'src/core/ext/filters/client_channel/client_channel.cc',
     'src/core/ext/filters/client_channel/client_channel.cc',
+    'src/core/ext/filters/client_channel/client_channel_channelz.cc',
     'src/core/ext/filters/client_channel/client_channel_factory.cc',
     'src/core/ext/filters/client_channel/client_channel_factory.cc',
     'src/core/ext/filters/client_channel/client_channel_plugin.cc',
     'src/core/ext/filters/client_channel/client_channel_plugin.cc',
     'src/core/ext/filters/client_channel/connector.cc',
     'src/core/ext/filters/client_channel/connector.cc',
@@ -325,6 +328,7 @@ CORE_SOURCE_FILES = [
     'src/core/ext/filters/deadline/deadline_filter.cc',
     'src/core/ext/filters/deadline/deadline_filter.cc',
     'src/core/tsi/alts_transport_security.cc',
     'src/core/tsi/alts_transport_security.cc',
     'src/core/tsi/fake_transport_security.cc',
     'src/core/tsi/fake_transport_security.cc',
+    'src/core/tsi/local_transport_security.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
     'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',

+ 18 - 14
src/ruby/ext/grpc/rb_grpc_imports.generated.c

@@ -142,6 +142,8 @@ grpc_alts_credentials_client_options_add_target_service_account_type grpc_alts_c
 grpc_alts_credentials_options_destroy_type grpc_alts_credentials_options_destroy_import;
 grpc_alts_credentials_options_destroy_type grpc_alts_credentials_options_destroy_import;
 grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
 grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
 grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
 grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
+grpc_local_credentials_create_type grpc_local_credentials_create_import;
+grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import;
 grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
 grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
 grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
 grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
@@ -152,6 +154,13 @@ grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
 grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
 grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
 grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
 grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
 grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
+gpr_log_severity_string_type gpr_log_severity_string_import;
+gpr_log_type gpr_log_import;
+gpr_should_log_type gpr_should_log_import;
+gpr_log_message_type gpr_log_message_import;
+gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+gpr_set_log_function_type gpr_set_log_function_import;
 grpc_slice_ref_type grpc_slice_ref_import;
 grpc_slice_ref_type grpc_slice_ref_import;
 grpc_slice_unref_type grpc_slice_unref_import;
 grpc_slice_unref_type grpc_slice_unref_import;
 grpc_slice_copy_type grpc_slice_copy_import;
 grpc_slice_copy_type grpc_slice_copy_import;
@@ -210,13 +219,6 @@ gpr_set_allocation_functions_type gpr_set_allocation_functions_import;
 gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
 gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
 gpr_cpu_num_cores_type gpr_cpu_num_cores_import;
 gpr_cpu_num_cores_type gpr_cpu_num_cores_import;
 gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
 gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
-gpr_log_severity_string_type gpr_log_severity_string_import;
-gpr_log_type gpr_log_import;
-gpr_should_log_type gpr_should_log_import;
-gpr_log_message_type gpr_log_message_import;
-gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
-gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
-gpr_set_log_function_type gpr_set_log_function_import;
 gpr_format_message_type gpr_format_message_import;
 gpr_format_message_type gpr_format_message_import;
 gpr_strdup_type gpr_strdup_import;
 gpr_strdup_type gpr_strdup_import;
 gpr_asprintf_type gpr_asprintf_import;
 gpr_asprintf_type gpr_asprintf_import;
@@ -388,6 +390,8 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_alts_credentials_options_destroy_import = (grpc_alts_credentials_options_destroy_type) GetProcAddress(library, "grpc_alts_credentials_options_destroy");
   grpc_alts_credentials_options_destroy_import = (grpc_alts_credentials_options_destroy_type) GetProcAddress(library, "grpc_alts_credentials_options_destroy");
   grpc_alts_credentials_create_import = (grpc_alts_credentials_create_type) GetProcAddress(library, "grpc_alts_credentials_create");
   grpc_alts_credentials_create_import = (grpc_alts_credentials_create_type) GetProcAddress(library, "grpc_alts_credentials_create");
   grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create");
   grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create");
+  grpc_local_credentials_create_import = (grpc_local_credentials_create_type) GetProcAddress(library, "grpc_local_credentials_create");
+  grpc_local_server_credentials_create_import = (grpc_local_server_credentials_create_type) GetProcAddress(library, "grpc_local_server_credentials_create");
   grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
   grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
   grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
   grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
   grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
   grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
@@ -398,6 +402,13 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next");
   grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next");
   grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall");
   grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall");
   grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
   grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
+  gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string");
+  gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
+  gpr_should_log_import = (gpr_should_log_type) GetProcAddress(library, "gpr_should_log");
+  gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
+  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
+  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
+  gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
   grpc_slice_ref_import = (grpc_slice_ref_type) GetProcAddress(library, "grpc_slice_ref");
   grpc_slice_ref_import = (grpc_slice_ref_type) GetProcAddress(library, "grpc_slice_ref");
   grpc_slice_unref_import = (grpc_slice_unref_type) GetProcAddress(library, "grpc_slice_unref");
   grpc_slice_unref_import = (grpc_slice_unref_type) GetProcAddress(library, "grpc_slice_unref");
   grpc_slice_copy_import = (grpc_slice_copy_type) GetProcAddress(library, "grpc_slice_copy");
   grpc_slice_copy_import = (grpc_slice_copy_type) GetProcAddress(library, "grpc_slice_copy");
@@ -456,13 +467,6 @@ void grpc_rb_load_imports(HMODULE library) {
   gpr_get_allocation_functions_import = (gpr_get_allocation_functions_type) GetProcAddress(library, "gpr_get_allocation_functions");
   gpr_get_allocation_functions_import = (gpr_get_allocation_functions_type) GetProcAddress(library, "gpr_get_allocation_functions");
   gpr_cpu_num_cores_import = (gpr_cpu_num_cores_type) GetProcAddress(library, "gpr_cpu_num_cores");
   gpr_cpu_num_cores_import = (gpr_cpu_num_cores_type) GetProcAddress(library, "gpr_cpu_num_cores");
   gpr_cpu_current_cpu_import = (gpr_cpu_current_cpu_type) GetProcAddress(library, "gpr_cpu_current_cpu");
   gpr_cpu_current_cpu_import = (gpr_cpu_current_cpu_type) GetProcAddress(library, "gpr_cpu_current_cpu");
-  gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string");
-  gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
-  gpr_should_log_import = (gpr_should_log_type) GetProcAddress(library, "gpr_should_log");
-  gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
-  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
-  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
-  gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
   gpr_format_message_import = (gpr_format_message_type) GetProcAddress(library, "gpr_format_message");
   gpr_format_message_import = (gpr_format_message_type) GetProcAddress(library, "gpr_format_message");
   gpr_strdup_import = (gpr_strdup_type) GetProcAddress(library, "gpr_strdup");
   gpr_strdup_import = (gpr_strdup_type) GetProcAddress(library, "gpr_strdup");
   gpr_asprintf_import = (gpr_asprintf_type) GetProcAddress(library, "gpr_asprintf");
   gpr_asprintf_import = (gpr_asprintf_type) GetProcAddress(library, "gpr_asprintf");

+ 28 - 22
src/ruby/ext/grpc/rb_grpc_imports.generated.h

@@ -30,11 +30,11 @@
 #include <grpc/grpc_posix.h>
 #include <grpc/grpc_posix.h>
 #include <grpc/grpc_security.h>
 #include <grpc/grpc_security.h>
 #include <grpc/impl/codegen/byte_buffer.h>
 #include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/log.h>
 #include <grpc/slice.h>
 #include <grpc/slice.h>
 #include <grpc/slice_buffer.h>
 #include <grpc/slice_buffer.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/cpu.h>
 #include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
 #include <grpc/support/log_windows.h>
 #include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/sync.h>
@@ -401,6 +401,12 @@ extern grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
 typedef grpc_server_credentials*(*grpc_alts_server_credentials_create_type)(const grpc_alts_credentials_options* options);
 typedef grpc_server_credentials*(*grpc_alts_server_credentials_create_type)(const grpc_alts_credentials_options* options);
 extern grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
 extern grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
 #define grpc_alts_server_credentials_create grpc_alts_server_credentials_create_import
 #define grpc_alts_server_credentials_create grpc_alts_server_credentials_create_import
+typedef grpc_channel_credentials*(*grpc_local_credentials_create_type)(grpc_local_connect_type type);
+extern grpc_local_credentials_create_type grpc_local_credentials_create_import;
+#define grpc_local_credentials_create grpc_local_credentials_create_import
+typedef grpc_server_credentials*(*grpc_local_server_credentials_create_type)(grpc_local_connect_type type);
+extern grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import;
+#define grpc_local_server_credentials_create grpc_local_server_credentials_create_import
 typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices);
 typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices);
 extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 #define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
 #define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
@@ -431,6 +437,27 @@ extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_impo
 typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader* reader);
 typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader* reader);
 extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 #define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
 #define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
+typedef const char*(*gpr_log_severity_string_type)(gpr_log_severity severity);
+extern gpr_log_severity_string_type gpr_log_severity_string_import;
+#define gpr_log_severity_string gpr_log_severity_string_import
+typedef void(*gpr_log_type)(const char* file, int line, gpr_log_severity severity, const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
+extern gpr_log_type gpr_log_import;
+#define gpr_log gpr_log_import
+typedef int(*gpr_should_log_type)(gpr_log_severity severity);
+extern gpr_should_log_type gpr_should_log_import;
+#define gpr_should_log gpr_should_log_import
+typedef void(*gpr_log_message_type)(const char* file, int line, gpr_log_severity severity, const char* message);
+extern gpr_log_message_type gpr_log_message_import;
+#define gpr_log_message gpr_log_message_import
+typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
+extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+#define gpr_set_log_verbosity gpr_set_log_verbosity_import
+typedef void(*gpr_log_verbosity_init_type)(void);
+extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+#define gpr_log_verbosity_init gpr_log_verbosity_init_import
+typedef void(*gpr_set_log_function_type)(gpr_log_func func);
+extern gpr_set_log_function_type gpr_set_log_function_import;
+#define gpr_set_log_function gpr_set_log_function_import
 typedef grpc_slice(*grpc_slice_ref_type)(grpc_slice s);
 typedef grpc_slice(*grpc_slice_ref_type)(grpc_slice s);
 extern grpc_slice_ref_type grpc_slice_ref_import;
 extern grpc_slice_ref_type grpc_slice_ref_import;
 #define grpc_slice_ref grpc_slice_ref_import
 #define grpc_slice_ref grpc_slice_ref_import
@@ -605,27 +632,6 @@ extern gpr_cpu_num_cores_type gpr_cpu_num_cores_import;
 typedef unsigned(*gpr_cpu_current_cpu_type)(void);
 typedef unsigned(*gpr_cpu_current_cpu_type)(void);
 extern gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
 extern gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
 #define gpr_cpu_current_cpu gpr_cpu_current_cpu_import
 #define gpr_cpu_current_cpu gpr_cpu_current_cpu_import
-typedef const char*(*gpr_log_severity_string_type)(gpr_log_severity severity);
-extern gpr_log_severity_string_type gpr_log_severity_string_import;
-#define gpr_log_severity_string gpr_log_severity_string_import
-typedef void(*gpr_log_type)(const char* file, int line, gpr_log_severity severity, const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
-extern gpr_log_type gpr_log_import;
-#define gpr_log gpr_log_import
-typedef int(*gpr_should_log_type)(gpr_log_severity severity);
-extern gpr_should_log_type gpr_should_log_import;
-#define gpr_should_log gpr_should_log_import
-typedef void(*gpr_log_message_type)(const char* file, int line, gpr_log_severity severity, const char* message);
-extern gpr_log_message_type gpr_log_message_import;
-#define gpr_log_message gpr_log_message_import
-typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
-extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
-#define gpr_set_log_verbosity gpr_set_log_verbosity_import
-typedef void(*gpr_log_verbosity_init_type)(void);
-extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
-#define gpr_log_verbosity_init gpr_log_verbosity_init_import
-typedef void(*gpr_set_log_function_type)(gpr_log_func func);
-extern gpr_set_log_function_type gpr_set_log_function_import;
-#define gpr_set_log_function gpr_set_log_function_import
 typedef char*(*gpr_format_message_type)(int messageid);
 typedef char*(*gpr_format_message_type)(int messageid);
 extern gpr_format_message_type gpr_format_message_import;
 extern gpr_format_message_type gpr_format_message_import;
 #define gpr_format_message gpr_format_message_import
 #define gpr_format_message gpr_format_message_import

+ 1 - 1
templates/Makefile.template

@@ -37,7 +37,7 @@
 
 
     # warnings we'd like, but that dont exist in all compilers
     # warnings we'd like, but that dont exist in all compilers
     PREFERRED_WARNINGS=['shadow', 'extra-semi']
     PREFERRED_WARNINGS=['shadow', 'extra-semi']
-    CHECK_WARNINGS=PREFERRED_WARNINGS + ['no-shift-negative-value', 'no-unused-but-set-variable']
+    CHECK_WARNINGS=PREFERRED_WARNINGS + ['no-shift-negative-value', 'no-unused-but-set-variable', 'no-maybe-uninitialized']
 
 
     def warning_var(fmt, warning):
     def warning_var(fmt, warning):
       return fmt % warning.replace('-', '_').replace('+', 'X').upper()
       return fmt % warning.replace('-', '_').replace('+', 'X').upper()

+ 9 - 1
templates/gRPC-C++.podspec.template

@@ -49,6 +49,7 @@
     out = grpc_lib_files(filegroups, ("grpc++_codegen_proto", "grpc++_config_proto"), ("headers", "src", "public_headers"))
     out = grpc_lib_files(filegroups, ("grpc++_codegen_proto", "grpc++_config_proto"), ("headers", "src", "public_headers"))
     excl_files = grpc_lib_files(filegroups, ("grpc++_codegen_base",), ("headers", "src", "public_headers"))
     excl_files = grpc_lib_files(filegroups, ("grpc++_codegen_base",), ("headers", "src", "public_headers"))
     out = [file for file in out if file not in excl_files]
     out = [file for file in out if file not in excl_files]
+    out = filter_grpcpp(out)
     return out
     return out
 
 
   def grpcpp_private_files(libs, filegroups):
   def grpcpp_private_files(libs, filegroups):
@@ -131,7 +132,7 @@
     s.name     = 'gRPC-C++'
     s.name     = 'gRPC-C++'
     # TODO (mxyan): use version that match gRPC version when pod is stabilized
     # TODO (mxyan): use version that match gRPC version when pod is stabilized
     # version = '${settings.version}'
     # version = '${settings.version}'
-    version = '0.0.2'
+    version = '0.0.3'
     s.version  = version
     s.version  = version
     s.summary  = 'gRPC C++ library'
     s.summary  = 'gRPC C++ library'
     s.homepage = 'https://grpc.io'
     s.homepage = 'https://grpc.io'
@@ -195,6 +196,13 @@
       ss.private_header_files = ${ruby_multiline_list(grpcpp_private_headers(libs, filegroups), 30)}
       ss.private_header_files = ${ruby_multiline_list(grpcpp_private_headers(libs, filegroups), 30)}
     end
     end
 
 
+    s.subspec 'Protobuf' do |ss|
+      ss.header_mappings_dir = 'include/grpcpp'
+      ss.dependency "#{s.name}/Interface", version
+
+      ss.source_files = ${ruby_multiline_list(grpcpp_proto_files(filegroups), 22)}
+    end
+
     s.prepare_command = <<-END_OF_COMMAND
     s.prepare_command = <<-END_OF_COMMAND
       find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
       find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
       find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm
       find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm

+ 3 - 0
templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template

@@ -16,5 +16,8 @@
 
 
   FROM google/dart:latest
   FROM google/dart:latest
 
 
+  # Upgrade Dart to version 2.
+  RUN apt-get update && apt-get upgrade -y dart
+
   # Define the default command.
   # Define the default command.
   CMD ["bash"]
   CMD ["bash"]

+ 19 - 0
test/build/no-maybe-uninitialized.c

@@ -0,0 +1,19 @@
+/*
+ *
+ * Copyright 2015 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.
+ *
+ */
+
+int main(void) {}

+ 9 - 0
test/core/channel/channelz_registry_test.cc

@@ -82,6 +82,15 @@ TEST(ChannelzRegistryTest, MultipleTypeTest) {
   EXPECT_EQ(&str_to_register, retrieved_str);
   EXPECT_EQ(&str_to_register, retrieved_str);
 }
 }
 
 
+TEST(ChannelzRegistryTest, RegisterManyItems) {
+  int object_to_register = 42;
+  for (int i = 0; i < 100; i++) {
+    intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
+    int* retrieved = ChannelzRegistry::Get<int>(uuid);
+    EXPECT_EQ(&object_to_register, retrieved);
+  }
+}
+
 namespace {
 namespace {
 class Foo {
 class Foo {
  public:
  public:

+ 154 - 0
test/core/end2end/fixtures/h2_local.cc

@@ -0,0 +1,154 @@
+/*
+ *
+ * Copyright 2015 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 "test/core/end2end/end2end_tests.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/security/credentials/credentials.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/server.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+typedef struct fullstack_fixture_data {
+  char* localaddr;
+} fullstack_fixture_data;
+
+static int unique = 1;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+    grpc_channel_args* client_args, grpc_channel_args* server_args) {
+  grpc_end2end_test_fixture f;
+  fullstack_fixture_data* ffd = static_cast<fullstack_fixture_data*>(
+      gpr_malloc(sizeof(fullstack_fixture_data)));
+  memset(&f, 0, sizeof(f));
+
+  gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(),
+               unique++);
+
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create_for_next(nullptr);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
+
+  return f;
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f,
+                                  grpc_channel_args* client_args) {
+  grpc_channel_credentials* creds = grpc_local_credentials_create(UDS);
+  fullstack_fixture_data* ffd =
+      static_cast<fullstack_fixture_data*>(f->fixture_data);
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr);
+  GPR_ASSERT(f->client != nullptr);
+  grpc_channel_credentials_release(creds);
+}
+
+/*
+ * Check if server should fail auth check. If it is true, a different metadata
+ * processor will be installed that always fails in processing client's
+ * metadata.
+ */
+static bool fail_server_auth_check(grpc_channel_args* server_args) {
+  size_t i;
+  if (server_args == nullptr) return 0;
+  for (i = 0; i < server_args->num_args; i++) {
+    if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+        0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static void process_auth_failure(void* state, grpc_auth_context* ctx,
+                                 const grpc_metadata* md, size_t md_count,
+                                 grpc_process_auth_metadata_done_cb cb,
+                                 void* user_data) {
+  GPR_ASSERT(state == nullptr);
+  cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f,
+                                  grpc_channel_args* server_args) {
+  grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS);
+  fullstack_fixture_data* ffd =
+      static_cast<fullstack_fixture_data*>(f->fixture_data);
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  f->server = grpc_server_create(server_args, nullptr);
+  grpc_server_register_completion_queue(f->server, f->cq, nullptr);
+  if (fail_server_auth_check(server_args)) {
+    grpc_auth_metadata_processor processor = {process_auth_failure, nullptr,
+                                              nullptr};
+    grpc_server_credentials_set_auth_metadata_processor(creds, processor);
+  }
+  GPR_ASSERT(
+      grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds));
+  grpc_server_credentials_release(creds);
+  grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) {
+  fullstack_fixture_data* ffd =
+      static_cast<fullstack_fixture_data*>(f->fixture_data);
+  gpr_free(ffd->localaddr);
+  gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+    {"chttp2/fullstack_local",
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+         FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+     nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+     chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
+
+int main(int argc, char** argv) {
+  size_t i;
+
+  grpc_test_init(argc, argv);
+  grpc_end2end_tests_pre_init();
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+
+  grpc_shutdown();
+
+  return 0;
+}

+ 4 - 0
test/core/end2end/gen_build_yaml.py

@@ -35,6 +35,9 @@ default_secure_fixture_options = default_unsecure_fixture_options._replace(
 uds_fixture_options = default_unsecure_fixture_options._replace(
 uds_fixture_options = default_unsecure_fixture_options._replace(
     dns_resolver=False, platforms=['linux', 'mac', 'posix'],
     dns_resolver=False, platforms=['linux', 'mac', 'posix'],
     exclude_iomgrs=['uv'])
     exclude_iomgrs=['uv'])
+local_fixture_options = default_secure_fixture_options._replace(
+    dns_resolver=False, platforms=['linux', 'mac', 'posix'],
+    exclude_iomgrs=['uv'])
 fd_unsecure_fixture_options = default_unsecure_fixture_options._replace(
 fd_unsecure_fixture_options = default_unsecure_fixture_options._replace(
     dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'],
     dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'],
     exclude_iomgrs=['uv'], client_channel=False)
     exclude_iomgrs=['uv'], client_channel=False)
@@ -71,6 +74,7 @@ END2END_FIXTURES = {
     'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
     'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
         ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']),
         ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']),
     'h2_ssl': default_secure_fixture_options,
     'h2_ssl': default_secure_fixture_options,
+    'h2_local': local_fixture_options,
     'h2_ssl_proxy': default_secure_fixture_options._replace(
     'h2_ssl_proxy': default_secure_fixture_options._replace(
         includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']),
         includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']),
     'h2_uds': uds_fixture_options,
     'h2_uds': uds_fixture_options,

+ 1 - 0
test/core/end2end/generate_tests.bzl

@@ -66,6 +66,7 @@ END2END_FIXTURES = {
     'h2_sockpair+trace': fixture_options(fullstack=False, dns_resolver=False,
     'h2_sockpair+trace': fixture_options(fullstack=False, dns_resolver=False,
                                          tracing=True, client_channel=False),
                                          tracing=True, client_channel=False),
     'h2_ssl': fixture_options(secure=True),
     'h2_ssl': fixture_options(secure=True),
+    'h2_local': fixture_options(secure=True, dns_resolver=False, platforms=['linux', 'mac', 'posix']),
     'h2_ssl_proxy': fixture_options(includes_proxy=True, secure=True),
     'h2_ssl_proxy': fixture_options(includes_proxy=True, secure=True),
     'h2_uds': fixture_options(dns_resolver=False,
     'h2_uds': fixture_options(dns_resolver=False,
                               platforms=['linux', 'mac', 'posix']),
                               platforms=['linux', 'mac', 'posix']),

+ 2 - 0
test/core/security/check_gcp_environment_linux_test.cc

@@ -16,6 +16,8 @@
  *
  *
  */
  */
 
 
+#include <grpc/support/port_platform.h>
+
 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
 
 
 #if GPR_LINUX
 #if GPR_LINUX

+ 2 - 0
test/core/security/check_gcp_environment_windows_test.cc

@@ -16,6 +16,8 @@
  *
  *
  */
  */
 
 
+#include <grpc/support/port_platform.h>
+
 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
 
 
 #ifdef GPR_WINDOWS
 #ifdef GPR_WINDOWS

+ 10 - 7
test/core/surface/public_headers_must_be_c89.c

@@ -33,6 +33,7 @@
 #include <grpc/impl/codegen/gpr_slice.h>
 #include <grpc/impl/codegen/gpr_slice.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/log.h>
 #include <grpc/impl/codegen/port_platform.h>
 #include <grpc/impl/codegen/port_platform.h>
 #include <grpc/impl/codegen/propagation_bits.h>
 #include <grpc/impl/codegen/propagation_bits.h>
 #include <grpc/impl/codegen/slice.h>
 #include <grpc/impl/codegen/slice.h>
@@ -177,6 +178,8 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_alts_credentials_options_destroy);
   printf("%lx", (unsigned long) grpc_alts_credentials_options_destroy);
   printf("%lx", (unsigned long) grpc_alts_credentials_create);
   printf("%lx", (unsigned long) grpc_alts_credentials_create);
   printf("%lx", (unsigned long) grpc_alts_server_credentials_create);
   printf("%lx", (unsigned long) grpc_alts_server_credentials_create);
+  printf("%lx", (unsigned long) grpc_local_credentials_create);
+  printf("%lx", (unsigned long) grpc_local_server_credentials_create);
   printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_byte_buffer_copy);
   printf("%lx", (unsigned long) grpc_byte_buffer_copy);
@@ -187,6 +190,13 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_byte_buffer_reader_next);
   printf("%lx", (unsigned long) grpc_byte_buffer_reader_next);
   printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall);
   printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall);
   printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader);
   printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader);
+  printf("%lx", (unsigned long) gpr_log_severity_string);
+  printf("%lx", (unsigned long) gpr_log);
+  printf("%lx", (unsigned long) gpr_should_log);
+  printf("%lx", (unsigned long) gpr_log_message);
+  printf("%lx", (unsigned long) gpr_set_log_verbosity);
+  printf("%lx", (unsigned long) gpr_log_verbosity_init);
+  printf("%lx", (unsigned long) gpr_set_log_function);
   printf("%lx", (unsigned long) grpc_slice_ref);
   printf("%lx", (unsigned long) grpc_slice_ref);
   printf("%lx", (unsigned long) grpc_slice_unref);
   printf("%lx", (unsigned long) grpc_slice_unref);
   printf("%lx", (unsigned long) grpc_slice_copy);
   printf("%lx", (unsigned long) grpc_slice_copy);
@@ -245,13 +255,6 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) gpr_get_allocation_functions);
   printf("%lx", (unsigned long) gpr_get_allocation_functions);
   printf("%lx", (unsigned long) gpr_cpu_num_cores);
   printf("%lx", (unsigned long) gpr_cpu_num_cores);
   printf("%lx", (unsigned long) gpr_cpu_current_cpu);
   printf("%lx", (unsigned long) gpr_cpu_current_cpu);
-  printf("%lx", (unsigned long) gpr_log_severity_string);
-  printf("%lx", (unsigned long) gpr_log);
-  printf("%lx", (unsigned long) gpr_should_log);
-  printf("%lx", (unsigned long) gpr_log_message);
-  printf("%lx", (unsigned long) gpr_set_log_verbosity);
-  printf("%lx", (unsigned long) gpr_log_verbosity_init);
-  printf("%lx", (unsigned long) gpr_set_log_function);
   printf("%lx", (unsigned long) gpr_strdup);
   printf("%lx", (unsigned long) gpr_strdup);
   printf("%lx", (unsigned long) gpr_asprintf);
   printf("%lx", (unsigned long) gpr_asprintf);
   printf("%lx", (unsigned long) gpr_mu_init);
   printf("%lx", (unsigned long) gpr_mu_init);

+ 17 - 9
test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc

@@ -109,7 +109,7 @@ static void alter_random_byte(grpc_slice_buffer* sb) {
 }
 }
 
 
 static alts_grpc_record_protocol_test_fixture*
 static alts_grpc_record_protocol_test_fixture*
-test_fixture_integrity_only_create(bool rekey) {
+test_fixture_integrity_only_create(bool rekey, bool extra_copy) {
   alts_grpc_record_protocol_test_fixture* fixture =
   alts_grpc_record_protocol_test_fixture* fixture =
       static_cast<alts_grpc_record_protocol_test_fixture*>(
       static_cast<alts_grpc_record_protocol_test_fixture*>(
           gpr_zalloc(sizeof(alts_grpc_record_protocol_test_fixture)));
           gpr_zalloc(sizeof(alts_grpc_record_protocol_test_fixture)));
@@ -124,41 +124,46 @@ test_fixture_integrity_only_create(bool rekey) {
                  &crypter, nullptr) == GRPC_STATUS_OK);
                  &crypter, nullptr) == GRPC_STATUS_OK);
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
                  crypter, 8, /*is_client=*/true, /*is_protect=*/true,
                  crypter, 8, /*is_client=*/true, /*is_protect=*/true,
-                 &fixture->client_protect) == TSI_OK);
+                 extra_copy, &fixture->client_protect) == TSI_OK);
   /* Create client record protocol for unprotect.  */
   /* Create client record protocol for unprotect.  */
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  &crypter, nullptr) == GRPC_STATUS_OK);
                  &crypter, nullptr) == GRPC_STATUS_OK);
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
                  crypter, 8, /*is_client=*/true, /*is_protect=*/false,
                  crypter, 8, /*is_client=*/true, /*is_protect=*/false,
-                 &fixture->client_unprotect) == TSI_OK);
+                 extra_copy, &fixture->client_unprotect) == TSI_OK);
   /* Create server record protocol for protect.  */
   /* Create server record protocol for protect.  */
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  &crypter, nullptr) == GRPC_STATUS_OK);
                  &crypter, nullptr) == GRPC_STATUS_OK);
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
                  crypter, 8, /*is_client=*/false, /*is_protect=*/true,
                  crypter, 8, /*is_client=*/false, /*is_protect=*/true,
-                 &fixture->server_protect) == TSI_OK);
+                 extra_copy, &fixture->server_protect) == TSI_OK);
   /* Create server record protocol for unprotect.  */
   /* Create server record protocol for unprotect.  */
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
   GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
                  &crypter, nullptr) == GRPC_STATUS_OK);
                  &crypter, nullptr) == GRPC_STATUS_OK);
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
   GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
                  crypter, 8, /*is_client=*/false, /*is_protect=*/false,
                  crypter, 8, /*is_client=*/false, /*is_protect=*/false,
-                 &fixture->server_unprotect) == TSI_OK);
+                 extra_copy, &fixture->server_unprotect) == TSI_OK);
 
 
   gpr_free(key);
   gpr_free(key);
   return fixture;
   return fixture;
 }
 }
 
 
 static alts_grpc_record_protocol_test_fixture*
 static alts_grpc_record_protocol_test_fixture*
-test_fixture_integrity_only_no_rekey_create() {
-  return test_fixture_integrity_only_create(false);
+test_fixture_integrity_only_no_rekey_no_extra_copy_create() {
+  return test_fixture_integrity_only_create(false, false);
 }
 }
 
 
 static alts_grpc_record_protocol_test_fixture*
 static alts_grpc_record_protocol_test_fixture*
 test_fixture_integrity_only_rekey_create() {
 test_fixture_integrity_only_rekey_create() {
-  return test_fixture_integrity_only_create(true);
+  return test_fixture_integrity_only_create(true, false);
+}
+
+static alts_grpc_record_protocol_test_fixture*
+test_fixture_integrity_only_extra_copy_create() {
+  return test_fixture_integrity_only_create(false, true);
 }
 }
 
 
 static alts_grpc_record_protocol_test_fixture*
 static alts_grpc_record_protocol_test_fixture*
@@ -440,8 +445,11 @@ static void alts_grpc_record_protocol_tests(
 }
 }
 
 
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
-  alts_grpc_record_protocol_tests(&test_fixture_integrity_only_no_rekey_create);
+  alts_grpc_record_protocol_tests(
+      &test_fixture_integrity_only_no_rekey_no_extra_copy_create);
   alts_grpc_record_protocol_tests(&test_fixture_integrity_only_rekey_create);
   alts_grpc_record_protocol_tests(&test_fixture_integrity_only_rekey_create);
+  alts_grpc_record_protocol_tests(
+      &test_fixture_integrity_only_extra_copy_create);
   alts_grpc_record_protocol_tests(
   alts_grpc_record_protocol_tests(
       &test_fixture_privacy_integrity_no_rekey_create);
       &test_fixture_privacy_integrity_no_rekey_create);
   alts_grpc_record_protocol_tests(&test_fixture_privacy_integrity_rekey_create);
   alts_grpc_record_protocol_tests(&test_fixture_privacy_integrity_rekey_create);

+ 26 - 15
test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc

@@ -100,7 +100,8 @@ static bool are_slice_buffers_equal(grpc_slice_buffer* first,
 
 
 static alts_zero_copy_grpc_protector_test_fixture*
 static alts_zero_copy_grpc_protector_test_fixture*
 alts_zero_copy_grpc_protector_test_fixture_create(bool rekey,
 alts_zero_copy_grpc_protector_test_fixture_create(bool rekey,
-                                                  bool integrity_only) {
+                                                  bool integrity_only,
+                                                  bool enable_extra_copy) {
   alts_zero_copy_grpc_protector_test_fixture* fixture =
   alts_zero_copy_grpc_protector_test_fixture* fixture =
       static_cast<alts_zero_copy_grpc_protector_test_fixture*>(
       static_cast<alts_zero_copy_grpc_protector_test_fixture*>(
           gpr_zalloc(sizeof(alts_zero_copy_grpc_protector_test_fixture)));
           gpr_zalloc(sizeof(alts_zero_copy_grpc_protector_test_fixture)));
@@ -111,10 +112,12 @@ alts_zero_copy_grpc_protector_test_fixture_create(bool rekey,
   gsec_test_random_array(&key, key_length);
   gsec_test_random_array(&key, key_length);
   GPR_ASSERT(alts_zero_copy_grpc_protector_create(
   GPR_ASSERT(alts_zero_copy_grpc_protector_create(
                  key, key_length, rekey, /*is_client=*/true, integrity_only,
                  key, key_length, rekey, /*is_client=*/true, integrity_only,
-                 &max_protected_frame_size, &fixture->client) == TSI_OK);
+                 enable_extra_copy, &max_protected_frame_size,
+                 &fixture->client) == TSI_OK);
   GPR_ASSERT(alts_zero_copy_grpc_protector_create(
   GPR_ASSERT(alts_zero_copy_grpc_protector_create(
                  key, key_length, rekey, /*is_client=*/false, integrity_only,
                  key, key_length, rekey, /*is_client=*/false, integrity_only,
-                 &max_protected_frame_size, &fixture->server) == TSI_OK);
+                 enable_extra_copy, &max_protected_frame_size,
+                 &fixture->server) == TSI_OK);
   gpr_free(key);
   gpr_free(key);
   grpc_core::ExecCtx::Get()->Flush();
   grpc_core::ExecCtx::Get()->Flush();
   return fixture;
   return fixture;
@@ -229,62 +232,70 @@ static void seal_unseal_large_buffer(tsi_zero_copy_grpc_protector* sender,
 
 
 /* --- Test cases. --- */
 /* --- Test cases. --- */
 
 
-static void alts_zero_copy_protector_seal_unseal_small_buffer_tests() {
+static void alts_zero_copy_protector_seal_unseal_small_buffer_tests(
+    bool enable_extra_copy) {
   alts_zero_copy_grpc_protector_test_fixture* fixture =
   alts_zero_copy_grpc_protector_test_fixture* fixture =
       alts_zero_copy_grpc_protector_test_fixture_create(
       alts_zero_copy_grpc_protector_test_fixture_create(
-          /*rekey=*/false, /*integrity_only=*/true);
+          /*rekey=*/false, /*integrity_only=*/true, enable_extra_copy);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/false, /*integrity_only=*/false);
+      /*rekey=*/false, /*integrity_only=*/false, enable_extra_copy);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/true, /*integrity_only=*/true);
+      /*rekey=*/true, /*integrity_only=*/true, enable_extra_copy);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/true, /*integrity_only=*/false);
+      /*rekey=*/true, /*integrity_only=*/false, enable_extra_copy);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->client, fixture->server);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   seal_unseal_small_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 }
 }
 
 
-static void alts_zero_copy_protector_seal_unseal_large_buffer_tests() {
+static void alts_zero_copy_protector_seal_unseal_large_buffer_tests(
+    bool enable_extra_copy) {
   alts_zero_copy_grpc_protector_test_fixture* fixture =
   alts_zero_copy_grpc_protector_test_fixture* fixture =
       alts_zero_copy_grpc_protector_test_fixture_create(
       alts_zero_copy_grpc_protector_test_fixture_create(
-          /*rekey=*/false, /*integrity_only=*/true);
+          /*rekey=*/false, /*integrity_only=*/true, enable_extra_copy);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/false, /*integrity_only=*/false);
+      /*rekey=*/false, /*integrity_only=*/false, enable_extra_copy);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/true, /*integrity_only=*/true);
+      /*rekey=*/true, /*integrity_only=*/true, enable_extra_copy);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 
 
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
   fixture = alts_zero_copy_grpc_protector_test_fixture_create(
-      /*rekey=*/true, /*integrity_only=*/false);
+      /*rekey=*/true, /*integrity_only=*/false, enable_extra_copy);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->client, fixture->server);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   seal_unseal_large_buffer(fixture->server, fixture->client);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
   alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
 }
 }
 
 
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
-  alts_zero_copy_protector_seal_unseal_small_buffer_tests();
-  alts_zero_copy_protector_seal_unseal_large_buffer_tests();
+  alts_zero_copy_protector_seal_unseal_small_buffer_tests(
+      /*enable_extra_copy=*/false);
+  alts_zero_copy_protector_seal_unseal_small_buffer_tests(
+      /*enable_extra_copy=*/true);
+  alts_zero_copy_protector_seal_unseal_large_buffer_tests(
+      /*enable_extra_copy=*/false);
+  alts_zero_copy_protector_seal_unseal_large_buffer_tests(
+      /*enable_extra_copy=*/true);
   return 0;
   return 0;
 }
 }

+ 114 - 13
test/cpp/codegen/compiler_test_golden

@@ -26,6 +26,7 @@
 
 
 #include "src/proto/grpc/testing/compiler_test.pb.h"
 #include "src/proto/grpc/testing/compiler_test.pb.h"
 
 
+#include <grpcpp/impl/codegen/async_generic_service.h>
 #include <grpcpp/impl/codegen/async_stream.h>
 #include <grpcpp/impl/codegen/async_stream.h>
 #include <grpcpp/impl/codegen/async_unary_call.h>
 #include <grpcpp/impl/codegen/async_unary_call.h>
 #include <grpcpp/impl/codegen/method_handler_impl.h>
 #include <grpcpp/impl/codegen/method_handler_impl.h>
@@ -207,7 +208,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -227,7 +228,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -247,7 +248,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -267,7 +268,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
+    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream)  override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -288,7 +289,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -305,7 +306,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -322,7 +323,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -339,12 +340,92 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
+    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream)  override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
   };
   };
   template <class BaseClass>
   template <class BaseClass>
+  class WithRawMethod_MethodA1 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithRawMethod_MethodA1() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_MethodA1() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_MethodA2 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithRawMethod_MethodA2() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_MethodA2() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA2(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_MethodA3 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithRawMethod_MethodA3() {
+      ::grpc::Service::MarkMethodRaw(2);
+    }
+    ~WithRawMethod_MethodA3() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA3(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_MethodA4 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithRawMethod_MethodA4() {
+      ::grpc::Service::MarkMethodRaw(3);
+    }
+    ~WithRawMethod_MethodA4() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream)  override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
   class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
   class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
    private:
    private:
     void BaseClassMustBeDerivedFromService(const Service *service) {}
     void BaseClassMustBeDerivedFromService(const Service *service) {}
@@ -357,7 +438,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable regular version of this method
     // disable regular version of this method
-    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -378,7 +459,7 @@ class ServiceA final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable regular version of this method
     // disable regular version of this method
-    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -450,7 +531,7 @@ class ServiceB final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
@@ -471,12 +552,32 @@ class ServiceB final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable synchronous version of this method
     // disable synchronous version of this method
-    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }
   };
   };
   template <class BaseClass>
   template <class BaseClass>
+  class WithRawMethod_MethodB1 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithRawMethod_MethodB1() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_MethodB1() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodB1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
   class WithStreamedUnaryMethod_MethodB1 : public BaseClass {
   class WithStreamedUnaryMethod_MethodB1 : public BaseClass {
    private:
    private:
     void BaseClassMustBeDerivedFromService(const Service *service) {}
     void BaseClassMustBeDerivedFromService(const Service *service) {}
@@ -489,7 +590,7 @@ class ServiceB final {
       BaseClassMustBeDerivedFromService(this);
       BaseClassMustBeDerivedFromService(this);
     }
     }
     // disable regular version of this method
     // disable regular version of this method
-    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) final override {
+    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override {
       abort();
       abort();
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
     }

+ 20 - 0
test/cpp/end2end/BUILD

@@ -241,6 +241,26 @@ grpc_cc_test(
     ],
     ],
 )
 )
 
 
+grpc_cc_test(
+    name = "raw_end2end_test",
+    srcs = ["raw_end2end_test.cc"],
+    external_deps = [
+        "gtest",
+    ],
+    deps = [
+        ":test_service_impl",
+        "//:gpr",
+        "//:grpc",
+        "//:grpc++",
+        "//src/proto/grpc/testing:echo_messages_proto",
+        "//src/proto/grpc/testing:echo_proto",
+        "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
+    ],
+)
+
 grpc_cc_test(
 grpc_cc_test(
     name = "mock_test",
     name = "mock_test",
     srcs = ["mock_test.cc"],
     srcs = ["mock_test.cc"],

Some files were not shown because too many files changed in this diff