瀏覽代碼

Merge remote-tracking branch 'upstream/master' into trailing_metadata_status

kpayson64 7 年之前
父節點
當前提交
86ac547c99
共有 100 個文件被更改,包括 3427 次插入921 次删除
  1. 8 0
      .gitmodules
  2. 75 14
      BUILD
  3. 3 1
      BUILDING.md
  4. 164 44
      CMakeLists.txt
  5. 3 3
      CONTRIBUTING.md
  6. 247 42
      Makefile
  7. 4 0
      README.md
  8. 43 0
      TROUBLESHOOTING.md
  9. 100 13
      build.yaml
  10. 8 3
      config.m4
  11. 9 3
      config.w32
  12. 21 3
      gRPC-C++.podspec
  13. 24 9
      gRPC-Core.podspec
  14. 9 7
      grpc.def
  15. 15 4
      grpc.gemspec
  16. 37 6
      grpc.gyp
  17. 30 0
      include/grpc/grpc_security.h
  18. 112 0
      include/grpc/impl/codegen/log.h
  19. 2 0
      include/grpc/module.modulemap
  20. 2 88
      include/grpc/support/log.h
  21. 2 56
      include/grpcpp/generic/async_generic_service.h
  22. 81 0
      include/grpcpp/impl/codegen/async_generic_service.h
  23. 6 5
      include/grpcpp/impl/codegen/method_handler_impl.h
  24. 42 2
      include/grpcpp/impl/codegen/rpc_service_method.h
  25. 19 2
      include/grpcpp/impl/codegen/service_type.h
  26. 3 2
      include/grpcpp/impl/server_builder_plugin.h
  27. 15 4
      package.xml
  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. 1 1
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
  33. 3 1
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
  34. 19 0
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
  35. 54 0
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
  36. 19 0
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
  37. 54 0
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
  38. 4 17
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
  39. 36 62
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
  40. 8 2
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
  41. 6 5
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  42. 4 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
  43. 22 21
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  44. 4 0
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  45. 19 6
      src/core/ext/filters/client_channel/subchannel.cc
  46. 108 0
      src/core/ext/filters/load_reporting/registered_opencensus_objects.h
  47. 269 161
      src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
  48. 97 2
      src/core/ext/filters/load_reporting/server_load_reporting_filter.h
  49. 0 71
      src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
  50. 0 61
      src/core/ext/filters/load_reporting/server_load_reporting_plugin.h
  51. 22 24
      src/core/lib/channel/channel_stack.cc
  52. 8 18
      src/core/lib/channel/channelz.cc
  53. 25 6
      src/core/lib/channel/channelz.h
  54. 28 0
      src/core/lib/gpr/alloc.h
  55. 8 8
      src/core/lib/gpr/arena.cc
  56. 2 2
      src/core/lib/gprpp/memory.h
  57. 5 0
      src/core/lib/gprpp/ref_counted_ptr.h
  58. 1 1
      src/core/lib/gprpp/thd_posix.cc
  59. 73 24
      src/core/lib/iomgr/ev_epollex_linux.cc
  60. 9 2
      src/core/lib/iomgr/exec_ctx.h
  61. 1 1
      src/core/lib/iomgr/executor.cc
  62. 2 0
      src/core/lib/iomgr/iomgr.cc
  63. 5 0
      src/core/lib/iomgr/iomgr.h
  64. 1 2
      src/core/lib/iomgr/timer_manager.cc
  65. 8 8
      src/core/lib/security/context/security_context.cc
  66. 6 2
      src/core/lib/security/context/security_context.h
  67. 77 0
      src/core/lib/security/credentials/local/local_credentials.cc
  68. 40 0
      src/core/lib/security/credentials/local/local_credentials.h
  69. 245 0
      src/core/lib/security/security_connector/local_security_connector.cc
  70. 58 0
      src/core/lib/security/security_connector/local_security_connector.h
  71. 5 1
      src/core/lib/security/transport/client_auth_filter.cc
  72. 4 5
      src/core/lib/security/transport/server_auth_filter.cc
  73. 6 7
      src/core/lib/surface/call.cc
  74. 2 0
      src/core/lib/surface/call.h
  75. 13 3
      src/core/lib/surface/channel.cc
  76. 0 4
      src/core/plugin_registry/grpc_cronet_plugin_registry.cc
  77. 0 4
      src/core/plugin_registry/grpc_plugin_registry.cc
  78. 0 4
      src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
  79. 2 1
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  80. 0 1
      src/core/tsi/alts/handshaker/altscontext.pb.c
  81. 0 1
      src/core/tsi/alts/handshaker/altscontext.pb.h
  82. 0 1
      src/core/tsi/alts/handshaker/handshaker.pb.c
  83. 0 1
      src/core/tsi/alts/handshaker/handshaker.pb.h
  84. 0 1
      src/core/tsi/alts/handshaker/transport_security_common.pb.c
  85. 47 1
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
  86. 3 1
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
  87. 12 11
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
  88. 7 2
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
  89. 209 0
      src/core/tsi/local_transport_security.cc
  90. 51 0
      src/core/tsi/local_transport_security.h
  91. 5 1
      src/cpp/README.md
  92. 12 0
      src/cpp/common/channel_filter.h
  93. 71 0
      src/cpp/server/load_reporter/constants.h
  94. 36 0
      src/cpp/server/load_reporter/get_cpu_stats.h
  95. 45 0
      src/cpp/server/load_reporter/get_cpu_stats_linux.cc
  96. 45 0
      src/cpp/server/load_reporter/get_cpu_stats_macos.cc
  97. 40 0
      src/cpp/server/load_reporter/get_cpu_stats_unsupported.cc
  98. 55 0
      src/cpp/server/load_reporter/get_cpu_stats_windows.cc
  99. 65 0
      src/cpp/server/load_reporter/load_data_store.cc
  100. 21 13
      src/cpp/server/load_reporter/load_data_store.h

+ 8 - 0
.gitmodules

@@ -34,3 +34,11 @@
 [submodule "third_party/abseil-cpp"]
 [submodule "third_party/abseil-cpp"]
 	path = third_party/abseil-cpp
 	path = third_party/abseil-cpp
 	url = https://github.com/abseil/abseil-cpp
 	url = https://github.com/abseil/abseil-cpp
+[submodule "third_party/libcxxabi"]
+	path = third_party/libcxxabi
+	url = https://github.com/llvm-mirror/libcxxabi.git
+	branch = release_60
+[submodule "third_party/libcxx"]
+	path = third_party/libcxx
+	url = https://github.com/llvm-mirror/libcxx.git
+	branch = release_60

+ 75 - 14
BUILD

@@ -29,8 +29,8 @@ package(
 load(
 load(
     "//bazel:grpc_build_system.bzl",
     "//bazel:grpc_build_system.bzl",
     "grpc_cc_library",
     "grpc_cc_library",
-    "grpc_proto_plugin",
     "grpc_generate_one_off_targets",
     "grpc_generate_one_off_targets",
+    "grpc_proto_plugin",
 )
 )
 
 
 config_setting(
 config_setting(
@@ -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",
@@ -675,8 +677,8 @@ grpc_cc_library(
         "src/core/lib/channel/channel_stack.cc",
         "src/core/lib/channel/channel_stack.cc",
         "src/core/lib/channel/channel_stack_builder.cc",
         "src/core/lib/channel/channel_stack_builder.cc",
         "src/core/lib/channel/channel_trace.cc",
         "src/core/lib/channel/channel_trace.cc",
-        "src/core/lib/channel/channelz_registry.cc",
         "src/core/lib/channel/channelz.cc",
         "src/core/lib/channel/channelz.cc",
+        "src/core/lib/channel/channelz_registry.cc",
         "src/core/lib/channel/connected_channel.cc",
         "src/core/lib/channel/connected_channel.cc",
         "src/core/lib/channel/handshaker.cc",
         "src/core/lib/channel/handshaker.cc",
         "src/core/lib/channel/handshaker_factory.cc",
         "src/core/lib/channel/handshaker_factory.cc",
@@ -823,8 +825,8 @@ grpc_cc_library(
         "src/core/lib/channel/channel_stack.h",
         "src/core/lib/channel/channel_stack.h",
         "src/core/lib/channel/channel_stack_builder.h",
         "src/core/lib/channel/channel_stack_builder.h",
         "src/core/lib/channel/channel_trace.h",
         "src/core/lib/channel/channel_trace.h",
-        "src/core/lib/channel/channelz_registry.h",
         "src/core/lib/channel/channelz.h",
         "src/core/lib/channel/channelz.h",
+        "src/core/lib/channel/channelz_registry.h",
         "src/core/lib/channel/connected_channel.h",
         "src/core/lib/channel/connected_channel.h",
         "src/core/lib/channel/context.h",
         "src/core/lib/channel/context.h",
         "src/core/lib/channel/handshaker.h",
         "src/core/lib/channel/handshaker.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",
@@ -987,7 +990,6 @@ grpc_cc_library(
         "grpc_client_authority_filter",
         "grpc_client_authority_filter",
         "grpc_lb_policy_pick_first",
         "grpc_lb_policy_pick_first",
         "grpc_lb_policy_round_robin",
         "grpc_lb_policy_round_robin",
-        "grpc_server_load_reporting",
         "grpc_max_age_filter",
         "grpc_max_age_filter",
         "grpc_message_size_filter",
         "grpc_message_size_filter",
         "grpc_resolver_dns_ares",
         "grpc_resolver_dns_ares",
@@ -1027,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",
@@ -1049,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",
@@ -1198,6 +1202,8 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
     ],
     ],
     hdrs = [
     hdrs = [
         "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
@@ -1206,6 +1212,8 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
     ],
     ],
     external_deps = [
     external_deps = [
         "nanopb",
         "nanopb",
@@ -1227,6 +1235,8 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
     ],
     ],
     hdrs = [
     hdrs = [
         "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
@@ -1235,6 +1245,8 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
         "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
     ],
     ],
     external_deps = [
     external_deps = [
         "nanopb",
         "nanopb",
@@ -1287,18 +1299,22 @@ grpc_cc_library(
 )
 )
 
 
 grpc_cc_library(
 grpc_cc_library(
-    name = "grpc_server_load_reporting",
+    name = "lb_server_load_reporting_filter",
     srcs = [
     srcs = [
         "src/core/ext/filters/load_reporting/server_load_reporting_filter.cc",
         "src/core/ext/filters/load_reporting/server_load_reporting_filter.cc",
-        "src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc",
     ],
     ],
     hdrs = [
     hdrs = [
+        "src/core/ext/filters/load_reporting/registered_opencensus_objects.h",
         "src/core/ext/filters/load_reporting/server_load_reporting_filter.h",
         "src/core/ext/filters/load_reporting/server_load_reporting_filter.h",
-        "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h",
+        "src/cpp/server/load_reporter/constants.h",
+    ],
+    external_deps = [
+        "opencensus-stats",
     ],
     ],
     language = "c++",
     language = "c++",
     deps = [
     deps = [
-        "grpc_base",
+        "grpc++_base",
+        "grpc_secure",
     ],
     ],
 )
 )
 
 
@@ -1308,6 +1324,7 @@ grpc_cc_library(
         "src/cpp/server/load_reporter/load_data_store.cc",
         "src/cpp/server/load_reporter/load_data_store.cc",
     ],
     ],
     hdrs = [
     hdrs = [
+        "src/cpp/server/load_reporter/constants.h",
         "src/cpp/server/load_reporter/load_data_store.h",
         "src/cpp/server/load_reporter/load_data_store.h",
     ],
     ],
     language = "c++",
     language = "c++",
@@ -1316,6 +1333,43 @@ grpc_cc_library(
     ],
     ],
 )
 )
 
 
+grpc_cc_library(
+    name = "lb_get_cpu_stats",
+    srcs = [
+        "src/cpp/server/load_reporter/get_cpu_stats_linux.cc",
+        "src/cpp/server/load_reporter/get_cpu_stats_macos.cc",
+        "src/cpp/server/load_reporter/get_cpu_stats_unsupported.cc",
+        "src/cpp/server/load_reporter/get_cpu_stats_windows.cc",
+    ],
+    hdrs = [
+        "src/cpp/server/load_reporter/get_cpu_stats.h",
+    ],
+    language = "c++",
+    deps = [
+        "grpc++",
+    ],
+)
+
+grpc_cc_library(
+    name = "lb_load_reporter",
+    srcs = [
+        "src/cpp/server/load_reporter/load_reporter.cc",
+    ],
+    hdrs = [
+        "src/cpp/server/load_reporter/constants.h",
+        "src/cpp/server/load_reporter/load_reporter.h",
+    ],
+    external_deps = [
+        "opencensus-stats",
+    ],
+    language = "c++",
+    deps = [
+        "lb_get_cpu_stats",
+        "lb_load_data_store",
+        "//src/proto/grpc/lb/v1:load_reporter_proto",
+    ],
+)
+
 grpc_cc_library(
 grpc_cc_library(
     name = "grpc_resolver_dns_native",
     name = "grpc_resolver_dns_native",
     srcs = [
     srcs = [
@@ -1392,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",
@@ -1418,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",
@@ -1739,11 +1797,11 @@ grpc_cc_library(
         "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h",
         "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h",
         "src/core/tsi/alts/handshaker/transport_security_common_api.h",
         "src/core/tsi/alts/handshaker/transport_security_common_api.h",
     ],
     ],
-    public_hdrs = GRPC_SECURE_PUBLIC_HDRS, 
     external_deps = [
     external_deps = [
         "nanopb",
         "nanopb",
     ],
     ],
     language = "c++",
     language = "c++",
+    public_hdrs = GRPC_SECURE_PUBLIC_HDRS,
     deps = [
     deps = [
         "alts_proto",
         "alts_proto",
         "gpr",
         "gpr",
@@ -1760,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",
@@ -1773,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",
@@ -1852,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",
@@ -1992,33 +2053,33 @@ grpc_cc_library(
 grpc_cc_library(
 grpc_cc_library(
     name = "grpc_opencensus_plugin",
     name = "grpc_opencensus_plugin",
     srcs = [
     srcs = [
-        "src/cpp/ext/filters/census/client_filter.cc",
-        "src/cpp/ext/filters/census/server_filter.cc",
         "src/cpp/ext/filters/census/channel_filter.cc",
         "src/cpp/ext/filters/census/channel_filter.cc",
+        "src/cpp/ext/filters/census/client_filter.cc",
         "src/cpp/ext/filters/census/context.cc",
         "src/cpp/ext/filters/census/context.cc",
         "src/cpp/ext/filters/census/grpc_context.cc",
         "src/cpp/ext/filters/census/grpc_context.cc",
         "src/cpp/ext/filters/census/grpc_plugin.cc",
         "src/cpp/ext/filters/census/grpc_plugin.cc",
         "src/cpp/ext/filters/census/measures.cc",
         "src/cpp/ext/filters/census/measures.cc",
         "src/cpp/ext/filters/census/rpc_encoding.cc",
         "src/cpp/ext/filters/census/rpc_encoding.cc",
+        "src/cpp/ext/filters/census/server_filter.cc",
         "src/cpp/ext/filters/census/views.cc",
         "src/cpp/ext/filters/census/views.cc",
     ],
     ],
     hdrs = [
     hdrs = [
         "include/grpcpp/opencensus.h",
         "include/grpcpp/opencensus.h",
-        "src/cpp/ext/filters/census/client_filter.h",
-        "src/cpp/ext/filters/census/server_filter.h",
         "src/cpp/ext/filters/census/channel_filter.h",
         "src/cpp/ext/filters/census/channel_filter.h",
+        "src/cpp/ext/filters/census/client_filter.h",
         "src/cpp/ext/filters/census/context.h",
         "src/cpp/ext/filters/census/context.h",
         "src/cpp/ext/filters/census/grpc_plugin.h",
         "src/cpp/ext/filters/census/grpc_plugin.h",
         "src/cpp/ext/filters/census/measures.h",
         "src/cpp/ext/filters/census/measures.h",
         "src/cpp/ext/filters/census/rpc_encoding.h",
         "src/cpp/ext/filters/census/rpc_encoding.h",
+        "src/cpp/ext/filters/census/server_filter.h",
     ],
     ],
-    language = "c++",
     external_deps = [
     external_deps = [
         "absl-base",
         "absl-base",
         "absl-time",
         "absl-time",
         "opencensus-trace",
         "opencensus-trace",
         "opencensus-stats",
         "opencensus-stats",
     ],
     ],
+    language = "c++",
     deps = [
     deps = [
         ":census",
         ":census",
         ":grpc++",
         ":grpc++",

+ 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).

+ 164 - 44
CMakeLists.txt

@@ -246,6 +246,9 @@ endif()
 add_dependencies(buildtests_c endpoint_pair_test)
 add_dependencies(buildtests_c endpoint_pair_test)
 add_dependencies(buildtests_c error_test)
 add_dependencies(buildtests_c error_test)
 if(_gRPC_PLATFORM_LINUX)
 if(_gRPC_PLATFORM_LINUX)
+add_dependencies(buildtests_c ev_epollex_linux_test)
+endif()
+if(_gRPC_PLATFORM_LINUX)
 add_dependencies(buildtests_c ev_epollsig_linux_test)
 add_dependencies(buildtests_c ev_epollsig_linux_test)
 endif()
 endif()
 add_dependencies(buildtests_c fake_resolver_test)
 add_dependencies(buildtests_c fake_resolver_test)
@@ -430,7 +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)
-add_dependencies(buildtests_c h2_load_reporting_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)
@@ -454,7 +459,6 @@ endif()
 add_dependencies(buildtests_c h2_full+trace_nosec_test)
 add_dependencies(buildtests_c h2_full+trace_nosec_test)
 add_dependencies(buildtests_c h2_full+workarounds_nosec_test)
 add_dependencies(buildtests_c h2_full+workarounds_nosec_test)
 add_dependencies(buildtests_c h2_http_proxy_nosec_test)
 add_dependencies(buildtests_c h2_http_proxy_nosec_test)
-add_dependencies(buildtests_c h2_load_reporting_nosec_test)
 add_dependencies(buildtests_c h2_proxy_nosec_test)
 add_dependencies(buildtests_c h2_proxy_nosec_test)
 add_dependencies(buildtests_c h2_sockpair_nosec_test)
 add_dependencies(buildtests_c h2_sockpair_nosec_test)
 add_dependencies(buildtests_c h2_sockpair+trace_nosec_test)
 add_dependencies(buildtests_c h2_sockpair+trace_nosec_test)
@@ -504,6 +508,9 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_call_create)
 add_dependencies(buildtests_cxx bm_call_create)
 endif()
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_channel)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_chttp2_hpack)
 add_dependencies(buildtests_cxx bm_chttp2_hpack)
 endif()
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -612,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)
@@ -866,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
@@ -1121,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
@@ -1176,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
@@ -1197,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
@@ -1213,6 +1226,8 @@ add_library(grpc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
   src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
   src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
   src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
   src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -1224,8 +1239,6 @@ add_library(grpc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
   src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
   src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
   src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
   src/cpp/ext/filters/census/grpc_context.cc
   src/cpp/ext/filters/census/grpc_context.cc
   src/core/ext/filters/max_age/max_age_filter.cc
   src/core/ext/filters/max_age/max_age_filter.cc
   src/core/ext/filters/message_size/message_size_filter.cc
   src/core/ext/filters/message_size/message_size_filter.cc
@@ -1286,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
@@ -1510,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
@@ -1542,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
@@ -1596,13 +1613,12 @@ 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
   src/core/tsi/ssl_transport_security.cc
   src/core/tsi/ssl_transport_security.cc
   src/core/tsi/transport_security_grpc.cc
   src/core/tsi/transport_security_grpc.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
   src/core/plugin_registry/grpc_cronet_plugin_registry.cc
   src/core/plugin_registry/grpc_cronet_plugin_registry.cc
 )
 )
 
 
@@ -1657,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
@@ -1866,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
@@ -1971,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
@@ -2172,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
@@ -2277,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
@@ -2491,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
@@ -2520,13 +2542,13 @@ add_library(grpc_unsecure
   src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
   src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
   src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
   src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
   src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
   src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
-  src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
   src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
   src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   third_party/nanopb/pb_common.c
   third_party/nanopb/pb_common.c
   third_party/nanopb/pb_decode.c
   third_party/nanopb/pb_decode.c
@@ -2592,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
@@ -2909,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
@@ -2965,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
@@ -3295,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
@@ -3473,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
@@ -3529,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
@@ -3938,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
@@ -3983,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
@@ -4114,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
@@ -4159,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
@@ -4373,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
@@ -4429,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
@@ -5298,7 +5332,6 @@ add_library(end2end_tests
   test/core/end2end/tests/invoke_large_request.cc
   test/core/end2end/tests/invoke_large_request.cc
   test/core/end2end/tests/keepalive_timeout.cc
   test/core/end2end/tests/keepalive_timeout.cc
   test/core/end2end/tests/large_metadata.cc
   test/core/end2end/tests/large_metadata.cc
-  test/core/end2end/tests/load_reporting_hook.cc
   test/core/end2end/tests/max_concurrent_streams.cc
   test/core/end2end/tests/max_concurrent_streams.cc
   test/core/end2end/tests/max_connection_age.cc
   test/core/end2end/tests/max_connection_age.cc
   test/core/end2end/tests/max_connection_idle.cc
   test/core/end2end/tests/max_connection_idle.cc
@@ -5419,7 +5452,6 @@ add_library(end2end_nosec_tests
   test/core/end2end/tests/invoke_large_request.cc
   test/core/end2end/tests/invoke_large_request.cc
   test/core/end2end/tests/keepalive_timeout.cc
   test/core/end2end/tests/keepalive_timeout.cc
   test/core/end2end/tests/large_metadata.cc
   test/core/end2end/tests/large_metadata.cc
-  test/core/end2end/tests/load_reporting_hook.cc
   test/core/end2end/tests/max_concurrent_streams.cc
   test/core/end2end/tests/max_concurrent_streams.cc
   test/core/end2end/tests/max_connection_age.cc
   test/core/end2end/tests/max_connection_age.cc
   test/core/end2end/tests/max_connection_idle.cc
   test/core/end2end/tests/max_connection_idle.cc
@@ -6194,6 +6226,37 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX)
 if(_gRPC_PLATFORM_LINUX)
 
 
+add_executable(ev_epollex_linux_test
+  test/core/iomgr/ev_epollex_linux_test.cc
+)
+
+
+target_include_directories(ev_epollex_linux_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(ev_epollex_linux_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX)
+
 add_executable(ev_epollsig_linux_test
 add_executable(ev_epollsig_linux_test
   test/core/iomgr/ev_epollsig_linux_test.cc
   test/core/iomgr/ev_epollsig_linux_test.cc
 )
 )
@@ -10027,6 +10090,51 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 
+add_executable(bm_channel
+  test/cpp/microbenchmarks/bm_channel.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(bm_channel
+  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(bm_channel
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  ${_gRPC_BENCHMARK_LIBRARIES}
+  grpc++_test_util_unsecure
+  grpc_test_util_unsecure
+  grpc++_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
 add_executable(bm_chttp2_hpack
 add_executable(bm_chttp2_hpack
   test/cpp/microbenchmarks/bm_chttp2_hpack.cc
   test/cpp/microbenchmarks/bm_chttp2_hpack.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googletest/src/gtest-all.cc
@@ -13181,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
@@ -15184,13 +15332,14 @@ target_link_libraries(h2_http_proxy_test
 
 
 endif (gRPC_BUILD_TESTS)
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 
-add_executable(h2_load_reporting_test
-  test/core/end2end/fixtures/h2_load_reporting.cc
+add_executable(h2_local_test
+  test/core/end2end/fixtures/h2_local.cc
 )
 )
 
 
 
 
-target_include_directories(h2_load_reporting_test
+target_include_directories(h2_local_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
   PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@@ -15203,7 +15352,7 @@ target_include_directories(h2_load_reporting_test
   PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
   PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
 )
 )
 
 
-target_link_libraries(h2_load_reporting_test
+target_link_libraries(h2_local_test
   ${_gRPC_ALLTARGETS_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   end2end_tests
   end2end_tests
   grpc_test_util
   grpc_test_util
@@ -15212,6 +15361,7 @@ target_link_libraries(h2_load_reporting_test
   gpr
   gpr
 )
 )
 
 
+endif()
 endif (gRPC_BUILD_TESTS)
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
 
@@ -15731,36 +15881,6 @@ target_link_libraries(h2_http_proxy_nosec_test
 endif (gRPC_BUILD_TESTS)
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
 
-add_executable(h2_load_reporting_nosec_test
-  test/core/end2end/fixtures/h2_load_reporting.cc
-)
-
-
-target_include_directories(h2_load_reporting_nosec_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_load_reporting_nosec_test
-  ${_gRPC_ALLTARGETS_LIBRARIES}
-  end2end_nosec_tests
-  grpc_test_util_unsecure
-  grpc_unsecure
-  gpr_test_util
-  gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
 add_executable(h2_proxy_nosec_test
 add_executable(h2_proxy_nosec_test
   test/core/end2end/fixtures/h2_proxy.cc
   test/core/end2end/fixtures/h2_proxy.cc
 )
 )

+ 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
 
 

+ 247 - 42
Makefile

@@ -300,6 +300,12 @@ else
 TMPOUT = `mktemp /tmp/test-out-XXXXXX`
 TMPOUT = `mktemp /tmp/test-out-XXXXXX`
 endif
 endif
 
 
+CHECK_NO_CXX14_COMPAT_WORKS_CMD = $(CC) -std=c++11 -Werror -Wno-c++14-compat -o $(TMPOUT) -c test/build/no-c++14-compat.cc
+HAS_WORKING_NO_CXX14_COMPAT = $(shell $(CHECK_NO_CXX14_COMPAT_WORKS_CMD) 2> /dev/null && echo true || echo false)
+ifeq ($(HAS_WORKING_NO_CXX14_COMPAT),true)
+W_NO_CXX14_COMPAT=-Wno-c++14-compat
+endif
+
 CHECK_SHADOW_WORKS_CMD = $(CC) -std=c99 -Werror -Wshadow -o $(TMPOUT) -c test/build/shadow.c
 CHECK_SHADOW_WORKS_CMD = $(CC) -std=c99 -Werror -Wshadow -o $(TMPOUT) -c test/build/shadow.c
 HAS_WORKING_SHADOW = $(shell $(CHECK_SHADOW_WORKS_CMD) 2> /dev/null && echo true || echo false)
 HAS_WORKING_SHADOW = $(shell $(CHECK_SHADOW_WORKS_CMD) 2> /dev/null && echo true || echo false)
 ifeq ($(HAS_WORKING_SHADOW),true)
 ifeq ($(HAS_WORKING_SHADOW),true)
@@ -318,6 +324,18 @@ ifeq ($(HAS_WORKING_NO_SHIFT_NEGATIVE_VALUE),true)
 W_NO_SHIFT_NEGATIVE_VALUE=-Wno-shift-negative-value
 W_NO_SHIFT_NEGATIVE_VALUE=-Wno-shift-negative-value
 NO_W_NO_SHIFT_NEGATIVE_VALUE=-Wshift-negative-value
 NO_W_NO_SHIFT_NEGATIVE_VALUE=-Wshift-negative-value
 endif
 endif
+CHECK_NO_UNUSED_BUT_SET_VARIABLE_WORKS_CMD = $(CC) -std=c99 -Werror -Wno-unused-but-set-variable -o $(TMPOUT) -c test/build/no-unused-but-set-variable.c
+HAS_WORKING_NO_UNUSED_BUT_SET_VARIABLE = $(shell $(CHECK_NO_UNUSED_BUT_SET_VARIABLE_WORKS_CMD) 2> /dev/null && echo true || echo false)
+ifeq ($(HAS_WORKING_NO_UNUSED_BUT_SET_VARIABLE),true)
+W_NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
+NO_W_NO_UNUSED_BUT_SET_VARIABLE=-Wunused-but-set-variable
+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
@@ -968,6 +986,7 @@ dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
 dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
 dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
 endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
 endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
 error_test: $(BINDIR)/$(CONFIG)/error_test
 error_test: $(BINDIR)/$(CONFIG)/error_test
+ev_epollex_linux_test: $(BINDIR)/$(CONFIG)/ev_epollex_linux_test
 ev_epollsig_linux_test: $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test
 ev_epollsig_linux_test: $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test
 fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test
 fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test
 fake_transport_security_test: $(BINDIR)/$(CONFIG)/fake_transport_security_test
 fake_transport_security_test: $(BINDIR)/$(CONFIG)/fake_transport_security_test
@@ -1105,6 +1124,7 @@ backoff_test: $(BINDIR)/$(CONFIG)/backoff_test
 bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
 bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
 bm_arena: $(BINDIR)/$(CONFIG)/bm_arena
 bm_arena: $(BINDIR)/$(CONFIG)/bm_arena
 bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create
 bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create
+bm_channel: $(BINDIR)/$(CONFIG)/bm_channel
 bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
 bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
 bm_chttp2_transport: $(BINDIR)/$(CONFIG)/bm_chttp2_transport
 bm_chttp2_transport: $(BINDIR)/$(CONFIG)/bm_chttp2_transport
 bm_closure: $(BINDIR)/$(CONFIG)/bm_closure
 bm_closure: $(BINDIR)/$(CONFIG)/bm_closure
@@ -1179,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
@@ -1284,7 +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_load_reporting_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_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
@@ -1302,7 +1323,6 @@ h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test
 h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
 h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
 h2_full+workarounds_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test
 h2_full+workarounds_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test
 h2_http_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test
 h2_http_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test
-h2_load_reporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test
 h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test
 h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test
 h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test
 h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test
 h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test
 h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test
@@ -1372,7 +1392,7 @@ plugins: $(PROTOC_PLUGINS)
 
 
 privatelibs: privatelibs_c privatelibs_cxx
 privatelibs: privatelibs_c privatelibs_cxx
 
 
-privatelibs_c:  $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
+privatelibs_c:  $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
 pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
 pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
 
 
 pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc
 pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc
@@ -1414,6 +1434,7 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/dualstack_socket_test \
   $(BINDIR)/$(CONFIG)/dualstack_socket_test \
   $(BINDIR)/$(CONFIG)/endpoint_pair_test \
   $(BINDIR)/$(CONFIG)/endpoint_pair_test \
   $(BINDIR)/$(CONFIG)/error_test \
   $(BINDIR)/$(CONFIG)/error_test \
+  $(BINDIR)/$(CONFIG)/ev_epollex_linux_test \
   $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test \
   $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test \
   $(BINDIR)/$(CONFIG)/fake_resolver_test \
   $(BINDIR)/$(CONFIG)/fake_resolver_test \
   $(BINDIR)/$(CONFIG)/fake_transport_security_test \
   $(BINDIR)/$(CONFIG)/fake_transport_security_test \
@@ -1539,7 +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_load_reporting_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 \
@@ -1557,7 +1578,6 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test \
-  $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \
@@ -1602,6 +1622,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/bdp_estimator_test \
   $(BINDIR)/$(CONFIG)/bdp_estimator_test \
   $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_call_create \
   $(BINDIR)/$(CONFIG)/bm_call_create \
+  $(BINDIR)/$(CONFIG)/bm_channel \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
   $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_closure \
   $(BINDIR)/$(CONFIG)/bm_closure \
@@ -1669,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 \
@@ -1778,6 +1800,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/bdp_estimator_test \
   $(BINDIR)/$(CONFIG)/bdp_estimator_test \
   $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_call_create \
   $(BINDIR)/$(CONFIG)/bm_call_create \
+  $(BINDIR)/$(CONFIG)/bm_channel \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
   $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_closure \
   $(BINDIR)/$(CONFIG)/bm_closure \
@@ -1845,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 \
@@ -1935,6 +1959,8 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
 	$(E) "[RUN]     Testing error_test"
 	$(E) "[RUN]     Testing error_test"
 	$(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 )
+	$(E) "[RUN]     Testing ev_epollex_linux_test"
+	$(Q) $(BINDIR)/$(CONFIG)/ev_epollex_linux_test || ( echo test ev_epollex_linux_test failed ; exit 1 )
 	$(E) "[RUN]     Testing ev_epollsig_linux_test"
 	$(E) "[RUN]     Testing ev_epollsig_linux_test"
 	$(Q) $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test || ( echo test ev_epollsig_linux_test failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test || ( echo test ev_epollsig_linux_test failed ; exit 1 )
 	$(E) "[RUN]     Testing fake_resolver_test"
 	$(E) "[RUN]     Testing fake_resolver_test"
@@ -2199,6 +2225,8 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_call_create"
 	$(E) "[RUN]     Testing bm_call_create"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_channel"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_channel || ( echo test bm_channel failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_chttp2_hpack"
 	$(E) "[RUN]     Testing bm_chttp2_hpack"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_chttp2_hpack || ( echo test bm_chttp2_hpack failed ; exit 1 )
 	$(Q) $(BINDIR)/$(CONFIG)/bm_chttp2_hpack || ( echo test bm_chttp2_hpack failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_chttp2_transport"
 	$(E) "[RUN]     Testing bm_chttp2_transport"
@@ -2311,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"
@@ -2854,6 +2884,11 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 
+$(OBJDIR)/$(CONFIG)/%.o : %.cpp
+	$(E) "[CXX]     Compiling $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+
 install: install_c install_cxx install-plugins install-certs
 install: install_c install_cxx install-plugins install-certs
 
 
 install_c: install-headers_c install-static_c install-shared_c
 install_c: install-headers_c install-static_c install-shared_c
@@ -3168,6 +3203,50 @@ endif
 endif
 endif
 
 
 
 
+LIBCXXABI_SRC = \
+    third_party/libcxxabi/src/abort_message.cpp \
+    third_party/libcxxabi/src/cxa_aux_runtime.cpp \
+    third_party/libcxxabi/src/cxa_default_handlers.cpp \
+    third_party/libcxxabi/src/cxa_demangle.cpp \
+    third_party/libcxxabi/src/cxa_exception_storage.cpp \
+    third_party/libcxxabi/src/cxa_guard.cpp \
+    third_party/libcxxabi/src/cxa_handlers.cpp \
+    third_party/libcxxabi/src/cxa_noexception.cpp \
+    third_party/libcxxabi/src/cxa_thread_atexit.cpp \
+    third_party/libcxxabi/src/cxa_unexpected.cpp \
+    third_party/libcxxabi/src/cxa_vector.cpp \
+    third_party/libcxxabi/src/cxa_virtual.cpp \
+    third_party/libcxxabi/src/fallback_malloc.cpp \
+    third_party/libcxxabi/src/private_typeinfo.cpp \
+    third_party/libcxxabi/src/stdlib_exception.cpp \
+    third_party/libcxxabi/src/stdlib_new_delete.cpp \
+    third_party/libcxxabi/src/stdlib_stdexcept.cpp \
+    third_party/libcxxabi/src/stdlib_typeinfo.cpp \
+
+PUBLIC_HEADERS_C += \
+
+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) $(W_NO_MAYBE_UNINITIALIZED) -fvisibility=hidden
+$(LIBCXXABI_OBJS): CXXFLAGS += $(W_NO_CXX14_COMPAT)
+
+$(LIBDIR)/$(CONFIG)/libcxxabi.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP)  $(LIBCXXABI_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libcxxabi.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBCXXABI_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libcxxabi.a
+endif
+
+
+
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBCXXABI_OBJS:.o=.dep)
+endif
+
+
 LIBGPR_SRC = \
 LIBGPR_SRC = \
     src/core/lib/gpr/alloc.cc \
     src/core/lib/gpr/alloc.cc \
     src/core/lib/gpr/arena.cc \
     src/core/lib/gpr/arena.cc \
@@ -3234,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 \
@@ -3496,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 \
@@ -3551,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 \
@@ -3572,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 \
@@ -3588,6 +3672,8 @@ LIBGRPC_SRC = \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
     src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
@@ -3599,8 +3685,6 @@ LIBGRPC_SRC = \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
     src/cpp/ext/filters/census/grpc_context.cc \
     src/cpp/ext/filters/census/grpc_context.cc \
     src/core/ext/filters/max_age/max_age_filter.cc \
     src/core/ext/filters/max_age/max_age_filter.cc \
     src/core/ext/filters/message_size/message_size_filter.cc \
     src/core/ext/filters/message_size/message_size_filter.cc \
@@ -3625,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 \
@@ -3884,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 \
@@ -3916,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 \
@@ -3970,13 +4058,12 @@ 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 \
     src/core/tsi/ssl_transport_security.cc \
     src/core/tsi/ssl_transport_security.cc \
     src/core/tsi/transport_security_grpc.cc \
     src/core/tsi/transport_security_grpc.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
     src/core/plugin_registry/grpc_cronet_plugin_registry.cc \
     src/core/plugin_registry/grpc_cronet_plugin_registry.cc \
 
 
 PUBLIC_HEADERS_C += \
 PUBLIC_HEADERS_C += \
@@ -3995,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 \
@@ -4238,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 \
@@ -4310,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 \
@@ -4535,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 \
@@ -4607,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 \
@@ -4832,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 \
@@ -4861,13 +4954,13 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_decode.c \
     third_party/nanopb/pb_decode.c \
@@ -4898,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 \
@@ -5194,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 \
@@ -5250,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 \
@@ -5624,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 \
@@ -5765,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 \
@@ -5821,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 \
@@ -6210,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 \
@@ -6255,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 \
@@ -6362,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 \
@@ -6407,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 \
@@ -6625,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 \
@@ -6681,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 \
@@ -9948,7 +10053,6 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/invoke_large_request.cc \
     test/core/end2end/tests/invoke_large_request.cc \
     test/core/end2end/tests/keepalive_timeout.cc \
     test/core/end2end/tests/keepalive_timeout.cc \
     test/core/end2end/tests/large_metadata.cc \
     test/core/end2end/tests/large_metadata.cc \
-    test/core/end2end/tests/load_reporting_hook.cc \
     test/core/end2end/tests/max_concurrent_streams.cc \
     test/core/end2end/tests/max_concurrent_streams.cc \
     test/core/end2end/tests/max_connection_age.cc \
     test/core/end2end/tests/max_connection_age.cc \
     test/core/end2end/tests/max_connection_idle.cc \
     test/core/end2end/tests/max_connection_idle.cc \
@@ -10066,7 +10170,6 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/invoke_large_request.cc \
     test/core/end2end/tests/invoke_large_request.cc \
     test/core/end2end/tests/keepalive_timeout.cc \
     test/core/end2end/tests/keepalive_timeout.cc \
     test/core/end2end/tests/large_metadata.cc \
     test/core/end2end/tests/large_metadata.cc \
-    test/core/end2end/tests/load_reporting_hook.cc \
     test/core/end2end/tests/max_concurrent_streams.cc \
     test/core/end2end/tests/max_concurrent_streams.cc \
     test/core/end2end/tests/max_connection_age.cc \
     test/core/end2end/tests/max_connection_age.cc \
     test/core/end2end/tests/max_connection_idle.cc \
     test/core/end2end/tests/max_connection_idle.cc \
@@ -11006,6 +11109,38 @@ endif
 endif
 endif
 
 
 
 
+EV_EPOLLEX_LINUX_TEST_SRC = \
+    test/core/iomgr/ev_epollex_linux_test.cc \
+
+EV_EPOLLEX_LINUX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(EV_EPOLLEX_LINUX_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(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) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(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)/ev_epollex_linux_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 EV_EPOLLSIG_LINUX_TEST_SRC = \
 EV_EPOLLSIG_LINUX_TEST_SRC = \
     test/core/iomgr/ev_epollsig_linux_test.cc \
     test/core/iomgr/ev_epollsig_linux_test.cc \
 
 
@@ -15636,6 +15771,50 @@ endif
 endif
 endif
 
 
 
 
+BM_CHANNEL_SRC = \
+    test/cpp/microbenchmarks/bm_channel.cc \
+
+BM_CHANNEL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CHANNEL_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/bm_channel: 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)/bm_channel: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_channel
+
+endif
+
+endif
+
+$(BM_CHANNEL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+
+deps_bm_channel: $(BM_CHANNEL_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(BM_CHANNEL_OBJS:.o=.dep)
+endif
+endif
+
+
 BM_CHTTP2_HPACK_SRC = \
 BM_CHTTP2_HPACK_SRC = \
     test/cpp/microbenchmarks/bm_chttp2_hpack.cc \
     test/cpp/microbenchmarks/bm_chttp2_hpack.cc \
 
 
@@ -18798,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 \
@@ -22812,34 +23034,34 @@ endif
 endif
 endif
 
 
 
 
-H2_LOAD_REPORTING_TEST_SRC = \
-    test/core/end2end/fixtures/h2_load_reporting.cc \
+H2_LOCAL_TEST_SRC = \
+    test/core/end2end/fixtures/h2_local.cc \
 
 
-H2_LOAD_REPORTING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOAD_REPORTING_TEST_SRC))))
+H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 ifeq ($(NO_SECURE),true)
 
 
 # You can't build secure targets if you don't have OpenSSL.
 # You can't build secure targets if you don't have OpenSSL.
 
 
-$(BINDIR)/$(CONFIG)/h2_load_reporting_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error
 
 
 else
 else
 
 
 
 
 
 
-$(BINDIR)/$(CONFIG)/h2_load_reporting_test: $(H2_LOAD_REPORTING_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
+$(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 $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_LOAD_REPORTING_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_load_reporting_test
+	$(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
 endif
 
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_load_reporting.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
+$(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_load_reporting_test: $(H2_LOAD_REPORTING_TEST_OBJS:.o=.dep)
+deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep)
 
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
 ifneq ($(NO_DEPS),true)
--include $(H2_LOAD_REPORTING_TEST_OBJS:.o=.dep)
+-include $(H2_LOCAL_TEST_OBJS:.o=.dep)
 endif
 endif
 endif
 endif
 
 
@@ -23292,26 +23514,6 @@ ifneq ($(NO_DEPS),true)
 endif
 endif
 
 
 
 
-H2_LOAD_REPORTING_NOSEC_TEST_SRC = \
-    test/core/end2end/fixtures/h2_load_reporting.cc \
-
-H2_LOAD_REPORTING_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOAD_REPORTING_NOSEC_TEST_SRC))))
-
-
-$(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test: $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test
-
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_load_reporting.o:  $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_h2_load_reporting_nosec_test: $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS:.o=.dep)
-endif
-
-
 H2_PROXY_NOSEC_TEST_SRC = \
 H2_PROXY_NOSEC_TEST_SRC = \
     test/core/end2end/fixtures/h2_proxy.cc \
     test/core/end2end/fixtures/h2_proxy.cc \
 
 
@@ -24257,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)
@@ -24298,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.

+ 100 - 13
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
@@ -646,6 +650,8 @@ filegroups:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
   src:
   src:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@@ -653,6 +659,8 @@ filegroups:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   plugin: grpc_lb_policy_grpclb
   plugin: grpc_lb_policy_grpclb
   uses:
   uses:
@@ -667,6 +675,8 @@ filegroups:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
   src:
   src:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@@ -674,6 +684,8 @@ filegroups:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   plugin: grpc_lb_policy_grpclb
   plugin: grpc_lb_policy_grpclb
   uses:
   uses:
@@ -772,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
@@ -797,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
@@ -823,16 +839,6 @@ filegroups:
   - src/core/ext/filters/workarounds/workaround_utils.cc
   - src/core/ext/filters/workarounds/workaround_utils.cc
   uses:
   uses:
   - grpc_base
   - grpc_base
-- name: grpc_server_load_reporting
-  headers:
-  - src/core/ext/filters/load_reporting/server_load_reporting_filter.h
-  - src/core/ext/filters/load_reporting/server_load_reporting_plugin.h
-  src:
-  - src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
-  - src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
-  plugin: grpc_server_load_reporting_plugin
-  uses:
-  - grpc_base
 - name: grpc_test_util_base
 - name: grpc_test_util_base
   build: test
   build: test
   headers:
   headers:
@@ -1071,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
@@ -1079,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
@@ -1140,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
@@ -1374,6 +1383,32 @@ libs:
   deps:
   deps:
   - grpc
   - grpc
   secure: true
   secure: true
+- name: cxxabi
+  build: private
+  language: c
+  src:
+  - third_party/libcxxabi/src/abort_message.cpp
+  - third_party/libcxxabi/src/cxa_aux_runtime.cpp
+  - third_party/libcxxabi/src/cxa_default_handlers.cpp
+  - third_party/libcxxabi/src/cxa_demangle.cpp
+  - third_party/libcxxabi/src/cxa_exception_storage.cpp
+  - third_party/libcxxabi/src/cxa_guard.cpp
+  - third_party/libcxxabi/src/cxa_handlers.cpp
+  - third_party/libcxxabi/src/cxa_noexception.cpp
+  - third_party/libcxxabi/src/cxa_thread_atexit.cpp
+  - third_party/libcxxabi/src/cxa_unexpected.cpp
+  - third_party/libcxxabi/src/cxa_vector.cpp
+  - third_party/libcxxabi/src/cxa_virtual.cpp
+  - third_party/libcxxabi/src/fallback_malloc.cpp
+  - third_party/libcxxabi/src/private_typeinfo.cpp
+  - third_party/libcxxabi/src/stdlib_exception.cpp
+  - third_party/libcxxabi/src/stdlib_new_delete.cpp
+  - third_party/libcxxabi/src/stdlib_stdexcept.cpp
+  - third_party/libcxxabi/src/stdlib_typeinfo.cpp
+  build_system:
+  - Makefile
+  defaults: cxxabi
+  secure: false
 - name: gpr
 - name: gpr
   build: all
   build: all
   language: c
   language: c
@@ -1414,7 +1449,6 @@ libs:
   - grpc_resolver_dns_native
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
   - grpc_resolver_sockaddr
   - grpc_resolver_fake
   - grpc_resolver_fake
-  - grpc_server_load_reporting
   - grpc_secure
   - grpc_secure
   - census
   - census
   - grpc_max_age_filter
   - grpc_max_age_filter
@@ -1441,7 +1475,6 @@ libs:
   - grpc_base
   - grpc_base
   - grpc_transport_cronet_client_secure
   - grpc_transport_cronet_client_secure
   - grpc_transport_chttp2_client_secure
   - grpc_transport_chttp2_client_secure
-  - grpc_server_load_reporting
   generate_plugin_registry: true
   generate_plugin_registry: true
   platforms:
   platforms:
   - linux
   - linux
@@ -1515,7 +1548,6 @@ libs:
   - grpc_resolver_dns_native
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
   - grpc_resolver_sockaddr
   - grpc_resolver_fake
   - grpc_resolver_fake
-  - grpc_server_load_reporting
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
   - grpc_lb_policy_round_robin
@@ -2270,6 +2302,21 @@ targets:
   - gpr_test_util
   - gpr_test_util
   - gpr
   - gpr
   uses_polling: false
   uses_polling: false
+- name: ev_epollex_linux_test
+  cpu_cost: 3
+  build: test
+  language: c
+  src:
+  - test/core/iomgr/ev_epollex_linux_test.cc
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  exclude_iomgrs:
+  - uv
+  platforms:
+  - linux
 - name: ev_epollsig_linux_test
 - name: ev_epollsig_linux_test
   cpu_cost: 3
   cpu_cost: 3
   build: test
   build: test
@@ -3899,6 +3946,28 @@ targets:
   - linux
   - linux
   - posix
   - posix
   uses_polling: false
   uses_polling: false
+- name: bm_channel
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_channel.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util_unsecure
+  - grpc_test_util_unsecure
+  - grpc++_unsecure
+  - grpc_unsecure
+  - gpr_test_util
+  - gpr
+  - grpc++_test_config
+  benchmark: true
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
+  uses_polling: false
 - name: bm_chttp2_hpack
 - name: bm_chttp2_hpack
   build: test
   build: test
   language: c++
   language: c++
@@ -5038,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
@@ -5633,6 +5715,11 @@ defaults:
     CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
     CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
       -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
       -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
     CXXFLAGS: -fno-rtti -fno-exceptions
     CXXFLAGS: -fno-rtti -fno-exceptions
+  cxxabi:
+    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
+    CXXFLAGS: $(W_NO_CXX14_COMPAT)
   global:
   global:
     COREFLAGS: -fno-rtti -fno-exceptions
     COREFLAGS: -fno-rtti -fno-exceptions
     CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
     CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1

+ 8 - 3
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 \
@@ -367,6 +371,8 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
     src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
@@ -378,8 +384,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
-    src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
     src/cpp/ext/filters/census/grpc_context.cc \
     src/cpp/ext/filters/census/grpc_context.cc \
     src/core/ext/filters/max_age/max_age_filter.cc \
     src/core/ext/filters/max_age/max_age_filter.cc \
     src/core/ext/filters/message_size/message_size_filter.cc \
     src/core/ext/filters/message_size/message_size_filter.cc \
@@ -654,6 +658,7 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
@@ -665,7 +670,6 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/client)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/client)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/message_compress)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/message_compress)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/server)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/server)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/load_reporting)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/max_age)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/max_age)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/message_size)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/message_size)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/workarounds)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/workarounds)
@@ -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)

+ 9 - 3
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 " +
@@ -342,6 +346,8 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_channel_secure.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_channel_secure.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.cc " +
+    "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf\\duration.pb.c " +
+    "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf\\timestamp.pb.c " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " +
@@ -353,8 +359,6 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " +
-    "src\\core\\ext\\filters\\load_reporting\\server_load_reporting_filter.cc " +
-    "src\\core\\ext\\filters\\load_reporting\\server_load_reporting_plugin.cc " +
     "src\\cpp\\ext\\filters\\census\\grpc_context.cc " +
     "src\\cpp\\ext\\filters\\census\\grpc_context.cc " +
     "src\\core\\ext\\filters\\max_age\\max_age_filter.cc " +
     "src\\core\\ext\\filters\\max_age\\max_age_filter.cc " +
     "src\\core\\ext\\filters\\message_size\\message_size_filter.cc " +
     "src\\core\\ext\\filters\\message_size\\message_size_filter.cc " +
@@ -663,6 +667,8 @@ if (PHP_GRPC != "no") {
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver");
@@ -676,7 +682,6 @@ if (PHP_GRPC != "no") {
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\client");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\client");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\message_compress");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\message_compress");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\server");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\server");
-  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\load_reporting");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\max_age");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\max_age");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\workarounds");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\workarounds");
@@ -712,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");

+ 21 - 3
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',
@@ -479,13 +485,13 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
                       'src/core/ext/filters/max_age/max_age_filter.h',
                       'src/core/ext/filters/max_age/max_age_filter.h',
                       'src/core/ext/filters/message_size/message_size_filter.h',
                       'src/core/ext/filters/message_size/message_size_filter.h',
                       'src/core/ext/filters/http/client_authority_filter.h',
                       'src/core/ext/filters/http/client_authority_filter.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

+ 24 - 9
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',
@@ -489,13 +496,13 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
                       'src/core/ext/filters/max_age/max_age_filter.h',
                       'src/core/ext/filters/max_age/max_age_filter.h',
                       'src/core/ext/filters/message_size/message_size_filter.h',
                       'src/core/ext/filters/message_size/message_size_filter.h',
                       'src/core/ext/filters/http/client_authority_filter.h',
                       'src/core/ext/filters/http/client_authority_filter.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',
@@ -782,6 +793,8 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
                       'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
                       'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
                       'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
@@ -793,8 +806,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
                       'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
                       'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
-                      'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
                       'src/cpp/ext/filters/census/grpc_context.cc',
                       'src/cpp/ext/filters/census/grpc_context.cc',
                       'src/core/ext/filters/max_age/max_age_filter.cc',
                       'src/core/ext/filters/max_age/max_age_filter.cc',
                       'src/core/ext/filters/message_size/message_size_filter.cc',
                       'src/core/ext/filters/message_size/message_size_filter.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',
@@ -1070,13 +1086,13 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                               'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                               'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
                               'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                               'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                               'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                               'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                               'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
                               'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
-                              'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
-                              'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
                               'src/core/ext/filters/max_age/max_age_filter.h',
                               'src/core/ext/filters/max_age/max_age_filter.h',
                               'src/core/ext/filters/message_size/message_size_filter.h',
                               'src/core/ext/filters/message_size/message_size_filter.h',
                               'src/core/ext/filters/http/client_authority_filter.h',
                               'src/core/ext/filters/http/client_authority_filter.h',
@@ -1214,7 +1230,6 @@ Pod::Spec.new do |s|
                       'test/core/end2end/tests/invoke_large_request.cc',
                       'test/core/end2end/tests/invoke_large_request.cc',
                       'test/core/end2end/tests/keepalive_timeout.cc',
                       'test/core/end2end/tests/keepalive_timeout.cc',
                       'test/core/end2end/tests/large_metadata.cc',
                       'test/core/end2end/tests/large_metadata.cc',
-                      'test/core/end2end/tests/load_reporting_hook.cc',
                       'test/core/end2end/tests/max_concurrent_streams.cc',
                       'test/core/end2end/tests/max_concurrent_streams.cc',
                       'test/core/end2end/tests/max_connection_age.cc',
                       'test/core/end2end/tests/max_connection_age.cc',
                       'test/core/end2end/tests/max_connection_idle.cc',
                       'test/core/end2end/tests/max_connection_idle.cc',

+ 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

+ 15 - 4
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 )
@@ -426,13 +433,13 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
-  s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_filter.h )
-  s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_plugin.h )
   s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
   s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
   s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
   s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
   s.files += %w( src/core/ext/filters/http/client_authority_filter.h )
   s.files += %w( src/core/ext/filters/http/client_authority_filter.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 )
@@ -722,6 +733,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
   s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc )
@@ -733,8 +746,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc )
-  s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_filter.cc )
-  s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc )
   s.files += %w( src/cpp/ext/filters/census/grpc_context.cc )
   s.files += %w( src/cpp/ext/filters/census/grpc_context.cc )
   s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc )
   s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc )
   s.files += %w( src/core/ext/filters/message_size/message_size_filter.cc )
   s.files += %w( src/core/ext/filters/message_size/message_size_filter.cc )

+ 37 - 6
grpc.gyp

@@ -185,6 +185,32 @@
         'test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc',
         'test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc',
       ],
       ],
     },
     },
+    {
+      'target_name': 'cxxabi',
+      'type': 'static_library',
+      'dependencies': [
+      ],
+      'sources': [
+        'third_party/libcxxabi/src/abort_message.cpp',
+        'third_party/libcxxabi/src/cxa_aux_runtime.cpp',
+        'third_party/libcxxabi/src/cxa_default_handlers.cpp',
+        'third_party/libcxxabi/src/cxa_demangle.cpp',
+        'third_party/libcxxabi/src/cxa_exception_storage.cpp',
+        'third_party/libcxxabi/src/cxa_guard.cpp',
+        'third_party/libcxxabi/src/cxa_handlers.cpp',
+        'third_party/libcxxabi/src/cxa_noexception.cpp',
+        'third_party/libcxxabi/src/cxa_thread_atexit.cpp',
+        'third_party/libcxxabi/src/cxa_unexpected.cpp',
+        'third_party/libcxxabi/src/cxa_vector.cpp',
+        'third_party/libcxxabi/src/cxa_virtual.cpp',
+        'third_party/libcxxabi/src/fallback_malloc.cpp',
+        'third_party/libcxxabi/src/private_typeinfo.cpp',
+        'third_party/libcxxabi/src/stdlib_exception.cpp',
+        'third_party/libcxxabi/src/stdlib_new_delete.cpp',
+        'third_party/libcxxabi/src/stdlib_stdexcept.cpp',
+        'third_party/libcxxabi/src/stdlib_typeinfo.cpp',
+      ],
+    },
     {
     {
       'target_name': 'gpr',
       'target_name': 'gpr',
       'type': 'static_library',
       'type': 'static_library',
@@ -441,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',
@@ -496,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',
@@ -517,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',
@@ -533,6 +563,8 @@
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
         'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
         'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
@@ -544,8 +576,6 @@
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
         'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
-        'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
-        'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
         'src/cpp/ext/filters/census/grpc_context.cc',
         'src/cpp/ext/filters/census/grpc_context.cc',
         'src/core/ext/filters/max_age/max_age_filter.cc',
         'src/core/ext/filters/max_age/max_age_filter.cc',
         'src/core/ext/filters/message_size/message_size_filter.cc',
         'src/core/ext/filters/message_size/message_size_filter.cc',
@@ -754,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',
@@ -986,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',
@@ -1230,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',
@@ -1259,13 +1292,13 @@
         'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
         'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
-        'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
-        'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'third_party/nanopb/pb_common.c',
         'third_party/nanopb/pb_common.c',
         'third_party/nanopb/pb_decode.c',
         'third_party/nanopb/pb_decode.c',
@@ -2627,7 +2660,6 @@
         'test/core/end2end/tests/invoke_large_request.cc',
         'test/core/end2end/tests/invoke_large_request.cc',
         'test/core/end2end/tests/keepalive_timeout.cc',
         'test/core/end2end/tests/keepalive_timeout.cc',
         'test/core/end2end/tests/large_metadata.cc',
         'test/core/end2end/tests/large_metadata.cc',
-        'test/core/end2end/tests/load_reporting_hook.cc',
         'test/core/end2end/tests/max_concurrent_streams.cc',
         'test/core/end2end/tests/max_concurrent_streams.cc',
         'test/core/end2end/tests/max_connection_age.cc',
         'test/core/end2end/tests/max_connection_age.cc',
         'test/core/end2end/tests/max_connection_idle.cc',
         'test/core/end2end/tests/max_connection_idle.cc',
@@ -2719,7 +2751,6 @@
         'test/core/end2end/tests/invoke_large_request.cc',
         'test/core/end2end/tests/invoke_large_request.cc',
         'test/core/end2end/tests/keepalive_timeout.cc',
         'test/core/end2end/tests/keepalive_timeout.cc',
         'test/core/end2end/tests/large_metadata.cc',
         'test/core/end2end/tests/large_metadata.cc',
-        'test/core/end2end/tests/load_reporting_hook.cc',
         'test/core/end2end/tests/max_concurrent_streams.cc',
         'test/core/end2end/tests/max_concurrent_streams.cc',
         'test/core/end2end/tests/max_connection_age.cc',
         'test/core/end2end/tests/max_connection_age.cc',
         'test/core/end2end/tests/max_connection_idle.cc',
         'test/core/end2end/tests/max_connection_idle.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

+ 15 - 4
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" />
@@ -431,13 +438,13 @@
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_filter.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/http/client_authority_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/http/client_authority_filter.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" />
@@ -727,6 +738,8 @@
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" />
@@ -738,8 +751,6 @@
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_filter.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc" role="src" />
     <file baseinstalldir="/" name="src/cpp/ext/filters/census/grpc_context.cc" role="src" />
     <file baseinstalldir="/" name="src/cpp/ext/filters/census/grpc_context.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.cc" role="src" />

+ 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);
 }
 }

+ 1 - 1
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc

@@ -73,7 +73,7 @@ grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name) {
 }
 }
 
 
 static void populate_timestamp(gpr_timespec timestamp,
 static void populate_timestamp(gpr_timespec timestamp,
-                               struct _grpc_lb_v1_Timestamp* timestamp_pb) {
+                               grpc_grpclb_timestamp* timestamp_pb) {
   timestamp_pb->has_seconds = true;
   timestamp_pb->has_seconds = true;
   timestamp_pb->seconds = timestamp.tv_sec;
   timestamp_pb->seconds = timestamp.tv_sec;
   timestamp_pb->has_nanos = true;
   timestamp_pb->has_nanos = true;

+ 3 - 1
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h

@@ -33,7 +33,9 @@ typedef grpc_lb_v1_Server_ip_address_t grpc_grpclb_ip_address;
 typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request;
 typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request;
 typedef grpc_lb_v1_InitialLoadBalanceResponse grpc_grpclb_initial_response;
 typedef grpc_lb_v1_InitialLoadBalanceResponse grpc_grpclb_initial_response;
 typedef grpc_lb_v1_Server grpc_grpclb_server;
 typedef grpc_lb_v1_Server grpc_grpclb_server;
-typedef grpc_lb_v1_Duration grpc_grpclb_duration;
+typedef google_protobuf_Duration grpc_grpclb_duration;
+typedef google_protobuf_Timestamp grpc_grpclb_timestamp;
+
 typedef struct {
 typedef struct {
   grpc_grpclb_server** servers;
   grpc_grpclb_server** servers;
   size_t num_servers;
   size_t num_servers;

+ 19 - 0
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c

@@ -0,0 +1,19 @@
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.7-dev */
+
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h"
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t google_protobuf_Duration_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, google_protobuf_Duration, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, google_protobuf_Duration, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
+
+/* @@protoc_insertion_point(eof) */

+ 54 - 0
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h

@@ -0,0 +1,54 @@
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.7-dev */
+
+#ifndef PB_GOOGLE_PROTOBUF_DURATION_PB_H_INCLUDED
+#define PB_GOOGLE_PROTOBUF_DURATION_PB_H_INCLUDED
+#include "pb.h"
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _google_protobuf_Duration {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+/* @@protoc_insertion_point(struct:google_protobuf_Duration) */
+} google_protobuf_Duration;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define google_protobuf_Duration_init_default    {false, 0, false, 0}
+#define google_protobuf_Duration_init_zero       {false, 0, false, 0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define google_protobuf_Duration_seconds_tag     1
+#define google_protobuf_Duration_nanos_tag       2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t google_protobuf_Duration_fields[3];
+
+/* Maximum encoded size of messages (where known) */
+#define google_protobuf_Duration_size            22
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define DURATION_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif

+ 19 - 0
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c

@@ -0,0 +1,19 @@
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.7-dev */
+
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h"
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t google_protobuf_Timestamp_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, google_protobuf_Timestamp, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, google_protobuf_Timestamp, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
+
+/* @@protoc_insertion_point(eof) */

+ 54 - 0
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h

@@ -0,0 +1,54 @@
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.7-dev */
+
+#ifndef PB_GOOGLE_PROTOBUF_TIMESTAMP_PB_H_INCLUDED
+#define PB_GOOGLE_PROTOBUF_TIMESTAMP_PB_H_INCLUDED
+#include "pb.h"
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _google_protobuf_Timestamp {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+/* @@protoc_insertion_point(struct:google_protobuf_Timestamp) */
+} google_protobuf_Timestamp;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define google_protobuf_Timestamp_init_default   {false, 0, false, 0}
+#define google_protobuf_Timestamp_init_zero      {false, 0, false, 0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define google_protobuf_Timestamp_seconds_tag    1
+#define google_protobuf_Timestamp_nanos_tag      2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t google_protobuf_Timestamp_fields[3];
+
+/* Maximum encoded size of messages (where known) */
+#define google_protobuf_Timestamp_size           22
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define TIMESTAMP_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif

+ 4 - 17
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c

@@ -2,7 +2,6 @@
 /* Generated by nanopb-0.3.7-dev */
 /* Generated by nanopb-0.3.7-dev */
 
 
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.
@@ -10,18 +9,6 @@
 
 
 
 
 
 
-const pb_field_t grpc_lb_v1_Duration_fields[3] = {
-    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Duration, seconds, seconds, 0),
-    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Duration, nanos, seconds, 0),
-    PB_LAST_FIELD
-};
-
-const pb_field_t grpc_lb_v1_Timestamp_fields[3] = {
-    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Timestamp, seconds, seconds, 0),
-    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Timestamp, nanos, seconds, 0),
-    PB_LAST_FIELD
-};
-
 const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3] = {
 const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3] = {
     PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v1_InitialLoadBalanceRequest_fields),
     PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v1_InitialLoadBalanceRequest_fields),
     PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v1_ClientStats_fields),
     PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v1_ClientStats_fields),
@@ -40,7 +27,7 @@ const pb_field_t grpc_lb_v1_ClientStatsPerToken_fields[3] = {
 };
 };
 
 
 const pb_field_t grpc_lb_v1_ClientStats_fields[7] = {
 const pb_field_t grpc_lb_v1_ClientStats_fields[7] = {
-    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_ClientStats, timestamp, timestamp, &grpc_lb_v1_Timestamp_fields),
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_ClientStats, timestamp, timestamp, &google_protobuf_Timestamp_fields),
     PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_started, timestamp, 0),
     PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_started, timestamp, 0),
     PB_FIELD(  3, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished, num_calls_started, 0),
     PB_FIELD(  3, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished, num_calls_started, 0),
     PB_FIELD(  6, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_with_client_failed_to_send, num_calls_finished, 0),
     PB_FIELD(  6, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_with_client_failed_to_send, num_calls_finished, 0),
@@ -57,7 +44,7 @@ const pb_field_t grpc_lb_v1_LoadBalanceResponse_fields[3] = {
 
 
 const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3] = {
 const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3] = {
     PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_InitialLoadBalanceResponse, load_balancer_delegate, load_balancer_delegate, 0),
     PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_InitialLoadBalanceResponse, load_balancer_delegate, load_balancer_delegate, 0),
-    PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v1_Duration_fields),
+    PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &google_protobuf_Duration_fields),
     PB_LAST_FIELD
     PB_LAST_FIELD
 };
 };
 
 
@@ -84,7 +71,7 @@ const pb_field_t grpc_lb_v1_Server_fields[5] = {
  * numbers or field sizes that are larger than what can fit in 8 or 16 bit
  * numbers or field sizes that are larger than what can fit in 8 or 16 bit
  * field descriptors.
  * field descriptors.
  */
  */
-PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
 #endif
 #endif
 
 
 #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
 #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
@@ -95,7 +82,7 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request)
  * numbers or field sizes that are larger than what can fit in the default
  * numbers or field sizes that are larger than what can fit in the default
  * 8 bit descriptors.
  * 8 bit descriptors.
  */
  */
-PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
 #endif
 #endif
 
 
 
 

+ 36 - 62
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h

@@ -4,6 +4,8 @@
 #ifndef PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
 #ifndef PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
 #define PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
 #define PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
 #include "pb.h"
 #include "pb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h"
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.
@@ -19,6 +21,21 @@ typedef struct _grpc_lb_v1_ServerList {
 /* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
 /* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
 } grpc_lb_v1_ServerList;
 } grpc_lb_v1_ServerList;
 
 
+typedef struct _grpc_lb_v1_ClientStats {
+    bool has_timestamp;
+    google_protobuf_Timestamp timestamp;
+    bool has_num_calls_started;
+    int64_t num_calls_started;
+    bool has_num_calls_finished;
+    int64_t num_calls_finished;
+    bool has_num_calls_finished_with_client_failed_to_send;
+    int64_t num_calls_finished_with_client_failed_to_send;
+    bool has_num_calls_finished_known_received;
+    int64_t num_calls_finished_known_received;
+    pb_callback_t calls_finished_with_drop;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStats) */
+} grpc_lb_v1_ClientStats;
+
 typedef struct _grpc_lb_v1_ClientStatsPerToken {
 typedef struct _grpc_lb_v1_ClientStatsPerToken {
     pb_callback_t load_balance_token;
     pb_callback_t load_balance_token;
     bool has_num_calls;
     bool has_num_calls;
@@ -26,20 +43,20 @@ typedef struct _grpc_lb_v1_ClientStatsPerToken {
 /* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStatsPerToken) */
 /* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStatsPerToken) */
 } grpc_lb_v1_ClientStatsPerToken;
 } grpc_lb_v1_ClientStatsPerToken;
 
 
-typedef struct _grpc_lb_v1_Duration {
-    bool has_seconds;
-    int64_t seconds;
-    bool has_nanos;
-    int32_t nanos;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_Duration) */
-} grpc_lb_v1_Duration;
-
 typedef struct _grpc_lb_v1_InitialLoadBalanceRequest {
 typedef struct _grpc_lb_v1_InitialLoadBalanceRequest {
     bool has_name;
     bool has_name;
     char name[128];
     char name[128];
 /* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceRequest) */
 /* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceRequest) */
 } grpc_lb_v1_InitialLoadBalanceRequest;
 } grpc_lb_v1_InitialLoadBalanceRequest;
 
 
+typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
+    bool has_load_balancer_delegate;
+    char load_balancer_delegate[64];
+    bool has_client_stats_report_interval;
+    google_protobuf_Duration client_stats_report_interval;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceResponse) */
+} grpc_lb_v1_InitialLoadBalanceResponse;
+
 typedef PB_BYTES_ARRAY_T(16) grpc_lb_v1_Server_ip_address_t;
 typedef PB_BYTES_ARRAY_T(16) grpc_lb_v1_Server_ip_address_t;
 typedef struct _grpc_lb_v1_Server {
 typedef struct _grpc_lb_v1_Server {
     bool has_ip_address;
     bool has_ip_address;
@@ -53,37 +70,6 @@ typedef struct _grpc_lb_v1_Server {
 /* @@protoc_insertion_point(struct:grpc_lb_v1_Server) */
 /* @@protoc_insertion_point(struct:grpc_lb_v1_Server) */
 } grpc_lb_v1_Server;
 } grpc_lb_v1_Server;
 
 
-typedef struct _grpc_lb_v1_Timestamp {
-    bool has_seconds;
-    int64_t seconds;
-    bool has_nanos;
-    int32_t nanos;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_Timestamp) */
-} grpc_lb_v1_Timestamp;
-
-typedef struct _grpc_lb_v1_ClientStats {
-    bool has_timestamp;
-    grpc_lb_v1_Timestamp timestamp;
-    bool has_num_calls_started;
-    int64_t num_calls_started;
-    bool has_num_calls_finished;
-    int64_t num_calls_finished;
-    bool has_num_calls_finished_with_client_failed_to_send;
-    int64_t num_calls_finished_with_client_failed_to_send;
-    bool has_num_calls_finished_known_received;
-    int64_t num_calls_finished_known_received;
-    pb_callback_t calls_finished_with_drop;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStats) */
-} grpc_lb_v1_ClientStats;
-
-typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
-    bool has_load_balancer_delegate;
-    char load_balancer_delegate[64];
-    bool has_client_stats_report_interval;
-    grpc_lb_v1_Duration client_stats_report_interval;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceResponse) */
-} grpc_lb_v1_InitialLoadBalanceResponse;
-
 typedef struct _grpc_lb_v1_LoadBalanceRequest {
 typedef struct _grpc_lb_v1_LoadBalanceRequest {
     bool has_initial_request;
     bool has_initial_request;
     grpc_lb_v1_InitialLoadBalanceRequest initial_request;
     grpc_lb_v1_InitialLoadBalanceRequest initial_request;
@@ -103,56 +89,46 @@ typedef struct _grpc_lb_v1_LoadBalanceResponse {
 /* Default values for struct fields */
 /* Default values for struct fields */
 
 
 /* Initializer values for message structs */
 /* Initializer values for message structs */
-#define grpc_lb_v1_Duration_init_default         {false, 0, false, 0}
-#define grpc_lb_v1_Timestamp_init_default        {false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceRequest_init_default {false, grpc_lb_v1_InitialLoadBalanceRequest_init_default, false, grpc_lb_v1_ClientStats_init_default}
 #define grpc_lb_v1_LoadBalanceRequest_init_default {false, grpc_lb_v1_InitialLoadBalanceRequest_init_default, false, grpc_lb_v1_ClientStats_init_default}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_default {false, ""}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_default {false, ""}
 #define grpc_lb_v1_ClientStatsPerToken_init_default {{{NULL}, NULL}, false, 0}
 #define grpc_lb_v1_ClientStatsPerToken_init_default {{{NULL}, NULL}, false, 0}
-#define grpc_lb_v1_ClientStats_init_default      {false, grpc_lb_v1_Timestamp_init_default, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
+#define grpc_lb_v1_ClientStats_init_default      {false, google_protobuf_Timestamp_init_default, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
 #define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
 #define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
-#define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, grpc_lb_v1_Duration_init_default}
+#define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, google_protobuf_Duration_init_default}
 #define grpc_lb_v1_ServerList_init_default       {{{NULL}, NULL}}
 #define grpc_lb_v1_ServerList_init_default       {{{NULL}, NULL}}
 #define grpc_lb_v1_Server_init_default           {false, {0, {0}}, false, 0, false, "", false, 0}
 #define grpc_lb_v1_Server_init_default           {false, {0, {0}}, false, 0, false, "", false, 0}
-#define grpc_lb_v1_Duration_init_zero            {false, 0, false, 0}
-#define grpc_lb_v1_Timestamp_init_zero           {false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceRequest_init_zero  {false, grpc_lb_v1_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v1_ClientStats_init_zero}
 #define grpc_lb_v1_LoadBalanceRequest_init_zero  {false, grpc_lb_v1_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v1_ClientStats_init_zero}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_zero {false, ""}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_zero {false, ""}
 #define grpc_lb_v1_ClientStatsPerToken_init_zero {{{NULL}, NULL}, false, 0}
 #define grpc_lb_v1_ClientStatsPerToken_init_zero {{{NULL}, NULL}, false, 0}
-#define grpc_lb_v1_ClientStats_init_zero         {false, grpc_lb_v1_Timestamp_init_zero, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
+#define grpc_lb_v1_ClientStats_init_zero         {false, google_protobuf_Timestamp_init_zero, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
 #define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
 #define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
-#define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, grpc_lb_v1_Duration_init_zero}
+#define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, google_protobuf_Duration_init_zero}
 #define grpc_lb_v1_ServerList_init_zero          {{{NULL}, NULL}}
 #define grpc_lb_v1_ServerList_init_zero          {{{NULL}, NULL}}
 #define grpc_lb_v1_Server_init_zero              {false, {0, {0}}, false, 0, false, "", false, 0}
 #define grpc_lb_v1_Server_init_zero              {false, {0, {0}}, false, 0, false, "", false, 0}
 
 
 /* Field tags (for use in manual encoding/decoding) */
 /* Field tags (for use in manual encoding/decoding) */
 #define grpc_lb_v1_ServerList_servers_tag        1
 #define grpc_lb_v1_ServerList_servers_tag        1
-#define grpc_lb_v1_ClientStatsPerToken_load_balance_token_tag 1
-#define grpc_lb_v1_ClientStatsPerToken_num_calls_tag 2
-#define grpc_lb_v1_Duration_seconds_tag          1
-#define grpc_lb_v1_Duration_nanos_tag            2
-#define grpc_lb_v1_InitialLoadBalanceRequest_name_tag 1
-#define grpc_lb_v1_Server_ip_address_tag         1
-#define grpc_lb_v1_Server_port_tag               2
-#define grpc_lb_v1_Server_load_balance_token_tag 3
-#define grpc_lb_v1_Server_drop_tag               4
-#define grpc_lb_v1_Timestamp_seconds_tag         1
-#define grpc_lb_v1_Timestamp_nanos_tag           2
 #define grpc_lb_v1_ClientStats_timestamp_tag     1
 #define grpc_lb_v1_ClientStats_timestamp_tag     1
 #define grpc_lb_v1_ClientStats_num_calls_started_tag 2
 #define grpc_lb_v1_ClientStats_num_calls_started_tag 2
 #define grpc_lb_v1_ClientStats_num_calls_finished_tag 3
 #define grpc_lb_v1_ClientStats_num_calls_finished_tag 3
 #define grpc_lb_v1_ClientStats_num_calls_finished_with_client_failed_to_send_tag 6
 #define grpc_lb_v1_ClientStats_num_calls_finished_with_client_failed_to_send_tag 6
 #define grpc_lb_v1_ClientStats_num_calls_finished_known_received_tag 7
 #define grpc_lb_v1_ClientStats_num_calls_finished_known_received_tag 7
 #define grpc_lb_v1_ClientStats_calls_finished_with_drop_tag 8
 #define grpc_lb_v1_ClientStats_calls_finished_with_drop_tag 8
+#define grpc_lb_v1_ClientStatsPerToken_load_balance_token_tag 1
+#define grpc_lb_v1_ClientStatsPerToken_num_calls_tag 2
+#define grpc_lb_v1_InitialLoadBalanceRequest_name_tag 1
 #define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 1
 #define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 1
 #define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 2
 #define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 2
+#define grpc_lb_v1_Server_ip_address_tag         1
+#define grpc_lb_v1_Server_port_tag               2
+#define grpc_lb_v1_Server_load_balance_token_tag 3
+#define grpc_lb_v1_Server_drop_tag               4
 #define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
 #define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
 #define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
 #define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
 #define grpc_lb_v1_LoadBalanceResponse_initial_response_tag 1
 #define grpc_lb_v1_LoadBalanceResponse_initial_response_tag 1
 #define grpc_lb_v1_LoadBalanceResponse_server_list_tag 2
 #define grpc_lb_v1_LoadBalanceResponse_server_list_tag 2
 
 
 /* Struct field encoding specification for nanopb */
 /* Struct field encoding specification for nanopb */
-extern const pb_field_t grpc_lb_v1_Duration_fields[3];
-extern const pb_field_t grpc_lb_v1_Timestamp_fields[3];
 extern const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3];
 extern const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3];
 extern const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2];
 extern const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2];
 extern const pb_field_t grpc_lb_v1_ClientStatsPerToken_fields[3];
 extern const pb_field_t grpc_lb_v1_ClientStatsPerToken_fields[3];
@@ -163,8 +139,6 @@ extern const pb_field_t grpc_lb_v1_ServerList_fields[2];
 extern const pb_field_t grpc_lb_v1_Server_fields[5];
 extern const pb_field_t grpc_lb_v1_Server_fields[5];
 
 
 /* Maximum encoded size of messages (where known) */
 /* Maximum encoded size of messages (where known) */
-#define grpc_lb_v1_Duration_size                 22
-#define grpc_lb_v1_Timestamp_size                22
 #define grpc_lb_v1_LoadBalanceRequest_size       (140 + grpc_lb_v1_ClientStats_size)
 #define grpc_lb_v1_LoadBalanceRequest_size       (140 + grpc_lb_v1_ClientStats_size)
 #define grpc_lb_v1_InitialLoadBalanceRequest_size 131
 #define grpc_lb_v1_InitialLoadBalanceRequest_size 131
 /* grpc_lb_v1_ClientStatsPerToken_size depends on runtime parameters */
 /* grpc_lb_v1_ClientStatsPerToken_size depends on runtime parameters */

+ 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");

+ 108 - 0
src/core/ext/filters/load_reporting/registered_opencensus_objects.h

@@ -0,0 +1,108 @@
+/*
+ *
+ * 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_LOAD_REPORTING_REGISTERED_OPENCENSUS_OBJECTS_H
+#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_REGISTERED_OPENCENSUS_OBJECTS_H
+
+#include <grpc/support/port_platform.h>
+
+#include "opencensus/stats/stats.h"
+
+#include "src/cpp/server/load_reporter/constants.h"
+
+namespace grpc {
+namespace load_reporter {
+
+// Measures.
+
+::opencensus::stats::MeasureInt64 MeasureStartCount() {
+  static const ::opencensus::stats::MeasureInt64 start_count =
+      ::opencensus::stats::MeasureInt64::Register(
+          kMeasureStartCount, kMeasureStartCount, kMeasureStartCount);
+  return start_count;
+}
+
+::opencensus::stats::MeasureInt64 MeasureEndCount() {
+  static const ::opencensus::stats::MeasureInt64 end_count =
+      ::opencensus::stats::MeasureInt64::Register(
+          kMeasureEndCount, kMeasureEndCount, kMeasureEndCount);
+  return end_count;
+}
+
+::opencensus::stats::MeasureInt64 MeasureEndBytesSent() {
+  static const ::opencensus::stats::MeasureInt64 end_bytes_sent =
+      ::opencensus::stats::MeasureInt64::Register(
+          kMeasureEndBytesSent, kMeasureEndBytesSent, kMeasureEndBytesSent);
+  return end_bytes_sent;
+}
+
+::opencensus::stats::MeasureInt64 MeasureEndBytesReceived() {
+  static const ::opencensus::stats::MeasureInt64 end_bytes_received =
+      ::opencensus::stats::MeasureInt64::Register(kMeasureEndBytesReceived,
+                                                  kMeasureEndBytesReceived,
+                                                  kMeasureEndBytesReceived);
+  return end_bytes_received;
+}
+
+::opencensus::stats::MeasureInt64 MeasureEndLatencyMs() {
+  static const ::opencensus::stats::MeasureInt64 end_latency_ms =
+      ::opencensus::stats::MeasureInt64::Register(
+          kMeasureEndLatencyMs, kMeasureEndLatencyMs, kMeasureEndLatencyMs);
+  return end_latency_ms;
+}
+
+::opencensus::stats::MeasureDouble MeasureOtherCallMetric() {
+  static const ::opencensus::stats::MeasureDouble other_call_metric =
+      ::opencensus::stats::MeasureDouble::Register(kMeasureOtherCallMetric,
+                                                   kMeasureOtherCallMetric,
+                                                   kMeasureOtherCallMetric);
+  return other_call_metric;
+}
+
+// Tags.
+
+opencensus::stats::TagKey TagKeyToken() {
+  static const auto token = opencensus::stats::TagKey::Register(kTagKeyToken);
+  return token;
+}
+
+opencensus::stats::TagKey TagKeyHost() {
+  static const auto token = opencensus::stats::TagKey::Register(kTagKeyHost);
+  return token;
+}
+opencensus::stats::TagKey TagKeyUserId() {
+  static const auto token = opencensus::stats::TagKey::Register(kTagKeyUserId);
+  return token;
+}
+
+opencensus::stats::TagKey TagKeyStatus() {
+  static const auto token = opencensus::stats::TagKey::Register(kTagKeyStatus);
+  return token;
+}
+
+opencensus::stats::TagKey TagKeyMetricName() {
+  static const auto token =
+      opencensus::stats::TagKey::Register(kTagKeyMetricName);
+  return token;
+}
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_REGISTERED_OPENCENSUS_OBJECTS_H \
+        */

+ 269 - 161
src/core/ext/filters/load_reporting/server_load_reporting_filter.cc

@@ -18,203 +18,311 @@
 
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
 
 
-#include <string.h>
-
+#include <grpc/grpc_security.h>
 #include <grpc/load_reporting.h>
 #include <grpc/load_reporting.h>
+#include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
 
 
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
+#include "src/core/ext/filters/load_reporting/registered_opencensus_objects.h"
 #include "src/core/ext/filters/load_reporting/server_load_reporting_filter.h"
 #include "src/core/ext/filters/load_reporting/server_load_reporting_filter.h"
-#include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/context.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/sockaddr_posix.h"
+#include "src/core/lib/iomgr/socket_utils.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/surface/call.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 
-namespace {
-struct call_data {
-  intptr_t id; /**< an id unique to the call */
-  bool have_trailing_md_string;
-  grpc_slice trailing_md_string;
-  bool have_initial_md_string;
-  grpc_slice initial_md_string;
-  bool have_service_method;
-  grpc_slice service_method;
-
-  /* stores the recv_initial_metadata op's ready closure, which we wrap with our
-   * own (on_initial_md_ready) in order to capture the incoming initial metadata
-   * */
-  grpc_closure* ops_recv_initial_metadata_ready;
-
-  /* to get notified of the availability of the incoming initial metadata. */
-  grpc_closure on_initial_md_ready;
-  grpc_metadata_batch* recv_initial_metadata;
-};
+namespace grpc {
 
 
-struct channel_data {
-  intptr_t id; /**< an id unique to the channel */
-};
-}  // namespace
-
-static void on_initial_md_ready(void* user_data, grpc_error* err) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
-  call_data* calld = static_cast<call_data*>(elem->call_data);
-
-  if (err == GRPC_ERROR_NONE) {
-    if (calld->recv_initial_metadata->idx.named.path != nullptr) {
-      calld->service_method = grpc_slice_ref_internal(
-          GRPC_MDVALUE(calld->recv_initial_metadata->idx.named.path->md));
-      calld->have_service_method = true;
-    } else {
-      err = grpc_error_add_child(
-          err, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing :path header"));
-    }
-    if (calld->recv_initial_metadata->idx.named.lb_token != nullptr) {
-      calld->initial_md_string = grpc_slice_ref_internal(
-          GRPC_MDVALUE(calld->recv_initial_metadata->idx.named.lb_token->md));
-      calld->have_initial_md_string = true;
-      grpc_metadata_batch_remove(
-          calld->recv_initial_metadata,
-          calld->recv_initial_metadata->idx.named.lb_token);
+grpc_error* ServerLoadReportingChannelData::Init(
+    grpc_channel_element* /* elem */, grpc_channel_element_args* args) {
+  GPR_ASSERT(!args->is_last);
+  // Find and record the peer_identity.
+  const grpc_auth_context* auth_context =
+      grpc_find_auth_context_in_args(args->channel_args);
+  if (auth_context != nullptr &&
+      grpc_auth_context_peer_is_authenticated(auth_context)) {
+    grpc_auth_property_iterator auth_it =
+        grpc_auth_context_peer_identity(auth_context);
+    const grpc_auth_property* auth_property =
+        grpc_auth_property_iterator_next(&auth_it);
+    if (auth_property != nullptr) {
+      peer_identity_ = auth_property->value;
+      peer_identity_len_ = auth_property->value_length;
     }
     }
-  } else {
-    GRPC_ERROR_REF(err);
   }
   }
-  GRPC_CLOSURE_RUN(calld->ops_recv_initial_metadata_ready, err);
-}
-
-/* Constructor for call_data */
-static grpc_error* init_call_elem(grpc_call_element* elem,
-                                  const grpc_call_element_args* args) {
-  call_data* calld = static_cast<call_data*>(elem->call_data);
-  calld->id = (intptr_t)args->call_stack;
-  GRPC_CLOSURE_INIT(&calld->on_initial_md_ready, on_initial_md_ready, elem,
-                    grpc_schedule_on_exec_ctx);
-
-  /* TODO(dgq): do something with the data
-  channel_data *chand = elem->channel_data;
-  grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_CREATION,
-                                                (intptr_t)chand->id,
-                                                (intptr_t)calld->id,
-                                                NULL,
-                                                NULL,
-                                                NULL,
-                                                NULL};
-  */
-
   return GRPC_ERROR_NONE;
   return GRPC_ERROR_NONE;
 }
 }
 
 
-/* Destructor for call_data */
-static void destroy_call_elem(grpc_call_element* elem,
-                              const grpc_call_final_info* final_info,
-                              grpc_closure* ignored) {
-  call_data* calld = static_cast<call_data*>(elem->call_data);
+void ServerLoadReportingCallData::Destroy(
+    grpc_call_element* elem, const grpc_call_final_info* final_info,
+    grpc_closure* then_call_closure) {
+  ServerLoadReportingChannelData* chand =
+      reinterpret_cast<ServerLoadReportingChannelData*>(elem->channel_data);
+  // Only record an end if we've recorded its corresponding start, which is
+  // indicated by a non-null client_ip_and_lr_token_. Note that it's possible
+  // that we attempt to record the call end before we have recorded the call
+  // start, because the data needed for recording the start comes from the
+  // initial metadata, which may not be ready before the call finishes.
+  if (client_ip_and_lr_token_ != nullptr) {
+    opencensus::stats::Record(
+        {{::grpc::load_reporter::MeasureEndCount(), 1},
+         {::grpc::load_reporter::MeasureEndBytesSent(),
+          final_info->stats.transport_stream_stats.outgoing.data_bytes},
+         {::grpc::load_reporter::MeasureEndBytesReceived(),
+          final_info->stats.transport_stream_stats.incoming.data_bytes},
+         {::grpc::load_reporter::MeasureEndLatencyMs(),
+          gpr_time_to_millis(final_info->stats.latency)}},
+        {{::grpc::load_reporter::TagKeyToken(),
+          {client_ip_and_lr_token_, client_ip_and_lr_token_len_}},
+         {::grpc::load_reporter::TagKeyHost(),
+          {target_host_, target_host_len_}},
+         {::grpc::load_reporter::TagKeyUserId(),
+          {chand->peer_identity(), chand->peer_identity_len()}},
+         {::grpc::load_reporter::TagKeyStatus(),
+          GetStatusTagForStatus(final_info->final_status)}});
+  }
+  grpc_slice_unref_internal(service_method_);
+}
 
 
-  /* TODO(dgq): do something with the data
-  channel_data *chand = elem->channel_data;
-  grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_DESTRUCTION,
-                                                (intptr_t)chand->id,
-                                                (intptr_t)calld->id,
-                                                final_info,
-                                                calld->initial_md_string,
-                                                calld->trailing_md_string,
-                                                calld->service_method};
-  */
+void ServerLoadReportingCallData::StartTransportStreamOpBatch(
+    grpc_call_element* elem, TransportStreamOpBatch* op) {
+  GPR_TIMER_SCOPE("lr_start_transport_stream_op", 0);
+  if (op->recv_initial_metadata() != nullptr) {
+    // Save some fields to use when initial metadata is ready.
+    peer_string_ = op->get_peer_string();
+    recv_initial_metadata_ = op->recv_initial_metadata();
+    original_recv_initial_metadata_ready_ = op->recv_initial_metadata_ready();
+    // Substitute the original closure for the wrapper closure.
+    op->set_recv_initial_metadata_ready(&recv_initial_metadata_ready_);
+  } else if (op->send_trailing_metadata() != nullptr) {
+    GRPC_LOG_IF_ERROR(
+        "server_load_reporting_filter",
+        grpc_metadata_batch_filter(op->send_trailing_metadata()->batch(),
+                                   SendTrailingMetadataFilter, elem,
+                                   "send_trailing_metadata filtering error"));
+  }
+  grpc_call_next_op(elem, op->op());
+}
 
 
-  if (calld->have_initial_md_string) {
-    grpc_slice_unref_internal(calld->initial_md_string);
+void ServerLoadReportingCallData::GetCensusSafeClientIpString(
+    char** client_ip_string, size_t* size) {
+  // Find the client URI string.
+  const char* client_uri_str =
+      reinterpret_cast<const char*>(gpr_atm_acq_load(peer_string_));
+  if (client_uri_str == nullptr) {
+    gpr_log(GPR_ERROR,
+            "Unable to extract client URI string (peer string) from gRPC "
+            "metadata.");
+    *client_ip_string = nullptr;
+    *size = 0;
+    return;
   }
   }
-  if (calld->have_trailing_md_string) {
-    grpc_slice_unref_internal(calld->trailing_md_string);
+  // Parse the client URI string into grpc_uri.
+  grpc_uri* client_uri = grpc_uri_parse(client_uri_str, true);
+  if (client_uri == nullptr) {
+    gpr_log(GPR_ERROR,
+            "Unable to parse the client URI string (peer string) to a client "
+            "URI.");
+    *client_ip_string = nullptr;
+    *size = 0;
+    return;
   }
   }
-  if (calld->have_service_method) {
-    grpc_slice_unref_internal(calld->service_method);
+  // Parse the client URI into grpc_resolved_address.
+  grpc_resolved_address resolved_address;
+  bool success = grpc_parse_uri(client_uri, &resolved_address);
+  grpc_uri_destroy(client_uri);
+  if (!success) {
+    gpr_log(GPR_ERROR,
+            "Unable to parse client URI into a grpc_resolved_address.");
+    *client_ip_string = nullptr;
+    *size = 0;
+    return;
+  }
+  // Convert the socket address in the grpc_resolved_address into a hex string
+  // according to the address family.
+  grpc_sockaddr* addr = reinterpret_cast<grpc_sockaddr*>(resolved_address.addr);
+  if (addr->sa_family == GRPC_AF_INET) {
+    grpc_sockaddr_in* addr4 = reinterpret_cast<grpc_sockaddr_in*>(addr);
+    gpr_asprintf(client_ip_string, "%08x", grpc_ntohl(addr4->sin_addr.s_addr));
+    *size = 8;
+  } else if (addr->sa_family == GRPC_AF_INET6) {
+    grpc_sockaddr_in6* addr6 = reinterpret_cast<grpc_sockaddr_in6*>(addr);
+    *client_ip_string = static_cast<char*>(gpr_malloc(32));
+    for (size_t i = 0; i < 16; ++i) {
+      sprintf(*client_ip_string + i, "%02x",
+              addr6->sin6_addr.__in6_u.__u6_addr8[i]);
+    }
+    *size = 32;
+  } else {
+    GPR_UNREACHABLE_CODE();
   }
   }
 }
 }
 
 
-/* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_channel_element* elem,
-                                     grpc_channel_element_args* args) {
-  GPR_ASSERT(!args->is_last);
-
-  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
-  chand->id = (intptr_t)args->channel_stack;
+void ServerLoadReportingCallData::StoreClientIpAndLrToken(const char* lr_token,
+                                                          size_t lr_token_len) {
+  char* client_ip;
+  size_t client_ip_len;
+  GetCensusSafeClientIpString(&client_ip, &client_ip_len);
+  client_ip_and_lr_token_len_ =
+      kLengthPrefixSize + client_ip_len + lr_token_len;
+  client_ip_and_lr_token_ = static_cast<char*>(
+      gpr_zalloc(client_ip_and_lr_token_len_ * sizeof(char)));
+  char* cur_pos = client_ip_and_lr_token_;
+  // Store the IP length prefix.
+  if (client_ip_len == 0) {
+    strncpy(cur_pos, kEmptyAddressLengthString, kLengthPrefixSize);
+  } else if (client_ip_len == 8) {
+    strncpy(cur_pos, kEncodedIpv4AddressLengthString, kLengthPrefixSize);
+  } else if (client_ip_len == 32) {
+    strncpy(cur_pos, kEncodedIpv6AddressLengthString, kLengthPrefixSize);
+  } else {
+    GPR_UNREACHABLE_CODE();
+  }
+  cur_pos += kLengthPrefixSize;
+  // Store the IP.
+  if (client_ip_len != 0) {
+    strncpy(cur_pos, client_ip, client_ip_len);
+  }
+  gpr_free(client_ip);
+  cur_pos += client_ip_len;
+  // Store the LR token.
+  if (lr_token_len != 0) {
+    strncpy(cur_pos, lr_token, lr_token_len);
+  }
+  GPR_ASSERT(cur_pos + lr_token_len - client_ip_and_lr_token_ ==
+             client_ip_and_lr_token_len_);
+}
 
 
-  /* TODO(dgq): do something with the data
-  grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CHANNEL_CREATION,
-                                                (intptr_t)chand,
-                                                0,
-                                                NULL,
-                                                NULL,
-                                                NULL,
-                                                NULL};
-                                                */
+grpc_filtered_mdelem ServerLoadReportingCallData::RecvInitialMetadataFilter(
+    void* user_data, grpc_mdelem md) {
+  grpc_call_element* elem = reinterpret_cast<grpc_call_element*>(user_data);
+  ServerLoadReportingCallData* calld =
+      reinterpret_cast<ServerLoadReportingCallData*>(elem->call_data);
+  if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_PATH)) {
+    calld->service_method_ = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+  } else if (calld->target_host_ == nullptr &&
+             grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY)) {
+    grpc_slice target_host_slice = GRPC_MDVALUE(md);
+    calld->target_host_len_ = GRPC_SLICE_LENGTH(target_host_slice);
+    calld->target_host_ =
+        reinterpret_cast<char*>(gpr_zalloc(calld->target_host_len_));
+    for (size_t i = 0; i < calld->target_host_len_; ++i) {
+      calld->target_host_[i] = static_cast<char>(
+          tolower(GRPC_SLICE_START_PTR(target_host_slice)[i]));
+    }
+  } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_LB_TOKEN)) {
+    if (calld->client_ip_and_lr_token_ == nullptr) {
+      calld->StoreClientIpAndLrToken(
+          reinterpret_cast<const char*> GRPC_SLICE_START_PTR(GRPC_MDVALUE(md)),
+          GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)));
+    }
+    return GRPC_FILTERED_REMOVE();
+  }
+  return GRPC_FILTERED_MDELEM(md);
+}
 
 
-  return GRPC_ERROR_NONE;
+void ServerLoadReportingCallData::RecvInitialMetadataReady(void* arg,
+                                                           grpc_error* err) {
+  grpc_call_element* elem = reinterpret_cast<grpc_call_element*>(arg);
+  ServerLoadReportingCallData* calld =
+      reinterpret_cast<ServerLoadReportingCallData*>(elem->call_data);
+  ServerLoadReportingChannelData* chand =
+      reinterpret_cast<ServerLoadReportingChannelData*>(elem->channel_data);
+  if (err == GRPC_ERROR_NONE) {
+    GRPC_LOG_IF_ERROR(
+        "server_load_reporting_filter",
+        grpc_metadata_batch_filter(calld->recv_initial_metadata_->batch(),
+                                   RecvInitialMetadataFilter, elem,
+                                   "recv_initial_metadata filtering error"));
+    // If the LB token was not found in the recv_initial_metadata, only the
+    // client IP part will be recorded (with an empty LB token).
+    if (calld->client_ip_and_lr_token_ == nullptr) {
+      calld->StoreClientIpAndLrToken(nullptr, 0);
+    }
+    opencensus::stats::Record(
+        {{::grpc::load_reporter::MeasureStartCount(), 1}},
+        {{::grpc::load_reporter::TagKeyToken(),
+          {calld->client_ip_and_lr_token_, calld->client_ip_and_lr_token_len_}},
+         {::grpc::load_reporter::TagKeyHost(),
+          {calld->target_host_, calld->target_host_len_}},
+         {::grpc::load_reporter::TagKeyUserId(),
+          {chand->peer_identity(), chand->peer_identity_len()}}});
+  }
+  GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready_,
+                   GRPC_ERROR_REF(err));
 }
 }
 
 
-/* Destructor for channel data */
-static void destroy_channel_elem(grpc_channel_element* elem) {
-  /* TODO(dgq): do something with the data
-  channel_data *chand = elem->channel_data;
-  grpc_load_reporting_call_data lr_call_data = {
-      GRPC_LR_POINT_CHANNEL_DESTRUCTION,
-      (intptr_t)chand->id,
-      0,
-      NULL,
-      NULL,
-      NULL,
-      NULL};
-  */
+grpc_error* ServerLoadReportingCallData::Init(
+    grpc_call_element* elem, const grpc_call_element_args* args) {
+  service_method_ = grpc_empty_slice();
+  GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady,
+                    elem, grpc_schedule_on_exec_ctx);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
-static grpc_filtered_mdelem lr_trailing_md_filter(void* user_data,
-                                                  grpc_mdelem md) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
-  call_data* calld = static_cast<call_data*>(elem->call_data);
+grpc_filtered_mdelem ServerLoadReportingCallData::SendTrailingMetadataFilter(
+    void* user_data, grpc_mdelem md) {
+  grpc_call_element* elem = reinterpret_cast<grpc_call_element*>(user_data);
+  ServerLoadReportingCallData* calld =
+      reinterpret_cast<ServerLoadReportingCallData*>(elem->call_data);
+  ServerLoadReportingChannelData* chand =
+      reinterpret_cast<ServerLoadReportingChannelData*>(elem->channel_data);
+  // TODO(juanlishen): GRPC_MDSTR_LB_COST_BIN meaning?
   if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_LB_COST_BIN)) {
   if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_LB_COST_BIN)) {
-    calld->trailing_md_string = GRPC_MDVALUE(md);
+    const grpc_slice value = GRPC_MDVALUE(md);
+    const size_t cost_entry_size = GRPC_SLICE_LENGTH(value);
+    if (cost_entry_size < sizeof(double)) {
+      gpr_log(GPR_ERROR,
+              "Cost metadata value too small (%zu bytes) to hold valid data. "
+              "Ignoring.",
+              cost_entry_size);
+      return GRPC_FILTERED_REMOVE();
+    }
+    const double* cost_entry_ptr =
+        reinterpret_cast<const double*>(GRPC_SLICE_START_PTR(value));
+    double cost_value = *cost_entry_ptr++;
+    const char* cost_name = reinterpret_cast<const char*>(cost_entry_ptr);
+    const size_t cost_name_len = cost_entry_size - sizeof(double);
+    opencensus::stats::Record(
+        {{::grpc::load_reporter::MeasureOtherCallMetric(), cost_value}},
+        {{::grpc::load_reporter::TagKeyToken(),
+          {calld->client_ip_and_lr_token_, calld->client_ip_and_lr_token_len_}},
+         {::grpc::load_reporter::TagKeyHost(),
+          {calld->target_host_, calld->target_host_len_}},
+         {::grpc::load_reporter::TagKeyUserId(),
+          {chand->peer_identity(), chand->peer_identity_len()}},
+         {::grpc::load_reporter::TagKeyMetricName(),
+          {cost_name, cost_name_len}}});
     return GRPC_FILTERED_REMOVE();
     return GRPC_FILTERED_REMOVE();
   }
   }
   return GRPC_FILTERED_MDELEM(md);
   return GRPC_FILTERED_MDELEM(md);
 }
 }
 
 
-static void lr_start_transport_stream_op_batch(
-    grpc_call_element* elem, grpc_transport_stream_op_batch* op) {
-  GPR_TIMER_SCOPE("lr_start_transport_stream_op_batch", 0);
-  call_data* calld = static_cast<call_data*>(elem->call_data);
-
-  if (op->recv_initial_metadata) {
-    /* substitute our callback for the higher callback */
-    calld->recv_initial_metadata =
-        op->payload->recv_initial_metadata.recv_initial_metadata;
-    calld->ops_recv_initial_metadata_ready =
-        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
-    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
-        &calld->on_initial_md_ready;
-  } else if (op->send_trailing_metadata) {
-    GRPC_LOG_IF_ERROR(
-        "grpc_metadata_batch_filter",
-        grpc_metadata_batch_filter(
-            op->payload->send_trailing_metadata.send_trailing_metadata,
-            lr_trailing_md_filter, elem,
-            "LR trailing metadata filtering error"));
+const char* ServerLoadReportingCallData::GetStatusTagForStatus(
+    grpc_status_code status) {
+  switch (status) {
+    case GRPC_STATUS_OK:
+      return ::grpc::load_reporter::kCallStatusOk;
+    case GRPC_STATUS_UNKNOWN:
+    case GRPC_STATUS_DEADLINE_EXCEEDED:
+    case GRPC_STATUS_UNIMPLEMENTED:
+    case GRPC_STATUS_INTERNAL:
+    case GRPC_STATUS_UNAVAILABLE:
+    case GRPC_STATUS_DATA_LOSS:
+      return ::grpc::load_reporter::kCallStatusServerError;
+    default:
+      return ::grpc::load_reporter::kCallStatusClientError;
   }
   }
-  grpc_call_next_op(elem, op);
 }
 }
 
 
-const grpc_channel_filter grpc_server_load_reporting_filter = {
-    lr_start_transport_stream_op_batch,
-    grpc_channel_next_op,
-    sizeof(call_data),
-    init_call_elem,
-    grpc_call_stack_ignore_set_pollset_or_pollset_set,
-    destroy_call_elem,
-    sizeof(channel_data),
-    init_channel_elem,
-    destroy_channel_elem,
-    grpc_channel_next_get_info,
-    "load_reporting"};
+}  // namespace grpc

+ 97 - 2
src/core/ext/filters/load_reporting/server_load_reporting_filter.h

@@ -21,10 +21,105 @@
 
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
 
 
-#include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/cpp/common/channel_filter.h"
 
 
-extern const grpc_channel_filter grpc_server_load_reporting_filter;
+namespace grpc {
+
+class ServerLoadReportingChannelData : public ChannelData {
+ public:
+  grpc_error* Init(grpc_channel_element* elem,
+                   grpc_channel_element_args* args) override;
+
+  // Getters.
+  const char* peer_identity() { return peer_identity_; }
+  size_t peer_identity_len() { return peer_identity_len_; }
+
+ private:
+  // The peer's authenticated identity.
+  char* peer_identity_ = nullptr;
+  size_t peer_identity_len_ = 0;
+};
+
+class ServerLoadReportingCallData : public CallData {
+ public:
+  grpc_error* Init(grpc_call_element* elem,
+                   const grpc_call_element_args* args) override;
+
+  void Destroy(grpc_call_element* elem, const grpc_call_final_info* final_info,
+               grpc_closure* then_call_closure) override;
+
+  void StartTransportStreamOpBatch(grpc_call_element* elem,
+                                   TransportStreamOpBatch* op) override;
+
+ private:
+  // From the peer_string_ in calld, extracts the client IP string (owned by
+  // caller), e.g., "01020a0b". Upon failure, set the output pointer to null and
+  // size to zero.
+  void GetCensusSafeClientIpString(char** client_ip_string, size_t* size);
+
+  // Concatenates the client IP address and the load reporting token, then
+  // stores the result into the call data.
+  void StoreClientIpAndLrToken(const char* lr_token, size_t lr_token_len);
+
+  // This matches the classification of the status codes in
+  // googleapis/google/rpc/code.proto.
+  static const char* GetStatusTagForStatus(grpc_status_code status);
+
+  // Records the call start.
+  static void RecvInitialMetadataReady(void* arg, grpc_error* err);
+
+  // From the initial metadata, extracts the service_method_, target_host_, and
+  // client_ip_and_lr_token_.
+  static grpc_filtered_mdelem RecvInitialMetadataFilter(void* user_data,
+                                                        grpc_mdelem md);
+
+  // Records the other call metrics.
+  static grpc_filtered_mdelem SendTrailingMetadataFilter(void* user_data,
+                                                         grpc_mdelem md);
+
+  // The peer string (a member of the recv_initial_metadata op). Note that
+  // gpr_atm itself is a pointer type here, making "peer_string_" effectively a
+  // double pointer.
+  const gpr_atm* peer_string_;
+
+  // The received initial metadata (a member of the recv_initial_metadata op).
+  // When it is ready, we will extract some data from it via
+  // recv_initial_metadata_ready_ closure, before the original
+  // recv_initial_metadata_ready closure,
+  MetadataBatch* recv_initial_metadata_;
+
+  // The original recv_initial_metadata closure, which is wrapped by our own
+  // closure (recv_initial_metadata_ready_) to capture the incoming initial
+  // metadata.
+  grpc_closure* original_recv_initial_metadata_ready_;
+
+  // The closure that wraps the original closure. Scheduled when
+  // recv_initial_metadata_ is ready.
+  grpc_closure recv_initial_metadata_ready_;
+
+  // Corresponds to the :path header.
+  grpc_slice service_method_;
+
+  // The backend host that the client thinks it's talking to. This may be
+  // different from the actual backend in the case of, for example,
+  // load-balanced targets. We store a copy of the metadata slice in order to
+  // lowercase it. */
+  char* target_host_;
+  size_t target_host_len_;
+
+  // The client IP address (including a length prefix) and the load reporting
+  // token.
+  char* client_ip_and_lr_token_;
+  size_t client_ip_and_lr_token_len_;
+
+  static constexpr char kEncodedIpv4AddressLengthString[] = "08";
+  static constexpr char kEncodedIpv6AddressLengthString[] = "32";
+  static constexpr char kEmptyAddressLengthString[] = "00";
+  static constexpr size_t kLengthPrefixSize = 2;
+};
+
+}  // namespace grpc
 
 
 #endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_FILTER_H \
 #endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_FILTER_H \
         */
         */

+ 0 - 71
src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc

@@ -1,71 +0,0 @@
-/*
- *
- * Copyright 2016 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 <limits.h>
-#include <string.h>
-
-#include <grpc/load_reporting.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/sync.h>
-
-#include "src/core/ext/filters/load_reporting/server_load_reporting_filter.h"
-#include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h"
-#include "src/core/lib/channel/channel_stack_builder.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/surface/call.h"
-#include "src/core/lib/surface/channel_init.h"
-
-static bool is_load_reporting_enabled(const grpc_channel_args* a) {
-  return grpc_channel_arg_get_bool(
-      grpc_channel_args_find(a, GRPC_ARG_ENABLE_LOAD_REPORTING), false);
-}
-
-static bool maybe_add_server_load_reporting_filter(
-    grpc_channel_stack_builder* builder, void* arg) {
-  const grpc_channel_args* args =
-      grpc_channel_stack_builder_get_channel_arguments(builder);
-  const grpc_channel_filter* filter =
-      static_cast<const grpc_channel_filter*>(arg);
-  grpc_channel_stack_builder_iterator* it =
-      grpc_channel_stack_builder_iterator_find(builder, filter->name);
-  const bool already_has_load_reporting_filter =
-      !grpc_channel_stack_builder_iterator_is_end(it);
-  grpc_channel_stack_builder_iterator_destroy(it);
-  if (is_load_reporting_enabled(args) && !already_has_load_reporting_filter) {
-    return grpc_channel_stack_builder_prepend_filter(builder, filter, nullptr,
-                                                     nullptr);
-  }
-  return true;
-}
-
-grpc_arg grpc_load_reporting_enable_arg() {
-  return grpc_channel_arg_integer_create((char*)GRPC_ARG_ENABLE_LOAD_REPORTING,
-                                         1);
-}
-
-/* Plugin registration */
-
-void grpc_server_load_reporting_plugin_init(void) {
-  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
-                                   maybe_add_server_load_reporting_filter,
-                                   (void*)&grpc_server_load_reporting_filter);
-}
-
-void grpc_server_load_reporting_plugin_shutdown() {}

+ 0 - 61
src/core/ext/filters/load_reporting/server_load_reporting_plugin.h

@@ -1,61 +0,0 @@
-/*
- *
- * Copyright 2016 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_LOAD_REPORTING_SERVER_LOAD_REPORTING_PLUGIN_H
-#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_PLUGIN_H
-
-#include <grpc/support/port_platform.h>
-
-#include <grpc/impl/codegen/grpc_types.h>
-
-#include "src/core/lib/channel/channel_stack.h"
-
-/** Identifiers for the invocation point of the users LR callback */
-typedef enum grpc_load_reporting_source {
-  GRPC_LR_POINT_UNKNOWN = 0,
-  GRPC_LR_POINT_CHANNEL_CREATION,
-  GRPC_LR_POINT_CHANNEL_DESTRUCTION,
-  GRPC_LR_POINT_CALL_CREATION,
-  GRPC_LR_POINT_CALL_DESTRUCTION
-} grpc_load_reporting_source;
-
-/** Call information to be passed to the provided LR callback. */
-typedef struct grpc_load_reporting_call_data {
-  const grpc_load_reporting_source source; /**< point of last data update. */
-
-  /** Unique identifier for the channel associated with the data */
-  intptr_t channel_id;
-
-  /** Unique identifier for the call associated with the data. If the call
-   * hasn't been created yet, it'll have a value of zero. */
-  intptr_t call_id;
-
-  /** Only valid when \a source is \a GRPC_LR_POINT_CALL_DESTRUCTION, that is,
-   * once the call has completed */
-  const grpc_call_final_info* final_info;
-
-  const char* initial_md_string;  /**< value string for LR's initial md key */
-  const char* trailing_md_string; /**< value string for LR's trailing md key */
-  const char* method_name;        /**< Corresponds to :path header */
-} grpc_load_reporting_call_data;
-
-/** Return a \a grpc_arg enabling load reporting */
-grpc_arg grpc_load_reporting_enable_arg();
-
-#endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_PLUGIN_H \
-        */

+ 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 - 18
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,13 +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 {
-    return grpc_channel_check_connectivity_state(channel_, false);
-  }
-}
+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
@@ -136,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
@@ -181,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
 
 

+ 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();

+ 73 - 24
src/core/lib/iomgr/ev_epollex_linux.cc

@@ -104,8 +104,10 @@ struct pollable {
   int epfd;
   int epfd;
   grpc_wakeup_fd wakeup;
   grpc_wakeup_fd wakeup;
 
 
-  // only for type fd... one ref to the owner fd
-  grpc_fd* owner_fd;
+  // The following are relevant only for type PO_FD
+  grpc_fd* owner_fd;       // Set to the owner_fd if the type is PO_FD
+  gpr_mu owner_orphan_mu;  // Synchronizes access to owner_orphaned field
+  bool owner_orphaned;     // Is the owner fd orphaned
 
 
   grpc_pollset_set* pollset_set;
   grpc_pollset_set* pollset_set;
   pollable* next;
   pollable* next;
@@ -338,21 +340,45 @@ static void ref_by(grpc_fd* fd, int n) {
   GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
   GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
 }
 }
 
 
+#ifndef NDEBUG
+#define INVALIDATE_FD(fd) invalidate_fd(fd)
+/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is
+ * hard to cases where fd fields are accessed even after calling fd_destroy().
+ * The following invalidates fd fields to make catching such errors easier */
+static void invalidate_fd(grpc_fd* fd) {
+  fd->fd = -1;
+  fd->salt = -1;
+  gpr_atm_no_barrier_store(&fd->refst, -1);
+  memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu));
+  memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu));
+  fd->pollable_obj = nullptr;
+  fd->on_done_closure = nullptr;
+  gpr_atm_no_barrier_store(&fd->read_notifier_pollset, 0);
+  memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object));
+  fd->track_err = false;
+}
+#else
+#define INVALIDATE_FD(fd)
+#endif
+
+/* Uninitialize and add to the freelist */
 static void fd_destroy(void* arg, grpc_error* error) {
 static void fd_destroy(void* arg, grpc_error* error) {
   grpc_fd* fd = static_cast<grpc_fd*>(arg);
   grpc_fd* fd = static_cast<grpc_fd*>(arg);
-  /* Add the fd to the freelist */
   grpc_iomgr_unregister_object(&fd->iomgr_object);
   grpc_iomgr_unregister_object(&fd->iomgr_object);
   POLLABLE_UNREF(fd->pollable_obj, "fd_pollable");
   POLLABLE_UNREF(fd->pollable_obj, "fd_pollable");
   gpr_mu_destroy(&fd->pollable_mu);
   gpr_mu_destroy(&fd->pollable_mu);
   gpr_mu_destroy(&fd->orphan_mu);
   gpr_mu_destroy(&fd->orphan_mu);
-  gpr_mu_lock(&fd_freelist_mu);
-  fd->freelist_next = fd_freelist;
-  fd_freelist = fd;
 
 
   fd->read_closure->DestroyEvent();
   fd->read_closure->DestroyEvent();
   fd->write_closure->DestroyEvent();
   fd->write_closure->DestroyEvent();
   fd->error_closure->DestroyEvent();
   fd->error_closure->DestroyEvent();
 
 
+  INVALIDATE_FD(fd);
+
+  /* Add the fd to the freelist */
+  gpr_mu_lock(&fd_freelist_mu);
+  fd->freelist_next = fd_freelist;
+  fd_freelist = fd;
   gpr_mu_unlock(&fd_freelist_mu);
   gpr_mu_unlock(&fd_freelist_mu);
 }
 }
 
 
@@ -408,20 +434,18 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
     new_fd->error_closure.Init();
     new_fd->error_closure.Init();
   }
   }
 
 
-  gpr_mu_init(&new_fd->pollable_mu);
-  gpr_mu_init(&new_fd->orphan_mu);
-  new_fd->pollable_obj = nullptr;
-  gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
   new_fd->fd = fd;
   new_fd->fd = fd;
-  new_fd->track_err = track_err;
   new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1);
   new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1);
+  gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
+  gpr_mu_init(&new_fd->orphan_mu);
+  gpr_mu_init(&new_fd->pollable_mu);
+  new_fd->pollable_obj = nullptr;
   new_fd->read_closure->InitEvent();
   new_fd->read_closure->InitEvent();
   new_fd->write_closure->InitEvent();
   new_fd->write_closure->InitEvent();
   new_fd->error_closure->InitEvent();
   new_fd->error_closure->InitEvent();
-  gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
-
   new_fd->freelist_next = nullptr;
   new_fd->freelist_next = nullptr;
   new_fd->on_done_closure = nullptr;
   new_fd->on_done_closure = nullptr;
+  gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
 
 
   char* fd_name;
   char* fd_name;
   gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
   gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
@@ -432,6 +456,8 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
   }
   }
 #endif
 #endif
   gpr_free(fd_name);
   gpr_free(fd_name);
+
+  new_fd->track_err = track_err;
   return new_fd;
   return new_fd;
 }
 }
 
 
@@ -446,6 +472,17 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
 
 
   gpr_mu_lock(&fd->orphan_mu);
   gpr_mu_lock(&fd->orphan_mu);
 
 
+  // Get the fd->pollable_obj and set the owner_orphaned on that pollable to
+  // true so that the pollable will no longer access its owner_fd field.
+  gpr_mu_lock(&fd->pollable_mu);
+  pollable* pollable_obj = fd->pollable_obj;
+  gpr_mu_unlock(&fd->pollable_mu);
+
+  if (pollable_obj) {
+    gpr_mu_lock(&pollable_obj->owner_orphan_mu);
+    pollable_obj->owner_orphaned = true;
+  }
+
   fd->on_done_closure = on_done;
   fd->on_done_closure = on_done;
 
 
   /* If release_fd is not NULL, we should be relinquishing control of the file
   /* If release_fd is not NULL, we should be relinquishing control of the file
@@ -467,6 +504,10 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
 
 
   GRPC_CLOSURE_SCHED(fd->on_done_closure, GRPC_ERROR_NONE);
   GRPC_CLOSURE_SCHED(fd->on_done_closure, GRPC_ERROR_NONE);
 
 
+  if (pollable_obj) {
+    gpr_mu_unlock(&pollable_obj->owner_orphan_mu);
+  }
+
   gpr_mu_unlock(&fd->orphan_mu);
   gpr_mu_unlock(&fd->orphan_mu);
 
 
   UNREF_BY(fd, 2, reason); /* Drop the reference */
   UNREF_BY(fd, 2, reason); /* Drop the reference */
@@ -551,6 +592,8 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) {
   gpr_mu_init(&(*p)->mu);
   gpr_mu_init(&(*p)->mu);
   (*p)->epfd = epfd;
   (*p)->epfd = epfd;
   (*p)->owner_fd = nullptr;
   (*p)->owner_fd = nullptr;
+  gpr_mu_init(&(*p)->owner_orphan_mu);
+  (*p)->owner_orphaned = false;
   (*p)->pollset_set = nullptr;
   (*p)->pollset_set = nullptr;
   (*p)->next = (*p)->prev = *p;
   (*p)->next = (*p)->prev = *p;
   (*p)->root_worker = nullptr;
   (*p)->root_worker = nullptr;
@@ -590,6 +633,7 @@ static void pollable_unref(pollable* p, int line, const char* reason) {
     GRPC_FD_TRACE("pollable_unref: Closing epfd: %d", p->epfd);
     GRPC_FD_TRACE("pollable_unref: Closing epfd: %d", p->epfd);
     close(p->epfd);
     close(p->epfd);
     grpc_wakeup_fd_destroy(&p->wakeup);
     grpc_wakeup_fd_destroy(&p->wakeup);
+    gpr_mu_destroy(&p->owner_orphan_mu);
     gpr_free(p);
     gpr_free(p);
   }
   }
 }
 }
@@ -846,10 +890,15 @@ static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
 
 
 static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
 static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
 
 
-static grpc_error* fd_get_or_become_pollable(grpc_fd* fd, pollable** p) {
+/* Get the pollable_obj attached to this fd. If none is attached, create a new
+ * pollable object (of type PO_FD), attach it to the fd and return it
+ *
+ * Note that if a pollable object is already attached to the fd, it may be of
+ * either PO_FD or PO_MULTI type */
+static grpc_error* get_fd_pollable(grpc_fd* fd, pollable** p) {
   gpr_mu_lock(&fd->pollable_mu);
   gpr_mu_lock(&fd->pollable_mu);
   grpc_error* error = GRPC_ERROR_NONE;
   grpc_error* error = GRPC_ERROR_NONE;
-  static const char* err_desc = "fd_get_or_become_pollable";
+  static const char* err_desc = "get_fd_pollable";
   if (fd->pollable_obj == nullptr) {
   if (fd->pollable_obj == nullptr) {
     if (append_error(&error, pollable_create(PO_FD, &fd->pollable_obj),
     if (append_error(&error, pollable_create(PO_FD, &fd->pollable_obj),
                      err_desc)) {
                      err_desc)) {
@@ -1186,7 +1235,7 @@ static grpc_error* pollset_transition_pollable_from_empty_to_fd_locked(
   }
   }
   append_error(&error, pollset_kick_all(pollset), err_desc);
   append_error(&error, pollset_kick_all(pollset), err_desc);
   POLLABLE_UNREF(pollset->active_pollable, "pollset");
   POLLABLE_UNREF(pollset->active_pollable, "pollset");
-  append_error(&error, fd_get_or_become_pollable(fd, &pollset->active_pollable),
+  append_error(&error, get_fd_pollable(fd, &pollset->active_pollable),
                err_desc);
                err_desc);
   return error;
   return error;
 }
 }
@@ -1230,9 +1279,8 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) {
       error = pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
       error = pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
       break;
       break;
     case PO_FD:
     case PO_FD:
-      gpr_mu_lock(&po_at_start->owner_fd->orphan_mu);
-      if ((gpr_atm_no_barrier_load(&pollset->active_pollable->owner_fd->refst) &
-           1) == 0) {
+      gpr_mu_lock(&po_at_start->owner_orphan_mu);
+      if (po_at_start->owner_orphaned) {
         error =
         error =
             pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
             pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
       } else {
       } else {
@@ -1240,7 +1288,7 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) {
         error =
         error =
             pollset_transition_pollable_from_fd_to_multi_locked(pollset, fd);
             pollset_transition_pollable_from_fd_to_multi_locked(pollset, fd);
       }
       }
-      gpr_mu_unlock(&po_at_start->owner_fd->orphan_mu);
+      gpr_mu_unlock(&po_at_start->owner_orphan_mu);
       break;
       break;
     case PO_MULTI:
     case PO_MULTI:
       error = pollable_add_fd(pollset->active_pollable, fd);
       error = pollable_add_fd(pollset->active_pollable, fd);
@@ -1276,16 +1324,17 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset,
       append_error(&error, pollset_kick_all(pollset), err_desc);
       append_error(&error, pollset_kick_all(pollset), err_desc);
       break;
       break;
     case PO_FD:
     case PO_FD:
-      gpr_mu_lock(&po_at_start->owner_fd->orphan_mu);
-      if ((gpr_atm_no_barrier_load(&pollset->active_pollable->owner_fd->refst) &
-           1) == 0) {
+      gpr_mu_lock(&po_at_start->owner_orphan_mu);
+      if (po_at_start->owner_orphaned) {
+        // Unlock before Unref'ing the pollable
+        gpr_mu_unlock(&po_at_start->owner_orphan_mu);
         POLLABLE_UNREF(pollset->active_pollable, "pollset");
         POLLABLE_UNREF(pollset->active_pollable, "pollset");
         error = pollable_create(PO_MULTI, &pollset->active_pollable);
         error = pollable_create(PO_MULTI, &pollset->active_pollable);
       } else {
       } else {
         error = pollset_transition_pollable_from_fd_to_multi_locked(pollset,
         error = pollset_transition_pollable_from_fd_to_multi_locked(pollset,
                                                                     nullptr);
                                                                     nullptr);
+        gpr_mu_unlock(&po_at_start->owner_orphan_mu);
       }
       }
-      gpr_mu_unlock(&po_at_start->owner_fd->orphan_mu);
       break;
       break;
     case PO_MULTI:
     case PO_MULTI:
       break;
       break;

+ 9 - 2
src/core/lib/iomgr/exec_ctx.h

@@ -45,6 +45,9 @@ typedef struct grpc_combiner grpc_combiner;
 /* The exec_ctx's thread is (potentially) owned by a call or channel: care
 /* The exec_ctx's thread is (potentially) owned by a call or channel: care
    should be given to not delete said call/channel from this exec_ctx */
    should be given to not delete said call/channel from this exec_ctx */
 #define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2
 #define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2
+/* This exec ctx was initialized by an internal thread, and should not
+   be counted by fork handlers */
+#define GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 4
 
 
 extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx;
 extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx;
 
 
@@ -93,7 +96,9 @@ class ExecCtx {
 
 
   /** Parameterised Constructor */
   /** Parameterised Constructor */
   ExecCtx(uintptr_t fl) : flags_(fl) {
   ExecCtx(uintptr_t fl) : flags_(fl) {
-    grpc_core::Fork::IncExecCtxCount();
+    if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) {
+      grpc_core::Fork::IncExecCtxCount();
+    }
     Set(this);
     Set(this);
   }
   }
 
 
@@ -102,7 +107,9 @@ class ExecCtx {
     flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
     flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
     Flush();
     Flush();
     Set(last_exec_ctx_);
     Set(last_exec_ctx_);
-    grpc_core::Fork::DecExecCtxCount();
+    if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) {
+      grpc_core::Fork::DecExecCtxCount();
+    }
   }
   }
 
 
   /** Disallow copy and assignment operators */
   /** Disallow copy and assignment operators */

+ 1 - 1
src/core/lib/iomgr/executor.cc

@@ -145,7 +145,7 @@ static void executor_thread(void* arg) {
   thread_state* ts = static_cast<thread_state*>(arg);
   thread_state* ts = static_cast<thread_state*>(arg);
   gpr_tls_set(&g_this_thread_state, (intptr_t)ts);
   gpr_tls_set(&g_this_thread_state, (intptr_t)ts);
 
 
-  grpc_core::ExecCtx exec_ctx(0);
+  grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD);
 
 
   size_t subtract_depth = 0;
   size_t subtract_depth = 0;
   for (;;) {
   for (;;) {

+ 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 */

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

@@ -265,7 +265,7 @@ static void timer_thread_cleanup(completed_thread* ct) {
 static void timer_thread(void* completed_thread_ptr) {
 static void timer_thread(void* completed_thread_ptr) {
   // this threads exec_ctx: we try to run things through to completion here
   // this threads exec_ctx: we try to run things through to completion here
   // since it's easy to spin up new threads
   // since it's easy to spin up new threads
-  grpc_core::ExecCtx exec_ctx(0);
+  grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD);
   timer_main_loop();
   timer_main_loop();
 
 
   timer_thread_cleanup(static_cast<completed_thread*>(completed_thread_ptr));
   timer_thread_cleanup(static_cast<completed_thread*>(completed_thread_ptr));
@@ -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);
   }
   }
 }
 }

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

@@ -21,6 +21,7 @@
 #include <string.h>
 #include <string.h>
 
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_args.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/security/context/security_context.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -49,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);
@@ -81,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) {
@@ -95,14 +97,13 @@ 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 --- */
-
-grpc_server_security_context* grpc_server_security_context_create(void) {
+grpc_server_security_context* grpc_server_security_context_create(
+    gpr_arena* arena) {
   return static_cast<grpc_server_security_context*>(
   return static_cast<grpc_server_security_context*>(
-      gpr_zalloc(sizeof(grpc_server_security_context)));
+      gpr_arena_alloc(arena, sizeof(grpc_server_security_context)));
 }
 }
 
 
 void grpc_server_security_context_destroy(void* ctx) {
 void grpc_server_security_context_destroy(void* ctx) {
@@ -112,7 +113,6 @@ void grpc_server_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_auth_context --- */
 /* --- grpc_auth_context --- */

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

@@ -26,6 +26,8 @@
 
 
 extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
 extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
 
 
+struct gpr_arena;
+
 /* --- grpc_auth_context ---
 /* --- grpc_auth_context ---
 
 
    High level authentication context object. Can optionally be chained. */
    High level authentication context object. Can optionally be chained. */
@@ -89,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 ---
@@ -101,7 +104,8 @@ typedef struct {
   grpc_security_context_extension extension;
   grpc_security_context_extension extension;
 } grpc_server_security_context;
 } grpc_server_security_context;
 
 
-grpc_server_security_context* grpc_server_security_context_create(void);
+grpc_server_security_context* grpc_server_security_context_create(
+    gpr_arena* arena);
 void grpc_server_security_context_destroy(void* ctx);
 void grpc_server_security_context_destroy(void* ctx);
 
 
 /* --- Channel args for auth context --- */
 /* --- Channel args for auth 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();

+ 4 - 5
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;
     }
     }
@@ -214,9 +213,9 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
   // Create server security context.  Set its auth context from channel
   // Create server security context.  Set its auth context from channel
   // 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();
-  server_ctx->auth_context = grpc_auth_context_create(chand->auth_context);
-  calld->auth_context = server_ctx->auth_context;
+      grpc_server_security_context_create(args->arena);
+  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);

+ 6 - 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"
@@ -227,16 +228,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)
@@ -301,7 +298,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);
   gpr_atm_no_barrier_store(&call->cancelled, 0);
   gpr_atm_no_barrier_store(&call->cancelled, 0);
@@ -1029,6 +1026,8 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b,
   GRPC_ERROR_UNREF(batch_error);
   GRPC_ERROR_UNREF(batch_error);
 }
 }
 
 
+gpr_arena* grpc_call_get_arena(grpc_call* call) { return call->arena; }
+
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) {
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) {
   return CALL_STACK_FROM_CALL(call);
   return CALL_STACK_FROM_CALL(call);
 }
 }

+ 2 - 0
src/core/lib/surface/call.h

@@ -71,6 +71,8 @@ void grpc_call_internal_unref(grpc_call* call);
 #define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call)
 #define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call)
 #endif
 #endif
 
 
+gpr_arena* grpc_call_get_arena(grpc_call* call);
+
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call);
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call);
 
 
 grpc_call_error grpc_call_start_batch_and_execute(grpc_call* call,
 grpc_call_error grpc_call_start_batch_and_execute(grpc_call* call,

+ 13 - 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;
 
 
@@ -145,14 +149,20 @@ grpc_channel* grpc_channel_create_with_builder(
           (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_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 +410,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));

+ 0 - 4
src/core/plugin_registry/grpc_cronet_plugin_registry.cc

@@ -30,8 +30,6 @@ void grpc_client_channel_init(void);
 void grpc_client_channel_shutdown(void);
 void grpc_client_channel_shutdown(void);
 void grpc_tsi_alts_init(void);
 void grpc_tsi_alts_init(void);
 void grpc_tsi_alts_shutdown(void);
 void grpc_tsi_alts_shutdown(void);
-void grpc_server_load_reporting_plugin_init(void);
-void grpc_server_load_reporting_plugin_shutdown(void);
 
 
 void grpc_register_built_in_plugins(void) {
 void grpc_register_built_in_plugins(void) {
   grpc_register_plugin(grpc_http_filters_init,
   grpc_register_plugin(grpc_http_filters_init,
@@ -44,6 +42,4 @@ void grpc_register_built_in_plugins(void) {
                        grpc_client_channel_shutdown);
                        grpc_client_channel_shutdown);
   grpc_register_plugin(grpc_tsi_alts_init,
   grpc_register_plugin(grpc_tsi_alts_init,
                        grpc_tsi_alts_shutdown);
                        grpc_tsi_alts_shutdown);
-  grpc_register_plugin(grpc_server_load_reporting_plugin_init,
-                       grpc_server_load_reporting_plugin_shutdown);
 }
 }

+ 0 - 4
src/core/plugin_registry/grpc_plugin_registry.cc

@@ -46,8 +46,6 @@ void grpc_resolver_dns_native_init(void);
 void grpc_resolver_dns_native_shutdown(void);
 void grpc_resolver_dns_native_shutdown(void);
 void grpc_resolver_sockaddr_init(void);
 void grpc_resolver_sockaddr_init(void);
 void grpc_resolver_sockaddr_shutdown(void);
 void grpc_resolver_sockaddr_shutdown(void);
-void grpc_server_load_reporting_plugin_init(void);
-void grpc_server_load_reporting_plugin_shutdown(void);
 void grpc_max_age_filter_init(void);
 void grpc_max_age_filter_init(void);
 void grpc_max_age_filter_shutdown(void);
 void grpc_max_age_filter_shutdown(void);
 void grpc_message_size_filter_init(void);
 void grpc_message_size_filter_init(void);
@@ -84,8 +82,6 @@ void grpc_register_built_in_plugins(void) {
                        grpc_resolver_dns_native_shutdown);
                        grpc_resolver_dns_native_shutdown);
   grpc_register_plugin(grpc_resolver_sockaddr_init,
   grpc_register_plugin(grpc_resolver_sockaddr_init,
                        grpc_resolver_sockaddr_shutdown);
                        grpc_resolver_sockaddr_shutdown);
-  grpc_register_plugin(grpc_server_load_reporting_plugin_init,
-                       grpc_server_load_reporting_plugin_shutdown);
   grpc_register_plugin(grpc_max_age_filter_init,
   grpc_register_plugin(grpc_max_age_filter_init,
                        grpc_max_age_filter_shutdown);
                        grpc_max_age_filter_shutdown);
   grpc_register_plugin(grpc_message_size_filter_init,
   grpc_register_plugin(grpc_message_size_filter_init,

+ 0 - 4
src/core/plugin_registry/grpc_unsecure_plugin_registry.cc

@@ -38,8 +38,6 @@ void grpc_resolver_sockaddr_init(void);
 void grpc_resolver_sockaddr_shutdown(void);
 void grpc_resolver_sockaddr_shutdown(void);
 void grpc_resolver_fake_init(void);
 void grpc_resolver_fake_init(void);
 void grpc_resolver_fake_shutdown(void);
 void grpc_resolver_fake_shutdown(void);
-void grpc_server_load_reporting_plugin_init(void);
-void grpc_server_load_reporting_plugin_shutdown(void);
 void grpc_lb_policy_grpclb_init(void);
 void grpc_lb_policy_grpclb_init(void);
 void grpc_lb_policy_grpclb_shutdown(void);
 void grpc_lb_policy_grpclb_shutdown(void);
 void grpc_lb_policy_pick_first_init(void);
 void grpc_lb_policy_pick_first_init(void);
@@ -74,8 +72,6 @@ void grpc_register_built_in_plugins(void) {
                        grpc_resolver_sockaddr_shutdown);
                        grpc_resolver_sockaddr_shutdown);
   grpc_register_plugin(grpc_resolver_fake_init,
   grpc_register_plugin(grpc_resolver_fake_init,
                        grpc_resolver_fake_shutdown);
                        grpc_resolver_fake_shutdown);
-  grpc_register_plugin(grpc_server_load_reporting_plugin_init,
-                       grpc_server_load_reporting_plugin_shutdown);
   grpc_register_plugin(grpc_lb_policy_grpclb_init,
   grpc_register_plugin(grpc_lb_policy_grpclb_init,
                        grpc_lb_policy_grpclb_shutdown);
                        grpc_lb_policy_grpclb_shutdown);
   grpc_register_plugin(grpc_lb_policy_pick_first_init,
   grpc_register_plugin(grpc_lb_policy_pick_first_init,

+ 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");
   }
   }

+ 0 - 1
src/core/tsi/alts/handshaker/altscontext.pb.c

@@ -2,7 +2,6 @@
 /* Generated by nanopb-0.3.7-dev */
 /* Generated by nanopb-0.3.7-dev */
 
 
 #include "src/core/tsi/alts/handshaker/altscontext.pb.h"
 #include "src/core/tsi/alts/handshaker/altscontext.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.

+ 0 - 1
src/core/tsi/alts/handshaker/altscontext.pb.h

@@ -5,7 +5,6 @@
 #define PB_GRPC_GCP_ALTSCONTEXT_PB_H_INCLUDED
 #define PB_GRPC_GCP_ALTSCONTEXT_PB_H_INCLUDED
 #include "pb.h"
 #include "pb.h"
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.

+ 0 - 1
src/core/tsi/alts/handshaker/handshaker.pb.c

@@ -2,7 +2,6 @@
 /* Generated by nanopb-0.3.7-dev */
 /* Generated by nanopb-0.3.7-dev */
 
 
 #include "src/core/tsi/alts/handshaker/handshaker.pb.h"
 #include "src/core/tsi/alts/handshaker/handshaker.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.

+ 0 - 1
src/core/tsi/alts/handshaker/handshaker.pb.h

@@ -5,7 +5,6 @@
 #define PB_GRPC_GCP_HANDSHAKER_PB_H_INCLUDED
 #define PB_GRPC_GCP_HANDSHAKER_PB_H_INCLUDED
 #include "pb.h"
 #include "pb.h"
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.

+ 0 - 1
src/core/tsi/alts/handshaker/transport_security_common.pb.c

@@ -2,7 +2,6 @@
 /* Generated by nanopb-0.3.7-dev */
 /* Generated by nanopb-0.3.7-dev */
 
 
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
 #include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
-
 /* @@protoc_insertion_point(includes) */
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #error Regenerate this file with the current version of nanopb generator.

+ 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.  */
+  size_t protected_frame_size =
+      unprotected_slices->length + rp->header_length + rp->tag_length;
+  grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
+  /* 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 + unprotected_slices->length,
+                       rp->tag_length};
+  alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
+                                                          unprotected_slices);
+  grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
+      rp->iovec_rp, rp->iovec_buf, unprotected_slices->count, 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;
+  }
+  /* Copies data from unprotected_slices to protected_slice.  */
+  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]);
+  }
+  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.

+ 12 - 0
src/cpp/common/channel_filter.h

@@ -207,6 +207,18 @@ class TransportStreamOpBatch {
         op_->payload->context[GRPC_CONTEXT_TRACING].value);
         op_->payload->context[GRPC_CONTEXT_TRACING].value);
   }
   }
 
 
+  const gpr_atm* get_peer_string() const {
+    if (op_->send_initial_metadata &&
+        op_->payload->send_initial_metadata.peer_string != nullptr) {
+      return op_->payload->send_initial_metadata.peer_string;
+    } else if (op_->recv_initial_metadata &&
+               op_->payload->recv_initial_metadata.peer_string != nullptr) {
+      return op_->payload->recv_initial_metadata.peer_string;
+    } else {
+      return nullptr;
+    }
+  }
+
  private:
  private:
   grpc_transport_stream_op_batch* op_;  // Not owned.
   grpc_transport_stream_op_batch* op_;  // Not owned.
   MetadataBatch send_initial_metadata_;
   MetadataBatch send_initial_metadata_;

+ 71 - 0
src/cpp/server/load_reporter/constants.h

@@ -0,0 +1,71 @@
+/*
+ *
+ * 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_SRC_CPP_SERVER_LOAD_REPORTER_UTIL_H
+#define GRPC_SRC_CPP_SERVER_LOAD_REPORTER_UTIL_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+namespace grpc {
+namespace load_reporter {
+
+constexpr size_t kLbIdLength = 8;
+constexpr size_t kIpv4AddressLength = 8;
+constexpr size_t kIpv6AddressLength = 32;
+
+constexpr char kInvalidLbId[] = "<INVALID_LBID_238dsb234890rb>";
+
+// Call statuses.
+
+constexpr char kCallStatusOk[] = "OK";
+constexpr char kCallStatusServerError[] = "5XX";
+constexpr char kCallStatusClientError[] = "4XX";
+
+// Tag keys.
+
+constexpr char kTagKeyToken[] = "token";
+constexpr char kTagKeyHost[] = "host";
+constexpr char kTagKeyUserId[] = "user_id";
+constexpr char kTagKeyStatus[] = "status";
+constexpr char kTagKeyMetricName[] = "metric_name";
+
+// Measure names.
+
+constexpr char kMeasureStartCount[] = "grpc.io/lb/start_count";
+constexpr char kMeasureEndCount[] = "grpc.io/lb/end_count";
+constexpr char kMeasureEndBytesSent[] = "grpc.io/lb/bytes_sent";
+constexpr char kMeasureEndBytesReceived[] = "grpc.io/lb/bytes_received";
+constexpr char kMeasureEndLatencyMs[] = "grpc.io/lb/latency_ms";
+constexpr char kMeasureOtherCallMetric[] = "grpc.io/lb/other_call_metric";
+
+// View names.
+
+constexpr char kViewStartCount[] = "grpc.io/lb_view/start_count";
+constexpr char kViewEndCount[] = "grpc.io/lb_view/end_count";
+constexpr char kViewEndBytesSent[] = "grpc.io/lb_view/bytes_sent";
+constexpr char kViewEndBytesReceived[] = "grpc.io/lb_view/bytes_received";
+constexpr char kViewEndLatencyMs[] = "grpc.io/lb_view/latency_ms";
+constexpr char kViewOtherCallMetricCount[] =
+    "grpc.io/lb_view/other_call_metric_count";
+constexpr char kViewOtherCallMetricValue[] =
+    "grpc.io/lb_view/other_call_metric_value";
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // GRPC_SRC_CPP_SERVER_LOAD_REPORTER_UTIL_H

+ 36 - 0
src/cpp/server/load_reporter/get_cpu_stats.h

@@ -0,0 +1,36 @@
+/*
+ *
+ * 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_SRC_CPP_SERVER_LOAD_REPORTER_GET_CPU_STATS_H
+#define GRPC_SRC_CPP_SERVER_LOAD_REPORTER_GET_CPU_STATS_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <utility>
+
+namespace grpc {
+namespace load_reporter {
+
+// Reads the CPU stats (in a pair of busy and total numbers) from the system.
+// The units of the stats should be the same.
+std::pair<uint64_t, uint64_t> GetCpuStatsImpl();
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // GRPC_SRC_CPP_SERVER_LOAD_REPORTER_GET_CPU_STATS_H

+ 45 - 0
src/cpp/server/load_reporter/get_cpu_stats_linux.cc

@@ -0,0 +1,45 @@
+/*
+ *
+ * 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>
+
+#ifdef GPR_LINUX
+
+#include <cstdio>
+
+#include "src/cpp/server/load_reporter/get_cpu_stats.h"
+
+namespace grpc {
+namespace load_reporter {
+
+std::pair<uint64_t, uint64_t> GetCpuStatsImpl() {
+  uint64_t busy = 0, total = 0;
+  FILE* fp;
+  fp = fopen("/proc/stat", "r");
+  uint64_t user, nice, system, idle;
+  fscanf(fp, "cpu %lu %lu %lu %lu", &user, &nice, &system, &idle);
+  fclose(fp);
+  busy = user + nice + system;
+  total = busy + idle;
+  return std::make_pair(busy, total);
+}
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // GPR_LINUX

+ 45 - 0
src/cpp/server/load_reporter/get_cpu_stats_macos.cc

@@ -0,0 +1,45 @@
+/*
+ *
+ * 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>
+
+#ifdef GPR_APPLE
+
+#include <mach/mach.h>
+
+#include "src/cpp/server/load_reporter/get_cpu_stats.h"
+
+namespace grpc {
+namespace load_reporter {
+
+std::pair<uint64_t, uint64_t> GetCpuStatsImpl() {
+  uint64_t busy = 0, total = 0;
+  host_cpu_load_info_data_t cpuinfo;
+  mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+  if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO,
+                      (host_info_t)&cpuinfo, &count) == KERN_SUCCESS) {
+    for (int i = 0; i < CPU_STATE_MAX; i++) total += cpuinfo.cpu_ticks[i];
+    busy = total - cpuinfo.cpu_ticks[CPU_STATE_IDLE];
+  }
+  return std::make_pair(busy, total);
+}
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // GPR_APPLE

+ 40 - 0
src/cpp/server/load_reporter/get_cpu_stats_unsupported.cc

@@ -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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#if !defined(GPR_LINUX) && !defined(GPR_WINDOWS) && !defined(GPR_APPLE)
+
+#include <grpc/support/log.h>
+
+#include "src/cpp/server/load_reporter/get_cpu_stats.h"
+
+namespace grpc {
+namespace load_reporter {
+
+std::pair<uint64_t, uint64_t> GetCpuStatsImpl() {
+  uint64_t busy = 0, total = 0;
+  gpr_log(GPR_ERROR,
+          "Platforms other than Linux, Windows, and MacOS are not supported.");
+  return std::make_pair(busy, total);
+}
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // !defined(GPR_LINUX) && !defined(GPR_WINDOWS) && !defined(GPR_APPLE)

+ 55 - 0
src/cpp/server/load_reporter/get_cpu_stats_windows.cc

@@ -0,0 +1,55 @@
+/*
+ *
+ * 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>
+
+#ifdef GPR_WINDOWS
+
+#include <windows.h>
+#include <cstdint>
+
+#include "src/cpp/server/load_reporter/get_cpu_stats.h"
+
+namespace grpc {
+namespace load_reporter {
+
+namespace {
+
+uint64_t FiletimeToInt(const FILETIME& ft) {
+  ULARGE_INTEGER i;
+  i.LowPart = ft.dwLowDateTime;
+  i.HighPart = ft.dwHighDateTime;
+  return i.QuadPart;
+}
+
+}  // namespace
+
+std::pair<uint64_t, uint64_t> GetCpuStatsImpl() {
+  uint64_t busy = 0, total = 0;
+  FILETIME idle, kernel, user;
+  if (GetSystemTimes(&idle, &kernel, &user) != 0) {
+    total = FiletimeToInt(kernel) + FiletimeToInt(user);
+    busy = total - FiletimeToInt(idle);
+  }
+  return std::make_pair(busy, total);
+}
+
+}  // namespace load_reporter
+}  // namespace grpc
+
+#endif  // GPR_WINDOWS

+ 65 - 0
src/cpp/server/load_reporter/load_data_store.cc

@@ -16,11 +16,15 @@
  *
  *
  */
  */
 
 
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <stdio.h>
 #include <cstdlib>
 #include <cstdlib>
 #include <set>
 #include <set>
 #include <unordered_map>
 #include <unordered_map>
 #include <vector>
 #include <vector>
 
 
+#include "src/core/lib/iomgr/socket_utils.h"
 #include "src/cpp/server/load_reporter/load_data_store.h"
 #include "src/cpp/server/load_reporter/load_data_store.h"
 
 
 namespace grpc {
 namespace grpc {
@@ -73,6 +77,67 @@ const typename C::value_type* RandomElement(const C& container) {
 
 
 }  // namespace
 }  // namespace
 
 
+LoadRecordKey::LoadRecordKey(const grpc::string& client_ip_and_token,
+                             grpc::string user_id)
+    : user_id_(std::move(user_id)) {
+  GPR_ASSERT(client_ip_and_token.size() >= 2);
+  int ip_hex_size;
+  GPR_ASSERT(sscanf(client_ip_and_token.substr(0, 2).c_str(), "%d",
+                    &ip_hex_size) == 1);
+  GPR_ASSERT(ip_hex_size == 0 || ip_hex_size == kIpv4AddressLength ||
+             ip_hex_size == kIpv6AddressLength);
+  size_t cur_pos = 2;
+  client_ip_hex_ = client_ip_and_token.substr(cur_pos, ip_hex_size);
+  cur_pos += ip_hex_size;
+  if (client_ip_and_token.size() - cur_pos < kLbIdLength) {
+    lb_id_ = kInvalidLbId;
+    lb_tag_ = "";
+  } else {
+    lb_id_ = client_ip_and_token.substr(cur_pos, kLbIdLength);
+    lb_tag_ = client_ip_and_token.substr(cur_pos + kLbIdLength);
+  }
+}
+
+grpc::string LoadRecordKey::GetClientIpBytes() const {
+  if (client_ip_hex_.empty()) {
+    return "";
+  } else if (client_ip_hex_.size() == kIpv4AddressLength) {
+    uint32_t ip_bytes;
+    if (sscanf(client_ip_hex_.c_str(), "%x", &ip_bytes) != 1) {
+      gpr_log(GPR_ERROR,
+              "Can't parse client IP (%s) from a hex string to an integer.",
+              client_ip_hex_.c_str());
+      return "";
+    }
+    ip_bytes = grpc_htonl(ip_bytes);
+    return grpc::string(reinterpret_cast<const char*>(&ip_bytes),
+                        sizeof(ip_bytes));
+  } else if (client_ip_hex_.size() == kIpv6AddressLength) {
+    uint32_t ip_bytes[4];
+    for (size_t i = 0; i < 4; ++i) {
+      if (sscanf(client_ip_hex_.substr(i * 8, (i + 1) * 8).c_str(), "%x",
+                 ip_bytes + i) != 1) {
+        gpr_log(
+            GPR_ERROR,
+            "Can't parse client IP part (%s) from a hex string to an integer.",
+            client_ip_hex_.substr(i * 8, (i + 1) * 8).c_str());
+        return "";
+      }
+      ip_bytes[i] = grpc_htonl(ip_bytes[i]);
+    }
+    return grpc::string(reinterpret_cast<const char*>(ip_bytes),
+                        sizeof(ip_bytes));
+  } else {
+    GPR_UNREACHABLE_CODE(return "");
+  }
+}
+
+LoadRecordValue::LoadRecordValue(grpc::string metric_name, uint64_t num_calls,
+                                 double total_metric_value) {
+  call_metrics_.emplace(std::move(metric_name),
+                        CallMetricValue(num_calls, total_metric_value));
+}
+
 void PerBalancerStore::MergeRow(const LoadRecordKey& key,
 void PerBalancerStore::MergeRow(const LoadRecordKey& key,
                                 const LoadRecordValue& value) {
                                 const LoadRecordValue& value) {
   // During suspension, the load data received will be dropped.
   // During suspension, the load data received will be dropped.

+ 21 - 13
src/cpp/server/load_reporter/load_data_store.h

@@ -28,12 +28,11 @@
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 #include <grpcpp/impl/codegen/config.h>
 #include <grpcpp/impl/codegen/config.h>
 
 
+#include "src/cpp/server/load_reporter/constants.h"
+
 namespace grpc {
 namespace grpc {
 namespace load_reporter {
 namespace load_reporter {
 
 
-constexpr char kInvalidLbId[] = "<INVALID_LBID_238dsb234890rb>";
-constexpr uint8_t kLbIdLen = 8;
-
 // The load data storage is organized in hierarchy. The LoadDataStore is the
 // The load data storage is organized in hierarchy. The LoadDataStore is the
 // top-level data store. In LoadDataStore, for each host we keep a
 // top-level data store. In LoadDataStore, for each host we keep a
 // PerHostStore, in which for each balancer we keep a PerBalancerStore. Each
 // PerHostStore, in which for each balancer we keep a PerBalancerStore. Each
@@ -68,13 +67,16 @@ class CallMetricValue {
 // The key of a load record.
 // The key of a load record.
 class LoadRecordKey {
 class LoadRecordKey {
  public:
  public:
-  explicit LoadRecordKey(grpc::string lb_id, grpc::string lb_tag,
-                         grpc::string user_id, grpc::string client_ip_hex)
+  LoadRecordKey(grpc::string lb_id, grpc::string lb_tag, grpc::string user_id,
+                grpc::string client_ip_hex)
       : lb_id_(std::move(lb_id)),
       : lb_id_(std::move(lb_id)),
         lb_tag_(std::move(lb_tag)),
         lb_tag_(std::move(lb_tag)),
         user_id_(std::move(user_id)),
         user_id_(std::move(user_id)),
         client_ip_hex_(std::move(client_ip_hex)) {}
         client_ip_hex_(std::move(client_ip_hex)) {}
 
 
+  // Parses the input client_ip_and_token to set client IP, LB ID, and LB tag.
+  LoadRecordKey(const grpc::string& client_ip_and_token, grpc::string user_id);
+
   grpc::string ToString() const {
   grpc::string ToString() const {
     return "[lb_id_=" + lb_id_ + ", lb_tag_=" + lb_tag_ +
     return "[lb_id_=" + lb_id_ + ", lb_tag_=" + lb_tag_ +
            ", user_id_=" + user_id_ + ", client_ip_hex_=" + client_ip_hex_ +
            ", user_id_=" + user_id_ + ", client_ip_hex_=" + client_ip_hex_ +
@@ -86,6 +88,9 @@ class LoadRecordKey {
            user_id_ == other.user_id_ && client_ip_hex_ == other.client_ip_hex_;
            user_id_ == other.user_id_ && client_ip_hex_ == other.client_ip_hex_;
   }
   }
 
 
+  // Gets the client IP bytes in network order (i.e., big-endian).
+  grpc::string GetClientIpBytes() const;
+
   // Getters.
   // Getters.
   const grpc::string& lb_id() const { return lb_id_; }
   const grpc::string& lb_id() const { return lb_id_; }
   const grpc::string& lb_tag() const { return lb_tag_; }
   const grpc::string& lb_tag() const { return lb_tag_; }
@@ -119,8 +124,8 @@ class LoadRecordKey {
 class LoadRecordValue {
 class LoadRecordValue {
  public:
  public:
   explicit LoadRecordValue(uint64_t start_count = 0, uint64_t ok_count = 0,
   explicit LoadRecordValue(uint64_t start_count = 0, uint64_t ok_count = 0,
-                           uint64_t error_count = 0, double bytes_sent = 0,
-                           double bytes_recv = 0, double latency_ms = 0)
+                           uint64_t error_count = 0, uint64_t bytes_sent = 0,
+                           uint64_t bytes_recv = 0, uint64_t latency_ms = 0)
       : start_count_(start_count),
       : start_count_(start_count),
         ok_count_(ok_count),
         ok_count_(ok_count),
         error_count_(error_count),
         error_count_(error_count),
@@ -128,6 +133,9 @@ class LoadRecordValue {
         bytes_recv_(bytes_recv),
         bytes_recv_(bytes_recv),
         latency_ms_(latency_ms) {}
         latency_ms_(latency_ms) {}
 
 
+  LoadRecordValue(grpc::string metric_name, uint64_t num_calls,
+                  double total_metric_value);
+
   void MergeFrom(const LoadRecordValue& other) {
   void MergeFrom(const LoadRecordValue& other) {
     start_count_ += other.start_count_;
     start_count_ += other.start_count_;
     ok_count_ += other.ok_count_;
     ok_count_ += other.ok_count_;
@@ -164,9 +172,9 @@ class LoadRecordValue {
   uint64_t start_count() const { return start_count_; }
   uint64_t start_count() const { return start_count_; }
   uint64_t ok_count() const { return ok_count_; }
   uint64_t ok_count() const { return ok_count_; }
   uint64_t error_count() const { return error_count_; }
   uint64_t error_count() const { return error_count_; }
-  double bytes_sent() const { return bytes_sent_; }
-  double bytes_recv() const { return bytes_recv_; }
-  double latency_ms() const { return latency_ms_; }
+  uint64_t bytes_sent() const { return bytes_sent_; }
+  uint64_t bytes_recv() const { return bytes_recv_; }
+  uint64_t latency_ms() const { return latency_ms_; }
   const std::unordered_map<grpc::string, CallMetricValue>& call_metrics()
   const std::unordered_map<grpc::string, CallMetricValue>& call_metrics()
       const {
       const {
     return call_metrics_;
     return call_metrics_;
@@ -176,9 +184,9 @@ class LoadRecordValue {
   uint64_t start_count_ = 0;
   uint64_t start_count_ = 0;
   uint64_t ok_count_ = 0;
   uint64_t ok_count_ = 0;
   uint64_t error_count_ = 0;
   uint64_t error_count_ = 0;
-  double bytes_sent_ = 0;
-  double bytes_recv_ = 0;
-  double latency_ms_ = 0;
+  uint64_t bytes_sent_ = 0;
+  uint64_t bytes_recv_ = 0;
+  uint64_t latency_ms_ = 0;
   std::unordered_map<grpc::string, CallMetricValue> call_metrics_;
   std::unordered_map<grpc::string, CallMetricValue> call_metrics_;
 };
 };
 
 

部分文件因文件數量過多而無法顯示