grpc 1.24.0 → 1.25.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (505) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +306 -243
  3. data/etc/roots.pem +0 -100
  4. data/include/grpc/grpc_security.h +44 -18
  5. data/include/grpc/impl/codegen/grpc_types.h +15 -0
  6. data/include/grpc/impl/codegen/port_platform.h +27 -11
  7. data/include/grpc/impl/codegen/sync_generic.h +1 -1
  8. data/src/boringssl/err_data.c +695 -650
  9. data/src/core/ext/filters/client_channel/client_channel.cc +257 -179
  10. data/src/core/ext/filters/client_channel/client_channel.h +24 -0
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +2 -3
  12. data/src/core/ext/filters/client_channel/client_channel_factory.h +1 -5
  13. data/src/core/ext/filters/client_channel/health/health_check_client.cc +18 -45
  14. data/src/core/ext/filters/client_channel/health/health_check_client.h +5 -13
  15. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  16. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -3
  17. data/src/core/ext/filters/client_channel/lb_policy.h +65 -55
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +14 -14
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +113 -36
  20. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +14 -19
  21. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +36 -13
  22. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +3 -10
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +814 -1589
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +2 -5
  25. data/src/core/ext/filters/client_channel/lb_policy_factory.h +3 -6
  26. data/src/core/ext/filters/client_channel/resolver.cc +1 -2
  27. data/src/core/ext/filters/client_channel/resolver.h +8 -16
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +25 -8
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +46 -12
  30. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +10 -17
  31. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +7 -8
  32. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +4 -4
  33. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +111 -44
  34. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +22 -14
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +2 -2
  37. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +29 -10
  38. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +27 -36
  39. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +7 -10
  40. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +60 -16
  41. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -8
  42. data/src/core/ext/filters/client_channel/resolver_registry.cc +1 -1
  43. data/src/core/ext/filters/client_channel/resolver_registry.h +1 -1
  44. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +7 -10
  45. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -1
  47. data/src/core/ext/filters/client_channel/retry_throttle.cc +5 -5
  48. data/src/core/ext/filters/client_channel/retry_throttle.h +1 -4
  49. data/src/core/ext/filters/client_channel/service_config.h +8 -8
  50. data/src/core/ext/filters/client_channel/subchannel.cc +53 -86
  51. data/src/core/ext/filters/client_channel/subchannel.h +7 -9
  52. data/src/core/ext/filters/client_channel/subchannel_interface.h +9 -13
  53. data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +3 -6
  54. data/src/core/ext/filters/client_channel/{lb_policy/xds/xds_load_balancer_api.cc → xds/xds_api.cc} +169 -52
  55. data/src/core/ext/filters/client_channel/xds/xds_api.h +171 -0
  56. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +450 -0
  57. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +99 -0
  58. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_channel.h +8 -6
  59. data/src/core/ext/filters/client_channel/xds/xds_channel_args.h +26 -0
  60. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_channel_secure.cc +28 -11
  61. data/src/core/ext/filters/client_channel/xds/xds_client.cc +1413 -0
  62. data/src/core/ext/filters/client_channel/xds/xds_client.h +221 -0
  63. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_client_stats.cc +1 -5
  64. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_client_stats.h +3 -4
  65. data/src/core/ext/filters/deadline/deadline_filter.cc +20 -20
  66. data/src/core/ext/filters/http/client/http_client_filter.cc +15 -15
  67. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  68. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +12 -12
  69. data/src/core/ext/filters/max_age/max_age_filter.cc +59 -50
  70. data/src/core/ext/filters/message_size/message_size_filter.cc +18 -18
  71. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +15 -14
  72. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +233 -175
  73. data/src/core/ext/transport/chttp2/transport/flow_control.h +21 -24
  74. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +253 -163
  75. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +24 -12
  76. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +2 -3
  77. data/src/core/ext/transport/chttp2/transport/internal.h +13 -15
  78. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -0
  79. data/src/core/ext/transport/inproc/inproc_transport.cc +20 -13
  80. data/src/core/lib/channel/channel_args.cc +16 -0
  81. data/src/core/lib/channel/channel_args.h +22 -0
  82. data/src/core/lib/channel/channelz.cc +5 -6
  83. data/src/core/lib/channel/channelz.h +1 -1
  84. data/src/core/lib/channel/connected_channel.cc +20 -20
  85. data/src/core/lib/channel/handshaker.h +3 -4
  86. data/src/core/lib/channel/handshaker_factory.h +1 -3
  87. data/src/core/lib/debug/trace.h +3 -2
  88. data/src/core/lib/gprpp/arena.cc +3 -3
  89. data/src/core/lib/gprpp/arena.h +2 -3
  90. data/src/core/lib/gprpp/inlined_vector.h +9 -0
  91. data/src/core/lib/gprpp/map.h +3 -501
  92. data/src/core/lib/gprpp/memory.h +45 -41
  93. data/src/core/lib/gprpp/mpscq.cc +108 -0
  94. data/src/core/lib/gprpp/mpscq.h +98 -0
  95. data/src/core/lib/gprpp/orphanable.h +6 -11
  96. data/src/core/lib/gprpp/ref_counted.h +25 -19
  97. data/src/core/lib/gprpp/set.h +33 -0
  98. data/src/core/lib/gprpp/thd.h +2 -4
  99. data/src/core/lib/http/httpcli.cc +1 -1
  100. data/src/core/lib/http/httpcli_security_connector.cc +15 -11
  101. data/src/core/lib/http/parser.cc +1 -1
  102. data/src/core/lib/iomgr/buffer_list.cc +4 -5
  103. data/src/core/lib/iomgr/buffer_list.h +5 -6
  104. data/src/core/lib/iomgr/call_combiner.cc +4 -5
  105. data/src/core/lib/iomgr/call_combiner.h +2 -2
  106. data/src/core/lib/iomgr/cfstream_handle.h +3 -5
  107. data/src/core/lib/iomgr/closure.h +8 -3
  108. data/src/core/lib/iomgr/combiner.cc +45 -82
  109. data/src/core/lib/iomgr/combiner.h +32 -8
  110. data/src/core/lib/iomgr/endpoint_cfstream.cc +5 -3
  111. data/src/core/lib/iomgr/ev_epoll1_linux.cc +19 -15
  112. data/src/core/lib/iomgr/ev_poll_posix.cc +3 -1
  113. data/src/core/lib/iomgr/exec_ctx.h +4 -3
  114. data/src/core/lib/iomgr/executor.cc +4 -2
  115. data/src/core/lib/iomgr/executor.h +3 -0
  116. data/src/core/lib/iomgr/executor/mpmcqueue.h +3 -6
  117. data/src/core/lib/iomgr/executor/threadpool.cc +1 -2
  118. data/src/core/lib/iomgr/executor/threadpool.h +7 -11
  119. data/src/core/lib/iomgr/resource_quota.cc +55 -51
  120. data/src/core/lib/iomgr/resource_quota.h +13 -9
  121. data/src/core/lib/iomgr/socket_utils_common_posix.cc +13 -0
  122. data/src/core/lib/iomgr/socket_utils_posix.h +4 -0
  123. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -11
  124. data/src/core/lib/iomgr/tcp_custom.cc +9 -7
  125. data/src/core/lib/iomgr/tcp_posix.cc +20 -16
  126. data/src/core/lib/iomgr/tcp_server.h +1 -4
  127. data/src/core/lib/iomgr/tcp_server_custom.cc +5 -5
  128. data/src/core/lib/iomgr/tcp_server_posix.cc +1 -1
  129. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +2 -11
  130. data/src/core/lib/iomgr/timer_custom.cc +2 -2
  131. data/src/core/lib/iomgr/udp_server.cc +3 -2
  132. data/src/core/lib/iomgr/udp_server.h +6 -12
  133. data/src/core/lib/json/json.h +1 -1
  134. data/src/core/lib/json/json_string.cc +2 -2
  135. data/src/core/lib/profiling/basic_timers.cc +2 -2
  136. data/src/core/lib/security/credentials/alts/alts_credentials.cc +2 -2
  137. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +1 -1
  138. data/src/core/lib/security/credentials/credentials.h +4 -20
  139. data/src/core/lib/security/credentials/fake/fake_credentials.cc +4 -4
  140. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +1 -3
  141. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +64 -0
  142. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +4 -4
  143. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +9 -7
  144. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +2 -0
  145. data/src/core/lib/security/security_connector/local/local_security_connector.cc +4 -4
  146. data/src/core/lib/security/security_connector/security_connector.cc +1 -0
  147. data/src/core/lib/security/security_connector/security_connector.h +19 -17
  148. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +8 -5
  149. data/src/core/lib/security/security_connector/ssl_utils.cc +2 -2
  150. data/src/core/lib/security/security_connector/ssl_utils.h +1 -1
  151. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +14 -6
  152. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -2
  153. data/src/core/lib/security/transport/client_auth_filter.cc +17 -17
  154. data/src/core/lib/security/transport/security_handshaker.cc +29 -13
  155. data/src/core/lib/security/transport/security_handshaker.h +4 -2
  156. data/src/core/lib/security/transport/server_auth_filter.cc +14 -14
  157. data/src/core/lib/slice/slice.cc +2 -10
  158. data/src/core/lib/slice/slice_hash_table.h +4 -6
  159. data/src/core/lib/slice/slice_intern.cc +42 -39
  160. data/src/core/lib/slice/slice_internal.h +3 -3
  161. data/src/core/lib/slice/slice_utils.h +21 -4
  162. data/src/core/lib/slice/slice_weak_hash_table.h +4 -6
  163. data/src/core/lib/surface/call.cc +3 -3
  164. data/src/core/lib/surface/channel.cc +7 -0
  165. data/src/core/lib/surface/completion_queue.cc +12 -11
  166. data/src/core/lib/surface/completion_queue.h +4 -2
  167. data/src/core/lib/surface/init.cc +1 -0
  168. data/src/core/lib/surface/lame_client.cc +33 -18
  169. data/src/core/lib/surface/server.cc +77 -76
  170. data/src/core/lib/surface/version.cc +1 -1
  171. data/src/core/lib/transport/byte_stream.h +3 -7
  172. data/src/core/lib/transport/connectivity_state.cc +112 -98
  173. data/src/core/lib/transport/connectivity_state.h +100 -50
  174. data/src/core/lib/transport/static_metadata.cc +276 -288
  175. data/src/core/lib/transport/static_metadata.h +73 -76
  176. data/src/core/lib/transport/status_conversion.cc +1 -1
  177. data/src/core/lib/transport/status_metadata.cc +1 -1
  178. data/src/core/lib/transport/transport.cc +2 -2
  179. data/src/core/lib/transport/transport.h +12 -4
  180. data/src/core/lib/transport/transport_op_string.cc +14 -11
  181. data/src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc +1 -1
  182. data/src/core/tsi/alts/handshaker/alts_shared_resource.cc +1 -1
  183. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +5 -5
  184. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +12 -2
  185. data/src/core/tsi/fake_transport_security.cc +7 -5
  186. data/src/core/tsi/grpc_shadow_boringssl.h +2918 -2627
  187. data/src/core/tsi/local_transport_security.cc +8 -6
  188. data/src/core/tsi/ssl/session_cache/ssl_session.h +1 -3
  189. data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +1 -2
  190. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +7 -5
  191. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +4 -6
  192. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +1 -2
  193. data/src/core/tsi/ssl_transport_security.cc +12 -12
  194. data/src/core/tsi/ssl_transport_security.h +2 -2
  195. data/src/core/tsi/transport_security_grpc.cc +7 -0
  196. data/src/core/tsi/transport_security_grpc.h +6 -0
  197. data/src/ruby/ext/grpc/extconf.rb +1 -0
  198. data/src/ruby/ext/grpc/rb_call.c +1 -1
  199. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  200. data/src/ruby/lib/grpc/generic/bidi_call.rb +1 -1
  201. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  202. data/src/ruby/lib/grpc/version.rb +1 -1
  203. data/src/ruby/spec/google_rpc_status_utils_spec.rb +2 -2
  204. data/third_party/boringssl/crypto/asn1/a_bool.c +18 -5
  205. data/third_party/boringssl/crypto/asn1/a_d2i_fp.c +17 -221
  206. data/third_party/boringssl/crypto/asn1/a_dup.c +0 -24
  207. data/third_party/boringssl/crypto/asn1/a_enum.c +2 -2
  208. data/third_party/boringssl/crypto/asn1/a_i2d_fp.c +10 -72
  209. data/third_party/boringssl/crypto/asn1/a_int.c +12 -71
  210. data/third_party/boringssl/crypto/asn1/a_mbstr.c +110 -216
  211. data/third_party/boringssl/crypto/asn1/a_object.c +16 -5
  212. data/third_party/boringssl/crypto/asn1/a_strnid.c +1 -0
  213. data/third_party/boringssl/crypto/asn1/asn1_lib.c +5 -1
  214. data/third_party/boringssl/crypto/asn1/tasn_enc.c +3 -1
  215. data/third_party/boringssl/crypto/base64/base64.c +2 -2
  216. data/third_party/boringssl/crypto/bio/bio.c +73 -9
  217. data/third_party/boringssl/crypto/bio/connect.c +4 -0
  218. data/third_party/boringssl/crypto/bio/fd.c +4 -0
  219. data/third_party/boringssl/crypto/bio/file.c +5 -2
  220. data/third_party/boringssl/crypto/bio/socket.c +4 -0
  221. data/third_party/boringssl/crypto/bio/socket_helper.c +4 -0
  222. data/third_party/boringssl/crypto/bn_extra/convert.c +11 -7
  223. data/third_party/boringssl/crypto/bytestring/ber.c +8 -4
  224. data/third_party/boringssl/crypto/bytestring/cbb.c +19 -7
  225. data/third_party/boringssl/crypto/bytestring/cbs.c +28 -15
  226. data/third_party/boringssl/crypto/bytestring/internal.h +28 -7
  227. data/third_party/boringssl/crypto/bytestring/unicode.c +155 -0
  228. data/third_party/boringssl/crypto/chacha/chacha.c +36 -19
  229. data/third_party/boringssl/crypto/chacha/internal.h +45 -0
  230. data/third_party/boringssl/crypto/cipher_extra/cipher_extra.c +29 -0
  231. data/third_party/boringssl/crypto/cipher_extra/e_aesccm.c +269 -25
  232. data/third_party/boringssl/crypto/cipher_extra/e_aesctrhmac.c +16 -14
  233. data/third_party/boringssl/crypto/cipher_extra/e_aesgcmsiv.c +54 -38
  234. data/third_party/boringssl/crypto/cipher_extra/e_chacha20poly1305.c +133 -41
  235. data/third_party/boringssl/crypto/cipher_extra/e_tls.c +23 -15
  236. data/third_party/boringssl/crypto/cipher_extra/tls_cbc.c +24 -15
  237. data/third_party/boringssl/crypto/cmac/cmac.c +62 -25
  238. data/third_party/boringssl/crypto/conf/conf.c +7 -0
  239. data/third_party/boringssl/crypto/cpu-arm-linux.c +4 -148
  240. data/third_party/boringssl/crypto/cpu-arm-linux.h +201 -0
  241. data/third_party/boringssl/crypto/cpu-intel.c +45 -51
  242. data/third_party/boringssl/crypto/crypto.c +39 -22
  243. data/third_party/boringssl/crypto/curve25519/spake25519.c +1 -1
  244. data/third_party/boringssl/crypto/dsa/dsa.c +77 -53
  245. data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +20 -8
  246. data/third_party/boringssl/crypto/ec_extra/ec_derive.c +96 -0
  247. data/third_party/boringssl/crypto/{ecdh/ecdh.c → ecdh_extra/ecdh_extra.c} +20 -58
  248. data/third_party/boringssl/crypto/ecdsa_extra/ecdsa_asn1.c +1 -9
  249. data/third_party/boringssl/crypto/engine/engine.c +2 -1
  250. data/third_party/boringssl/crypto/err/err.c +2 -0
  251. data/third_party/boringssl/crypto/err/internal.h +2 -2
  252. data/third_party/boringssl/crypto/evp/evp.c +89 -8
  253. data/third_party/boringssl/crypto/evp/evp_asn1.c +56 -5
  254. data/third_party/boringssl/crypto/evp/evp_ctx.c +52 -14
  255. data/third_party/boringssl/crypto/evp/internal.h +18 -1
  256. data/third_party/boringssl/crypto/evp/p_dsa_asn1.c +5 -0
  257. data/third_party/boringssl/crypto/evp/p_ec.c +51 -3
  258. data/third_party/boringssl/crypto/evp/p_ec_asn1.c +6 -7
  259. data/third_party/boringssl/crypto/evp/p_ed25519.c +36 -3
  260. data/third_party/boringssl/crypto/evp/p_ed25519_asn1.c +76 -45
  261. data/third_party/boringssl/crypto/evp/p_rsa.c +3 -1
  262. data/third_party/boringssl/crypto/evp/p_rsa_asn1.c +5 -0
  263. data/third_party/boringssl/crypto/evp/p_x25519.c +110 -0
  264. data/third_party/boringssl/crypto/evp/p_x25519_asn1.c +249 -0
  265. data/third_party/boringssl/crypto/evp/scrypt.c +6 -2
  266. data/third_party/boringssl/crypto/fipsmodule/aes/aes.c +34 -274
  267. data/third_party/boringssl/crypto/fipsmodule/aes/internal.h +161 -21
  268. data/third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c +111 -13
  269. data/third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c +17 -21
  270. data/third_party/boringssl/crypto/fipsmodule/bcm.c +119 -7
  271. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +19 -2
  272. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +2 -2
  273. data/third_party/boringssl/crypto/fipsmodule/bn/ctx.c +93 -160
  274. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +48 -57
  275. data/third_party/boringssl/crypto/fipsmodule/bn/div_extra.c +87 -0
  276. data/third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c +143 -211
  277. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +0 -305
  278. data/third_party/boringssl/crypto/fipsmodule/bn/gcd_extra.c +325 -0
  279. data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +168 -50
  280. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +68 -92
  281. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +7 -6
  282. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +11 -14
  283. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +358 -443
  284. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +25 -35
  285. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c +20 -25
  286. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h +76 -5
  287. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +14 -14
  288. data/third_party/boringssl/crypto/fipsmodule/cipher/cipher.c +7 -2
  289. data/third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c +383 -516
  290. data/third_party/boringssl/crypto/fipsmodule/cipher/e_des.c +4 -0
  291. data/third_party/boringssl/crypto/fipsmodule/cipher/internal.h +3 -4
  292. data/third_party/boringssl/crypto/fipsmodule/delocate.h +3 -2
  293. data/third_party/boringssl/crypto/fipsmodule/digest/digest.c +32 -17
  294. data/third_party/boringssl/crypto/fipsmodule/digest/md32_common.h +3 -3
  295. data/third_party/boringssl/crypto/fipsmodule/ec/ec.c +228 -122
  296. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +34 -8
  297. data/third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c +311 -98
  298. data/third_party/boringssl/crypto/fipsmodule/ec/felem.c +82 -0
  299. data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +263 -97
  300. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +22 -59
  301. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +317 -234
  302. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +9473 -9475
  303. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c +313 -109
  304. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h +36 -0
  305. data/third_party/boringssl/crypto/fipsmodule/ec/scalar.c +96 -0
  306. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +126 -792
  307. data/third_party/boringssl/crypto/fipsmodule/ec/simple_mul.c +84 -0
  308. data/third_party/boringssl/crypto/fipsmodule/ec/util.c +163 -12
  309. data/third_party/boringssl/crypto/fipsmodule/ec/wnaf.c +84 -211
  310. data/third_party/boringssl/crypto/fipsmodule/ecdh/ecdh.c +122 -0
  311. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +60 -205
  312. data/third_party/boringssl/crypto/fipsmodule/fips_shared_support.c +32 -0
  313. data/third_party/boringssl/crypto/fipsmodule/is_fips.c +2 -0
  314. data/third_party/boringssl/crypto/fipsmodule/md4/md4.c +3 -1
  315. data/third_party/boringssl/crypto/fipsmodule/md5/internal.h +37 -0
  316. data/third_party/boringssl/crypto/fipsmodule/md5/md5.c +11 -8
  317. data/third_party/boringssl/crypto/fipsmodule/modes/cbc.c +35 -79
  318. data/third_party/boringssl/crypto/fipsmodule/modes/cfb.c +7 -39
  319. data/third_party/boringssl/crypto/fipsmodule/modes/ctr.c +7 -27
  320. data/third_party/boringssl/crypto/fipsmodule/modes/gcm.c +123 -309
  321. data/third_party/boringssl/crypto/fipsmodule/modes/internal.h +189 -126
  322. data/third_party/boringssl/crypto/fipsmodule/modes/ofb.c +3 -2
  323. data/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c +2 -2
  324. data/third_party/boringssl/crypto/fipsmodule/rand/internal.h +35 -0
  325. data/third_party/boringssl/crypto/fipsmodule/rand/rand.c +24 -19
  326. data/third_party/boringssl/crypto/fipsmodule/rand/urandom.c +256 -77
  327. data/third_party/boringssl/crypto/fipsmodule/rsa/padding.c +10 -7
  328. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +5 -1
  329. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +131 -14
  330. data/third_party/boringssl/crypto/fipsmodule/self_check/self_check.c +83 -10
  331. data/third_party/boringssl/crypto/fipsmodule/sha/internal.h +53 -0
  332. data/third_party/boringssl/crypto/fipsmodule/sha/sha1.c +9 -13
  333. data/third_party/boringssl/crypto/fipsmodule/sha/sha256.c +18 -12
  334. data/third_party/boringssl/crypto/fipsmodule/sha/sha512.c +95 -168
  335. data/third_party/boringssl/crypto/hrss/hrss.c +2201 -0
  336. data/third_party/boringssl/crypto/hrss/internal.h +62 -0
  337. data/third_party/boringssl/crypto/internal.h +95 -20
  338. data/third_party/boringssl/crypto/lhash/lhash.c +45 -33
  339. data/third_party/boringssl/crypto/mem.c +39 -2
  340. data/third_party/boringssl/crypto/obj/obj.c +4 -4
  341. data/third_party/boringssl/crypto/obj/obj_dat.h +6181 -875
  342. data/third_party/boringssl/crypto/pem/pem_all.c +2 -3
  343. data/third_party/boringssl/crypto/pem/pem_info.c +144 -162
  344. data/third_party/boringssl/crypto/pem/pem_lib.c +53 -52
  345. data/third_party/boringssl/crypto/pem/pem_pkey.c +13 -21
  346. data/third_party/boringssl/crypto/pkcs7/pkcs7.c +15 -22
  347. data/third_party/boringssl/crypto/pkcs7/pkcs7_x509.c +168 -16
  348. data/third_party/boringssl/crypto/pkcs8/internal.h +11 -0
  349. data/third_party/boringssl/crypto/pkcs8/p5_pbev2.c +24 -15
  350. data/third_party/boringssl/crypto/pkcs8/pkcs8.c +42 -25
  351. data/third_party/boringssl/crypto/pkcs8/pkcs8_x509.c +559 -43
  352. data/third_party/boringssl/crypto/pool/internal.h +1 -1
  353. data/third_party/boringssl/crypto/pool/pool.c +21 -0
  354. data/third_party/boringssl/crypto/rand_extra/deterministic.c +8 -0
  355. data/third_party/boringssl/crypto/rand_extra/fuchsia.c +1 -14
  356. data/third_party/boringssl/crypto/refcount_lock.c +2 -2
  357. data/third_party/boringssl/crypto/rsa_extra/rsa_print.c +22 -0
  358. data/third_party/boringssl/crypto/siphash/siphash.c +80 -0
  359. data/third_party/boringssl/crypto/stack/stack.c +83 -32
  360. data/third_party/boringssl/crypto/thread_none.c +2 -2
  361. data/third_party/boringssl/crypto/thread_pthread.c +2 -2
  362. data/third_party/boringssl/crypto/thread_win.c +38 -19
  363. data/third_party/boringssl/crypto/x509/a_strex.c +22 -2
  364. data/third_party/boringssl/crypto/x509/asn1_gen.c +2 -1
  365. data/third_party/boringssl/crypto/x509/by_dir.c +7 -0
  366. data/third_party/boringssl/crypto/x509/by_file.c +12 -10
  367. data/third_party/boringssl/crypto/x509/t_crl.c +5 -8
  368. data/third_party/boringssl/crypto/x509/t_req.c +1 -3
  369. data/third_party/boringssl/crypto/x509/t_x509.c +5 -8
  370. data/third_party/boringssl/crypto/x509/x509_cmp.c +1 -1
  371. data/third_party/boringssl/crypto/x509/x509_def.c +1 -1
  372. data/third_party/boringssl/crypto/x509/x509_lu.c +114 -5
  373. data/third_party/boringssl/crypto/x509/x509_req.c +20 -0
  374. data/third_party/boringssl/crypto/x509/x509_set.c +5 -0
  375. data/third_party/boringssl/crypto/x509/x509_trs.c +1 -0
  376. data/third_party/boringssl/crypto/x509/x509_txt.c +4 -5
  377. data/third_party/boringssl/crypto/x509/x509_vfy.c +145 -138
  378. data/third_party/boringssl/crypto/x509/x509_vpm.c +2 -0
  379. data/third_party/boringssl/crypto/x509/x509cset.c +40 -0
  380. data/third_party/boringssl/crypto/x509/x509name.c +2 -3
  381. data/third_party/boringssl/crypto/x509/x_all.c +109 -210
  382. data/third_party/boringssl/crypto/x509/x_x509.c +6 -0
  383. data/third_party/boringssl/crypto/x509v3/ext_dat.h +1 -3
  384. data/third_party/boringssl/crypto/x509v3/internal.h +56 -0
  385. data/third_party/boringssl/crypto/x509v3/pcy_cache.c +2 -0
  386. data/third_party/boringssl/crypto/x509v3/pcy_node.c +1 -0
  387. data/third_party/boringssl/crypto/x509v3/pcy_tree.c +4 -2
  388. data/third_party/boringssl/crypto/x509v3/v3_akey.c +5 -2
  389. data/third_party/boringssl/crypto/x509v3/v3_alt.c +19 -13
  390. data/third_party/boringssl/crypto/x509v3/v3_conf.c +2 -1
  391. data/third_party/boringssl/crypto/x509v3/v3_cpols.c +3 -2
  392. data/third_party/boringssl/crypto/x509v3/v3_genn.c +1 -6
  393. data/third_party/boringssl/crypto/x509v3/v3_lib.c +1 -0
  394. data/third_party/boringssl/crypto/x509v3/v3_ocsp.c +68 -0
  395. data/third_party/boringssl/crypto/x509v3/v3_pci.c +2 -1
  396. data/third_party/boringssl/crypto/x509v3/v3_purp.c +47 -69
  397. data/third_party/boringssl/crypto/x509v3/v3_skey.c +5 -2
  398. data/third_party/boringssl/crypto/x509v3/v3_utl.c +69 -25
  399. data/third_party/boringssl/include/openssl/aead.h +45 -19
  400. data/third_party/boringssl/include/openssl/aes.h +32 -7
  401. data/third_party/boringssl/include/openssl/asn1.h +7 -77
  402. data/third_party/boringssl/include/openssl/base.h +120 -6
  403. data/third_party/boringssl/include/openssl/base64.h +4 -1
  404. data/third_party/boringssl/include/openssl/bio.h +112 -81
  405. data/third_party/boringssl/include/openssl/blowfish.h +3 -3
  406. data/third_party/boringssl/include/openssl/bn.h +55 -29
  407. data/third_party/boringssl/include/openssl/buf.h +2 -2
  408. data/third_party/boringssl/include/openssl/bytestring.h +54 -32
  409. data/third_party/boringssl/include/openssl/cast.h +2 -2
  410. data/third_party/boringssl/include/openssl/cipher.h +46 -16
  411. data/third_party/boringssl/include/openssl/cmac.h +6 -2
  412. data/third_party/boringssl/include/openssl/conf.h +3 -6
  413. data/third_party/boringssl/include/openssl/cpu.h +25 -9
  414. data/third_party/boringssl/include/openssl/crypto.h +32 -10
  415. data/third_party/boringssl/include/openssl/curve25519.h +4 -4
  416. data/third_party/boringssl/include/openssl/dh.h +3 -2
  417. data/third_party/boringssl/include/openssl/digest.h +21 -7
  418. data/third_party/boringssl/include/openssl/dsa.h +8 -2
  419. data/third_party/boringssl/include/openssl/e_os2.h +18 -0
  420. data/third_party/boringssl/include/openssl/ec.h +25 -21
  421. data/third_party/boringssl/include/openssl/ec_key.h +36 -8
  422. data/third_party/boringssl/include/openssl/ecdh.h +17 -0
  423. data/third_party/boringssl/include/openssl/ecdsa.h +3 -3
  424. data/third_party/boringssl/include/openssl/engine.h +4 -4
  425. data/third_party/boringssl/include/openssl/err.h +3 -0
  426. data/third_party/boringssl/include/openssl/evp.h +199 -42
  427. data/third_party/boringssl/include/openssl/hmac.h +4 -4
  428. data/third_party/boringssl/include/openssl/hrss.h +100 -0
  429. data/third_party/boringssl/include/openssl/lhash.h +131 -23
  430. data/third_party/boringssl/include/openssl/md4.h +6 -4
  431. data/third_party/boringssl/include/openssl/md5.h +6 -4
  432. data/third_party/boringssl/include/openssl/mem.h +6 -2
  433. data/third_party/boringssl/include/openssl/nid.h +3 -0
  434. data/third_party/boringssl/include/openssl/obj.h +3 -0
  435. data/third_party/boringssl/include/openssl/pem.h +102 -64
  436. data/third_party/boringssl/include/openssl/pkcs7.h +136 -3
  437. data/third_party/boringssl/include/openssl/pkcs8.h +42 -3
  438. data/third_party/boringssl/include/openssl/pool.h +13 -2
  439. data/third_party/boringssl/include/openssl/ripemd.h +5 -4
  440. data/third_party/boringssl/include/openssl/rsa.h +46 -15
  441. data/third_party/boringssl/include/openssl/sha.h +40 -28
  442. data/third_party/boringssl/include/openssl/siphash.h +37 -0
  443. data/third_party/boringssl/include/openssl/span.h +17 -9
  444. data/third_party/boringssl/include/openssl/ssl.h +766 -393
  445. data/third_party/boringssl/include/openssl/ssl3.h +4 -3
  446. data/third_party/boringssl/include/openssl/stack.h +134 -77
  447. data/third_party/boringssl/include/openssl/thread.h +1 -1
  448. data/third_party/boringssl/include/openssl/tls1.h +25 -9
  449. data/third_party/boringssl/include/openssl/type_check.h +14 -15
  450. data/third_party/boringssl/include/openssl/x509.h +28 -3
  451. data/third_party/boringssl/include/openssl/x509_vfy.h +98 -32
  452. data/third_party/boringssl/include/openssl/x509v3.h +17 -13
  453. data/third_party/boringssl/ssl/d1_both.cc +9 -18
  454. data/third_party/boringssl/ssl/d1_lib.cc +4 -3
  455. data/third_party/boringssl/ssl/d1_pkt.cc +4 -4
  456. data/third_party/boringssl/ssl/d1_srtp.cc +15 -15
  457. data/third_party/boringssl/ssl/dtls_method.cc +0 -1
  458. data/third_party/boringssl/ssl/dtls_record.cc +28 -28
  459. data/third_party/boringssl/ssl/handoff.cc +295 -91
  460. data/third_party/boringssl/ssl/handshake.cc +133 -72
  461. data/third_party/boringssl/ssl/handshake_client.cc +218 -189
  462. data/third_party/boringssl/ssl/handshake_server.cc +399 -272
  463. data/third_party/boringssl/ssl/internal.h +1413 -928
  464. data/third_party/boringssl/ssl/s3_both.cc +175 -36
  465. data/third_party/boringssl/ssl/s3_lib.cc +9 -13
  466. data/third_party/boringssl/ssl/s3_pkt.cc +63 -29
  467. data/third_party/boringssl/ssl/ssl_aead_ctx.cc +55 -35
  468. data/third_party/boringssl/ssl/ssl_asn1.cc +57 -73
  469. data/third_party/boringssl/ssl/ssl_buffer.cc +13 -12
  470. data/third_party/boringssl/ssl/ssl_cert.cc +313 -210
  471. data/third_party/boringssl/ssl/ssl_cipher.cc +159 -221
  472. data/third_party/boringssl/ssl/ssl_file.cc +2 -0
  473. data/third_party/boringssl/ssl/ssl_key_share.cc +164 -19
  474. data/third_party/boringssl/ssl/ssl_lib.cc +847 -555
  475. data/third_party/boringssl/ssl/ssl_privkey.cc +441 -111
  476. data/third_party/boringssl/ssl/ssl_session.cc +230 -178
  477. data/third_party/boringssl/ssl/ssl_transcript.cc +21 -142
  478. data/third_party/boringssl/ssl/ssl_versions.cc +88 -93
  479. data/third_party/boringssl/ssl/ssl_x509.cc +279 -218
  480. data/third_party/boringssl/ssl/t1_enc.cc +5 -96
  481. data/third_party/boringssl/ssl/t1_lib.cc +931 -678
  482. data/third_party/boringssl/ssl/tls13_both.cc +251 -121
  483. data/third_party/boringssl/ssl/tls13_client.cc +129 -73
  484. data/third_party/boringssl/ssl/tls13_enc.cc +350 -282
  485. data/third_party/boringssl/ssl/tls13_server.cc +259 -192
  486. data/third_party/boringssl/ssl/tls_method.cc +26 -21
  487. data/third_party/boringssl/ssl/tls_record.cc +42 -47
  488. data/third_party/boringssl/third_party/fiat/curve25519.c +261 -1324
  489. data/third_party/boringssl/third_party/fiat/curve25519_32.h +911 -0
  490. data/third_party/boringssl/third_party/fiat/curve25519_64.h +559 -0
  491. data/third_party/boringssl/third_party/fiat/p256.c +238 -999
  492. data/third_party/boringssl/third_party/fiat/p256_32.h +3226 -0
  493. data/third_party/boringssl/third_party/fiat/p256_64.h +1217 -0
  494. data/third_party/upb/upb/port_def.inc +1 -1
  495. data/third_party/upb/upb/table.c +2 -1
  496. metadata +72 -44
  497. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +0 -127
  498. data/src/core/lib/gpr/mpscq.cc +0 -117
  499. data/src/core/lib/gpr/mpscq.h +0 -88
  500. data/src/core/lib/gprpp/abstract.h +0 -47
  501. data/src/core/lib/gprpp/pair.h +0 -38
  502. data/third_party/boringssl/crypto/cipher_extra/e_ssl3.c +0 -460
  503. data/third_party/boringssl/crypto/fipsmodule/modes/ccm.c +0 -256
  504. data/third_party/boringssl/include/openssl/lhash_macros.h +0 -174
  505. data/third_party/boringssl/ssl/custom_extensions.cc +0 -265
@@ -0,0 +1,99 @@
1
+ //
2
+ // Copyright 2019 gRPC authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_BOOTSTRAP_H
18
+ #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_BOOTSTRAP_H
19
+
20
+ #include <grpc/support/port_platform.h>
21
+
22
+ #include <vector>
23
+
24
+ #include <grpc/impl/codegen/slice.h>
25
+
26
+ #include "src/core/lib/gprpp/inlined_vector.h"
27
+ #include "src/core/lib/gprpp/map.h"
28
+ #include "src/core/lib/gprpp/memory.h"
29
+ #include "src/core/lib/iomgr/error.h"
30
+ #include "src/core/lib/json/json.h"
31
+
32
+ namespace grpc_core {
33
+
34
+ class XdsBootstrap {
35
+ public:
36
+ struct MetadataValue {
37
+ enum class Type { MD_NULL, DOUBLE, STRING, BOOL, STRUCT, LIST };
38
+ Type type = Type::MD_NULL;
39
+ // TODO(roth): Once we can use C++17, these can be in a std::variant.
40
+ double double_value;
41
+ const char* string_value;
42
+ bool bool_value;
43
+ Map<const char*, MetadataValue, StringLess> struct_value;
44
+ std::vector<MetadataValue> list_value;
45
+ };
46
+
47
+ struct Node {
48
+ const char* id = nullptr;
49
+ const char* cluster = nullptr;
50
+ const char* locality_region = nullptr;
51
+ const char* locality_zone = nullptr;
52
+ const char* locality_subzone = nullptr;
53
+ Map<const char*, MetadataValue, StringLess> metadata;
54
+ };
55
+
56
+ struct ChannelCreds {
57
+ const char* type = nullptr;
58
+ grpc_json* config = nullptr;
59
+ };
60
+
61
+ // If *error is not GRPC_ERROR_NONE after returning, then there was an
62
+ // error reading the file.
63
+ static UniquePtr<XdsBootstrap> ReadFromFile(grpc_error** error);
64
+
65
+ // Do not instantiate directly -- use ReadFromFile() above instead.
66
+ XdsBootstrap(grpc_slice contents, grpc_error** error);
67
+ ~XdsBootstrap();
68
+
69
+ const char* server_uri() const { return server_uri_; }
70
+ const InlinedVector<ChannelCreds, 1>& channel_creds() const {
71
+ return channel_creds_;
72
+ }
73
+ const Node* node() const { return node_.get(); }
74
+
75
+ private:
76
+ grpc_error* ParseXdsServer(grpc_json* json);
77
+ grpc_error* ParseChannelCredsArray(grpc_json* json);
78
+ grpc_error* ParseChannelCreds(grpc_json* json, size_t idx);
79
+ grpc_error* ParseNode(grpc_json* json);
80
+ grpc_error* ParseLocality(grpc_json* json);
81
+
82
+ InlinedVector<grpc_error*, 1> ParseMetadataStruct(
83
+ grpc_json* json, Map<const char*, MetadataValue, StringLess>* result);
84
+ InlinedVector<grpc_error*, 1> ParseMetadataList(
85
+ grpc_json* json, std::vector<MetadataValue>* result);
86
+ grpc_error* ParseMetadataValue(grpc_json* json, size_t idx,
87
+ MetadataValue* result);
88
+
89
+ grpc_slice contents_;
90
+ grpc_json* tree_ = nullptr;
91
+
92
+ const char* server_uri_ = nullptr;
93
+ InlinedVector<ChannelCreds, 1> channel_creds_;
94
+ UniquePtr<Node> node_;
95
+ };
96
+
97
+ } // namespace grpc_core
98
+
99
+ #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_BOOTSTRAP_H */
@@ -16,13 +16,15 @@
16
16
  *
17
17
  */
18
18
 
19
- #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_H
20
- #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_H
19
+ #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_H
20
+ #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_H
21
21
 
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
24
  #include <grpc/impl/codegen/grpc_types.h>
25
25
 
26
+ #include "src/core/ext/filters/client_channel/xds/xds_bootstrap.h"
27
+
26
28
  namespace grpc_core {
27
29
 
28
30
  /// Makes any necessary modifications to \a args for use in the xds
@@ -31,12 +33,12 @@ namespace grpc_core {
31
33
  /// Takes ownership of \a args.
32
34
  ///
33
35
  /// Caller takes ownership of the returned args.
34
- grpc_channel_args* ModifyXdsBalancerChannelArgs(grpc_channel_args* args);
36
+ grpc_channel_args* ModifyXdsChannelArgs(grpc_channel_args* args);
35
37
 
36
- grpc_channel* CreateXdsBalancerChannel(const char* target_uri,
37
- const grpc_channel_args& args);
38
+ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
39
+ const grpc_channel_args& args);
38
40
 
39
41
  } // namespace grpc_core
40
42
 
41
- #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_H \
43
+ #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_H \
42
44
  */
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2019 gRPC authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_ARGS_H
18
+ #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_ARGS_H
19
+
20
+ // Boolean channel arg indicating whether the target is an xds server.
21
+ #define GRPC_ARG_ADDRESS_IS_XDS_SERVER "grpc.address_is_xds_server"
22
+
23
+ // Pointer channel arg containing a ref to the XdsClient object.
24
+ #define GRPC_ARG_XDS_CLIENT "grpc.xds_client"
25
+
26
+ #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_CHANNEL_ARGS_H */
@@ -18,7 +18,7 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
- #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h"
21
+ #include "src/core/ext/filters/client_channel/xds/xds_channel.h"
22
22
 
23
23
  #include <string.h>
24
24
 
@@ -32,12 +32,13 @@
32
32
  #include "src/core/lib/gpr/string.h"
33
33
  #include "src/core/lib/iomgr/sockaddr_utils.h"
34
34
  #include "src/core/lib/security/credentials/credentials.h"
35
+ #include "src/core/lib/security/credentials/fake/fake_credentials.h"
35
36
  #include "src/core/lib/security/transport/target_authority_table.h"
36
37
  #include "src/core/lib/slice/slice_internal.h"
37
38
 
38
39
  namespace grpc_core {
39
40
 
40
- grpc_channel_args* ModifyXdsBalancerChannelArgs(grpc_channel_args* args) {
41
+ grpc_channel_args* ModifyXdsChannelArgs(grpc_channel_args* args) {
41
42
  InlinedVector<const char*, 1> args_to_remove;
42
43
  InlinedVector<grpc_arg, 2> args_to_add;
43
44
  // Substitute the channel credentials with a version without call
@@ -62,19 +63,35 @@ grpc_channel_args* ModifyXdsBalancerChannelArgs(grpc_channel_args* args) {
62
63
  return result;
63
64
  }
64
65
 
65
- grpc_channel* CreateXdsBalancerChannel(const char* target_uri,
66
- const grpc_channel_args& args) {
67
- grpc_channel_credentials* creds =
68
- grpc_channel_credentials_find_in_args(&args);
69
- if (creds == nullptr) {
70
- // Build with security but parent channel is insecure.
71
- return grpc_insecure_channel_create(target_uri, &args, nullptr);
66
+ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
67
+ const grpc_channel_args& args) {
68
+ grpc_channel_credentials* creds = nullptr;
69
+ RefCountedPtr<grpc_channel_credentials> creds_to_unref;
70
+ if (!bootstrap.channel_creds().empty()) {
71
+ for (size_t i = 0; i < bootstrap.channel_creds().size(); ++i) {
72
+ if (strcmp(bootstrap.channel_creds()[i].type, "google_default") == 0) {
73
+ creds = grpc_google_default_credentials_create();
74
+ break;
75
+ } else if (strcmp(bootstrap.channel_creds()[i].type, "fake") == 0) {
76
+ creds = grpc_fake_transport_security_credentials_create();
77
+ break;
78
+ }
79
+ }
80
+ if (creds == nullptr) return nullptr;
81
+ creds_to_unref.reset(creds);
82
+ } else {
83
+ creds = grpc_channel_credentials_find_in_args(&args);
84
+ if (creds == nullptr) {
85
+ // Built with security but parent channel is insecure.
86
+ return grpc_insecure_channel_create(bootstrap.server_uri(), &args,
87
+ nullptr);
88
+ }
72
89
  }
73
90
  const char* arg_to_remove = GRPC_ARG_CHANNEL_CREDENTIALS;
74
91
  grpc_channel_args* new_args =
75
92
  grpc_channel_args_copy_and_remove(&args, &arg_to_remove, 1);
76
- grpc_channel* channel =
77
- grpc_secure_channel_create(creds, target_uri, new_args, nullptr);
93
+ grpc_channel* channel = grpc_secure_channel_create(
94
+ creds, bootstrap.server_uri(), new_args, nullptr);
78
95
  grpc_channel_args_destroy(new_args);
79
96
  return channel;
80
97
  }
@@ -0,0 +1,1413 @@
1
+ /*
2
+ *
3
+ * Copyright 2018 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #include <grpc/support/port_platform.h>
20
+
21
+ #include <inttypes.h>
22
+ #include <limits.h>
23
+ #include <string.h>
24
+
25
+ #include <grpc/byte_buffer_reader.h>
26
+ #include <grpc/grpc.h>
27
+ #include <grpc/support/alloc.h>
28
+ #include <grpc/support/string_util.h>
29
+ #include <grpc/support/time.h>
30
+
31
+ #include "src/core/ext/filters/client_channel/client_channel.h"
32
+ #include "src/core/ext/filters/client_channel/parse_address.h"
33
+ #include "src/core/ext/filters/client_channel/server_address.h"
34
+ #include "src/core/ext/filters/client_channel/service_config.h"
35
+ #include "src/core/ext/filters/client_channel/xds/xds_api.h"
36
+ #include "src/core/ext/filters/client_channel/xds/xds_channel.h"
37
+ #include "src/core/ext/filters/client_channel/xds/xds_channel_args.h"
38
+ #include "src/core/ext/filters/client_channel/xds/xds_client.h"
39
+ #include "src/core/ext/filters/client_channel/xds/xds_client_stats.h"
40
+ #include "src/core/lib/backoff/backoff.h"
41
+ #include "src/core/lib/channel/channel_args.h"
42
+ #include "src/core/lib/channel/channel_stack.h"
43
+ #include "src/core/lib/gpr/string.h"
44
+ #include "src/core/lib/gprpp/map.h"
45
+ #include "src/core/lib/gprpp/memory.h"
46
+ #include "src/core/lib/gprpp/orphanable.h"
47
+ #include "src/core/lib/gprpp/ref_counted_ptr.h"
48
+ #include "src/core/lib/gprpp/sync.h"
49
+ #include "src/core/lib/iomgr/combiner.h"
50
+ #include "src/core/lib/iomgr/sockaddr.h"
51
+ #include "src/core/lib/iomgr/sockaddr_utils.h"
52
+ #include "src/core/lib/iomgr/timer.h"
53
+ #include "src/core/lib/slice/slice_hash_table.h"
54
+ #include "src/core/lib/slice/slice_internal.h"
55
+ #include "src/core/lib/slice/slice_string_helpers.h"
56
+ #include "src/core/lib/surface/call.h"
57
+ #include "src/core/lib/surface/channel.h"
58
+ #include "src/core/lib/surface/channel_init.h"
59
+ #include "src/core/lib/transport/static_metadata.h"
60
+
61
+ #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1
62
+ #define GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER 1.6
63
+ #define GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS 120
64
+ #define GRPC_XDS_RECONNECT_JITTER 0.2
65
+ #define GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS 1000
66
+
67
+ namespace grpc_core {
68
+
69
+ TraceFlag grpc_xds_client_trace(false, "xds_client");
70
+
71
+ //
72
+ // Internal class declarations
73
+ //
74
+
75
+ // An xds call wrapper that can restart a call upon failure. Holds a ref to
76
+ // the xds channel. The template parameter is the kind of wrapped xds call.
77
+ template <typename T>
78
+ class XdsClient::ChannelState::RetryableCall
79
+ : public InternallyRefCounted<RetryableCall<T>> {
80
+ public:
81
+ explicit RetryableCall(RefCountedPtr<ChannelState> chand);
82
+
83
+ void Orphan() override;
84
+
85
+ void OnCallFinishedLocked();
86
+
87
+ T* calld() const { return calld_.get(); }
88
+ ChannelState* chand() const { return chand_.get(); }
89
+
90
+ bool IsCurrentCallOnChannel() const;
91
+
92
+ private:
93
+ void StartNewCallLocked();
94
+ void StartRetryTimerLocked();
95
+ static void OnRetryTimer(void* arg, grpc_error* error);
96
+ static void OnRetryTimerLocked(void* arg, grpc_error* error);
97
+
98
+ // The wrapped xds call that talks to the xds server. It's instantiated
99
+ // every time we start a new call. It's null during call retry backoff.
100
+ OrphanablePtr<T> calld_;
101
+ // The owning xds channel.
102
+ RefCountedPtr<ChannelState> chand_;
103
+
104
+ // Retry state.
105
+ BackOff backoff_;
106
+ grpc_timer retry_timer_;
107
+ grpc_closure on_retry_timer_;
108
+ bool retry_timer_callback_pending_ = false;
109
+
110
+ bool shutting_down_ = false;
111
+ };
112
+
113
+ // Contains an ADS call to the xds server.
114
+ class XdsClient::ChannelState::AdsCallState
115
+ : public InternallyRefCounted<AdsCallState> {
116
+ public:
117
+ // The ctor and dtor should not be used directly.
118
+ explicit AdsCallState(RefCountedPtr<RetryableCall<AdsCallState>> parent);
119
+ ~AdsCallState() override;
120
+
121
+ void Orphan() override;
122
+
123
+ RetryableCall<AdsCallState>* parent() const { return parent_.get(); }
124
+ ChannelState* chand() const { return parent_->chand(); }
125
+ XdsClient* xds_client() const { return chand()->xds_client(); }
126
+ bool seen_response() const { return seen_response_; }
127
+
128
+ private:
129
+ static void OnResponseReceived(void* arg, grpc_error* error);
130
+ static void OnStatusReceived(void* arg, grpc_error* error);
131
+ static void OnResponseReceivedLocked(void* arg, grpc_error* error);
132
+ static void OnStatusReceivedLocked(void* arg, grpc_error* error);
133
+
134
+ bool IsCurrentCallOnChannel() const;
135
+
136
+ // The owning RetryableCall<>.
137
+ RefCountedPtr<RetryableCall<AdsCallState>> parent_;
138
+ bool seen_response_ = false;
139
+
140
+ // Always non-NULL.
141
+ grpc_call* call_;
142
+
143
+ // recv_initial_metadata
144
+ grpc_metadata_array initial_metadata_recv_;
145
+
146
+ // send_message
147
+ grpc_byte_buffer* send_message_payload_ = nullptr;
148
+
149
+ // recv_message
150
+ grpc_byte_buffer* recv_message_payload_ = nullptr;
151
+ grpc_closure on_response_received_;
152
+
153
+ // recv_trailing_metadata
154
+ grpc_metadata_array trailing_metadata_recv_;
155
+ grpc_status_code status_code_;
156
+ grpc_slice status_details_;
157
+ grpc_closure on_status_received_;
158
+ };
159
+
160
+ // Contains an LRS call to the xds server.
161
+ class XdsClient::ChannelState::LrsCallState
162
+ : public InternallyRefCounted<LrsCallState> {
163
+ public:
164
+ // The ctor and dtor should not be used directly.
165
+ explicit LrsCallState(RefCountedPtr<RetryableCall<LrsCallState>> parent);
166
+ ~LrsCallState() override;
167
+
168
+ void Orphan() override;
169
+
170
+ void MaybeStartReportingLocked();
171
+
172
+ RetryableCall<LrsCallState>* parent() { return parent_.get(); }
173
+ ChannelState* chand() const { return parent_->chand(); }
174
+ XdsClient* xds_client() const { return chand()->xds_client(); }
175
+ bool seen_response() const { return seen_response_; }
176
+
177
+ private:
178
+ // Reports client-side load stats according to a fixed interval.
179
+ class Reporter : public InternallyRefCounted<Reporter> {
180
+ public:
181
+ Reporter(RefCountedPtr<LrsCallState> parent, grpc_millis report_interval)
182
+ : parent_(std::move(parent)), report_interval_(report_interval) {
183
+ ScheduleNextReportLocked();
184
+ }
185
+
186
+ void Orphan() override;
187
+
188
+ private:
189
+ void ScheduleNextReportLocked();
190
+ static void OnNextReportTimer(void* arg, grpc_error* error);
191
+ static void OnNextReportTimerLocked(void* arg, grpc_error* error);
192
+ void SendReportLocked();
193
+ static void OnReportDone(void* arg, grpc_error* error);
194
+ static void OnReportDoneLocked(void* arg, grpc_error* error);
195
+
196
+ bool IsCurrentReporterOnCall() const {
197
+ return this == parent_->reporter_.get();
198
+ }
199
+ XdsClient* xds_client() const { return parent_->xds_client(); }
200
+
201
+ // The owning LRS call.
202
+ RefCountedPtr<LrsCallState> parent_;
203
+
204
+ // The load reporting state.
205
+ const grpc_millis report_interval_;
206
+ bool last_report_counters_were_zero_ = false;
207
+ bool next_report_timer_callback_pending_ = false;
208
+ grpc_timer next_report_timer_;
209
+ grpc_closure on_next_report_timer_;
210
+ grpc_closure on_report_done_;
211
+ };
212
+
213
+ static void OnInitialRequestSent(void* arg, grpc_error* error);
214
+ static void OnResponseReceived(void* arg, grpc_error* error);
215
+ static void OnStatusReceived(void* arg, grpc_error* error);
216
+ static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
217
+ static void OnResponseReceivedLocked(void* arg, grpc_error* error);
218
+ static void OnStatusReceivedLocked(void* arg, grpc_error* error);
219
+
220
+ bool IsCurrentCallOnChannel() const;
221
+
222
+ // The owning RetryableCall<>.
223
+ RefCountedPtr<RetryableCall<LrsCallState>> parent_;
224
+ bool seen_response_ = false;
225
+
226
+ // Always non-NULL.
227
+ grpc_call* call_;
228
+
229
+ // recv_initial_metadata
230
+ grpc_metadata_array initial_metadata_recv_;
231
+
232
+ // send_message
233
+ grpc_byte_buffer* send_message_payload_ = nullptr;
234
+ grpc_closure on_initial_request_sent_;
235
+
236
+ // recv_message
237
+ grpc_byte_buffer* recv_message_payload_ = nullptr;
238
+ grpc_closure on_response_received_;
239
+
240
+ // recv_trailing_metadata
241
+ grpc_metadata_array trailing_metadata_recv_;
242
+ grpc_status_code status_code_;
243
+ grpc_slice status_details_;
244
+ grpc_closure on_status_received_;
245
+
246
+ // Load reporting state.
247
+ UniquePtr<char> cluster_name_;
248
+ grpc_millis load_reporting_interval_ = 0;
249
+ OrphanablePtr<Reporter> reporter_;
250
+ };
251
+
252
+ //
253
+ // XdsClient::ChannelState::StateWatcher
254
+ //
255
+
256
+ class XdsClient::ChannelState::StateWatcher
257
+ : public AsyncConnectivityStateWatcherInterface {
258
+ public:
259
+ explicit StateWatcher(RefCountedPtr<ChannelState> parent)
260
+ : AsyncConnectivityStateWatcherInterface(parent->xds_client()->combiner_),
261
+ parent_(std::move(parent)) {}
262
+
263
+ private:
264
+ void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
265
+ if (!parent_->shutting_down_ &&
266
+ new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
267
+ // In TRANSIENT_FAILURE. Notify all watchers of error.
268
+ gpr_log(GPR_INFO,
269
+ "[xds_client %p] xds channel in state TRANSIENT_FAILURE",
270
+ parent_->xds_client());
271
+ parent_->xds_client()->NotifyOnError(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
272
+ "xds channel in TRANSIENT_FAILURE"));
273
+ }
274
+ }
275
+
276
+ RefCountedPtr<ChannelState> parent_;
277
+ };
278
+
279
+ //
280
+ // XdsClient::ChannelState
281
+ //
282
+
283
+ namespace {
284
+
285
+ // Returns the channel args for the xds channel.
286
+ grpc_channel_args* BuildXdsChannelArgs(const grpc_channel_args& args) {
287
+ static const char* args_to_remove[] = {
288
+ // LB policy name, since we want to use the default (pick_first) in
289
+ // the LB channel.
290
+ GRPC_ARG_LB_POLICY_NAME,
291
+ // The service config that contains the LB config. We don't want to
292
+ // recursively use xds in the LB channel.
293
+ GRPC_ARG_SERVICE_CONFIG,
294
+ // The channel arg for the server URI, since that will be different for
295
+ // the xds channel than for the parent channel. The client channel
296
+ // factory will re-add this arg with the right value.
297
+ GRPC_ARG_SERVER_URI,
298
+ // The xds channel should use the authority indicated by the target
299
+ // authority table (see \a ModifyXdsChannelArgs),
300
+ // as opposed to the authority from the parent channel.
301
+ GRPC_ARG_DEFAULT_AUTHORITY,
302
+ // Just as for \a GRPC_ARG_DEFAULT_AUTHORITY, the xds channel should be
303
+ // treated as a stand-alone channel and not inherit this argument from the
304
+ // args of the parent channel.
305
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
306
+ // Don't want to pass down channelz node from parent; the balancer
307
+ // channel will get its own.
308
+ GRPC_ARG_CHANNELZ_CHANNEL_NODE,
309
+ };
310
+ // Channel args to add.
311
+ InlinedVector<grpc_arg, 2> args_to_add;
312
+ // A channel arg indicating that the target is an xds server.
313
+ // TODO(roth): Once we figure out our fallback and credentials story, decide
314
+ // whether this is actually needed. Note that it's currently used by the
315
+ // fake security connector as well.
316
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
317
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_XDS_SERVER), 1));
318
+ // The parent channel's channelz uuid.
319
+ channelz::ChannelNode* channelz_node = nullptr;
320
+ const grpc_arg* arg =
321
+ grpc_channel_args_find(&args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
322
+ if (arg != nullptr && arg->type == GRPC_ARG_POINTER &&
323
+ arg->value.pointer.p != nullptr) {
324
+ channelz_node = static_cast<channelz::ChannelNode*>(arg->value.pointer.p);
325
+ args_to_add.emplace_back(
326
+ channelz::MakeParentUuidArg(channelz_node->uuid()));
327
+ }
328
+ // Construct channel args.
329
+ grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
330
+ &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add.data(),
331
+ args_to_add.size());
332
+ // Make any necessary modifications for security.
333
+ return ModifyXdsChannelArgs(new_args);
334
+ }
335
+
336
+ } // namespace
337
+
338
+ XdsClient::ChannelState::ChannelState(RefCountedPtr<XdsClient> xds_client,
339
+ const grpc_channel_args& args)
340
+ : InternallyRefCounted<ChannelState>(&grpc_xds_client_trace),
341
+ xds_client_(std::move(xds_client)) {
342
+ grpc_channel_args* new_args = BuildXdsChannelArgs(args);
343
+ channel_ = CreateXdsChannel(*xds_client_->bootstrap_, *new_args);
344
+ grpc_channel_args_destroy(new_args);
345
+ GPR_ASSERT(channel_ != nullptr);
346
+ StartConnectivityWatchLocked();
347
+ }
348
+
349
+ XdsClient::ChannelState::~ChannelState() {
350
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
351
+ gpr_log(GPR_INFO, "[xds_client %p] Destroying xds channel %p", xds_client(),
352
+ this);
353
+ }
354
+ grpc_channel_destroy(channel_);
355
+ }
356
+
357
+ void XdsClient::ChannelState::Orphan() {
358
+ shutting_down_ = true;
359
+ CancelConnectivityWatchLocked();
360
+ ads_calld_.reset();
361
+ lrs_calld_.reset();
362
+ Unref(DEBUG_LOCATION, "ChannelState+orphaned");
363
+ }
364
+
365
+ XdsClient::ChannelState::AdsCallState* XdsClient::ChannelState::ads_calld()
366
+ const {
367
+ return ads_calld_->calld();
368
+ }
369
+
370
+ XdsClient::ChannelState::LrsCallState* XdsClient::ChannelState::lrs_calld()
371
+ const {
372
+ return lrs_calld_->calld();
373
+ }
374
+
375
+ bool XdsClient::ChannelState::HasActiveAdsCall() const {
376
+ return ads_calld_->calld() != nullptr;
377
+ }
378
+
379
+ void XdsClient::ChannelState::MaybeStartAdsCall() {
380
+ if (ads_calld_ != nullptr) return;
381
+ ads_calld_.reset(New<RetryableCall<AdsCallState>>(
382
+ Ref(DEBUG_LOCATION, "ChannelState+ads")));
383
+ }
384
+
385
+ void XdsClient::ChannelState::StopAdsCall() { ads_calld_.reset(); }
386
+
387
+ void XdsClient::ChannelState::MaybeStartLrsCall() {
388
+ if (lrs_calld_ != nullptr) return;
389
+ lrs_calld_.reset(New<RetryableCall<LrsCallState>>(
390
+ Ref(DEBUG_LOCATION, "ChannelState+lrs")));
391
+ }
392
+
393
+ void XdsClient::ChannelState::StopLrsCall() { lrs_calld_.reset(); }
394
+
395
+ void XdsClient::ChannelState::StartConnectivityWatchLocked() {
396
+ grpc_channel_element* client_channel_elem =
397
+ grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_));
398
+ GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
399
+ watcher_ = New<StateWatcher>(Ref());
400
+ grpc_client_channel_start_connectivity_watch(
401
+ client_channel_elem, GRPC_CHANNEL_IDLE,
402
+ OrphanablePtr<AsyncConnectivityStateWatcherInterface>(watcher_));
403
+ }
404
+
405
+ void XdsClient::ChannelState::CancelConnectivityWatchLocked() {
406
+ grpc_channel_element* client_channel_elem =
407
+ grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_));
408
+ GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
409
+ grpc_client_channel_stop_connectivity_watch(client_channel_elem, watcher_);
410
+ }
411
+
412
+ //
413
+ // XdsClient::ChannelState::RetryableCall<>
414
+ //
415
+
416
+ template <typename T>
417
+ XdsClient::ChannelState::RetryableCall<T>::RetryableCall(
418
+ RefCountedPtr<ChannelState> chand)
419
+ : chand_(std::move(chand)),
420
+ backoff_(
421
+ BackOff::Options()
422
+ .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS *
423
+ 1000)
424
+ .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER)
425
+ .set_jitter(GRPC_XDS_RECONNECT_JITTER)
426
+ .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
427
+ StartNewCallLocked();
428
+ }
429
+
430
+ template <typename T>
431
+ void XdsClient::ChannelState::RetryableCall<T>::Orphan() {
432
+ shutting_down_ = true;
433
+ calld_.reset();
434
+ if (retry_timer_callback_pending_) grpc_timer_cancel(&retry_timer_);
435
+ this->Unref(DEBUG_LOCATION, "RetryableCall+orphaned");
436
+ }
437
+
438
+ template <typename T>
439
+ void XdsClient::ChannelState::RetryableCall<T>::OnCallFinishedLocked() {
440
+ const bool seen_response = calld_->seen_response();
441
+ calld_.reset();
442
+ if (seen_response) {
443
+ // If we lost connection to the xds server, reset backoff and restart the
444
+ // call immediately.
445
+ backoff_.Reset();
446
+ StartNewCallLocked();
447
+ } else {
448
+ // If we failed to connect to the xds server, retry later.
449
+ StartRetryTimerLocked();
450
+ }
451
+ }
452
+
453
+ template <typename T>
454
+ void XdsClient::ChannelState::RetryableCall<T>::StartNewCallLocked() {
455
+ if (shutting_down_) return;
456
+ GPR_ASSERT(chand_->channel_ != nullptr);
457
+ GPR_ASSERT(calld_ == nullptr);
458
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
459
+ gpr_log(GPR_INFO,
460
+ "[xds_client %p] Start new call from retryable call (chand: %p, "
461
+ "retryable call: %p)",
462
+ chand()->xds_client(), chand(), this);
463
+ }
464
+ calld_ = MakeOrphanable<T>(
465
+ this->Ref(DEBUG_LOCATION, "RetryableCall+start_new_call"));
466
+ }
467
+
468
+ template <typename T>
469
+ void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
470
+ if (shutting_down_) return;
471
+ const grpc_millis next_attempt_time = backoff_.NextAttemptTime();
472
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
473
+ grpc_millis timeout = GPR_MAX(next_attempt_time - ExecCtx::Get()->Now(), 0);
474
+ gpr_log(GPR_INFO,
475
+ "[xds_client %p] Failed to connect to xds server (chand: %p) "
476
+ "retry timer will fire in %" PRId64 "ms.",
477
+ chand()->xds_client(), chand(), timeout);
478
+ }
479
+ this->Ref(DEBUG_LOCATION, "RetryableCall+retry_timer_start").release();
480
+ GRPC_CLOSURE_INIT(&on_retry_timer_, OnRetryTimer, this,
481
+ grpc_schedule_on_exec_ctx);
482
+ grpc_timer_init(&retry_timer_, next_attempt_time, &on_retry_timer_);
483
+ retry_timer_callback_pending_ = true;
484
+ }
485
+
486
+ template <typename T>
487
+ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimer(
488
+ void* arg, grpc_error* error) {
489
+ RetryableCall* calld = static_cast<RetryableCall*>(arg);
490
+ calld->chand_->xds_client()->combiner_->Run(
491
+ GRPC_CLOSURE_INIT(&calld->on_retry_timer_, OnRetryTimerLocked, calld,
492
+ nullptr),
493
+ GRPC_ERROR_REF(error));
494
+ }
495
+
496
+ template <typename T>
497
+ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimerLocked(
498
+ void* arg, grpc_error* error) {
499
+ RetryableCall* calld = static_cast<RetryableCall*>(arg);
500
+ calld->retry_timer_callback_pending_ = false;
501
+ if (!calld->shutting_down_ && error == GRPC_ERROR_NONE) {
502
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
503
+ gpr_log(
504
+ GPR_INFO,
505
+ "[xds_client %p] Retry timer fires (chand: %p, retryable call: %p)",
506
+ calld->chand()->xds_client(), calld->chand(), calld);
507
+ }
508
+ calld->StartNewCallLocked();
509
+ }
510
+ calld->Unref(DEBUG_LOCATION, "RetryableCall+retry_timer_done");
511
+ }
512
+
513
+ //
514
+ // XdsClient::ChannelState::AdsCallState
515
+ //
516
+
517
+ XdsClient::ChannelState::AdsCallState::AdsCallState(
518
+ RefCountedPtr<RetryableCall<AdsCallState>> parent)
519
+ : InternallyRefCounted<AdsCallState>(&grpc_xds_client_trace),
520
+ parent_(std::move(parent)) {
521
+ // Init the ADS call. Note that the call will progress every time there's
522
+ // activity in xds_client()->interested_parties_, which is comprised of
523
+ // the polling entities from client_channel.
524
+ GPR_ASSERT(xds_client() != nullptr);
525
+ GPR_ASSERT(xds_client()->server_name_ != nullptr);
526
+ GPR_ASSERT(*xds_client()->server_name_.get() != '\0');
527
+ // Create a call with the specified method name.
528
+ call_ = grpc_channel_create_pollset_set_call(
529
+ chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
530
+ xds_client()->interested_parties_,
531
+ GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES,
532
+ nullptr, GRPC_MILLIS_INF_FUTURE, nullptr);
533
+ GPR_ASSERT(call_ != nullptr);
534
+ // Init the request payload.
535
+ grpc_slice request_payload_slice = XdsEdsRequestCreateAndEncode(
536
+ xds_client()->server_name_.get(), xds_client()->bootstrap_->node(),
537
+ xds_client()->build_version_.get());
538
+ send_message_payload_ =
539
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
540
+ grpc_slice_unref_internal(request_payload_slice);
541
+ // Init other data associated with the call.
542
+ grpc_metadata_array_init(&initial_metadata_recv_);
543
+ grpc_metadata_array_init(&trailing_metadata_recv_);
544
+ // Start the call.
545
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
546
+ gpr_log(GPR_INFO,
547
+ "[xds_client %p] Starting ADS call (chand: %p, calld: %p, "
548
+ "call: %p)",
549
+ xds_client(), chand(), this, call_);
550
+ }
551
+ // Create the ops.
552
+ grpc_call_error call_error;
553
+ grpc_op ops[3];
554
+ memset(ops, 0, sizeof(ops));
555
+ // Op: send initial metadata.
556
+ grpc_op* op = ops;
557
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
558
+ op->data.send_initial_metadata.count = 0;
559
+ op->flags = 0;
560
+ op->reserved = nullptr;
561
+ op++;
562
+ // Op: send request message.
563
+ GPR_ASSERT(send_message_payload_ != nullptr);
564
+ op->op = GRPC_OP_SEND_MESSAGE;
565
+ op->data.send_message.send_message = send_message_payload_;
566
+ op->flags = 0;
567
+ op->reserved = nullptr;
568
+ op++;
569
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
570
+ nullptr);
571
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
572
+ // Op: recv initial metadata.
573
+ op = ops;
574
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
575
+ op->data.recv_initial_metadata.recv_initial_metadata =
576
+ &initial_metadata_recv_;
577
+ op->flags = 0;
578
+ op->reserved = nullptr;
579
+ op++;
580
+ // Op: recv response.
581
+ op->op = GRPC_OP_RECV_MESSAGE;
582
+ op->data.recv_message.recv_message = &recv_message_payload_;
583
+ op->flags = 0;
584
+ op->reserved = nullptr;
585
+ op++;
586
+ Ref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked").release();
587
+ GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceived, this,
588
+ grpc_schedule_on_exec_ctx);
589
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
590
+ &on_response_received_);
591
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
592
+ // Op: recv server status.
593
+ op = ops;
594
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
595
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv_;
596
+ op->data.recv_status_on_client.status = &status_code_;
597
+ op->data.recv_status_on_client.status_details = &status_details_;
598
+ op->flags = 0;
599
+ op->reserved = nullptr;
600
+ op++;
601
+ // This callback signals the end of the call, so it relies on the initial
602
+ // ref instead of a new ref. When it's invoked, it's the initial ref that is
603
+ // unreffed.
604
+ GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceived, this,
605
+ grpc_schedule_on_exec_ctx);
606
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
607
+ &on_status_received_);
608
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
609
+ }
610
+
611
+ XdsClient::ChannelState::AdsCallState::~AdsCallState() {
612
+ grpc_metadata_array_destroy(&initial_metadata_recv_);
613
+ grpc_metadata_array_destroy(&trailing_metadata_recv_);
614
+ grpc_byte_buffer_destroy(send_message_payload_);
615
+ grpc_byte_buffer_destroy(recv_message_payload_);
616
+ grpc_slice_unref_internal(status_details_);
617
+ GPR_ASSERT(call_ != nullptr);
618
+ grpc_call_unref(call_);
619
+ }
620
+
621
+ void XdsClient::ChannelState::AdsCallState::Orphan() {
622
+ GPR_ASSERT(call_ != nullptr);
623
+ // If we are here because xds_client wants to cancel the call,
624
+ // on_status_received_ will complete the cancellation and clean up. Otherwise,
625
+ // we are here because xds_client has to orphan a failed call, then the
626
+ // following cancellation will be a no-op.
627
+ grpc_call_cancel(call_, nullptr);
628
+ // Note that the initial ref is hold by on_status_received_. So the
629
+ // corresponding unref happens in on_status_received_ instead of here.
630
+ }
631
+
632
+ void XdsClient::ChannelState::AdsCallState::OnResponseReceived(
633
+ void* arg, grpc_error* error) {
634
+ AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
635
+ ads_calld->xds_client()->combiner_->Run(
636
+ GRPC_CLOSURE_INIT(&ads_calld->on_response_received_,
637
+ OnResponseReceivedLocked, ads_calld, nullptr),
638
+ GRPC_ERROR_REF(error));
639
+ }
640
+
641
+ void XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked(
642
+ void* arg, grpc_error* error) {
643
+ AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
644
+ XdsClient* xds_client = ads_calld->xds_client();
645
+ // Empty payload means the call was cancelled.
646
+ if (!ads_calld->IsCurrentCallOnChannel() ||
647
+ ads_calld->recv_message_payload_ == nullptr) {
648
+ ads_calld->Unref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked");
649
+ return;
650
+ }
651
+ // Read the response.
652
+ grpc_byte_buffer_reader bbr;
653
+ grpc_byte_buffer_reader_init(&bbr, ads_calld->recv_message_payload_);
654
+ grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
655
+ grpc_byte_buffer_reader_destroy(&bbr);
656
+ grpc_byte_buffer_destroy(ads_calld->recv_message_payload_);
657
+ ads_calld->recv_message_payload_ = nullptr;
658
+ // TODO(juanlishen): When we convert this to use the xds protocol, the
659
+ // balancer will send us a fallback timeout such that we should go into
660
+ // fallback mode if we have lost contact with the balancer after a certain
661
+ // period of time. We will need to save the timeout value here, and then
662
+ // when the balancer call ends, we will need to start a timer for the
663
+ // specified period of time, and if the timer fires, we go into fallback
664
+ // mode. We will also need to cancel the timer when we receive a serverlist
665
+ // from the balancer.
666
+ // This anonymous lambda is a hack to avoid the usage of goto.
667
+ [&]() {
668
+ // Parse the response.
669
+ EdsUpdate update;
670
+ grpc_error* parse_error =
671
+ XdsEdsResponseDecodeAndParse(response_slice, &update);
672
+ if (parse_error != GRPC_ERROR_NONE) {
673
+ gpr_log(GPR_ERROR,
674
+ "[xds_client %p] ADS response parsing failed. error=%s",
675
+ xds_client, grpc_error_string(parse_error));
676
+ GRPC_ERROR_UNREF(parse_error);
677
+ return;
678
+ }
679
+ if (update.priority_list_update.empty() && !update.drop_all) {
680
+ char* response_slice_str =
681
+ grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX);
682
+ gpr_log(GPR_ERROR,
683
+ "[xds_client %p] ADS response '%s' doesn't contain any valid "
684
+ "locality but doesn't require to drop all calls. Ignoring.",
685
+ xds_client, response_slice_str);
686
+ gpr_free(response_slice_str);
687
+ return;
688
+ }
689
+ ads_calld->seen_response_ = true;
690
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
691
+ gpr_log(GPR_INFO,
692
+ "[xds_client %p] ADS response with %" PRIuPTR
693
+ " priorities and %" PRIuPTR
694
+ " drop categories received (drop_all=%d)",
695
+ xds_client, update.priority_list_update.size(),
696
+ update.drop_config->drop_category_list().size(), update.drop_all);
697
+ for (size_t priority = 0; priority < update.priority_list_update.size();
698
+ ++priority) {
699
+ const auto* locality_map_update =
700
+ update.priority_list_update.Find(static_cast<uint32_t>(priority));
701
+ gpr_log(GPR_INFO,
702
+ "[xds_client %p] Priority %" PRIuPTR " contains %" PRIuPTR
703
+ " localities",
704
+ xds_client, priority, locality_map_update->size());
705
+ size_t locality_count = 0;
706
+ for (const auto& p : locality_map_update->localities) {
707
+ const auto& locality = p.second;
708
+ gpr_log(GPR_INFO,
709
+ "[xds_client %p] Priority %" PRIuPTR ", locality %" PRIuPTR
710
+ " %s contains %" PRIuPTR " server addresses",
711
+ xds_client, priority, locality_count,
712
+ locality.name->AsHumanReadableString(),
713
+ locality.serverlist.size());
714
+ for (size_t i = 0; i < locality.serverlist.size(); ++i) {
715
+ char* ipport;
716
+ grpc_sockaddr_to_string(&ipport, &locality.serverlist[i].address(),
717
+ false);
718
+ gpr_log(GPR_INFO,
719
+ "[xds_client %p] Priority %" PRIuPTR ", locality %" PRIuPTR
720
+ " %s, server address %" PRIuPTR ": %s",
721
+ xds_client, priority, locality_count,
722
+ locality.name->AsHumanReadableString(), i, ipport);
723
+ gpr_free(ipport);
724
+ }
725
+ ++locality_count;
726
+ }
727
+ }
728
+ for (size_t i = 0; i < update.drop_config->drop_category_list().size();
729
+ ++i) {
730
+ const XdsDropConfig::DropCategory& drop_category =
731
+ update.drop_config->drop_category_list()[i];
732
+ gpr_log(GPR_INFO,
733
+ "[xds_client %p] Drop category %s has drop rate %d per million",
734
+ xds_client, drop_category.name.get(),
735
+ drop_category.parts_per_million);
736
+ }
737
+ }
738
+ // Start load reporting if needed.
739
+ LrsCallState* lrs_calld = ads_calld->chand()->lrs_calld_->calld();
740
+ if (lrs_calld != nullptr) lrs_calld->MaybeStartReportingLocked();
741
+ // Ignore identical update.
742
+ const EdsUpdate& prev_update = xds_client->cluster_state_.eds_update;
743
+ const bool priority_list_changed =
744
+ prev_update.priority_list_update != update.priority_list_update;
745
+ const bool drop_config_changed =
746
+ prev_update.drop_config == nullptr ||
747
+ *prev_update.drop_config != *update.drop_config;
748
+ if (!priority_list_changed && !drop_config_changed) {
749
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
750
+ gpr_log(GPR_INFO,
751
+ "[xds_client %p] EDS update identical to current, ignoring.",
752
+ xds_client);
753
+ }
754
+ return;
755
+ }
756
+ // Update the cluster state.
757
+ ClusterState& cluster_state = xds_client->cluster_state_;
758
+ cluster_state.eds_update = std::move(update);
759
+ // Notify all watchers.
760
+ for (const auto& p : cluster_state.endpoint_watchers) {
761
+ p.first->OnEndpointChanged(cluster_state.eds_update);
762
+ }
763
+ }();
764
+ grpc_slice_unref_internal(response_slice);
765
+ if (xds_client->shutting_down_) {
766
+ ads_calld->Unref(DEBUG_LOCATION,
767
+ "ADS+OnResponseReceivedLocked+xds_shutdown");
768
+ return;
769
+ }
770
+ // Keep listening for serverlist updates.
771
+ grpc_op op;
772
+ memset(&op, 0, sizeof(op));
773
+ op.op = GRPC_OP_RECV_MESSAGE;
774
+ op.data.recv_message.recv_message = &ads_calld->recv_message_payload_;
775
+ op.flags = 0;
776
+ op.reserved = nullptr;
777
+ GPR_ASSERT(ads_calld->call_ != nullptr);
778
+ // Reuse the "ADS+OnResponseReceivedLocked" ref taken in ctor.
779
+ GRPC_CLOSURE_INIT(&ads_calld->on_response_received_, OnResponseReceived,
780
+ ads_calld, grpc_schedule_on_exec_ctx);
781
+ const grpc_call_error call_error = grpc_call_start_batch_and_execute(
782
+ ads_calld->call_, &op, 1, &ads_calld->on_response_received_);
783
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
784
+ }
785
+
786
+ void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
787
+ void* arg, grpc_error* error) {
788
+ AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
789
+ ads_calld->xds_client()->combiner_->Run(
790
+ GRPC_CLOSURE_INIT(&ads_calld->on_status_received_, OnStatusReceivedLocked,
791
+ ads_calld, nullptr),
792
+ GRPC_ERROR_REF(error));
793
+ }
794
+
795
+ void XdsClient::ChannelState::AdsCallState::OnStatusReceivedLocked(
796
+ void* arg, grpc_error* error) {
797
+ AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
798
+ ChannelState* chand = ads_calld->chand();
799
+ XdsClient* xds_client = ads_calld->xds_client();
800
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
801
+ char* status_details = grpc_slice_to_c_string(ads_calld->status_details_);
802
+ gpr_log(GPR_INFO,
803
+ "[xds_client %p] ADS call status received. Status = %d, details "
804
+ "= '%s', (chand: %p, ads_calld: %p, call: %p), error '%s'",
805
+ xds_client, ads_calld->status_code_, status_details, chand,
806
+ ads_calld, ads_calld->call_, grpc_error_string(error));
807
+ gpr_free(status_details);
808
+ }
809
+ // Ignore status from a stale call.
810
+ if (ads_calld->IsCurrentCallOnChannel()) {
811
+ // Try to restart the call.
812
+ ads_calld->parent_->OnCallFinishedLocked();
813
+ // Send error to all watchers.
814
+ xds_client->NotifyOnError(
815
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("xds call failed"));
816
+ }
817
+ ads_calld->Unref(DEBUG_LOCATION, "ADS+OnStatusReceivedLocked");
818
+ }
819
+
820
+ bool XdsClient::ChannelState::AdsCallState::IsCurrentCallOnChannel() const {
821
+ // If the retryable ADS call is null (which only happens when the xds channel
822
+ // is shutting down), all the ADS calls are stale.
823
+ if (chand()->ads_calld_ == nullptr) return false;
824
+ return this == chand()->ads_calld_->calld();
825
+ }
826
+
827
+ //
828
+ // XdsClient::ChannelState::LrsCallState::Reporter
829
+ //
830
+
831
+ void XdsClient::ChannelState::LrsCallState::Reporter::Orphan() {
832
+ if (next_report_timer_callback_pending_) {
833
+ grpc_timer_cancel(&next_report_timer_);
834
+ }
835
+ }
836
+
837
+ void XdsClient::ChannelState::LrsCallState::Reporter::
838
+ ScheduleNextReportLocked() {
839
+ const grpc_millis next_report_time = ExecCtx::Get()->Now() + report_interval_;
840
+ GRPC_CLOSURE_INIT(&on_next_report_timer_, OnNextReportTimer, this,
841
+ grpc_schedule_on_exec_ctx);
842
+ grpc_timer_init(&next_report_timer_, next_report_time,
843
+ &on_next_report_timer_);
844
+ next_report_timer_callback_pending_ = true;
845
+ }
846
+
847
+ void XdsClient::ChannelState::LrsCallState::Reporter::OnNextReportTimer(
848
+ void* arg, grpc_error* error) {
849
+ Reporter* self = static_cast<Reporter*>(arg);
850
+ self->xds_client()->combiner_->Run(
851
+ GRPC_CLOSURE_INIT(&self->on_next_report_timer_, OnNextReportTimerLocked,
852
+ self, nullptr),
853
+ GRPC_ERROR_REF(error));
854
+ }
855
+
856
+ void XdsClient::ChannelState::LrsCallState::Reporter::OnNextReportTimerLocked(
857
+ void* arg, grpc_error* error) {
858
+ Reporter* self = static_cast<Reporter*>(arg);
859
+ self->next_report_timer_callback_pending_ = false;
860
+ if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
861
+ self->Unref(DEBUG_LOCATION, "Reporter+timer");
862
+ return;
863
+ }
864
+ self->SendReportLocked();
865
+ }
866
+
867
+ void XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
868
+ // Create a request that contains the load report.
869
+ // TODO(roth): Currently, it is not possible to have multiple client
870
+ // stats objects for a given cluster. However, in the future, we may
871
+ // run into cases where this happens (e.g., due to graceful LB policy
872
+ // switching). If/when this becomes a problem, replace this assertion
873
+ // with code to merge data from multiple client stats objects.
874
+ GPR_ASSERT(xds_client()->cluster_state_.client_stats.size() == 1);
875
+ auto* client_stats = *xds_client()->cluster_state_.client_stats.begin();
876
+ grpc_slice request_payload_slice =
877
+ XdsLrsRequestCreateAndEncode(parent_->cluster_name_.get(), client_stats);
878
+ // Skip client load report if the counters were all zero in the last
879
+ // report and they are still zero in this one.
880
+ const bool old_val = last_report_counters_were_zero_;
881
+ last_report_counters_were_zero_ = static_cast<bool>(
882
+ grpc_slice_eq(request_payload_slice, grpc_empty_slice()));
883
+ if (old_val && last_report_counters_were_zero_) {
884
+ ScheduleNextReportLocked();
885
+ return;
886
+ }
887
+ parent_->send_message_payload_ =
888
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
889
+ grpc_slice_unref_internal(request_payload_slice);
890
+ // Send the report.
891
+ grpc_op op;
892
+ memset(&op, 0, sizeof(op));
893
+ op.op = GRPC_OP_SEND_MESSAGE;
894
+ op.data.send_message.send_message = parent_->send_message_payload_;
895
+ GRPC_CLOSURE_INIT(&on_report_done_, OnReportDone, this,
896
+ grpc_schedule_on_exec_ctx);
897
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
898
+ parent_->call_, &op, 1, &on_report_done_);
899
+ if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
900
+ gpr_log(GPR_ERROR,
901
+ "[xds_client %p] calld=%p call_error=%d sending client load report",
902
+ xds_client(), this, call_error);
903
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
904
+ }
905
+ }
906
+
907
+ void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDone(
908
+ void* arg, grpc_error* error) {
909
+ Reporter* self = static_cast<Reporter*>(arg);
910
+ self->xds_client()->combiner_->Run(
911
+ GRPC_CLOSURE_INIT(&self->on_report_done_, OnReportDoneLocked, self,
912
+ nullptr),
913
+ GRPC_ERROR_REF(error));
914
+ }
915
+
916
+ void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked(
917
+ void* arg, grpc_error* error) {
918
+ Reporter* self = static_cast<Reporter*>(arg);
919
+ grpc_byte_buffer_destroy(self->parent_->send_message_payload_);
920
+ self->parent_->send_message_payload_ = nullptr;
921
+ if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
922
+ // If this reporter is no longer the current one on the call, the reason
923
+ // might be that it was orphaned for a new one due to config update.
924
+ if (!self->IsCurrentReporterOnCall()) {
925
+ self->parent_->MaybeStartReportingLocked();
926
+ }
927
+ self->Unref(DEBUG_LOCATION, "Reporter+report_done");
928
+ return;
929
+ }
930
+ self->ScheduleNextReportLocked();
931
+ }
932
+
933
+ //
934
+ // XdsClient::ChannelState::LrsCallState
935
+ //
936
+
937
+ XdsClient::ChannelState::LrsCallState::LrsCallState(
938
+ RefCountedPtr<RetryableCall<LrsCallState>> parent)
939
+ : InternallyRefCounted<LrsCallState>(&grpc_xds_client_trace),
940
+ parent_(std::move(parent)) {
941
+ // Init the LRS call. Note that the call will progress every time there's
942
+ // activity in xds_client()->interested_parties_, which is comprised of
943
+ // the polling entities from client_channel.
944
+ GPR_ASSERT(xds_client() != nullptr);
945
+ GPR_ASSERT(xds_client()->server_name_ != nullptr);
946
+ GPR_ASSERT(*xds_client()->server_name_.get() != '\0');
947
+ call_ = grpc_channel_create_pollset_set_call(
948
+ chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
949
+ xds_client()->interested_parties_,
950
+ GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V2_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS,
951
+ nullptr, GRPC_MILLIS_INF_FUTURE, nullptr);
952
+ GPR_ASSERT(call_ != nullptr);
953
+ // Init the request payload.
954
+ grpc_slice request_payload_slice = XdsLrsRequestCreateAndEncode(
955
+ xds_client()->server_name_.get(), xds_client()->bootstrap_->node(),
956
+ xds_client()->build_version_.get());
957
+ send_message_payload_ =
958
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
959
+ grpc_slice_unref_internal(request_payload_slice);
960
+ // Init other data associated with the LRS call.
961
+ grpc_metadata_array_init(&initial_metadata_recv_);
962
+ grpc_metadata_array_init(&trailing_metadata_recv_);
963
+ // Start the call.
964
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
965
+ gpr_log(GPR_INFO,
966
+ "[xds_client %p] Starting LRS call (chand: %p, calld: %p, "
967
+ "call: %p)",
968
+ xds_client(), chand(), this, call_);
969
+ }
970
+ // Create the ops.
971
+ grpc_call_error call_error;
972
+ grpc_op ops[3];
973
+ memset(ops, 0, sizeof(ops));
974
+ // Op: send initial metadata.
975
+ grpc_op* op = ops;
976
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
977
+ op->data.send_initial_metadata.count = 0;
978
+ op->flags = 0;
979
+ op->reserved = nullptr;
980
+ op++;
981
+ // Op: send request message.
982
+ GPR_ASSERT(send_message_payload_ != nullptr);
983
+ op->op = GRPC_OP_SEND_MESSAGE;
984
+ op->data.send_message.send_message = send_message_payload_;
985
+ op->flags = 0;
986
+ op->reserved = nullptr;
987
+ op++;
988
+ Ref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked").release();
989
+ GRPC_CLOSURE_INIT(&on_initial_request_sent_, OnInitialRequestSent, this,
990
+ grpc_schedule_on_exec_ctx);
991
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
992
+ &on_initial_request_sent_);
993
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
994
+ // Op: recv initial metadata.
995
+ op = ops;
996
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
997
+ op->data.recv_initial_metadata.recv_initial_metadata =
998
+ &initial_metadata_recv_;
999
+ op->flags = 0;
1000
+ op->reserved = nullptr;
1001
+ op++;
1002
+ // Op: recv response.
1003
+ op->op = GRPC_OP_RECV_MESSAGE;
1004
+ op->data.recv_message.recv_message = &recv_message_payload_;
1005
+ op->flags = 0;
1006
+ op->reserved = nullptr;
1007
+ op++;
1008
+ Ref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked").release();
1009
+ GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceived, this,
1010
+ grpc_schedule_on_exec_ctx);
1011
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
1012
+ &on_response_received_);
1013
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
1014
+ // Op: recv server status.
1015
+ op = ops;
1016
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
1017
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv_;
1018
+ op->data.recv_status_on_client.status = &status_code_;
1019
+ op->data.recv_status_on_client.status_details = &status_details_;
1020
+ op->flags = 0;
1021
+ op->reserved = nullptr;
1022
+ op++;
1023
+ // This callback signals the end of the call, so it relies on the initial
1024
+ // ref instead of a new ref. When it's invoked, it's the initial ref that is
1025
+ // unreffed.
1026
+ GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceived, this,
1027
+ grpc_schedule_on_exec_ctx);
1028
+ call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
1029
+ &on_status_received_);
1030
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
1031
+ }
1032
+
1033
+ XdsClient::ChannelState::LrsCallState::~LrsCallState() {
1034
+ grpc_metadata_array_destroy(&initial_metadata_recv_);
1035
+ grpc_metadata_array_destroy(&trailing_metadata_recv_);
1036
+ grpc_byte_buffer_destroy(send_message_payload_);
1037
+ grpc_byte_buffer_destroy(recv_message_payload_);
1038
+ grpc_slice_unref_internal(status_details_);
1039
+ GPR_ASSERT(call_ != nullptr);
1040
+ grpc_call_unref(call_);
1041
+ }
1042
+
1043
+ void XdsClient::ChannelState::LrsCallState::Orphan() {
1044
+ reporter_.reset();
1045
+ GPR_ASSERT(call_ != nullptr);
1046
+ // If we are here because xds_client wants to cancel the call,
1047
+ // on_status_received_ will complete the cancellation and clean up. Otherwise,
1048
+ // we are here because xds_client has to orphan a failed call, then the
1049
+ // following cancellation will be a no-op.
1050
+ grpc_call_cancel(call_, nullptr);
1051
+ // Note that the initial ref is hold by on_status_received_. So the
1052
+ // corresponding unref happens in on_status_received_ instead of here.
1053
+ }
1054
+
1055
+ void XdsClient::ChannelState::LrsCallState::MaybeStartReportingLocked() {
1056
+ // Don't start again if already started.
1057
+ if (reporter_ != nullptr) return;
1058
+ // Don't start if the previous send_message op (of the initial request or the
1059
+ // last report of the previous reporter) hasn't completed.
1060
+ if (send_message_payload_ != nullptr) return;
1061
+ // Don't start if no LRS response has arrived.
1062
+ if (!seen_response()) return;
1063
+ // Don't start if the ADS call hasn't received any valid response. Note that
1064
+ // this must be the first channel because it is the current channel but its
1065
+ // ADS call hasn't seen any response.
1066
+ AdsCallState* ads_calld = chand()->ads_calld_->calld();
1067
+ if (ads_calld == nullptr || !ads_calld->seen_response()) return;
1068
+ // Start reporting.
1069
+ for (auto* client_stats : chand()->xds_client_->cluster_state_.client_stats) {
1070
+ client_stats->MaybeInitLastReportTime();
1071
+ }
1072
+ reporter_ = MakeOrphanable<Reporter>(
1073
+ Ref(DEBUG_LOCATION, "LRS+load_report+start"), load_reporting_interval_);
1074
+ }
1075
+
1076
+ void XdsClient::ChannelState::LrsCallState::OnInitialRequestSent(
1077
+ void* arg, grpc_error* error) {
1078
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1079
+ lrs_calld->xds_client()->combiner_->Run(
1080
+ GRPC_CLOSURE_INIT(&lrs_calld->on_initial_request_sent_,
1081
+ OnInitialRequestSentLocked, lrs_calld, nullptr),
1082
+ GRPC_ERROR_REF(error));
1083
+ }
1084
+
1085
+ void XdsClient::ChannelState::LrsCallState::OnInitialRequestSentLocked(
1086
+ void* arg, grpc_error* error) {
1087
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1088
+ // Clear the send_message_payload_.
1089
+ grpc_byte_buffer_destroy(lrs_calld->send_message_payload_);
1090
+ lrs_calld->send_message_payload_ = nullptr;
1091
+ lrs_calld->MaybeStartReportingLocked();
1092
+ lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked");
1093
+ }
1094
+
1095
+ void XdsClient::ChannelState::LrsCallState::OnResponseReceived(
1096
+ void* arg, grpc_error* error) {
1097
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1098
+ lrs_calld->xds_client()->combiner_->Run(
1099
+ GRPC_CLOSURE_INIT(&lrs_calld->on_response_received_,
1100
+ OnResponseReceivedLocked, lrs_calld, nullptr),
1101
+ GRPC_ERROR_REF(error));
1102
+ }
1103
+
1104
+ void XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked(
1105
+ void* arg, grpc_error* error) {
1106
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1107
+ XdsClient* xds_client = lrs_calld->xds_client();
1108
+ // Empty payload means the call was cancelled.
1109
+ if (!lrs_calld->IsCurrentCallOnChannel() ||
1110
+ lrs_calld->recv_message_payload_ == nullptr) {
1111
+ lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked");
1112
+ return;
1113
+ }
1114
+ // Read the response.
1115
+ grpc_byte_buffer_reader bbr;
1116
+ grpc_byte_buffer_reader_init(&bbr, lrs_calld->recv_message_payload_);
1117
+ grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
1118
+ grpc_byte_buffer_reader_destroy(&bbr);
1119
+ grpc_byte_buffer_destroy(lrs_calld->recv_message_payload_);
1120
+ lrs_calld->recv_message_payload_ = nullptr;
1121
+ // This anonymous lambda is a hack to avoid the usage of goto.
1122
+ [&]() {
1123
+ // Parse the response.
1124
+ UniquePtr<char> new_cluster_name;
1125
+ grpc_millis new_load_reporting_interval;
1126
+ grpc_error* parse_error = XdsLrsResponseDecodeAndParse(
1127
+ response_slice, &new_cluster_name, &new_load_reporting_interval);
1128
+ if (parse_error != GRPC_ERROR_NONE) {
1129
+ gpr_log(GPR_ERROR,
1130
+ "[xds_client %p] LRS response parsing failed. error=%s",
1131
+ xds_client, grpc_error_string(parse_error));
1132
+ GRPC_ERROR_UNREF(parse_error);
1133
+ return;
1134
+ }
1135
+ lrs_calld->seen_response_ = true;
1136
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1137
+ gpr_log(GPR_INFO,
1138
+ "[xds_client %p] LRS response received, cluster_name=%s, "
1139
+ "load_report_interval=%" PRId64 "ms",
1140
+ xds_client, new_cluster_name.get(), new_load_reporting_interval);
1141
+ }
1142
+ if (new_load_reporting_interval <
1143
+ GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS) {
1144
+ new_load_reporting_interval =
1145
+ GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS;
1146
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1147
+ gpr_log(GPR_INFO,
1148
+ "[xds_client %p] Increased load_report_interval to minimum "
1149
+ "value %dms",
1150
+ xds_client, GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1151
+ }
1152
+ }
1153
+ // Ignore identical update.
1154
+ if (lrs_calld->load_reporting_interval_ == new_load_reporting_interval &&
1155
+ strcmp(lrs_calld->cluster_name_.get(), new_cluster_name.get()) == 0) {
1156
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1157
+ gpr_log(GPR_INFO,
1158
+ "[xds_client %p] Incoming LRS response identical to current, "
1159
+ "ignoring.",
1160
+ xds_client);
1161
+ }
1162
+ return;
1163
+ }
1164
+ // Stop current load reporting (if any) to adopt the new config.
1165
+ lrs_calld->reporter_.reset();
1166
+ // Record the new config.
1167
+ lrs_calld->cluster_name_ = std::move(new_cluster_name);
1168
+ lrs_calld->load_reporting_interval_ = new_load_reporting_interval;
1169
+ // Try starting sending load report.
1170
+ lrs_calld->MaybeStartReportingLocked();
1171
+ }();
1172
+ grpc_slice_unref_internal(response_slice);
1173
+ if (xds_client->shutting_down_) {
1174
+ lrs_calld->Unref(DEBUG_LOCATION,
1175
+ "LRS+OnResponseReceivedLocked+xds_shutdown");
1176
+ return;
1177
+ }
1178
+ // Keep listening for LRS config updates.
1179
+ grpc_op op;
1180
+ memset(&op, 0, sizeof(op));
1181
+ op.op = GRPC_OP_RECV_MESSAGE;
1182
+ op.data.recv_message.recv_message = &lrs_calld->recv_message_payload_;
1183
+ op.flags = 0;
1184
+ op.reserved = nullptr;
1185
+ GPR_ASSERT(lrs_calld->call_ != nullptr);
1186
+ // Reuse the "OnResponseReceivedLocked" ref taken in ctor.
1187
+ GRPC_CLOSURE_INIT(&lrs_calld->on_response_received_, OnResponseReceived,
1188
+ lrs_calld, grpc_schedule_on_exec_ctx);
1189
+ const grpc_call_error call_error = grpc_call_start_batch_and_execute(
1190
+ lrs_calld->call_, &op, 1, &lrs_calld->on_response_received_);
1191
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
1192
+ }
1193
+
1194
+ void XdsClient::ChannelState::LrsCallState::OnStatusReceived(
1195
+ void* arg, grpc_error* error) {
1196
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1197
+ lrs_calld->xds_client()->combiner_->Run(
1198
+ GRPC_CLOSURE_INIT(&lrs_calld->on_status_received_, OnStatusReceivedLocked,
1199
+ lrs_calld, nullptr),
1200
+ GRPC_ERROR_REF(error));
1201
+ }
1202
+
1203
+ void XdsClient::ChannelState::LrsCallState::OnStatusReceivedLocked(
1204
+ void* arg, grpc_error* error) {
1205
+ LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1206
+ XdsClient* xds_client = lrs_calld->xds_client();
1207
+ ChannelState* chand = lrs_calld->chand();
1208
+ GPR_ASSERT(lrs_calld->call_ != nullptr);
1209
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1210
+ char* status_details = grpc_slice_to_c_string(lrs_calld->status_details_);
1211
+ gpr_log(GPR_INFO,
1212
+ "[xds_client %p] LRS call status received. Status = %d, details "
1213
+ "= '%s', (chand: %p, calld: %p, call: %p), error '%s'",
1214
+ xds_client, lrs_calld->status_code_, status_details, chand,
1215
+ lrs_calld, lrs_calld->call_, grpc_error_string(error));
1216
+ gpr_free(status_details);
1217
+ }
1218
+ // Ignore status from a stale call.
1219
+ if (lrs_calld->IsCurrentCallOnChannel()) {
1220
+ GPR_ASSERT(!xds_client->shutting_down_);
1221
+ // Try to restart the call.
1222
+ lrs_calld->parent_->OnCallFinishedLocked();
1223
+ }
1224
+ lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnStatusReceivedLocked");
1225
+ }
1226
+
1227
+ bool XdsClient::ChannelState::LrsCallState::IsCurrentCallOnChannel() const {
1228
+ // If the retryable LRS call is null (which only happens when the xds channel
1229
+ // is shutting down), all the LRS calls are stale.
1230
+ if (chand()->lrs_calld_ == nullptr) return false;
1231
+ return this == chand()->lrs_calld_->calld();
1232
+ }
1233
+
1234
+ //
1235
+ // XdsClient
1236
+ //
1237
+
1238
+ namespace {
1239
+
1240
+ UniquePtr<char> GenerateBuildVersionString() {
1241
+ char* build_version_str;
1242
+ gpr_asprintf(&build_version_str, "gRPC C-core %s %s", grpc_version_string(),
1243
+ GPR_PLATFORM_STRING);
1244
+ return UniquePtr<char>(build_version_str);
1245
+ }
1246
+
1247
+ } // namespace
1248
+
1249
+ XdsClient::XdsClient(Combiner* combiner, grpc_pollset_set* interested_parties,
1250
+ StringView server_name,
1251
+ UniquePtr<ServiceConfigWatcherInterface> watcher,
1252
+ const grpc_channel_args& channel_args, grpc_error** error)
1253
+ : build_version_(GenerateBuildVersionString()),
1254
+ combiner_(GRPC_COMBINER_REF(combiner, "xds_client")),
1255
+ interested_parties_(interested_parties),
1256
+ bootstrap_(XdsBootstrap::ReadFromFile(error)),
1257
+ server_name_(server_name.dup()),
1258
+ service_config_watcher_(std::move(watcher)) {
1259
+ if (*error != GRPC_ERROR_NONE) {
1260
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1261
+ gpr_log(GPR_INFO, "[xds_client %p: failed to read bootstrap file: %s",
1262
+ this, grpc_error_string(*error));
1263
+ }
1264
+ return;
1265
+ }
1266
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1267
+ gpr_log(GPR_INFO, "[xds_client %p: creating channel to %s", this,
1268
+ bootstrap_->server_uri());
1269
+ }
1270
+ chand_ = MakeOrphanable<ChannelState>(
1271
+ Ref(DEBUG_LOCATION, "XdsClient+ChannelState"), channel_args);
1272
+ if (service_config_watcher_ != nullptr) {
1273
+ // TODO(juanlishen): Start LDS call and do not return service config
1274
+ // until we get the first LDS response.
1275
+ GRPC_CLOSURE_INIT(&service_config_notify_, NotifyOnServiceConfig,
1276
+ Ref().release(), nullptr);
1277
+ combiner_->Run(&service_config_notify_, GRPC_ERROR_NONE);
1278
+ }
1279
+ }
1280
+
1281
+ XdsClient::~XdsClient() { GRPC_COMBINER_UNREF(combiner_, "xds_client"); }
1282
+
1283
+ void XdsClient::Orphan() {
1284
+ shutting_down_ = true;
1285
+ chand_.reset();
1286
+ Unref(DEBUG_LOCATION, "XdsClient::Orphan()");
1287
+ }
1288
+
1289
+ void XdsClient::WatchClusterData(StringView cluster,
1290
+ UniquePtr<ClusterWatcherInterface> watcher) {
1291
+ // TODO(juanlishen): Implement.
1292
+ }
1293
+
1294
+ void XdsClient::CancelClusterDataWatch(StringView cluster,
1295
+ ClusterWatcherInterface* watcher) {
1296
+ // TODO(juanlishen): Implement.
1297
+ }
1298
+
1299
+ void XdsClient::WatchEndpointData(StringView cluster,
1300
+ UniquePtr<EndpointWatcherInterface> watcher) {
1301
+ EndpointWatcherInterface* w = watcher.get();
1302
+ cluster_state_.endpoint_watchers[w] = std::move(watcher);
1303
+ // If we've already received an EDS update, notify the new watcher
1304
+ // immediately.
1305
+ if (!cluster_state_.eds_update.priority_list_update.empty()) {
1306
+ w->OnEndpointChanged(cluster_state_.eds_update);
1307
+ }
1308
+ chand_->MaybeStartAdsCall();
1309
+ }
1310
+
1311
+ void XdsClient::CancelEndpointDataWatch(StringView cluster,
1312
+ EndpointWatcherInterface* watcher) {
1313
+ auto it = cluster_state_.endpoint_watchers.find(watcher);
1314
+ if (it != cluster_state_.endpoint_watchers.end()) {
1315
+ cluster_state_.endpoint_watchers.erase(it);
1316
+ }
1317
+ if (chand_ != nullptr && cluster_state_.endpoint_watchers.empty()) {
1318
+ chand_->StopAdsCall();
1319
+ }
1320
+ }
1321
+
1322
+ void XdsClient::AddClientStats(StringView cluster,
1323
+ XdsClientStats* client_stats) {
1324
+ cluster_state_.client_stats.insert(client_stats);
1325
+ chand_->MaybeStartLrsCall();
1326
+ }
1327
+
1328
+ void XdsClient::RemoveClientStats(StringView cluster,
1329
+ XdsClientStats* client_stats) {
1330
+ // TODO(roth): In principle, we should try to send a final load report
1331
+ // containing whatever final stats have been accumulated since the
1332
+ // last load report.
1333
+ auto it = cluster_state_.client_stats.find(client_stats);
1334
+ if (it != cluster_state_.client_stats.end()) {
1335
+ cluster_state_.client_stats.erase(it);
1336
+ }
1337
+ if (chand_ != nullptr && cluster_state_.client_stats.empty()) {
1338
+ chand_->StopLrsCall();
1339
+ }
1340
+ }
1341
+
1342
+ void XdsClient::ResetBackoff() {
1343
+ if (chand_ != nullptr) {
1344
+ grpc_channel_reset_connect_backoff(chand_->channel());
1345
+ }
1346
+ }
1347
+
1348
+ void XdsClient::NotifyOnError(grpc_error* error) {
1349
+ if (service_config_watcher_ != nullptr) {
1350
+ service_config_watcher_->OnError(GRPC_ERROR_REF(error));
1351
+ }
1352
+ for (const auto& p : cluster_state_.cluster_watchers) {
1353
+ p.first->OnError(GRPC_ERROR_REF(error));
1354
+ }
1355
+ for (const auto& p : cluster_state_.endpoint_watchers) {
1356
+ p.first->OnError(GRPC_ERROR_REF(error));
1357
+ }
1358
+ GRPC_ERROR_UNREF(error);
1359
+ }
1360
+
1361
+ void XdsClient::NotifyOnServiceConfig(void* arg, grpc_error* error) {
1362
+ XdsClient* self = static_cast<XdsClient*>(arg);
1363
+ // TODO(roth): When we add support for WeightedClusters, select the
1364
+ // LB policy based on that functionality.
1365
+ static const char* json =
1366
+ "{\n"
1367
+ " \"loadBalancingConfig\":[\n"
1368
+ " { \"xds_experimental\":{} }\n"
1369
+ " ]\n"
1370
+ "}";
1371
+ RefCountedPtr<ServiceConfig> service_config =
1372
+ ServiceConfig::Create(json, &error);
1373
+ if (error != GRPC_ERROR_NONE) {
1374
+ self->service_config_watcher_->OnError(error);
1375
+ } else {
1376
+ self->service_config_watcher_->OnServiceConfigChanged(
1377
+ std::move(service_config));
1378
+ }
1379
+ self->Unref();
1380
+ }
1381
+
1382
+ void* XdsClient::ChannelArgCopy(void* p) {
1383
+ XdsClient* xds_client = static_cast<XdsClient*>(p);
1384
+ xds_client->Ref().release();
1385
+ return p;
1386
+ }
1387
+
1388
+ void XdsClient::ChannelArgDestroy(void* p) {
1389
+ XdsClient* xds_client = static_cast<XdsClient*>(p);
1390
+ xds_client->Unref();
1391
+ }
1392
+
1393
+ int XdsClient::ChannelArgCmp(void* p, void* q) { return GPR_ICMP(p, q); }
1394
+
1395
+ const grpc_arg_pointer_vtable XdsClient::kXdsClientVtable = {
1396
+ XdsClient::ChannelArgCopy, XdsClient::ChannelArgDestroy,
1397
+ XdsClient::ChannelArgCmp};
1398
+
1399
+ grpc_arg XdsClient::MakeChannelArg() const {
1400
+ return grpc_channel_arg_pointer_create(const_cast<char*>(GRPC_ARG_XDS_CLIENT),
1401
+ const_cast<XdsClient*>(this),
1402
+ &XdsClient::kXdsClientVtable);
1403
+ }
1404
+
1405
+ RefCountedPtr<XdsClient> XdsClient::GetFromChannelArgs(
1406
+ const grpc_channel_args& args) {
1407
+ XdsClient* xds_client =
1408
+ grpc_channel_args_find_pointer<XdsClient>(&args, GRPC_ARG_XDS_CLIENT);
1409
+ if (xds_client != nullptr) return xds_client->Ref();
1410
+ return nullptr;
1411
+ }
1412
+
1413
+ } // namespace grpc_core