grpc 1.43.1 → 1.44.0.pre2

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 (382) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +84 -64
  3. data/include/grpc/grpc_security.h +10 -0
  4. data/include/grpc/impl/codegen/compression_types.h +0 -2
  5. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  6. data/src/core/ext/filters/client_channel/backend_metric.h +1 -1
  7. data/src/core/ext/filters/client_channel/client_channel.cc +62 -68
  8. data/src/core/ext/filters/client_channel/client_channel.h +8 -8
  9. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
  10. data/src/core/ext/filters/client_channel/config_selector.h +4 -4
  11. data/src/core/ext/filters/client_channel/dynamic_filters.h +1 -1
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +16 -14
  13. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  14. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +4 -3
  16. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +6 -5
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +3 -7
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +31 -32
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +0 -7
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +1 -1
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +1 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +43 -29
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +6 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +120 -68
  26. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +60 -48
  27. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +62 -61
  28. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +16 -11
  29. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -5
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +19 -15
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +14 -12
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +3 -2
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +50 -105
  35. data/src/core/ext/filters/client_channel/lb_policy.cc +15 -14
  36. data/src/core/ext/filters/client_channel/lb_policy.h +19 -3
  37. data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +3 -3
  38. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +207 -81
  39. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +22 -12
  40. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +19 -15
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +23 -38
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +118 -207
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +25 -32
  44. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +1 -1
  45. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +82 -73
  46. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +10 -10
  47. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +2 -1
  48. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -5
  49. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +5 -5
  50. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +157 -67
  51. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +1 -1
  52. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +2 -2
  53. data/src/core/ext/filters/client_channel/retry_filter.cc +37 -64
  54. data/src/core/ext/filters/client_channel/retry_service_config.cc +1 -1
  55. data/src/core/ext/filters/client_channel/retry_service_config.h +1 -1
  56. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +1 -1
  57. data/src/core/ext/filters/client_channel/subchannel.cc +12 -16
  58. data/src/core/ext/filters/client_channel/subchannel.h +2 -3
  59. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +37 -48
  60. data/src/core/ext/filters/fault_injection/service_config_parser.cc +6 -8
  61. data/src/core/ext/filters/fault_injection/service_config_parser.h +1 -1
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +51 -122
  63. data/src/core/ext/filters/http/client_authority_filter.cc +8 -24
  64. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +42 -140
  65. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +5 -25
  66. data/src/core/ext/filters/http/server/http_server_filter.cc +50 -135
  67. data/src/core/ext/filters/message_size/message_size_filter.cc +1 -1
  68. data/src/core/ext/filters/message_size/message_size_filter.h +1 -1
  69. data/src/core/ext/filters/rbac/rbac_filter.cc +157 -0
  70. data/src/core/ext/filters/rbac/rbac_filter.h +74 -0
  71. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +605 -0
  72. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +70 -0
  73. data/src/core/ext/filters/server_config_selector/server_config_selector.h +3 -2
  74. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +11 -6
  75. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +1 -1
  76. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +1 -1
  77. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +89 -29
  78. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +0 -1
  79. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +45 -186
  80. data/src/core/ext/transport/chttp2/transport/frame_data.cc +0 -1
  81. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +341 -279
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +69 -159
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +1 -1
  84. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h +2 -0
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +19 -32
  86. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -1
  87. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +94 -1
  88. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +2 -24
  89. data/src/core/ext/transport/chttp2/transport/internal.h +0 -33
  90. data/src/core/ext/transport/chttp2/transport/parsing.cc +0 -6
  91. data/src/core/ext/transport/chttp2/transport/writing.cc +47 -116
  92. data/src/core/ext/transport/inproc/inproc_plugin.cc +0 -4
  93. data/src/core/ext/transport/inproc/inproc_transport.cc +11 -63
  94. data/src/core/ext/transport/inproc/inproc_transport.h +0 -3
  95. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c +61 -0
  96. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +146 -0
  97. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.c +188 -0
  98. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.h +70 -0
  99. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +56 -0
  100. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.h +40 -0
  101. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.c +154 -0
  102. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.h +95 -0
  103. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.c +58 -0
  104. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.h +55 -0
  105. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.c +44 -0
  106. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.h +40 -0
  107. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.c +153 -0
  108. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.h +100 -0
  109. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.c +75 -0
  110. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.h +55 -0
  111. data/src/core/ext/xds/upb_utils.h +65 -0
  112. data/src/core/ext/xds/xds_api.cc +81 -3458
  113. data/src/core/ext/xds/xds_api.h +56 -611
  114. data/src/core/ext/xds/xds_bootstrap.cc +189 -125
  115. data/src/core/ext/xds/xds_bootstrap.h +20 -15
  116. data/src/core/ext/xds/xds_certificate_provider.h +1 -0
  117. data/src/core/ext/xds/xds_channel_creds.cc +108 -0
  118. data/src/core/ext/xds/xds_channel_creds.h +50 -0
  119. data/src/core/ext/xds/xds_client.cc +584 -994
  120. data/src/core/ext/xds/xds_client.h +78 -135
  121. data/src/core/ext/xds/xds_cluster.cc +451 -0
  122. data/src/core/ext/xds/xds_cluster.h +111 -0
  123. data/src/core/ext/xds/xds_common_types.cc +388 -0
  124. data/src/core/ext/xds/xds_common_types.h +110 -0
  125. data/src/core/ext/xds/xds_endpoint.cc +364 -0
  126. data/src/core/ext/xds/xds_endpoint.h +135 -0
  127. data/src/core/ext/xds/xds_http_filters.cc +5 -0
  128. data/src/core/ext/xds/xds_http_rbac_filter.cc +563 -0
  129. data/src/core/ext/xds/xds_http_rbac_filter.h +54 -0
  130. data/src/core/ext/xds/xds_listener.cc +1036 -0
  131. data/src/core/ext/xds/xds_listener.h +220 -0
  132. data/src/core/ext/{transport/chttp2/transport/hpack_utils.h → xds/xds_resource_type.cc} +12 -9
  133. data/src/core/ext/xds/xds_resource_type.h +98 -0
  134. data/src/core/ext/xds/xds_resource_type_impl.h +87 -0
  135. data/src/core/ext/xds/xds_route_config.cc +993 -0
  136. data/src/core/ext/xds/xds_route_config.h +215 -0
  137. data/src/core/ext/xds/xds_routing.cc +11 -8
  138. data/src/core/ext/xds/xds_routing.h +8 -5
  139. data/src/core/ext/xds/xds_server_config_fetcher.cc +159 -99
  140. data/src/core/lib/address_utils/parse_address.cc +20 -0
  141. data/src/core/lib/address_utils/parse_address.h +5 -0
  142. data/src/core/lib/address_utils/sockaddr_utils.cc +33 -36
  143. data/src/core/lib/address_utils/sockaddr_utils.h +1 -16
  144. data/src/core/lib/backoff/backoff.cc +4 -30
  145. data/src/core/lib/backoff/backoff.h +3 -3
  146. data/src/core/lib/channel/channel_args.cc +0 -1
  147. data/src/core/lib/channel/channel_stack.cc +8 -0
  148. data/src/core/lib/channel/channel_stack.h +1 -1
  149. data/src/core/lib/channel/channel_stack_builder.cc +5 -9
  150. data/src/core/lib/channel/channel_stack_builder.h +4 -7
  151. data/src/core/lib/channel/channelz.cc +1 -0
  152. data/src/core/lib/compression/compression.cc +19 -111
  153. data/src/core/lib/compression/compression_internal.cc +142 -202
  154. data/src/core/lib/compression/compression_internal.h +64 -69
  155. data/src/core/lib/compression/message_compress.cc +11 -11
  156. data/src/core/lib/compression/message_compress.h +2 -2
  157. data/src/core/lib/gpr/useful.h +4 -0
  158. data/src/core/lib/gprpp/bitset.h +7 -0
  159. data/src/core/lib/gprpp/chunked_vector.h +45 -3
  160. data/src/core/lib/gprpp/status_helper.cc +20 -28
  161. data/src/core/lib/gprpp/status_helper.h +6 -19
  162. data/src/core/lib/gprpp/table.h +11 -0
  163. data/src/core/lib/http/httpcli.cc +37 -46
  164. data/src/core/lib/http/httpcli.h +3 -15
  165. data/src/core/lib/iomgr/call_combiner.cc +15 -4
  166. data/src/core/lib/iomgr/closure.h +29 -9
  167. data/src/core/lib/iomgr/combiner.cc +25 -3
  168. data/src/core/lib/iomgr/error.cc +2 -0
  169. data/src/core/lib/iomgr/error.h +3 -0
  170. data/src/core/lib/iomgr/event_engine/iomgr.cc +3 -2
  171. data/src/core/lib/iomgr/event_engine/resolved_address_internal.cc +6 -0
  172. data/src/core/lib/iomgr/event_engine/resolved_address_internal.h +2 -0
  173. data/src/core/lib/iomgr/event_engine/resolver.cc +66 -48
  174. data/src/core/lib/iomgr/event_engine/resolver.h +56 -0
  175. data/src/core/lib/iomgr/exec_ctx.cc +22 -9
  176. data/src/core/lib/iomgr/executor.cc +10 -1
  177. data/src/core/lib/iomgr/fork_posix.cc +3 -2
  178. data/src/core/lib/iomgr/iomgr_custom.cc +4 -1
  179. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  180. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -2
  181. data/src/core/lib/iomgr/iomgr_windows.cc +2 -2
  182. data/src/core/lib/iomgr/port.h +2 -2
  183. data/src/core/lib/iomgr/resolve_address.cc +5 -24
  184. data/src/core/lib/iomgr/resolve_address.h +47 -44
  185. data/src/core/lib/iomgr/resolve_address_custom.cc +131 -109
  186. data/src/core/lib/iomgr/resolve_address_custom.h +101 -19
  187. data/src/core/lib/iomgr/resolve_address_impl.h +59 -0
  188. data/src/core/lib/iomgr/resolve_address_posix.cc +82 -66
  189. data/src/core/lib/iomgr/resolve_address_posix.h +47 -0
  190. data/src/core/lib/iomgr/resolve_address_windows.cc +93 -74
  191. data/src/core/lib/iomgr/resolve_address_windows.h +47 -0
  192. data/src/core/lib/iomgr/resolved_address.h +39 -0
  193. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -0
  194. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +1 -0
  195. data/src/core/lib/iomgr/unix_sockets_posix.cc +22 -34
  196. data/src/core/lib/iomgr/unix_sockets_posix.h +4 -7
  197. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +6 -15
  198. data/src/core/lib/matchers/matchers.cc +1 -1
  199. data/src/core/lib/promise/activity.h +49 -20
  200. data/src/core/lib/promise/detail/status.h +5 -0
  201. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.cc +17 -25
  202. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.h +43 -44
  203. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_factory.h +10 -5
  204. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.cc +3 -2
  205. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.h +4 -5
  206. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.cc +1 -1
  207. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.h +4 -4
  208. data/src/core/lib/resource_quota/api.h +0 -1
  209. data/src/core/lib/{gprpp → resource_quota}/arena.cc +16 -13
  210. data/src/core/lib/{gprpp → resource_quota}/arena.h +24 -13
  211. data/src/core/lib/security/authorization/evaluate_args.cc +30 -15
  212. data/src/core/lib/security/authorization/evaluate_args.h +1 -0
  213. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +60 -0
  214. data/src/core/lib/security/authorization/grpc_authorization_engine.h +62 -0
  215. data/src/core/lib/security/authorization/matchers.cc +227 -0
  216. data/src/core/lib/security/authorization/matchers.h +211 -0
  217. data/src/core/lib/security/authorization/rbac_policy.cc +442 -0
  218. data/src/core/lib/security/authorization/rbac_policy.h +170 -0
  219. data/src/core/lib/security/context/security_context.cc +4 -2
  220. data/src/core/lib/security/context/security_context.h +1 -1
  221. data/src/core/lib/security/credentials/composite/composite_credentials.cc +5 -5
  222. data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -3
  223. data/src/core/lib/security/credentials/credentials.h +10 -20
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +6 -9
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +7 -9
  226. data/src/core/lib/security/credentials/external/external_account_credentials.h +2 -7
  227. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +2 -3
  228. data/src/core/lib/security/credentials/fake/fake_credentials.cc +5 -4
  229. data/src/core/lib/security/credentials/fake/fake_credentials.h +8 -7
  230. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +2 -5
  231. data/src/core/lib/security/credentials/iam/iam_credentials.cc +16 -19
  232. data/src/core/lib/security/credentials/iam/iam_credentials.h +6 -5
  233. data/src/core/lib/security/credentials/jwt/json_token.cc +4 -6
  234. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +16 -28
  235. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +8 -8
  236. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +6 -13
  237. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +44 -57
  238. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +13 -15
  239. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -7
  240. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +5 -4
  241. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +1 -10
  242. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +6 -0
  243. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +7 -0
  244. data/src/core/lib/security/credentials/xds/xds_credentials.h +1 -1
  245. data/src/core/lib/security/security_connector/security_connector.cc +0 -4
  246. data/src/core/lib/security/security_connector/security_connector.h +5 -1
  247. data/src/core/lib/security/security_connector/ssl_utils.cc +14 -24
  248. data/src/core/lib/security/security_connector/ssl_utils.h +5 -14
  249. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +2 -3
  250. data/src/core/lib/security/transport/auth_filters.h +7 -0
  251. data/src/core/lib/security/transport/client_auth_filter.cc +53 -33
  252. data/src/core/lib/security/transport/server_auth_filter.cc +40 -35
  253. data/src/core/{ext → lib}/service_config/service_config.cc +2 -2
  254. data/src/core/{ext → lib}/service_config/service_config.h +4 -4
  255. data/src/core/{ext → lib}/service_config/service_config_call_data.h +5 -5
  256. data/src/core/{ext → lib}/service_config/service_config_parser.cc +1 -1
  257. data/src/core/{ext → lib}/service_config/service_config_parser.h +3 -3
  258. data/src/core/lib/slice/slice.cc +3 -1
  259. data/src/core/lib/slice/slice.h +43 -13
  260. data/src/core/lib/slice/slice_intern.cc +3 -101
  261. data/src/core/lib/slice/slice_internal.h +1 -2
  262. data/src/core/lib/slice/slice_refcount.h +4 -13
  263. data/src/core/lib/slice/slice_refcount_base.h +0 -16
  264. data/src/core/lib/surface/call.cc +140 -382
  265. data/src/core/lib/surface/call.h +4 -4
  266. data/src/core/lib/surface/channel.cc +42 -44
  267. data/src/core/lib/surface/channel.h +4 -4
  268. data/src/core/lib/surface/init.cc +0 -2
  269. data/src/core/lib/surface/lame_client.cc +0 -1
  270. data/src/core/lib/surface/server.cc +12 -29
  271. data/src/core/lib/surface/server.h +2 -2
  272. data/src/core/lib/surface/version.cc +2 -2
  273. data/src/core/lib/transport/error_utils.h +14 -0
  274. data/src/core/lib/transport/metadata_batch.h +799 -717
  275. data/src/core/lib/transport/parsed_metadata.cc +2 -0
  276. data/src/core/lib/transport/parsed_metadata.h +95 -92
  277. data/src/core/lib/transport/timeout_encoding.cc +200 -66
  278. data/src/core/lib/transport/timeout_encoding.h +40 -10
  279. data/src/core/lib/transport/transport.h +1 -1
  280. data/src/core/lib/transport/transport_op_string.cc +6 -39
  281. data/src/core/lib/uri/uri_parser.cc +223 -53
  282. data/src/core/lib/uri/uri_parser.h +36 -23
  283. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -3
  284. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  285. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -4
  286. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +3 -5
  287. data/src/core/tsi/ssl_transport_security.cc +53 -13
  288. data/src/core/tsi/ssl_transport_security.h +18 -6
  289. data/src/ruby/ext/grpc/extconf.rb +10 -3
  290. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  291. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  292. data/src/ruby/lib/grpc/version.rb +1 -1
  293. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -1
  294. data/third_party/abseil-cpp/absl/base/internal/fast_type_id.h +48 -0
  295. data/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +200 -0
  296. data/third_party/abseil-cpp/absl/random/beta_distribution.h +427 -0
  297. data/third_party/abseil-cpp/absl/random/discrete_distribution.cc +98 -0
  298. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +247 -0
  299. data/third_party/abseil-cpp/absl/random/distributions.h +452 -0
  300. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +165 -0
  301. data/third_party/abseil-cpp/absl/random/gaussian_distribution.cc +104 -0
  302. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +275 -0
  303. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +92 -0
  304. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +268 -0
  305. data/third_party/abseil-cpp/absl/random/internal/fastmath.h +57 -0
  306. data/third_party/abseil-cpp/absl/random/internal/generate_real.h +144 -0
  307. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +245 -0
  308. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +150 -0
  309. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +308 -0
  310. data/third_party/abseil-cpp/absl/random/internal/platform.h +171 -0
  311. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc +253 -0
  312. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +131 -0
  313. data/third_party/abseil-cpp/absl/random/internal/randen.cc +91 -0
  314. data/third_party/abseil-cpp/absl/random/internal/randen.h +102 -0
  315. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +221 -0
  316. data/third_party/abseil-cpp/absl/random/internal/randen_detect.h +33 -0
  317. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +239 -0
  318. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc +526 -0
  319. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h +50 -0
  320. data/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc +462 -0
  321. data/third_party/abseil-cpp/absl/random/internal/randen_slow.cc +471 -0
  322. data/third_party/abseil-cpp/absl/random/internal/randen_slow.h +40 -0
  323. data/third_party/abseil-cpp/absl/random/internal/randen_traits.h +88 -0
  324. data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +167 -0
  325. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +267 -0
  326. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +104 -0
  327. data/third_party/abseil-cpp/absl/random/internal/traits.h +101 -0
  328. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +244 -0
  329. data/third_party/abseil-cpp/absl/random/internal/wide_multiply.h +111 -0
  330. data/third_party/abseil-cpp/absl/random/log_uniform_int_distribution.h +257 -0
  331. data/third_party/abseil-cpp/absl/random/poisson_distribution.h +258 -0
  332. data/third_party/abseil-cpp/absl/random/random.h +189 -0
  333. data/third_party/abseil-cpp/absl/random/seed_gen_exception.cc +46 -0
  334. data/third_party/abseil-cpp/absl/random/seed_gen_exception.h +55 -0
  335. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +29 -0
  336. data/third_party/abseil-cpp/absl/random/seed_sequences.h +110 -0
  337. data/third_party/abseil-cpp/absl/random/uniform_int_distribution.h +275 -0
  338. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +202 -0
  339. data/third_party/abseil-cpp/absl/random/zipf_distribution.h +271 -0
  340. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c +1 -0
  341. data/third_party/boringssl-with-bazel/src/crypto/base64/base64.c +13 -0
  342. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +21 -0
  343. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c +12 -0
  344. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +1 -2
  345. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +2 -2
  346. data/third_party/boringssl-with-bazel/src/crypto/mem.c +1 -1
  347. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7.c +29 -0
  348. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +0 -1
  349. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8.c +1 -1
  350. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +1 -1
  351. data/third_party/boringssl-with-bazel/src/include/openssl/base64.h +8 -0
  352. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +13 -1
  353. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +10 -0
  354. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +1 -1
  355. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +9 -4
  356. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs8.h +6 -1
  357. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +23 -2
  358. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +4 -0
  359. data/third_party/xxhash/xxhash.h +607 -352
  360. metadata +149 -77
  361. data/src/core/ext/transport/chttp2/transport/hpack_encoder_index.h +0 -107
  362. data/src/core/ext/transport/chttp2/transport/hpack_utils.cc +0 -46
  363. data/src/core/ext/transport/chttp2/transport/popularity_count.h +0 -60
  364. data/src/core/lib/compression/algorithm_metadata.h +0 -62
  365. data/src/core/lib/compression/compression_args.cc +0 -140
  366. data/src/core/lib/compression/compression_args.h +0 -58
  367. data/src/core/lib/compression/stream_compression.cc +0 -81
  368. data/src/core/lib/compression/stream_compression.h +0 -117
  369. data/src/core/lib/compression/stream_compression_gzip.cc +0 -231
  370. data/src/core/lib/compression/stream_compression_gzip.h +0 -28
  371. data/src/core/lib/compression/stream_compression_identity.cc +0 -91
  372. data/src/core/lib/compression/stream_compression_identity.h +0 -29
  373. data/src/core/lib/security/credentials/credentials_metadata.cc +0 -61
  374. data/src/core/lib/slice/static_slice.cc +0 -377
  375. data/src/core/lib/slice/static_slice.h +0 -300
  376. data/src/core/lib/transport/metadata.cc +0 -714
  377. data/src/core/lib/transport/metadata.h +0 -449
  378. data/src/core/lib/transport/metadata_batch.cc +0 -99
  379. data/src/core/lib/transport/static_metadata.cc +0 -1032
  380. data/src/core/lib/transport/static_metadata.h +0 -322
  381. data/src/core/lib/transport/status_metadata.cc +0 -63
  382. data/src/core/lib/transport/status_metadata.h +0 -48
@@ -0,0 +1,993 @@
1
+ //
2
+ // Copyright 2018 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
+ #include <grpc/support/port_platform.h>
18
+
19
+ #include "absl/memory/memory.h"
20
+ #include "absl/strings/str_cat.h"
21
+ #include "absl/strings/str_format.h"
22
+ #include "absl/strings/str_join.h"
23
+ #include "absl/strings/str_split.h"
24
+ #include "absl/strings/string_view.h"
25
+ #include "envoy/config/core/v3/base.upb.h"
26
+ #include "envoy/config/route/v3/route.upb.h"
27
+ #include "envoy/config/route/v3/route.upbdefs.h"
28
+ #include "envoy/config/route/v3/route_components.upb.h"
29
+ #include "envoy/config/route/v3/route_components.upbdefs.h"
30
+ #include "envoy/type/matcher/v3/regex.upb.h"
31
+ #include "envoy/type/matcher/v3/string.upb.h"
32
+ #include "envoy/type/v3/percent.upb.h"
33
+ #include "envoy/type/v3/range.upb.h"
34
+ #include "google/protobuf/any.upb.h"
35
+ #include "google/protobuf/wrappers.upb.h"
36
+ #include "upb/text_encode.h"
37
+ #include "upb/upb.h"
38
+ #include "upb/upb.hpp"
39
+
40
+ #include "src/core/ext/xds/upb_utils.h"
41
+ #include "src/core/ext/xds/xds_api.h"
42
+ #include "src/core/ext/xds/xds_common_types.h"
43
+ #include "src/core/ext/xds/xds_resource_type.h"
44
+ #include "src/core/ext/xds/xds_routing.h"
45
+ #include "src/core/lib/gpr/env.h"
46
+ #include "src/core/lib/gpr/string.h"
47
+ #include "src/core/lib/iomgr/error.h"
48
+
49
+ namespace grpc_core {
50
+
51
+ // TODO(yashykt): Remove once RBAC is no longer experimental
52
+ bool XdsRbacEnabled() {
53
+ char* value = gpr_getenv("GRPC_XDS_EXPERIMENTAL_RBAC");
54
+ bool parsed_value;
55
+ bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value);
56
+ gpr_free(value);
57
+ return parse_succeeded && parsed_value;
58
+ }
59
+
60
+ //
61
+ // XdsRouteConfigResource::RetryPolicy
62
+ //
63
+
64
+ std::string XdsRouteConfigResource::RetryPolicy::RetryBackOff::ToString()
65
+ const {
66
+ std::vector<std::string> contents;
67
+ contents.push_back(
68
+ absl::StrCat("RetryBackOff Base: ", base_interval.ToString()));
69
+ contents.push_back(
70
+ absl::StrCat("RetryBackOff max: ", max_interval.ToString()));
71
+ return absl::StrJoin(contents, ",");
72
+ }
73
+
74
+ std::string XdsRouteConfigResource::RetryPolicy::ToString() const {
75
+ std::vector<std::string> contents;
76
+ contents.push_back(absl::StrFormat("num_retries=%d", num_retries));
77
+ contents.push_back(retry_back_off.ToString());
78
+ return absl::StrCat("{", absl::StrJoin(contents, ","), "}");
79
+ }
80
+
81
+ //
82
+ // XdsRouteConfigResource::Route::Matchers
83
+ //
84
+
85
+ std::string XdsRouteConfigResource::Route::Matchers::ToString() const {
86
+ std::vector<std::string> contents;
87
+ contents.push_back(
88
+ absl::StrFormat("PathMatcher{%s}", path_matcher.ToString()));
89
+ for (const HeaderMatcher& header_matcher : header_matchers) {
90
+ contents.push_back(header_matcher.ToString());
91
+ }
92
+ if (fraction_per_million.has_value()) {
93
+ contents.push_back(absl::StrFormat("Fraction Per Million %d",
94
+ fraction_per_million.value()));
95
+ }
96
+ return absl::StrJoin(contents, "\n");
97
+ }
98
+
99
+ //
100
+ // XdsRouteConfigResource::Route::RouteAction::HashPolicy
101
+ //
102
+
103
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy::HashPolicy(
104
+ const HashPolicy& other)
105
+ : type(other.type),
106
+ header_name(other.header_name),
107
+ regex_substitution(other.regex_substitution) {
108
+ if (other.regex != nullptr) {
109
+ regex =
110
+ absl::make_unique<RE2>(other.regex->pattern(), other.regex->options());
111
+ }
112
+ }
113
+
114
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy&
115
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy::operator=(
116
+ const HashPolicy& other) {
117
+ type = other.type;
118
+ header_name = other.header_name;
119
+ if (other.regex != nullptr) {
120
+ regex =
121
+ absl::make_unique<RE2>(other.regex->pattern(), other.regex->options());
122
+ }
123
+ regex_substitution = other.regex_substitution;
124
+ return *this;
125
+ }
126
+
127
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy::HashPolicy(
128
+ HashPolicy&& other) noexcept
129
+ : type(other.type),
130
+ header_name(std::move(other.header_name)),
131
+ regex(std::move(other.regex)),
132
+ regex_substitution(std::move(other.regex_substitution)) {}
133
+
134
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy&
135
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy::operator=(
136
+ HashPolicy&& other) noexcept {
137
+ type = other.type;
138
+ header_name = std::move(other.header_name);
139
+ regex = std::move(other.regex);
140
+ regex_substitution = std::move(other.regex_substitution);
141
+ return *this;
142
+ }
143
+
144
+ bool XdsRouteConfigResource::Route::RouteAction::HashPolicy::HashPolicy::
145
+ operator==(const HashPolicy& other) const {
146
+ if (type != other.type) return false;
147
+ if (type == Type::HEADER) {
148
+ if (regex == nullptr) {
149
+ if (other.regex != nullptr) return false;
150
+ } else {
151
+ if (other.regex == nullptr) return false;
152
+ return header_name == other.header_name &&
153
+ regex->pattern() == other.regex->pattern() &&
154
+ regex_substitution == other.regex_substitution;
155
+ }
156
+ }
157
+ return true;
158
+ }
159
+
160
+ std::string XdsRouteConfigResource::Route::RouteAction::HashPolicy::ToString()
161
+ const {
162
+ std::vector<std::string> contents;
163
+ switch (type) {
164
+ case Type::HEADER:
165
+ contents.push_back("type=HEADER");
166
+ break;
167
+ case Type::CHANNEL_ID:
168
+ contents.push_back("type=CHANNEL_ID");
169
+ break;
170
+ }
171
+ contents.push_back(
172
+ absl::StrFormat("terminal=%s", terminal ? "true" : "false"));
173
+ if (type == Type::HEADER) {
174
+ contents.push_back(absl::StrFormat(
175
+ "Header %s:/%s/%s", header_name,
176
+ (regex == nullptr) ? "" : regex->pattern(), regex_substitution));
177
+ }
178
+ return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
179
+ }
180
+
181
+ //
182
+ // XdsRouteConfigResource::Route::RouteAction::ClusterWeight
183
+ //
184
+
185
+ std::string
186
+ XdsRouteConfigResource::Route::RouteAction::ClusterWeight::ToString() const {
187
+ std::vector<std::string> contents;
188
+ contents.push_back(absl::StrCat("cluster=", name));
189
+ contents.push_back(absl::StrCat("weight=", weight));
190
+ if (!typed_per_filter_config.empty()) {
191
+ std::vector<std::string> parts;
192
+ for (const auto& p : typed_per_filter_config) {
193
+ const std::string& key = p.first;
194
+ const auto& config = p.second;
195
+ parts.push_back(absl::StrCat(key, "=", config.ToString()));
196
+ }
197
+ contents.push_back(absl::StrCat("typed_per_filter_config={",
198
+ absl::StrJoin(parts, ", "), "}"));
199
+ }
200
+ return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
201
+ }
202
+
203
+ //
204
+ // XdsRouteConfigResource::Route::RouteAction
205
+ //
206
+
207
+ std::string XdsRouteConfigResource::Route::RouteAction::ToString() const {
208
+ std::vector<std::string> contents;
209
+ for (const HashPolicy& hash_policy : hash_policies) {
210
+ contents.push_back(absl::StrCat("hash_policy=", hash_policy.ToString()));
211
+ }
212
+ if (retry_policy.has_value()) {
213
+ contents.push_back(absl::StrCat("retry_policy=", retry_policy->ToString()));
214
+ }
215
+ if (!cluster_name.empty()) {
216
+ contents.push_back(absl::StrFormat("Cluster name: %s", cluster_name));
217
+ }
218
+ for (const ClusterWeight& cluster_weight : weighted_clusters) {
219
+ contents.push_back(cluster_weight.ToString());
220
+ }
221
+ if (max_stream_duration.has_value()) {
222
+ contents.push_back(max_stream_duration->ToString());
223
+ }
224
+ return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
225
+ }
226
+
227
+ //
228
+ // XdsRouteConfigResource::Route
229
+ //
230
+
231
+ std::string XdsRouteConfigResource::Route::ToString() const {
232
+ std::vector<std::string> contents;
233
+ contents.push_back(matchers.ToString());
234
+ auto* route_action =
235
+ absl::get_if<XdsRouteConfigResource::Route::RouteAction>(&action);
236
+ if (route_action != nullptr) {
237
+ contents.push_back(absl::StrCat("route=", route_action->ToString()));
238
+ } else if (absl::holds_alternative<
239
+ XdsRouteConfigResource::Route::NonForwardingAction>(action)) {
240
+ contents.push_back("non_forwarding_action={}");
241
+ } else {
242
+ contents.push_back("unknown_action={}");
243
+ }
244
+ if (!typed_per_filter_config.empty()) {
245
+ contents.push_back("typed_per_filter_config={");
246
+ for (const auto& p : typed_per_filter_config) {
247
+ const std::string& name = p.first;
248
+ const auto& config = p.second;
249
+ contents.push_back(absl::StrCat(" ", name, "=", config.ToString()));
250
+ }
251
+ contents.push_back("}");
252
+ }
253
+ return absl::StrJoin(contents, "\n");
254
+ }
255
+
256
+ //
257
+ // XdsRouteConfigResource
258
+ //
259
+
260
+ std::string XdsRouteConfigResource::ToString() const {
261
+ std::vector<std::string> vhosts;
262
+ for (const VirtualHost& vhost : virtual_hosts) {
263
+ vhosts.push_back(
264
+ absl::StrCat("vhost={\n"
265
+ " domains=[",
266
+ absl::StrJoin(vhost.domains, ", "),
267
+ "]\n"
268
+ " routes=[\n"));
269
+ for (const XdsRouteConfigResource::Route& route : vhost.routes) {
270
+ vhosts.push_back(" {\n");
271
+ vhosts.push_back(route.ToString());
272
+ vhosts.push_back("\n }\n");
273
+ }
274
+ vhosts.push_back(" ]\n");
275
+ vhosts.push_back(" typed_per_filter_config={\n");
276
+ for (const auto& p : vhost.typed_per_filter_config) {
277
+ const std::string& name = p.first;
278
+ const auto& config = p.second;
279
+ vhosts.push_back(
280
+ absl::StrCat(" ", name, "=", config.ToString(), "\n"));
281
+ }
282
+ vhosts.push_back(" }\n");
283
+ vhosts.push_back("]\n");
284
+ }
285
+ return absl::StrJoin(vhosts, "");
286
+ }
287
+
288
+ namespace {
289
+
290
+ grpc_error_handle RoutePathMatchParse(
291
+ const envoy_config_route_v3_RouteMatch* match,
292
+ XdsRouteConfigResource::Route* route, bool* ignore_route) {
293
+ auto* case_sensitive_ptr =
294
+ envoy_config_route_v3_RouteMatch_case_sensitive(match);
295
+ bool case_sensitive = true;
296
+ if (case_sensitive_ptr != nullptr) {
297
+ case_sensitive = google_protobuf_BoolValue_value(case_sensitive_ptr);
298
+ }
299
+ StringMatcher::Type type;
300
+ std::string match_string;
301
+ if (envoy_config_route_v3_RouteMatch_has_prefix(match)) {
302
+ absl::string_view prefix =
303
+ UpbStringToAbsl(envoy_config_route_v3_RouteMatch_prefix(match));
304
+ // Empty prefix "" is accepted.
305
+ if (!prefix.empty()) {
306
+ // Prefix "/" is accepted.
307
+ if (prefix[0] != '/') {
308
+ // Prefix which does not start with a / will never match anything, so
309
+ // ignore this route.
310
+ *ignore_route = true;
311
+ return GRPC_ERROR_NONE;
312
+ }
313
+ std::vector<absl::string_view> prefix_elements =
314
+ absl::StrSplit(prefix.substr(1), absl::MaxSplits('/', 2));
315
+ if (prefix_elements.size() > 2) {
316
+ // Prefix cannot have more than 2 slashes.
317
+ *ignore_route = true;
318
+ return GRPC_ERROR_NONE;
319
+ } else if (prefix_elements.size() == 2 && prefix_elements[0].empty()) {
320
+ // Prefix contains empty string between the 2 slashes
321
+ *ignore_route = true;
322
+ return GRPC_ERROR_NONE;
323
+ }
324
+ }
325
+ type = StringMatcher::Type::kPrefix;
326
+ match_string = std::string(prefix);
327
+ } else if (envoy_config_route_v3_RouteMatch_has_path(match)) {
328
+ absl::string_view path =
329
+ UpbStringToAbsl(envoy_config_route_v3_RouteMatch_path(match));
330
+ if (path.empty()) {
331
+ // Path that is empty will never match anything, so ignore this route.
332
+ *ignore_route = true;
333
+ return GRPC_ERROR_NONE;
334
+ }
335
+ if (path[0] != '/') {
336
+ // Path which does not start with a / will never match anything, so
337
+ // ignore this route.
338
+ *ignore_route = true;
339
+ return GRPC_ERROR_NONE;
340
+ }
341
+ std::vector<absl::string_view> path_elements =
342
+ absl::StrSplit(path.substr(1), absl::MaxSplits('/', 2));
343
+ if (path_elements.size() != 2) {
344
+ // Path not in the required format of /service/method will never match
345
+ // anything, so ignore this route.
346
+ *ignore_route = true;
347
+ return GRPC_ERROR_NONE;
348
+ } else if (path_elements[0].empty()) {
349
+ // Path contains empty service name will never match anything, so ignore
350
+ // this route.
351
+ *ignore_route = true;
352
+ return GRPC_ERROR_NONE;
353
+ } else if (path_elements[1].empty()) {
354
+ // Path contains empty method name will never match anything, so ignore
355
+ // this route.
356
+ *ignore_route = true;
357
+ return GRPC_ERROR_NONE;
358
+ }
359
+ type = StringMatcher::Type::kExact;
360
+ match_string = std::string(path);
361
+ } else if (envoy_config_route_v3_RouteMatch_has_safe_regex(match)) {
362
+ const envoy_type_matcher_v3_RegexMatcher* regex_matcher =
363
+ envoy_config_route_v3_RouteMatch_safe_regex(match);
364
+ GPR_ASSERT(regex_matcher != nullptr);
365
+ type = StringMatcher::Type::kSafeRegex;
366
+ match_string = UpbStringToStdString(
367
+ envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
368
+ } else {
369
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
370
+ "Invalid route path specifier specified.");
371
+ }
372
+ absl::StatusOr<StringMatcher> string_matcher =
373
+ StringMatcher::Create(type, match_string, case_sensitive);
374
+ if (!string_matcher.ok()) {
375
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
376
+ absl::StrCat("path matcher: ", string_matcher.status().message()));
377
+ }
378
+ route->matchers.path_matcher = std::move(string_matcher.value());
379
+ return GRPC_ERROR_NONE;
380
+ }
381
+
382
+ grpc_error_handle RouteHeaderMatchersParse(
383
+ const envoy_config_route_v3_RouteMatch* match,
384
+ XdsRouteConfigResource::Route* route) {
385
+ size_t size;
386
+ const envoy_config_route_v3_HeaderMatcher* const* headers =
387
+ envoy_config_route_v3_RouteMatch_headers(match, &size);
388
+ for (size_t i = 0; i < size; ++i) {
389
+ const envoy_config_route_v3_HeaderMatcher* header = headers[i];
390
+ const std::string name =
391
+ UpbStringToStdString(envoy_config_route_v3_HeaderMatcher_name(header));
392
+ HeaderMatcher::Type type;
393
+ std::string match_string;
394
+ int64_t range_start = 0;
395
+ int64_t range_end = 0;
396
+ bool present_match = false;
397
+ if (envoy_config_route_v3_HeaderMatcher_has_exact_match(header)) {
398
+ type = HeaderMatcher::Type::kExact;
399
+ match_string = UpbStringToStdString(
400
+ envoy_config_route_v3_HeaderMatcher_exact_match(header));
401
+ } else if (envoy_config_route_v3_HeaderMatcher_has_safe_regex_match(
402
+ header)) {
403
+ const envoy_type_matcher_v3_RegexMatcher* regex_matcher =
404
+ envoy_config_route_v3_HeaderMatcher_safe_regex_match(header);
405
+ GPR_ASSERT(regex_matcher != nullptr);
406
+ type = HeaderMatcher::Type::kSafeRegex;
407
+ match_string = UpbStringToStdString(
408
+ envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
409
+ } else if (envoy_config_route_v3_HeaderMatcher_has_range_match(header)) {
410
+ type = HeaderMatcher::Type::kRange;
411
+ const envoy_type_v3_Int64Range* range_matcher =
412
+ envoy_config_route_v3_HeaderMatcher_range_match(header);
413
+ range_start = envoy_type_v3_Int64Range_start(range_matcher);
414
+ range_end = envoy_type_v3_Int64Range_end(range_matcher);
415
+ } else if (envoy_config_route_v3_HeaderMatcher_has_present_match(header)) {
416
+ type = HeaderMatcher::Type::kPresent;
417
+ present_match = envoy_config_route_v3_HeaderMatcher_present_match(header);
418
+ } else if (envoy_config_route_v3_HeaderMatcher_has_prefix_match(header)) {
419
+ type = HeaderMatcher::Type::kPrefix;
420
+ match_string = UpbStringToStdString(
421
+ envoy_config_route_v3_HeaderMatcher_prefix_match(header));
422
+ } else if (envoy_config_route_v3_HeaderMatcher_has_suffix_match(header)) {
423
+ type = HeaderMatcher::Type::kSuffix;
424
+ match_string = UpbStringToStdString(
425
+ envoy_config_route_v3_HeaderMatcher_suffix_match(header));
426
+ } else if (envoy_config_route_v3_HeaderMatcher_has_contains_match(header)) {
427
+ type = HeaderMatcher::Type::kContains;
428
+ match_string = UpbStringToStdString(
429
+ envoy_config_route_v3_HeaderMatcher_contains_match(header));
430
+ } else {
431
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
432
+ "Invalid route header matcher specified.");
433
+ }
434
+ bool invert_match =
435
+ envoy_config_route_v3_HeaderMatcher_invert_match(header);
436
+ absl::StatusOr<HeaderMatcher> header_matcher =
437
+ HeaderMatcher::Create(name, type, match_string, range_start, range_end,
438
+ present_match, invert_match);
439
+ if (!header_matcher.ok()) {
440
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
441
+ absl::StrCat("header matcher: ", header_matcher.status().message()));
442
+ }
443
+ route->matchers.header_matchers.emplace_back(
444
+ std::move(header_matcher.value()));
445
+ }
446
+ return GRPC_ERROR_NONE;
447
+ }
448
+
449
+ grpc_error_handle RouteRuntimeFractionParse(
450
+ const envoy_config_route_v3_RouteMatch* match,
451
+ XdsRouteConfigResource::Route* route) {
452
+ const envoy_config_core_v3_RuntimeFractionalPercent* runtime_fraction =
453
+ envoy_config_route_v3_RouteMatch_runtime_fraction(match);
454
+ if (runtime_fraction != nullptr) {
455
+ const envoy_type_v3_FractionalPercent* fraction =
456
+ envoy_config_core_v3_RuntimeFractionalPercent_default_value(
457
+ runtime_fraction);
458
+ if (fraction != nullptr) {
459
+ uint32_t numerator = envoy_type_v3_FractionalPercent_numerator(fraction);
460
+ const auto denominator =
461
+ static_cast<envoy_type_v3_FractionalPercent_DenominatorType>(
462
+ envoy_type_v3_FractionalPercent_denominator(fraction));
463
+ // Normalize to million.
464
+ switch (denominator) {
465
+ case envoy_type_v3_FractionalPercent_HUNDRED:
466
+ numerator *= 10000;
467
+ break;
468
+ case envoy_type_v3_FractionalPercent_TEN_THOUSAND:
469
+ numerator *= 100;
470
+ break;
471
+ case envoy_type_v3_FractionalPercent_MILLION:
472
+ break;
473
+ default:
474
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
475
+ "Unknown denominator type");
476
+ }
477
+ route->matchers.fraction_per_million = numerator;
478
+ }
479
+ }
480
+ return GRPC_ERROR_NONE;
481
+ }
482
+
483
+ template <typename ParentType, typename EntryType>
484
+ grpc_error_handle ParseTypedPerFilterConfig(
485
+ const XdsEncodingContext& context, const ParentType* parent,
486
+ const EntryType* (*entry_func)(const ParentType*, size_t*),
487
+ upb_strview (*key_func)(const EntryType*),
488
+ const google_protobuf_Any* (*value_func)(const EntryType*),
489
+ XdsRouteConfigResource::TypedPerFilterConfig* typed_per_filter_config) {
490
+ size_t filter_it = UPB_MAP_BEGIN;
491
+ while (true) {
492
+ const auto* filter_entry = entry_func(parent, &filter_it);
493
+ if (filter_entry == nullptr) break;
494
+ absl::string_view key = UpbStringToAbsl(key_func(filter_entry));
495
+ if (key.empty()) {
496
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("empty filter name in map");
497
+ }
498
+ const google_protobuf_Any* any = value_func(filter_entry);
499
+ GPR_ASSERT(any != nullptr);
500
+ absl::string_view filter_type =
501
+ UpbStringToAbsl(google_protobuf_Any_type_url(any));
502
+ if (filter_type.empty()) {
503
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
504
+ absl::StrCat("no filter config specified for filter name ", key));
505
+ }
506
+ bool is_optional = false;
507
+ if (filter_type ==
508
+ "type.googleapis.com/envoy.config.route.v3.FilterConfig") {
509
+ upb_strview any_value = google_protobuf_Any_value(any);
510
+ const auto* filter_config = envoy_config_route_v3_FilterConfig_parse(
511
+ any_value.data, any_value.size, context.arena);
512
+ if (filter_config == nullptr) {
513
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
514
+ absl::StrCat("could not parse FilterConfig wrapper for ", key));
515
+ }
516
+ is_optional =
517
+ envoy_config_route_v3_FilterConfig_is_optional(filter_config);
518
+ any = envoy_config_route_v3_FilterConfig_config(filter_config);
519
+ if (any == nullptr) {
520
+ if (is_optional) continue;
521
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
522
+ absl::StrCat("no filter config specified for filter name ", key));
523
+ }
524
+ }
525
+ grpc_error_handle error =
526
+ ExtractHttpFilterTypeName(context, any, &filter_type);
527
+ if (error != GRPC_ERROR_NONE) return error;
528
+ const XdsHttpFilterImpl* filter_impl =
529
+ XdsHttpFilterRegistry::GetFilterForType(filter_type);
530
+ if (filter_impl == nullptr) {
531
+ if (is_optional) continue;
532
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
533
+ absl::StrCat("no filter registered for config type ", filter_type));
534
+ }
535
+ absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config =
536
+ filter_impl->GenerateFilterConfigOverride(
537
+ google_protobuf_Any_value(any), context.arena);
538
+ if (!filter_config.ok()) {
539
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
540
+ "filter config for type ", filter_type,
541
+ " failed to parse: ", StatusToString(filter_config.status())));
542
+ }
543
+ (*typed_per_filter_config)[std::string(key)] = std::move(*filter_config);
544
+ }
545
+ return GRPC_ERROR_NONE;
546
+ }
547
+
548
+ grpc_error_handle RetryPolicyParse(
549
+ const XdsEncodingContext& context,
550
+ const envoy_config_route_v3_RetryPolicy* retry_policy,
551
+ absl::optional<XdsRouteConfigResource::RetryPolicy>* retry) {
552
+ std::vector<grpc_error_handle> errors;
553
+ XdsRouteConfigResource::RetryPolicy retry_to_return;
554
+ auto retry_on = UpbStringToStdString(
555
+ envoy_config_route_v3_RetryPolicy_retry_on(retry_policy));
556
+ std::vector<absl::string_view> codes = absl::StrSplit(retry_on, ',');
557
+ for (const auto& code : codes) {
558
+ if (code == "cancelled") {
559
+ retry_to_return.retry_on.Add(GRPC_STATUS_CANCELLED);
560
+ } else if (code == "deadline-exceeded") {
561
+ retry_to_return.retry_on.Add(GRPC_STATUS_DEADLINE_EXCEEDED);
562
+ } else if (code == "internal") {
563
+ retry_to_return.retry_on.Add(GRPC_STATUS_INTERNAL);
564
+ } else if (code == "resource-exhausted") {
565
+ retry_to_return.retry_on.Add(GRPC_STATUS_RESOURCE_EXHAUSTED);
566
+ } else if (code == "unavailable") {
567
+ retry_to_return.retry_on.Add(GRPC_STATUS_UNAVAILABLE);
568
+ } else {
569
+ if (GRPC_TRACE_FLAG_ENABLED(*context.tracer)) {
570
+ gpr_log(GPR_INFO, "Unsupported retry_on policy %s.",
571
+ std::string(code).c_str());
572
+ }
573
+ }
574
+ }
575
+ const google_protobuf_UInt32Value* num_retries =
576
+ envoy_config_route_v3_RetryPolicy_num_retries(retry_policy);
577
+ if (num_retries != nullptr) {
578
+ uint32_t num_retries_value = google_protobuf_UInt32Value_value(num_retries);
579
+ if (num_retries_value == 0) {
580
+ errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
581
+ "RouteAction RetryPolicy num_retries set to invalid value 0."));
582
+ } else {
583
+ retry_to_return.num_retries = num_retries_value;
584
+ }
585
+ } else {
586
+ retry_to_return.num_retries = 1;
587
+ }
588
+ const envoy_config_route_v3_RetryPolicy_RetryBackOff* backoff =
589
+ envoy_config_route_v3_RetryPolicy_retry_back_off(retry_policy);
590
+ if (backoff != nullptr) {
591
+ const google_protobuf_Duration* base_interval =
592
+ envoy_config_route_v3_RetryPolicy_RetryBackOff_base_interval(backoff);
593
+ if (base_interval == nullptr) {
594
+ errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
595
+ "RouteAction RetryPolicy RetryBackoff missing base interval."));
596
+ } else {
597
+ retry_to_return.retry_back_off.base_interval =
598
+ Duration::Parse(base_interval);
599
+ }
600
+ const google_protobuf_Duration* max_interval =
601
+ envoy_config_route_v3_RetryPolicy_RetryBackOff_max_interval(backoff);
602
+ Duration max;
603
+ if (max_interval != nullptr) {
604
+ max = Duration::Parse(max_interval);
605
+ } else {
606
+ // if max interval is not set, it is 10x the base, if the value in nanos
607
+ // can yield another second, adjust the value in seconds accordingly.
608
+ max.seconds = retry_to_return.retry_back_off.base_interval.seconds * 10;
609
+ max.nanos = retry_to_return.retry_back_off.base_interval.nanos * 10;
610
+ if (max.nanos > 1000000000) {
611
+ max.seconds += max.nanos / 1000000000;
612
+ max.nanos = max.nanos % 1000000000;
613
+ }
614
+ }
615
+ retry_to_return.retry_back_off.max_interval = max;
616
+ } else {
617
+ retry_to_return.retry_back_off.base_interval.seconds = 0;
618
+ retry_to_return.retry_back_off.base_interval.nanos = 25000000;
619
+ retry_to_return.retry_back_off.max_interval.seconds = 0;
620
+ retry_to_return.retry_back_off.max_interval.nanos = 250000000;
621
+ }
622
+ if (errors.empty()) {
623
+ *retry = retry_to_return;
624
+ return GRPC_ERROR_NONE;
625
+ } else {
626
+ return GRPC_ERROR_CREATE_FROM_VECTOR("errors parsing retry policy",
627
+ &errors);
628
+ }
629
+ }
630
+
631
+ grpc_error_handle RouteActionParse(
632
+ const XdsEncodingContext& context,
633
+ const envoy_config_route_v3_Route* route_msg,
634
+ XdsRouteConfigResource::Route::RouteAction* route, bool* ignore_route) {
635
+ const envoy_config_route_v3_RouteAction* route_action =
636
+ envoy_config_route_v3_Route_route(route_msg);
637
+ // Get the cluster or weighted_clusters in the RouteAction.
638
+ if (envoy_config_route_v3_RouteAction_has_cluster(route_action)) {
639
+ route->cluster_name = UpbStringToStdString(
640
+ envoy_config_route_v3_RouteAction_cluster(route_action));
641
+ if (route->cluster_name.empty()) {
642
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
643
+ "RouteAction cluster contains empty cluster name.");
644
+ }
645
+ } else if (envoy_config_route_v3_RouteAction_has_weighted_clusters(
646
+ route_action)) {
647
+ const envoy_config_route_v3_WeightedCluster* weighted_cluster =
648
+ envoy_config_route_v3_RouteAction_weighted_clusters(route_action);
649
+ uint32_t total_weight = 100;
650
+ const google_protobuf_UInt32Value* weight =
651
+ envoy_config_route_v3_WeightedCluster_total_weight(weighted_cluster);
652
+ if (weight != nullptr) {
653
+ total_weight = google_protobuf_UInt32Value_value(weight);
654
+ }
655
+ size_t clusters_size;
656
+ const envoy_config_route_v3_WeightedCluster_ClusterWeight* const* clusters =
657
+ envoy_config_route_v3_WeightedCluster_clusters(weighted_cluster,
658
+ &clusters_size);
659
+ uint32_t sum_of_weights = 0;
660
+ for (size_t j = 0; j < clusters_size; ++j) {
661
+ const envoy_config_route_v3_WeightedCluster_ClusterWeight*
662
+ cluster_weight = clusters[j];
663
+ XdsRouteConfigResource::Route::RouteAction::ClusterWeight cluster;
664
+ cluster.name = UpbStringToStdString(
665
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_name(
666
+ cluster_weight));
667
+ if (cluster.name.empty()) {
668
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
669
+ "RouteAction weighted_cluster cluster contains empty cluster "
670
+ "name.");
671
+ }
672
+ const google_protobuf_UInt32Value* weight =
673
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_weight(
674
+ cluster_weight);
675
+ if (weight == nullptr) {
676
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
677
+ "RouteAction weighted_cluster cluster missing weight");
678
+ }
679
+ cluster.weight = google_protobuf_UInt32Value_value(weight);
680
+ if (cluster.weight == 0) continue;
681
+ sum_of_weights += cluster.weight;
682
+ if (context.use_v3) {
683
+ grpc_error_handle error = ParseTypedPerFilterConfig<
684
+ envoy_config_route_v3_WeightedCluster_ClusterWeight,
685
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry>(
686
+ context, cluster_weight,
687
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_next,
688
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_key,
689
+ envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_value,
690
+ &cluster.typed_per_filter_config);
691
+ if (error != GRPC_ERROR_NONE) return error;
692
+ }
693
+ route->weighted_clusters.emplace_back(std::move(cluster));
694
+ }
695
+ if (total_weight != sum_of_weights) {
696
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
697
+ "RouteAction weighted_cluster has incorrect total weight");
698
+ }
699
+ if (route->weighted_clusters.empty()) {
700
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
701
+ "RouteAction weighted_cluster has no valid clusters specified.");
702
+ }
703
+ } else {
704
+ // No cluster or weighted_clusters found in RouteAction, ignore this route.
705
+ *ignore_route = true;
706
+ }
707
+ if (!*ignore_route) {
708
+ const envoy_config_route_v3_RouteAction_MaxStreamDuration*
709
+ max_stream_duration =
710
+ envoy_config_route_v3_RouteAction_max_stream_duration(route_action);
711
+ if (max_stream_duration != nullptr) {
712
+ const google_protobuf_Duration* duration =
713
+ envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_max(
714
+ max_stream_duration);
715
+ if (duration == nullptr) {
716
+ duration =
717
+ envoy_config_route_v3_RouteAction_MaxStreamDuration_max_stream_duration(
718
+ max_stream_duration);
719
+ }
720
+ if (duration != nullptr) {
721
+ route->max_stream_duration = Duration::Parse(duration);
722
+ }
723
+ }
724
+ }
725
+ // Get HashPolicy from RouteAction
726
+ size_t size = 0;
727
+ const envoy_config_route_v3_RouteAction_HashPolicy* const* hash_policies =
728
+ envoy_config_route_v3_RouteAction_hash_policy(route_action, &size);
729
+ for (size_t i = 0; i < size; ++i) {
730
+ const envoy_config_route_v3_RouteAction_HashPolicy* hash_policy =
731
+ hash_policies[i];
732
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy policy;
733
+ policy.terminal =
734
+ envoy_config_route_v3_RouteAction_HashPolicy_terminal(hash_policy);
735
+ const envoy_config_route_v3_RouteAction_HashPolicy_Header* header;
736
+ const envoy_config_route_v3_RouteAction_HashPolicy_FilterState*
737
+ filter_state;
738
+ if ((header = envoy_config_route_v3_RouteAction_HashPolicy_header(
739
+ hash_policy)) != nullptr) {
740
+ policy.type =
741
+ XdsRouteConfigResource::Route::RouteAction::HashPolicy::Type::HEADER;
742
+ policy.header_name = UpbStringToStdString(
743
+ envoy_config_route_v3_RouteAction_HashPolicy_Header_header_name(
744
+ header));
745
+ const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*
746
+ regex_rewrite =
747
+ envoy_config_route_v3_RouteAction_HashPolicy_Header_regex_rewrite(
748
+ header);
749
+ if (regex_rewrite != nullptr) {
750
+ const envoy_type_matcher_v3_RegexMatcher* regex_matcher =
751
+ envoy_type_matcher_v3_RegexMatchAndSubstitute_pattern(
752
+ regex_rewrite);
753
+ if (regex_matcher == nullptr) {
754
+ gpr_log(
755
+ GPR_DEBUG,
756
+ "RouteAction HashPolicy contains policy specifier Header with "
757
+ "RegexMatchAndSubstitution but RegexMatcher pattern is "
758
+ "missing");
759
+ continue;
760
+ }
761
+ RE2::Options options;
762
+ policy.regex = absl::make_unique<RE2>(
763
+ UpbStringToStdString(
764
+ envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher)),
765
+ options);
766
+ if (!policy.regex->ok()) {
767
+ gpr_log(
768
+ GPR_DEBUG,
769
+ "RouteAction HashPolicy contains policy specifier Header with "
770
+ "RegexMatchAndSubstitution but RegexMatcher pattern does not "
771
+ "compile");
772
+ continue;
773
+ }
774
+ policy.regex_substitution = UpbStringToStdString(
775
+ envoy_type_matcher_v3_RegexMatchAndSubstitute_substitution(
776
+ regex_rewrite));
777
+ }
778
+ } else if ((filter_state =
779
+ envoy_config_route_v3_RouteAction_HashPolicy_filter_state(
780
+ hash_policy)) != nullptr) {
781
+ std::string key = UpbStringToStdString(
782
+ envoy_config_route_v3_RouteAction_HashPolicy_FilterState_key(
783
+ filter_state));
784
+ if (key == "io.grpc.channel_id") {
785
+ policy.type = XdsRouteConfigResource::Route::RouteAction::HashPolicy::
786
+ Type::CHANNEL_ID;
787
+ } else {
788
+ gpr_log(GPR_DEBUG,
789
+ "RouteAction HashPolicy contains policy specifier "
790
+ "FilterState but "
791
+ "key is not io.grpc.channel_id.");
792
+ continue;
793
+ }
794
+ } else {
795
+ gpr_log(GPR_DEBUG,
796
+ "RouteAction HashPolicy contains unsupported policy specifier.");
797
+ continue;
798
+ }
799
+ route->hash_policies.emplace_back(std::move(policy));
800
+ }
801
+ // Get retry policy
802
+ const envoy_config_route_v3_RetryPolicy* retry_policy =
803
+ envoy_config_route_v3_RouteAction_retry_policy(route_action);
804
+ if (retry_policy != nullptr) {
805
+ absl::optional<XdsRouteConfigResource::RetryPolicy> retry;
806
+ grpc_error_handle error = RetryPolicyParse(context, retry_policy, &retry);
807
+ if (error != GRPC_ERROR_NONE) return error;
808
+ route->retry_policy = retry;
809
+ }
810
+ return GRPC_ERROR_NONE;
811
+ }
812
+
813
+ } // namespace
814
+
815
+ grpc_error_handle XdsRouteConfigResource::Parse(
816
+ const XdsEncodingContext& context,
817
+ const envoy_config_route_v3_RouteConfiguration* route_config,
818
+ XdsRouteConfigResource* rds_update) {
819
+ // Get the virtual hosts.
820
+ size_t num_virtual_hosts;
821
+ const envoy_config_route_v3_VirtualHost* const* virtual_hosts =
822
+ envoy_config_route_v3_RouteConfiguration_virtual_hosts(
823
+ route_config, &num_virtual_hosts);
824
+ for (size_t i = 0; i < num_virtual_hosts; ++i) {
825
+ rds_update->virtual_hosts.emplace_back();
826
+ XdsRouteConfigResource::VirtualHost& vhost =
827
+ rds_update->virtual_hosts.back();
828
+ // Parse domains.
829
+ size_t domain_size;
830
+ upb_strview const* domains = envoy_config_route_v3_VirtualHost_domains(
831
+ virtual_hosts[i], &domain_size);
832
+ for (size_t j = 0; j < domain_size; ++j) {
833
+ std::string domain_pattern = UpbStringToStdString(domains[j]);
834
+ if (!XdsRouting::IsValidDomainPattern(domain_pattern)) {
835
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
836
+ absl::StrCat("Invalid domain pattern \"", domain_pattern, "\"."));
837
+ }
838
+ vhost.domains.emplace_back(std::move(domain_pattern));
839
+ }
840
+ if (vhost.domains.empty()) {
841
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("VirtualHost has no domains");
842
+ }
843
+ // Parse typed_per_filter_config.
844
+ if (context.use_v3) {
845
+ grpc_error_handle error = ParseTypedPerFilterConfig<
846
+ envoy_config_route_v3_VirtualHost,
847
+ envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry>(
848
+ context, virtual_hosts[i],
849
+ envoy_config_route_v3_VirtualHost_typed_per_filter_config_next,
850
+ envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_key,
851
+ envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_value,
852
+ &vhost.typed_per_filter_config);
853
+ if (error != GRPC_ERROR_NONE) return error;
854
+ }
855
+ // Parse retry policy.
856
+ absl::optional<XdsRouteConfigResource::RetryPolicy>
857
+ virtual_host_retry_policy;
858
+ const envoy_config_route_v3_RetryPolicy* retry_policy =
859
+ envoy_config_route_v3_VirtualHost_retry_policy(virtual_hosts[i]);
860
+ if (retry_policy != nullptr) {
861
+ grpc_error_handle error =
862
+ RetryPolicyParse(context, retry_policy, &virtual_host_retry_policy);
863
+ if (error != GRPC_ERROR_NONE) return error;
864
+ }
865
+ // Parse routes.
866
+ size_t num_routes;
867
+ const envoy_config_route_v3_Route* const* routes =
868
+ envoy_config_route_v3_VirtualHost_routes(virtual_hosts[i], &num_routes);
869
+ if (num_routes < 1) {
870
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
871
+ "No route found in the virtual host.");
872
+ }
873
+ // Loop over the whole list of routes
874
+ for (size_t j = 0; j < num_routes; ++j) {
875
+ const envoy_config_route_v3_RouteMatch* match =
876
+ envoy_config_route_v3_Route_match(routes[j]);
877
+ if (match == nullptr) {
878
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Match can't be null.");
879
+ }
880
+ size_t query_parameters_size;
881
+ static_cast<void>(envoy_config_route_v3_RouteMatch_query_parameters(
882
+ match, &query_parameters_size));
883
+ if (query_parameters_size > 0) {
884
+ continue;
885
+ }
886
+ XdsRouteConfigResource::Route route;
887
+ bool ignore_route = false;
888
+ grpc_error_handle error =
889
+ RoutePathMatchParse(match, &route, &ignore_route);
890
+ if (error != GRPC_ERROR_NONE) return error;
891
+ if (ignore_route) continue;
892
+ error = RouteHeaderMatchersParse(match, &route);
893
+ if (error != GRPC_ERROR_NONE) return error;
894
+ error = RouteRuntimeFractionParse(match, &route);
895
+ if (error != GRPC_ERROR_NONE) return error;
896
+ if (envoy_config_route_v3_Route_has_route(routes[j])) {
897
+ route.action.emplace<XdsRouteConfigResource::Route::RouteAction>();
898
+ auto& route_action =
899
+ absl::get<XdsRouteConfigResource::Route::RouteAction>(route.action);
900
+ error =
901
+ RouteActionParse(context, routes[j], &route_action, &ignore_route);
902
+ if (error != GRPC_ERROR_NONE) return error;
903
+ if (ignore_route) continue;
904
+ if (route_action.retry_policy == absl::nullopt &&
905
+ retry_policy != nullptr) {
906
+ route_action.retry_policy = virtual_host_retry_policy;
907
+ }
908
+ } else if (envoy_config_route_v3_Route_has_non_forwarding_action(
909
+ routes[j])) {
910
+ route.action
911
+ .emplace<XdsRouteConfigResource::Route::NonForwardingAction>();
912
+ }
913
+ if (context.use_v3) {
914
+ grpc_error_handle error = ParseTypedPerFilterConfig<
915
+ envoy_config_route_v3_Route,
916
+ envoy_config_route_v3_Route_TypedPerFilterConfigEntry>(
917
+ context, routes[j],
918
+ envoy_config_route_v3_Route_typed_per_filter_config_next,
919
+ envoy_config_route_v3_Route_TypedPerFilterConfigEntry_key,
920
+ envoy_config_route_v3_Route_TypedPerFilterConfigEntry_value,
921
+ &route.typed_per_filter_config);
922
+ if (error != GRPC_ERROR_NONE) return error;
923
+ }
924
+ vhost.routes.emplace_back(std::move(route));
925
+ }
926
+ if (vhost.routes.empty()) {
927
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No valid routes specified.");
928
+ }
929
+ }
930
+ return GRPC_ERROR_NONE;
931
+ }
932
+
933
+ //
934
+ // XdsRouteConfigResourceType
935
+ //
936
+
937
+ namespace {
938
+
939
+ void MaybeLogRouteConfiguration(
940
+ const XdsEncodingContext& context,
941
+ const envoy_config_route_v3_RouteConfiguration* route_config) {
942
+ if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
943
+ gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
944
+ const upb_msgdef* msg_type =
945
+ envoy_config_route_v3_RouteConfiguration_getmsgdef(context.symtab);
946
+ char buf[10240];
947
+ upb_text_encode(route_config, msg_type, nullptr, 0, buf, sizeof(buf));
948
+ gpr_log(GPR_DEBUG, "[xds_client %p] RouteConfiguration: %s", context.client,
949
+ buf);
950
+ }
951
+ }
952
+
953
+ } // namespace
954
+
955
+ absl::StatusOr<XdsResourceType::DecodeResult>
956
+ XdsRouteConfigResourceType::Decode(const XdsEncodingContext& context,
957
+ absl::string_view serialized_resource,
958
+ bool /*is_v2*/) const {
959
+ // Parse serialized proto.
960
+ auto* resource = envoy_config_route_v3_RouteConfiguration_parse(
961
+ serialized_resource.data(), serialized_resource.size(), context.arena);
962
+ if (resource == nullptr) {
963
+ return absl::InvalidArgumentError(
964
+ "Can't parse RouteConfiguration resource.");
965
+ }
966
+ MaybeLogRouteConfiguration(context, resource);
967
+ // Validate resource.
968
+ DecodeResult result;
969
+ result.name = UpbStringToStdString(
970
+ envoy_config_route_v3_RouteConfiguration_name(resource));
971
+ auto route_config_data = absl::make_unique<ResourceDataSubclass>();
972
+ grpc_error_handle error = XdsRouteConfigResource::Parse(
973
+ context, resource, &route_config_data->resource);
974
+ if (error != GRPC_ERROR_NONE) {
975
+ std::string error_str = grpc_error_std_string(error);
976
+ GRPC_ERROR_UNREF(error);
977
+ if (GRPC_TRACE_FLAG_ENABLED(*context.tracer)) {
978
+ gpr_log(GPR_ERROR, "[xds_client %p] invalid RouteConfiguration %s: %s",
979
+ context.client, result.name.c_str(), error_str.c_str());
980
+ }
981
+ result.resource = absl::InvalidArgumentError(error_str);
982
+ } else {
983
+ if (GRPC_TRACE_FLAG_ENABLED(*context.tracer)) {
984
+ gpr_log(GPR_INFO, "[xds_client %p] parsed RouteConfiguration %s: %s",
985
+ context.client, result.name.c_str(),
986
+ route_config_data->resource.ToString().c_str());
987
+ }
988
+ result.resource = std::move(route_config_data);
989
+ }
990
+ return std::move(result);
991
+ }
992
+
993
+ } // namespace grpc_core