grpc 1.50.0.pre1 → 1.51.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 (459) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +131 -42
  3. data/include/grpc/event_engine/event_engine.h +10 -3
  4. data/include/grpc/event_engine/slice_buffer.h +17 -0
  5. data/include/grpc/grpc.h +0 -10
  6. data/include/grpc/impl/codegen/grpc_types.h +1 -5
  7. data/include/grpc/impl/codegen/port_platform.h +0 -3
  8. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +19 -13
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +1 -0
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +3 -3
  11. data/src/core/ext/filters/client_channel/channel_connectivity.cc +7 -5
  12. data/src/core/ext/filters/client_channel/client_channel.cc +120 -140
  13. data/src/core/ext/filters/client_channel/client_channel.h +3 -4
  14. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +0 -2
  15. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
  16. data/src/core/ext/filters/client_channel/client_channel_service_config.cc +153 -0
  17. data/src/core/ext/filters/client_channel/{resolver_result_parsing.h → client_channel_service_config.h} +26 -23
  18. data/src/core/ext/filters/client_channel/connector.h +1 -1
  19. data/src/core/ext/filters/client_channel/dynamic_filters.cc +20 -47
  20. data/src/core/ext/filters/client_channel/dynamic_filters.h +7 -8
  21. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -4
  22. data/src/core/ext/filters/client_channel/http_proxy.cc +0 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +3 -4
  24. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +5 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +8 -7
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +35 -44
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +0 -1
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -3
  29. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +3 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.h +1 -1
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +41 -29
  32. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +2 -2
  33. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +9 -11
  34. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +15 -12
  35. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +8 -10
  36. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +26 -27
  37. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +7 -9
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +44 -26
  39. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +17 -27
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_attributes.cc +42 -0
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/{xds.h → xds_attributes.h} +15 -17
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +13 -7
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +48 -47
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +40 -126
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +364 -0
  46. data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +9 -9
  47. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +23 -32
  48. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +1 -2
  49. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +22 -23
  50. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +50 -52
  51. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
  52. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +2 -4
  53. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +1 -3
  54. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +34 -26
  55. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +3 -4
  56. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +4 -7
  57. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +63 -46
  58. data/src/core/ext/filters/client_channel/retry_filter.cc +80 -102
  59. data/src/core/ext/filters/client_channel/retry_service_config.cc +192 -234
  60. data/src/core/ext/filters/client_channel/retry_service_config.h +20 -23
  61. data/src/core/ext/filters/client_channel/retry_throttle.cc +8 -8
  62. data/src/core/ext/filters/client_channel/retry_throttle.h +8 -7
  63. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -2
  64. data/src/core/ext/filters/client_channel/subchannel.cc +21 -25
  65. data/src/core/ext/filters/client_channel/subchannel.h +2 -2
  66. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +11 -12
  67. data/src/core/ext/filters/deadline/deadline_filter.cc +13 -14
  68. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
  69. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +0 -4
  70. data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc +118 -0
  71. data/src/core/ext/filters/fault_injection/{service_config_parser.h → fault_injection_service_config_parser.h} +20 -12
  72. data/src/core/ext/filters/http/client/http_client_filter.cc +16 -16
  73. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  74. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +13 -13
  75. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +34 -34
  76. data/src/core/ext/filters/http/server/http_server_filter.cc +26 -25
  77. data/src/core/ext/filters/message_size/message_size_filter.cc +86 -117
  78. data/src/core/ext/filters/message_size/message_size_filter.h +22 -15
  79. data/src/core/ext/filters/rbac/rbac_filter.cc +12 -12
  80. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +728 -530
  81. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +4 -3
  82. data/src/core/ext/filters/server_config_selector/server_config_selector.h +1 -1
  83. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +6 -7
  84. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +17 -21
  85. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +57 -72
  86. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +5 -5
  87. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -1
  88. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +212 -253
  89. data/src/core/ext/transport/chttp2/transport/flow_control.cc +42 -11
  90. data/src/core/ext/transport/chttp2/transport/flow_control.h +4 -3
  91. data/src/core/ext/transport/chttp2/transport/frame_data.cc +16 -15
  92. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  93. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +13 -13
  94. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +4 -3
  95. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +10 -7
  96. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +15 -17
  97. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +5 -4
  98. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +5 -6
  99. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +1 -1
  100. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +2 -1
  101. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +31 -39
  102. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +7 -6
  103. data/src/core/ext/transport/chttp2/transport/internal.h +24 -8
  104. data/src/core/ext/transport/chttp2/transport/parsing.cc +51 -52
  105. data/src/core/ext/transport/chttp2/transport/varint.cc +2 -3
  106. data/src/core/ext/transport/chttp2/transport/varint.h +11 -8
  107. data/src/core/ext/transport/chttp2/transport/writing.cc +16 -16
  108. data/src/core/ext/transport/inproc/inproc_transport.cc +97 -115
  109. data/src/core/ext/xds/certificate_provider_store.cc +4 -4
  110. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +4 -7
  111. data/src/core/ext/xds/xds_api.cc +15 -68
  112. data/src/core/ext/xds/xds_api.h +3 -7
  113. data/src/core/ext/xds/xds_bootstrap.h +0 -1
  114. data/src/core/ext/xds/xds_bootstrap_grpc.cc +3 -12
  115. data/src/core/ext/xds/xds_bootstrap_grpc.h +16 -1
  116. data/src/core/ext/xds/xds_certificate_provider.cc +22 -25
  117. data/src/core/ext/xds/xds_channel_stack_modifier.cc +0 -1
  118. data/src/core/ext/xds/xds_client.cc +122 -90
  119. data/src/core/ext/xds/xds_client.h +7 -2
  120. data/src/core/ext/xds/xds_client_grpc.cc +5 -24
  121. data/src/core/ext/xds/xds_cluster.cc +291 -183
  122. data/src/core/ext/xds/xds_cluster.h +11 -15
  123. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +32 -29
  124. data/src/core/ext/xds/xds_cluster_specifier_plugin.h +35 -16
  125. data/src/core/ext/xds/xds_common_types.cc +208 -141
  126. data/src/core/ext/xds/xds_common_types.h +19 -13
  127. data/src/core/ext/xds/xds_endpoint.cc +214 -129
  128. data/src/core/ext/xds/xds_endpoint.h +4 -7
  129. data/src/core/ext/xds/xds_http_fault_filter.cc +56 -43
  130. data/src/core/ext/xds/xds_http_fault_filter.h +13 -21
  131. data/src/core/ext/xds/xds_http_filters.cc +60 -73
  132. data/src/core/ext/xds/xds_http_filters.h +67 -19
  133. data/src/core/ext/xds/xds_http_rbac_filter.cc +152 -207
  134. data/src/core/ext/xds/xds_http_rbac_filter.h +12 -15
  135. data/src/core/ext/xds/xds_lb_policy_registry.cc +122 -169
  136. data/src/core/ext/xds/xds_lb_policy_registry.h +10 -11
  137. data/src/core/ext/xds/xds_listener.cc +459 -417
  138. data/src/core/ext/xds/xds_listener.h +43 -47
  139. data/src/core/ext/xds/xds_resource_type.h +3 -11
  140. data/src/core/ext/xds/xds_resource_type_impl.h +8 -13
  141. data/src/core/ext/xds/xds_route_config.cc +94 -80
  142. data/src/core/ext/xds/xds_route_config.h +10 -10
  143. data/src/core/ext/xds/xds_routing.cc +2 -1
  144. data/src/core/ext/xds/xds_routing.h +2 -0
  145. data/src/core/ext/xds/xds_server_config_fetcher.cc +109 -94
  146. data/src/core/ext/xds/xds_transport_grpc.cc +4 -5
  147. data/src/core/lib/address_utils/parse_address.cc +11 -10
  148. data/src/core/lib/channel/channel_args.h +16 -1
  149. data/src/core/lib/channel/channel_stack.cc +23 -20
  150. data/src/core/lib/channel/channel_stack.h +17 -4
  151. data/src/core/lib/channel/channel_stack_builder.cc +4 -7
  152. data/src/core/lib/channel/channel_stack_builder.h +14 -6
  153. data/src/core/lib/channel/channel_stack_builder_impl.cc +25 -7
  154. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -0
  155. data/src/core/lib/channel/channel_trace.cc +4 -5
  156. data/src/core/lib/channel/channelz.cc +1 -1
  157. data/src/core/lib/channel/connected_channel.cc +695 -35
  158. data/src/core/lib/channel/connected_channel.h +0 -4
  159. data/src/core/lib/channel/promise_based_filter.cc +1004 -140
  160. data/src/core/lib/channel/promise_based_filter.h +364 -87
  161. data/src/core/lib/compression/message_compress.cc +5 -5
  162. data/src/core/lib/debug/event_log.cc +88 -0
  163. data/src/core/lib/debug/event_log.h +81 -0
  164. data/src/core/lib/debug/histogram_view.cc +69 -0
  165. data/src/core/lib/{slice/slice_refcount.cc → debug/histogram_view.h} +15 -13
  166. data/src/core/lib/debug/stats.cc +22 -119
  167. data/src/core/lib/debug/stats.h +29 -35
  168. data/src/core/lib/debug/stats_data.cc +224 -73
  169. data/src/core/lib/debug/stats_data.h +263 -122
  170. data/src/core/lib/event_engine/common_closures.h +71 -0
  171. data/src/core/lib/event_engine/default_event_engine.cc +38 -15
  172. data/src/core/lib/event_engine/default_event_engine.h +15 -3
  173. data/src/core/lib/event_engine/default_event_engine_factory.cc +2 -4
  174. data/src/core/lib/event_engine/memory_allocator.cc +1 -1
  175. data/src/core/lib/event_engine/poller.h +10 -4
  176. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +618 -0
  177. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +129 -0
  178. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +901 -0
  179. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +97 -0
  180. data/src/core/lib/event_engine/posix_engine/event_poller.h +111 -0
  181. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +74 -0
  182. data/src/core/lib/event_engine/{executor/threaded_executor.cc → posix_engine/event_poller_posix_default.h} +13 -16
  183. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +77 -0
  184. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +179 -0
  185. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +267 -0
  186. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +73 -0
  187. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1270 -0
  188. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +682 -0
  189. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +453 -18
  190. data/src/core/lib/event_engine/posix_engine/posix_engine.h +148 -24
  191. data/src/core/lib/event_engine/posix_engine/posix_engine_closure.h +80 -0
  192. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1081 -0
  193. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +361 -0
  194. data/src/core/lib/event_engine/posix_engine/timer.h +9 -8
  195. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +57 -194
  196. data/src/core/lib/event_engine/posix_engine/timer_manager.h +21 -49
  197. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +301 -0
  198. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +179 -0
  199. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +126 -0
  200. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +45 -0
  201. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +151 -0
  202. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +45 -0
  203. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +76 -0
  204. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +67 -0
  205. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +37 -0
  206. data/src/core/lib/event_engine/slice.cc +7 -6
  207. data/src/core/lib/event_engine/slice_buffer.cc +2 -2
  208. data/src/core/lib/event_engine/thread_pool.cc +106 -25
  209. data/src/core/lib/event_engine/thread_pool.h +32 -9
  210. data/src/core/lib/event_engine/windows/win_socket.cc +7 -7
  211. data/src/core/lib/event_engine/windows/windows_engine.cc +18 -12
  212. data/src/core/lib/event_engine/windows/windows_engine.h +8 -4
  213. data/src/core/lib/experiments/config.cc +1 -1
  214. data/src/core/lib/experiments/experiments.cc +13 -2
  215. data/src/core/lib/experiments/experiments.h +8 -1
  216. data/src/core/lib/gpr/cpu_linux.cc +6 -2
  217. data/src/core/lib/gpr/log_linux.cc +3 -4
  218. data/src/core/lib/gpr/string.h +1 -1
  219. data/src/core/lib/gpr/tmpfile_posix.cc +3 -2
  220. data/src/core/lib/gprpp/load_file.cc +75 -0
  221. data/src/core/lib/gprpp/load_file.h +33 -0
  222. data/src/core/lib/gprpp/per_cpu.h +46 -0
  223. data/src/core/lib/gprpp/stat_posix.cc +5 -4
  224. data/src/core/lib/gprpp/stat_windows.cc +3 -2
  225. data/src/core/lib/gprpp/status_helper.h +1 -3
  226. data/src/core/lib/gprpp/strerror.cc +41 -0
  227. data/src/core/{ext/xds/xds_resource_type.cc → lib/gprpp/strerror.h} +9 -13
  228. data/src/core/lib/gprpp/thd_windows.cc +1 -2
  229. data/src/core/lib/gprpp/time.cc +3 -4
  230. data/src/core/lib/gprpp/time.h +13 -2
  231. data/src/core/lib/gprpp/validation_errors.h +18 -1
  232. data/src/core/lib/http/httpcli.cc +40 -44
  233. data/src/core/lib/http/httpcli.h +6 -5
  234. data/src/core/lib/http/httpcli_security_connector.cc +4 -6
  235. data/src/core/lib/http/parser.cc +54 -65
  236. data/src/core/lib/iomgr/buffer_list.cc +105 -116
  237. data/src/core/lib/iomgr/buffer_list.h +60 -44
  238. data/src/core/lib/iomgr/call_combiner.cc +11 -10
  239. data/src/core/lib/iomgr/call_combiner.h +3 -4
  240. data/src/core/lib/iomgr/cfstream_handle.cc +13 -16
  241. data/src/core/lib/iomgr/closure.h +49 -5
  242. data/src/core/lib/iomgr/combiner.cc +2 -2
  243. data/src/core/lib/iomgr/endpoint.h +1 -1
  244. data/src/core/lib/iomgr/endpoint_cfstream.cc +26 -25
  245. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  246. data/src/core/lib/iomgr/error.cc +27 -42
  247. data/src/core/lib/iomgr/error.h +22 -152
  248. data/src/core/lib/iomgr/ev_apple.cc +4 -4
  249. data/src/core/lib/iomgr/ev_epoll1_linux.cc +26 -25
  250. data/src/core/lib/iomgr/ev_poll_posix.cc +27 -31
  251. data/src/core/lib/iomgr/exec_ctx.cc +3 -4
  252. data/src/core/lib/iomgr/exec_ctx.h +2 -3
  253. data/src/core/lib/iomgr/executor.cc +1 -2
  254. data/src/core/lib/iomgr/internal_errqueue.cc +3 -1
  255. data/src/core/lib/iomgr/iocp_windows.cc +1 -0
  256. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  257. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -1
  258. data/src/core/lib/iomgr/iomgr_windows.cc +2 -1
  259. data/src/core/lib/iomgr/load_file.cc +5 -9
  260. data/src/core/lib/iomgr/lockfree_event.cc +10 -10
  261. data/src/core/lib/iomgr/pollset_windows.cc +4 -4
  262. data/src/core/lib/iomgr/python_util.h +2 -2
  263. data/src/core/lib/iomgr/resolve_address.cc +8 -3
  264. data/src/core/lib/iomgr/resolve_address.h +3 -4
  265. data/src/core/lib/iomgr/resolve_address_impl.h +1 -1
  266. data/src/core/lib/iomgr/resolve_address_posix.cc +14 -25
  267. data/src/core/lib/iomgr/resolve_address_posix.h +1 -2
  268. data/src/core/lib/iomgr/resolve_address_windows.cc +14 -17
  269. data/src/core/lib/iomgr/resolve_address_windows.h +1 -2
  270. data/src/core/lib/iomgr/socket_utils_common_posix.cc +30 -29
  271. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -0
  272. data/src/core/lib/iomgr/socket_utils_posix.h +2 -2
  273. data/src/core/lib/iomgr/socket_windows.cc +2 -2
  274. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -10
  275. data/src/core/lib/iomgr/tcp_client_posix.cc +31 -35
  276. data/src/core/lib/iomgr/tcp_client_windows.cc +8 -12
  277. data/src/core/lib/iomgr/tcp_posix.cc +92 -108
  278. data/src/core/lib/iomgr/tcp_server_posix.cc +34 -34
  279. data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -1
  280. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +18 -21
  281. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +12 -13
  282. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc +1 -1
  283. data/src/core/lib/iomgr/tcp_server_windows.cc +26 -29
  284. data/src/core/lib/iomgr/tcp_windows.cc +27 -34
  285. data/src/core/lib/iomgr/timer.h +8 -8
  286. data/src/core/lib/iomgr/timer_generic.cc +9 -15
  287. data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -4
  288. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +4 -3
  289. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +10 -8
  290. data/src/core/lib/json/json_channel_args.h +42 -0
  291. data/src/core/lib/json/json_object_loader.cc +7 -2
  292. data/src/core/lib/json/json_object_loader.h +22 -0
  293. data/src/core/lib/json/json_util.cc +5 -5
  294. data/src/core/lib/json/json_util.h +4 -4
  295. data/src/core/lib/load_balancing/lb_policy.cc +1 -1
  296. data/src/core/lib/load_balancing/lb_policy.h +4 -0
  297. data/src/core/lib/load_balancing/subchannel_interface.h +0 -7
  298. data/src/core/lib/matchers/matchers.cc +3 -4
  299. data/src/core/lib/promise/activity.cc +16 -2
  300. data/src/core/lib/promise/activity.h +38 -15
  301. data/src/core/lib/promise/arena_promise.h +80 -51
  302. data/src/core/lib/promise/context.h +13 -6
  303. data/src/core/lib/promise/detail/basic_seq.h +9 -28
  304. data/src/core/lib/promise/detail/promise_factory.h +58 -10
  305. data/src/core/lib/promise/detail/status.h +28 -0
  306. data/src/core/lib/promise/detail/switch.h +1455 -0
  307. data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +3 -1
  308. data/src/core/lib/promise/for_each.h +129 -0
  309. data/src/core/lib/promise/loop.h +7 -5
  310. data/src/core/lib/promise/map_pipe.h +87 -0
  311. data/src/core/lib/promise/pipe.cc +19 -0
  312. data/src/core/lib/promise/pipe.h +505 -0
  313. data/src/core/lib/promise/poll.h +13 -0
  314. data/src/core/lib/promise/seq.h +3 -5
  315. data/src/core/lib/promise/sleep.cc +5 -4
  316. data/src/core/lib/promise/sleep.h +1 -2
  317. data/src/core/lib/promise/try_concurrently.h +341 -0
  318. data/src/core/lib/promise/try_seq.h +10 -13
  319. data/src/core/lib/resolver/server_address.cc +1 -0
  320. data/src/core/lib/resolver/server_address.h +1 -3
  321. data/src/core/lib/resource_quota/api.cc +0 -1
  322. data/src/core/lib/resource_quota/arena.cc +19 -0
  323. data/src/core/lib/resource_quota/arena.h +89 -0
  324. data/src/core/lib/resource_quota/memory_quota.cc +1 -0
  325. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +1 -3
  326. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +4 -2
  327. data/src/core/lib/security/authorization/matchers.cc +25 -22
  328. data/src/core/lib/security/authorization/rbac_policy.cc +2 -3
  329. data/src/core/lib/security/context/security_context.h +10 -0
  330. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +3 -4
  331. data/src/core/lib/security/credentials/composite/composite_credentials.cc +1 -1
  332. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +77 -55
  333. data/src/core/lib/security/credentials/external/aws_request_signer.cc +4 -3
  334. data/src/core/lib/security/credentials/external/external_account_credentials.cc +40 -51
  335. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +17 -21
  336. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +21 -25
  337. data/src/core/lib/security/credentials/fake/fake_credentials.cc +1 -0
  338. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +27 -24
  339. data/src/core/lib/security/credentials/iam/iam_credentials.cc +1 -0
  340. data/src/core/lib/security/credentials/jwt/json_token.cc +1 -2
  341. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
  342. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +5 -5
  343. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +24 -30
  344. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -5
  345. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +3 -3
  346. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +19 -27
  347. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +4 -11
  348. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +29 -41
  349. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +1 -1
  350. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +6 -11
  351. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +8 -15
  352. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +2 -2
  353. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +2 -6
  354. data/src/core/lib/security/security_connector/load_system_roots_supported.cc +1 -4
  355. data/src/core/lib/security/security_connector/local/local_security_connector.cc +7 -11
  356. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +9 -14
  357. data/src/core/lib/security/security_connector/ssl_utils.cc +5 -7
  358. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +21 -27
  359. data/src/core/lib/security/transport/client_auth_filter.cc +1 -1
  360. data/src/core/lib/security/transport/secure_endpoint.cc +26 -28
  361. data/src/core/lib/security/transport/security_handshaker.cc +53 -53
  362. data/src/core/lib/security/transport/server_auth_filter.cc +21 -21
  363. data/src/core/lib/security/transport/tsi_error.cc +6 -3
  364. data/src/core/lib/security/util/json_util.cc +4 -5
  365. data/src/core/lib/service_config/service_config.h +1 -1
  366. data/src/core/lib/service_config/service_config_impl.cc +111 -158
  367. data/src/core/lib/service_config/service_config_impl.h +14 -17
  368. data/src/core/lib/service_config/service_config_parser.cc +14 -31
  369. data/src/core/lib/service_config/service_config_parser.h +14 -10
  370. data/src/core/lib/slice/b64.cc +2 -2
  371. data/src/core/lib/slice/slice.cc +7 -1
  372. data/src/core/lib/slice/slice.h +19 -6
  373. data/src/core/lib/slice/slice_buffer.cc +13 -14
  374. data/src/core/lib/slice/slice_internal.h +13 -21
  375. data/src/core/lib/slice/slice_refcount.h +34 -19
  376. data/src/core/lib/surface/byte_buffer.cc +3 -4
  377. data/src/core/lib/surface/byte_buffer_reader.cc +4 -4
  378. data/src/core/lib/surface/call.cc +1366 -239
  379. data/src/core/lib/surface/call.h +44 -0
  380. data/src/core/lib/surface/call_details.cc +3 -3
  381. data/src/core/lib/surface/call_trace.cc +113 -0
  382. data/src/core/lib/surface/call_trace.h +30 -0
  383. data/src/core/lib/surface/channel.cc +44 -49
  384. data/src/core/lib/surface/channel.h +9 -1
  385. data/src/core/lib/surface/channel_ping.cc +1 -1
  386. data/src/core/lib/surface/channel_stack_type.cc +4 -0
  387. data/src/core/lib/surface/channel_stack_type.h +2 -0
  388. data/src/core/lib/surface/completion_queue.cc +38 -52
  389. data/src/core/lib/surface/init.cc +8 -39
  390. data/src/core/lib/surface/init_internally.h +8 -0
  391. data/src/core/lib/surface/lame_client.cc +10 -8
  392. data/src/core/lib/surface/server.cc +48 -70
  393. data/src/core/lib/surface/server.h +3 -4
  394. data/src/core/lib/surface/validate_metadata.cc +11 -12
  395. data/src/core/lib/surface/version.cc +2 -2
  396. data/src/core/lib/transport/connectivity_state.cc +2 -2
  397. data/src/core/lib/transport/error_utils.cc +34 -28
  398. data/src/core/lib/transport/error_utils.h +3 -3
  399. data/src/core/lib/transport/handshaker.cc +14 -14
  400. data/src/core/lib/transport/handshaker.h +1 -1
  401. data/src/core/lib/transport/handshaker_factory.h +26 -0
  402. data/src/core/lib/transport/handshaker_registry.cc +8 -2
  403. data/src/core/lib/transport/handshaker_registry.h +3 -4
  404. data/src/core/lib/transport/http_connect_handshaker.cc +23 -24
  405. data/src/core/lib/transport/metadata_batch.h +17 -1
  406. data/src/core/lib/transport/parsed_metadata.cc +2 -6
  407. data/src/core/lib/transport/tcp_connect_handshaker.cc +15 -20
  408. data/src/core/lib/transport/transport.cc +63 -17
  409. data/src/core/lib/transport/transport.h +64 -68
  410. data/src/core/lib/transport/transport_impl.h +1 -1
  411. data/src/core/lib/transport/transport_op_string.cc +7 -6
  412. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -10
  413. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -14
  414. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +10 -10
  415. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -8
  416. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +2 -1
  417. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +7 -7
  418. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +7 -6
  419. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +1 -1
  420. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +5 -5
  421. data/src/core/tsi/fake_transport_security.cc +3 -3
  422. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +7 -3
  423. data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +1 -1
  424. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +6 -2
  425. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +0 -2
  426. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +0 -3
  427. data/src/ruby/lib/grpc/version.rb +1 -1
  428. data/src/ruby/spec/channel_spec.rb +0 -43
  429. data/src/ruby/spec/generic/active_call_spec.rb +12 -3
  430. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +140 -0
  431. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +100 -0
  432. data/third_party/zlib/compress.c +3 -3
  433. data/third_party/zlib/crc32.c +21 -12
  434. data/third_party/zlib/deflate.c +112 -106
  435. data/third_party/zlib/deflate.h +2 -2
  436. data/third_party/zlib/gzlib.c +1 -1
  437. data/third_party/zlib/gzread.c +3 -5
  438. data/third_party/zlib/gzwrite.c +1 -1
  439. data/third_party/zlib/infback.c +10 -7
  440. data/third_party/zlib/inflate.c +5 -2
  441. data/third_party/zlib/inftrees.c +2 -2
  442. data/third_party/zlib/inftrees.h +1 -1
  443. data/third_party/zlib/trees.c +61 -62
  444. data/third_party/zlib/uncompr.c +2 -2
  445. data/third_party/zlib/zconf.h +16 -3
  446. data/third_party/zlib/zlib.h +10 -10
  447. data/third_party/zlib/zutil.c +9 -7
  448. data/third_party/zlib/zutil.h +1 -0
  449. metadata +57 -20
  450. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +0 -188
  451. data/src/core/ext/filters/fault_injection/service_config_parser.cc +0 -187
  452. data/src/core/lib/event_engine/executor/threaded_executor.h +0 -44
  453. data/src/core/lib/gpr/murmur_hash.cc +0 -82
  454. data/src/core/lib/gpr/murmur_hash.h +0 -29
  455. data/src/core/lib/gpr/tls.h +0 -156
  456. data/src/core/lib/promise/call_push_pull.h +0 -148
  457. data/src/core/lib/slice/slice_api.cc +0 -39
  458. data/src/core/lib/slice/slice_buffer_api.cc +0 -35
  459. data/src/core/lib/slice/slice_refcount_base.h +0 -60
@@ -23,13 +23,11 @@
23
23
  #include <set>
24
24
  #include <utility>
25
25
 
26
- #include "absl/memory/memory.h"
27
26
  #include "absl/status/status.h"
28
27
  #include "absl/status/statusor.h"
29
28
  #include "absl/strings/str_cat.h"
30
29
  #include "absl/strings/str_format.h"
31
30
  #include "absl/strings/str_join.h"
32
- #include "absl/strings/strip.h"
33
31
  #include "envoy/config/core/v3/address.upb.h"
34
32
  #include "envoy/config/core/v3/base.upb.h"
35
33
  #include "envoy/config/core/v3/config_source.upb.h"
@@ -57,44 +55,32 @@
57
55
  #include "src/core/lib/address_utils/sockaddr_utils.h"
58
56
  #include "src/core/lib/debug/trace.h"
59
57
  #include "src/core/lib/gprpp/host_port.h"
60
- #include "src/core/lib/gprpp/status_helper.h"
61
- #include "src/core/lib/iomgr/error.h"
58
+ #include "src/core/lib/gprpp/match.h"
59
+ #include "src/core/lib/gprpp/validation_errors.h"
62
60
  #include "src/core/lib/iomgr/sockaddr.h"
63
- #include "src/core/lib/json/json.h"
61
+ #include "src/core/lib/matchers/matchers.h"
64
62
 
65
63
  namespace grpc_core {
66
64
 
67
- //
68
- // XdsListenerResource::DownstreamTlsContext
69
- //
70
-
71
- std::string XdsListenerResource::DownstreamTlsContext::ToString() const {
72
- return absl::StrFormat("common_tls_context=%s, require_client_certificate=%s",
73
- common_tls_context.ToString(),
74
- require_client_certificate ? "true" : "false");
75
- }
76
-
77
- bool XdsListenerResource::DownstreamTlsContext::Empty() const {
78
- return common_tls_context.Empty();
79
- }
80
-
81
65
  //
82
66
  // XdsListenerResource::HttpConnectionManager
83
67
  //
84
68
 
85
69
  std::string XdsListenerResource::HttpConnectionManager::ToString() const {
86
70
  std::vector<std::string> contents;
87
- contents.push_back(absl::StrFormat(
88
- "route_config_name=%s",
89
- !route_config_name.empty() ? route_config_name.c_str() : "<inlined>"));
90
- contents.push_back(absl::StrFormat("http_max_stream_duration=%s",
91
- http_max_stream_duration.ToString()));
92
- if (rds_update.has_value()) {
93
- contents.push_back(
94
- absl::StrFormat("rds_update=%s", rds_update->ToString()));
95
- }
71
+ contents.push_back(Match(
72
+ route_config,
73
+ [](const std::string& rds_name) {
74
+ return absl::StrCat("rds_name=", rds_name);
75
+ },
76
+ [](const XdsRouteConfigResource& route_config) {
77
+ return absl::StrCat("route_config=", route_config.ToString());
78
+ }));
79
+ contents.push_back(absl::StrCat("http_max_stream_duration=",
80
+ http_max_stream_duration.ToString()));
96
81
  if (!http_filters.empty()) {
97
82
  std::vector<std::string> filter_strings;
83
+ filter_strings.reserve(http_filters.size());
98
84
  for (const auto& http_filter : http_filters) {
99
85
  filter_strings.push_back(http_filter.ToString());
100
86
  }
@@ -105,7 +91,7 @@ std::string XdsListenerResource::HttpConnectionManager::ToString() const {
105
91
  }
106
92
 
107
93
  //
108
- // XdsListenerResource::HttpFilter
94
+ // XdsListenerResource::HttpConnectionManager::HttpFilter
109
95
  //
110
96
 
111
97
  std::string XdsListenerResource::HttpConnectionManager::HttpFilter::ToString()
@@ -113,6 +99,20 @@ std::string XdsListenerResource::HttpConnectionManager::HttpFilter::ToString()
113
99
  return absl::StrCat("{name=", name, ", config=", config.ToString(), "}");
114
100
  }
115
101
 
102
+ //
103
+ // XdsListenerResource::DownstreamTlsContext
104
+ //
105
+
106
+ std::string XdsListenerResource::DownstreamTlsContext::ToString() const {
107
+ return absl::StrFormat("common_tls_context=%s, require_client_certificate=%s",
108
+ common_tls_context.ToString(),
109
+ require_client_certificate ? "true" : "false");
110
+ }
111
+
112
+ bool XdsListenerResource::DownstreamTlsContext::Empty() const {
113
+ return common_tls_context.Empty();
114
+ }
115
+
116
116
  //
117
117
  // XdsListenerResource::FilterChainData
118
118
  //
@@ -165,6 +165,7 @@ std::string FilterChain::FilterChainMatch::ToString() const {
165
165
  }
166
166
  if (!prefix_ranges.empty()) {
167
167
  std::vector<std::string> prefix_ranges_content;
168
+ prefix_ranges_content.reserve(prefix_ranges.size());
168
169
  for (const auto& range : prefix_ranges) {
169
170
  prefix_ranges_content.push_back(range.ToString());
170
171
  }
@@ -180,6 +181,7 @@ std::string FilterChain::FilterChainMatch::ToString() const {
180
181
  }
181
182
  if (!source_prefix_ranges.empty()) {
182
183
  std::vector<std::string> source_prefix_ranges_content;
184
+ source_prefix_ranges_content.reserve(source_prefix_ranges.size());
183
185
  for (const auto& range : source_prefix_ranges) {
184
186
  source_prefix_ranges_content.push_back(range.ToString());
185
187
  }
@@ -244,26 +246,36 @@ std::string XdsListenerResource::FilterChainMap::ToString() const {
244
246
  }
245
247
 
246
248
  //
247
- // XdsListenerResource
249
+ // XdsListenerResource::TcpListener
248
250
  //
249
251
 
250
- std::string XdsListenerResource::ToString() const {
252
+ std::string XdsListenerResource::TcpListener::ToString() const {
251
253
  std::vector<std::string> contents;
252
- if (type == ListenerType::kTcpListener) {
253
- contents.push_back(absl::StrCat("address=", address));
254
- contents.push_back(
255
- absl::StrCat("filter_chain_map=", filter_chain_map.ToString()));
256
- if (default_filter_chain.has_value()) {
257
- contents.push_back(absl::StrCat("default_filter_chain=",
258
- default_filter_chain->ToString()));
259
- }
260
- } else if (type == ListenerType::kHttpApiListener) {
261
- contents.push_back(absl::StrFormat("http_connection_manager=%s",
262
- http_connection_manager.ToString()));
254
+ contents.push_back(absl::StrCat("address=", address));
255
+ contents.push_back(
256
+ absl::StrCat("filter_chain_map=", filter_chain_map.ToString()));
257
+ if (default_filter_chain.has_value()) {
258
+ contents.push_back(absl::StrCat("default_filter_chain=",
259
+ default_filter_chain->ToString()));
263
260
  }
264
261
  return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
265
262
  }
266
263
 
264
+ //
265
+ // XdsListenerResource
266
+ //
267
+
268
+ std::string XdsListenerResource::ToString() const {
269
+ return Match(
270
+ listener,
271
+ [](const HttpConnectionManager& hcm) {
272
+ return absl::StrCat("{http_connection_manager=", hcm.ToString(), "}");
273
+ },
274
+ [](const TcpListener& tcp) {
275
+ return absl::StrCat("{tcp_listener=", tcp.ToString(), "}");
276
+ });
277
+ }
278
+
267
279
  //
268
280
  // XdsListenerResourceType
269
281
  //
@@ -287,111 +299,136 @@ void MaybeLogHttpConnectionManager(
287
299
  }
288
300
  }
289
301
 
290
- absl::StatusOr<XdsListenerResource::HttpConnectionManager>
291
- HttpConnectionManagerParse(
302
+ XdsListenerResource::HttpConnectionManager HttpConnectionManagerParse(
292
303
  bool is_client, const XdsResourceType::DecodeContext& context,
293
- const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager*
294
- http_connection_manager_proto,
295
- bool is_v2) {
304
+ XdsExtension extension, ValidationErrors* errors) {
305
+ if (extension.type !=
306
+ "envoy.extensions.filters.network.http_connection_manager.v3"
307
+ ".HttpConnectionManager") {
308
+ errors->AddError("unsupported filter type");
309
+ return {};
310
+ }
311
+ auto* serialized_hcm_config =
312
+ absl::get_if<absl::string_view>(&extension.value);
313
+ if (serialized_hcm_config == nullptr) {
314
+ errors->AddError("could not parse HttpConnectionManager config");
315
+ return {};
316
+ }
317
+ const auto* http_connection_manager_proto =
318
+ envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse(
319
+ serialized_hcm_config->data(), serialized_hcm_config->size(),
320
+ context.arena);
321
+ if (http_connection_manager_proto == nullptr) {
322
+ errors->AddError("could not parse HttpConnectionManager config");
323
+ return {};
324
+ }
296
325
  MaybeLogHttpConnectionManager(context, http_connection_manager_proto);
297
- std::vector<std::string> errors;
298
326
  XdsListenerResource::HttpConnectionManager http_connection_manager;
299
- // NACK a non-zero `xff_num_trusted_hops` and a `non-empty
300
- // original_ip_detection_extensions` as mentioned in
327
+ // xff_num_trusted_hops -- must be zero as per
301
328
  // https://github.com/grpc/proposal/blob/master/A41-xds-rbac.md
302
329
  if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_xff_num_trusted_hops(
303
330
  http_connection_manager_proto) != 0) {
304
- errors.emplace_back("'xff_num_trusted_hops' must be zero");
331
+ ValidationErrors::ScopedField field(errors, ".xff_num_trusted_hops");
332
+ errors->AddError("must be zero");
305
333
  }
334
+ // original_ip_detection_extensions -- must be empty as per
335
+ // https://github.com/grpc/proposal/blob/master/A41-xds-rbac.md
306
336
  if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_original_ip_detection_extensions(
307
337
  http_connection_manager_proto)) {
308
- errors.emplace_back("'original_ip_detection_extensions' must be empty");
338
+ ValidationErrors::ScopedField field(errors,
339
+ ".original_ip_detection_extensions");
340
+ errors->AddError("must be empty");
309
341
  }
310
- // Obtain max_stream_duration from Http Protocol Options.
342
+ // common_http_protocol_options
311
343
  const envoy_config_core_v3_HttpProtocolOptions* options =
312
344
  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options(
313
345
  http_connection_manager_proto);
314
346
  if (options != nullptr) {
347
+ // max_stream_duration
315
348
  const google_protobuf_Duration* duration =
316
349
  envoy_config_core_v3_HttpProtocolOptions_max_stream_duration(options);
317
350
  if (duration != nullptr) {
351
+ ValidationErrors::ScopedField field(
352
+ errors, ".common_http_protocol_options.max_stream_duration");
318
353
  http_connection_manager.http_max_stream_duration =
319
- ParseDuration(duration);
354
+ ParseDuration(duration, errors);
320
355
  }
321
356
  }
322
- // Parse filters.
323
- if (!is_v2) {
357
+ // http_filters
358
+ {
359
+ ValidationErrors::ScopedField field(errors, ".http_filters");
360
+ const auto& http_filter_registry =
361
+ static_cast<const GrpcXdsBootstrap&>(context.client->bootstrap())
362
+ .http_filter_registry();
324
363
  size_t num_filters = 0;
325
364
  const auto* http_filters =
326
365
  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_filters(
327
366
  http_connection_manager_proto, &num_filters);
328
367
  std::set<absl::string_view> names_seen;
368
+ const size_t original_error_size = errors->size();
329
369
  for (size_t i = 0; i < num_filters; ++i) {
370
+ ValidationErrors::ScopedField field(errors, absl::StrCat("[", i, "]"));
330
371
  const auto* http_filter = http_filters[i];
372
+ // name
331
373
  absl::string_view name = UpbStringToAbsl(
332
374
  envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_name(
333
375
  http_filter));
334
- if (name.empty()) {
335
- errors.emplace_back(absl::StrCat("empty filter name at index ", i));
336
- continue;
337
- }
338
- if (names_seen.find(name) != names_seen.end()) {
339
- errors.emplace_back(absl::StrCat("duplicate HTTP filter name: ", name));
340
- continue;
376
+ {
377
+ ValidationErrors::ScopedField field(errors, ".name");
378
+ if (name.empty()) {
379
+ errors->AddError("empty filter name");
380
+ continue;
381
+ }
382
+ if (names_seen.find(name) != names_seen.end()) {
383
+ errors->AddError(absl::StrCat("duplicate HTTP filter name: ", name));
384
+ continue;
385
+ }
341
386
  }
342
387
  names_seen.insert(name);
388
+ // is_optional
343
389
  const bool is_optional =
344
390
  envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_is_optional(
345
391
  http_filter);
346
- const google_protobuf_Any* any =
347
- envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_typed_config(
348
- http_filter);
349
- if (any == nullptr) {
350
- if (!is_optional) {
351
- errors.emplace_back(absl::StrCat(
352
- "no filter config specified for filter name ", name));
392
+ // typed_config
393
+ {
394
+ ValidationErrors::ScopedField field(errors, ".typed_config");
395
+ const google_protobuf_Any* typed_config =
396
+ envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_typed_config(
397
+ http_filter);
398
+ if (typed_config == nullptr) {
399
+ if (!is_optional) errors->AddError("field not present");
400
+ continue;
353
401
  }
354
- continue;
355
- }
356
- auto filter_type = ExtractExtensionTypeName(context, any);
357
- if (!filter_type.ok()) {
358
- errors.emplace_back(absl::StrCat("filter name ", name, ": ",
359
- filter_type.status().message()));
360
- continue;
361
- }
362
- const XdsHttpFilterImpl* filter_impl =
363
- XdsHttpFilterRegistry::GetFilterForType(filter_type->type);
364
- if (filter_impl == nullptr) {
365
- if (!is_optional) {
366
- errors.emplace_back(absl::StrCat(
367
- "no filter registered for config type ", filter_type->type));
402
+ auto extension = ExtractXdsExtension(context, typed_config, errors);
403
+ const XdsHttpFilterImpl* filter_impl = nullptr;
404
+ if (extension.has_value()) {
405
+ filter_impl = http_filter_registry.GetFilterForType(extension->type);
368
406
  }
369
- continue;
370
- }
371
- if ((is_client && !filter_impl->IsSupportedOnClients()) ||
372
- (!is_client && !filter_impl->IsSupportedOnServers())) {
373
- if (!is_optional) {
374
- errors.emplace_back(absl::StrFormat(
375
- "Filter %s is not supported on %s", filter_type->type,
376
- is_client ? "clients" : "servers"));
407
+ if (filter_impl == nullptr) {
408
+ if (!is_optional) errors->AddError("unsupported filter type");
409
+ continue;
410
+ }
411
+ if ((is_client && !filter_impl->IsSupportedOnClients()) ||
412
+ (!is_client && !filter_impl->IsSupportedOnServers())) {
413
+ if (!is_optional) {
414
+ errors->AddError(absl::StrCat("filter is not supported on ",
415
+ is_client ? "clients" : "servers"));
416
+ }
417
+ continue;
418
+ }
419
+ absl::optional<XdsHttpFilterImpl::FilterConfig> filter_config =
420
+ filter_impl->GenerateFilterConfig(std::move(*extension),
421
+ context.arena, errors);
422
+ if (filter_config.has_value()) {
423
+ http_connection_manager.http_filters.emplace_back(
424
+ XdsListenerResource::HttpConnectionManager::HttpFilter{
425
+ std::string(name), std::move(*filter_config)});
377
426
  }
378
- continue;
379
- }
380
- absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config =
381
- filter_impl->GenerateFilterConfig(google_protobuf_Any_value(any),
382
- context.arena);
383
- if (!filter_config.ok()) {
384
- errors.emplace_back(absl::StrCat(
385
- "filter config for type ", filter_type->type,
386
- " failed to parse: ", StatusToString(filter_config.status())));
387
- continue;
388
427
  }
389
- http_connection_manager.http_filters.emplace_back(
390
- XdsListenerResource::HttpConnectionManager::HttpFilter{
391
- std::string(name), std::move(*filter_config)});
392
428
  }
393
- if (http_connection_manager.http_filters.empty()) {
394
- errors.emplace_back("Expected at least one HTTP filter");
429
+ if (errors->size() == original_error_size &&
430
+ http_connection_manager.http_filters.empty()) {
431
+ errors->AddError("expected at least one HTTP filter");
395
432
  }
396
433
  // Make sure that the last filter is terminal and non-last filters are
397
434
  // non-terminal. Note that this check is being performed in a separate loop
@@ -399,12 +436,12 @@ HttpConnectionManagerParse(
399
436
  // out of which only one gets added in the final list.
400
437
  for (const auto& http_filter : http_connection_manager.http_filters) {
401
438
  const XdsHttpFilterImpl* filter_impl =
402
- XdsHttpFilterRegistry::GetFilterForType(
439
+ http_filter_registry.GetFilterForType(
403
440
  http_filter.config.config_proto_type_name);
404
441
  if (&http_filter != &http_connection_manager.http_filters.back()) {
405
442
  // Filters before the last filter must not be terminal.
406
443
  if (filter_impl->IsTerminalFilter()) {
407
- errors.emplace_back(
444
+ errors->AddError(
408
445
  absl::StrCat("terminal filter for config type ",
409
446
  http_filter.config.config_proto_type_name,
410
447
  " must be the last filter in the chain"));
@@ -412,187 +449,176 @@ HttpConnectionManagerParse(
412
449
  } else {
413
450
  // The last filter must be terminal.
414
451
  if (!filter_impl->IsTerminalFilter()) {
415
- errors.emplace_back(
452
+ errors->AddError(
416
453
  absl::StrCat("non-terminal filter for config type ",
417
454
  http_filter.config.config_proto_type_name,
418
455
  " is the last filter in the chain"));
419
456
  }
420
457
  }
421
458
  }
459
+ }
460
+ // Found inlined route_config. Parse it to find the cluster_name.
461
+ if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config(
462
+ http_connection_manager_proto)) {
463
+ const envoy_config_route_v3_RouteConfiguration* route_config =
464
+ envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config(
465
+ http_connection_manager_proto);
466
+ auto rds_update = XdsRouteConfigResource::Parse(context, route_config);
467
+ if (!rds_update.ok()) {
468
+ ValidationErrors::ScopedField field(errors, ".route_config");
469
+ errors->AddError(rds_update.status().message());
470
+ } else {
471
+ http_connection_manager.route_config = std::move(*rds_update);
472
+ }
422
473
  } else {
423
- // If using a v2 config, we just hard-code a list containing only the
424
- // router filter without actually looking at the config. This ensures
425
- // that the right thing happens in the xds resolver without having
426
- // to expose whether the resource we received was v2 or v3.
427
- http_connection_manager.http_filters.emplace_back(
428
- XdsListenerResource::HttpConnectionManager::HttpFilter{
429
- "router", {kXdsHttpRouterFilterConfigName, Json()}});
430
- }
431
- // Guarding parsing of RouteConfig on the server side with the environmental
432
- // variable since that's the first feature on the server side that will be
433
- // using this.
434
- if (is_client || XdsRbacEnabled()) {
435
- // Found inlined route_config. Parse it to find the cluster_name.
436
- if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config(
437
- http_connection_manager_proto)) {
438
- const envoy_config_route_v3_RouteConfiguration* route_config =
439
- envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config(
440
- http_connection_manager_proto);
441
- auto rds_update = XdsRouteConfigResource::Parse(context, route_config);
442
- if (!rds_update.ok()) {
443
- errors.emplace_back(rds_update.status().message());
444
- } else {
445
- http_connection_manager.rds_update = std::move(*rds_update);
446
- }
474
+ // Validate that RDS must be used to get the route_config dynamically.
475
+ const envoy_extensions_filters_network_http_connection_manager_v3_Rds* rds =
476
+ envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds(
477
+ http_connection_manager_proto);
478
+ if (rds == nullptr) {
479
+ errors->AddError("neither route_config nor rds fields are present");
447
480
  } else {
448
- // Validate that RDS must be used to get the route_config dynamically.
449
- const envoy_extensions_filters_network_http_connection_manager_v3_Rds* rds =
450
- envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds(
451
- http_connection_manager_proto);
452
- if (rds == nullptr) {
453
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
454
- "HttpConnectionManager neither has inlined route_config nor RDS.");
455
- }
481
+ // Get the route_config_name.
482
+ http_connection_manager.route_config = UpbStringToStdString(
483
+ envoy_extensions_filters_network_http_connection_manager_v3_Rds_route_config_name(
484
+ rds));
456
485
  // Check that the ConfigSource specifies ADS.
457
486
  const envoy_config_core_v3_ConfigSource* config_source =
458
487
  envoy_extensions_filters_network_http_connection_manager_v3_Rds_config_source(
459
488
  rds);
489
+ ValidationErrors::ScopedField field(errors, ".rds.config_source");
460
490
  if (config_source == nullptr) {
461
- errors.emplace_back(
462
- "HttpConnectionManager missing config_source for RDS.");
491
+ errors->AddError("field not present");
463
492
  } else if (!envoy_config_core_v3_ConfigSource_has_ads(config_source) &&
464
493
  !envoy_config_core_v3_ConfigSource_has_self(config_source)) {
465
- errors.emplace_back(
466
- "HttpConnectionManager ConfigSource for RDS does not specify ADS "
467
- "or SELF.");
468
- } else {
469
- // Get the route_config_name.
470
- http_connection_manager.route_config_name = UpbStringToStdString(
471
- envoy_extensions_filters_network_http_connection_manager_v3_Rds_route_config_name(
472
- rds));
494
+ errors->AddError("ConfigSource does not specify ADS or SELF");
473
495
  }
474
496
  }
475
497
  }
476
- // Return result.
477
- if (!errors.empty()) {
478
- return absl::InvalidArgumentError(
479
- absl::StrCat("Errors parsing HttpConnectionManager config: [",
480
- absl::StrJoin(errors, "; "), "]"));
481
- }
482
498
  return http_connection_manager;
483
499
  }
484
500
 
485
501
  absl::StatusOr<XdsListenerResource> LdsResourceParseClient(
486
502
  const XdsResourceType::DecodeContext& context,
487
- const envoy_config_listener_v3_ApiListener* api_listener, bool is_v2) {
488
- const upb_StringView encoded_api_listener = google_protobuf_Any_value(
489
- envoy_config_listener_v3_ApiListener_api_listener(api_listener));
490
- const auto* http_connection_manager =
491
- envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse(
492
- encoded_api_listener.data, encoded_api_listener.size, context.arena);
493
- if (http_connection_manager == nullptr) {
494
- return absl::InvalidArgumentError(
495
- "Could not parse HttpConnectionManager config from ApiListener");
496
- }
497
- auto hcm = HttpConnectionManagerParse(true /* is_client */, context,
498
- http_connection_manager, is_v2);
499
- if (!hcm.ok()) return hcm.status();
503
+ const envoy_config_listener_v3_ApiListener* api_listener) {
500
504
  XdsListenerResource lds_update;
501
- lds_update.type = XdsListenerResource::ListenerType::kHttpApiListener;
502
- lds_update.http_connection_manager = std::move(*hcm);
503
- return lds_update;
505
+ ValidationErrors errors;
506
+ ValidationErrors::ScopedField field(&errors, "api_listener.api_listener");
507
+ auto* api_listener_field =
508
+ envoy_config_listener_v3_ApiListener_api_listener(api_listener);
509
+ if (api_listener_field == nullptr) {
510
+ errors.AddError("field not present");
511
+ } else {
512
+ auto extension = ExtractXdsExtension(context, api_listener_field, &errors);
513
+ if (extension.has_value()) {
514
+ lds_update.listener = HttpConnectionManagerParse(
515
+ /*is_client=*/true, context, std::move(*extension), &errors);
516
+ }
517
+ }
518
+ if (!errors.ok()) return errors.status("errors validating ApiListener");
519
+ return std::move(lds_update);
504
520
  }
505
521
 
506
- absl::StatusOr<XdsListenerResource::DownstreamTlsContext>
507
- DownstreamTlsContextParse(
522
+ XdsListenerResource::DownstreamTlsContext DownstreamTlsContextParse(
508
523
  const XdsResourceType::DecodeContext& context,
509
- const envoy_config_core_v3_TransportSocket* transport_socket) {
524
+ const envoy_config_core_v3_TransportSocket* transport_socket,
525
+ ValidationErrors* errors) {
526
+ ValidationErrors::ScopedField field(errors, ".typed_config");
510
527
  const auto* typed_config =
511
528
  envoy_config_core_v3_TransportSocket_typed_config(transport_socket);
512
- if (typed_config == nullptr) {
513
- return absl::InvalidArgumentError("transport socket typed config unset");
514
- }
515
- absl::string_view type_url = absl::StripPrefix(
516
- UpbStringToAbsl(google_protobuf_Any_type_url(typed_config)),
517
- "type.googleapis.com/");
518
- if (type_url !=
529
+ auto extension = ExtractXdsExtension(context, typed_config, errors);
530
+ if (!extension.has_value()) return {};
531
+ if (extension->type !=
519
532
  "envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext") {
520
- return absl::InvalidArgumentError(
521
- absl::StrCat("Unrecognized transport socket type: ", type_url));
533
+ ValidationErrors::ScopedField field(errors, ".type_url");
534
+ errors->AddError("unsupported transport socket type");
535
+ return {};
536
+ }
537
+ absl::string_view* serialized_downstream_tls_context =
538
+ absl::get_if<absl::string_view>(&extension->value);
539
+ if (serialized_downstream_tls_context == nullptr) {
540
+ errors->AddError("can't decode DownstreamTlsContext");
541
+ return {};
522
542
  }
523
- const upb_StringView encoded_downstream_tls_context =
524
- google_protobuf_Any_value(typed_config);
525
543
  const auto* downstream_tls_context_proto =
526
544
  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_parse(
527
- encoded_downstream_tls_context.data,
528
- encoded_downstream_tls_context.size, context.arena);
545
+ serialized_downstream_tls_context->data(),
546
+ serialized_downstream_tls_context->size(), context.arena);
529
547
  if (downstream_tls_context_proto == nullptr) {
530
- return absl::InvalidArgumentError("Can't decode downstream tls context.");
548
+ errors->AddError("can't decode DownstreamTlsContext");
549
+ return {};
531
550
  }
532
- std::vector<std::string> errors;
533
551
  XdsListenerResource::DownstreamTlsContext downstream_tls_context;
534
552
  auto* common_tls_context =
535
553
  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_common_tls_context(
536
554
  downstream_tls_context_proto);
537
555
  if (common_tls_context != nullptr) {
538
- auto common_context = CommonTlsContext::Parse(context, common_tls_context);
539
- if (!common_context.ok()) {
540
- errors.emplace_back(common_context.status().message());
541
- } else {
542
- downstream_tls_context.common_tls_context = std::move(*common_context);
556
+ ValidationErrors::ScopedField field(errors, ".common_tls_context");
557
+ downstream_tls_context.common_tls_context =
558
+ CommonTlsContext::Parse(context, common_tls_context, errors);
559
+ // Note: We can't be more specific about the field name for this
560
+ // error, because we don't know which fields they were found in
561
+ // inside of CommonTlsContext, so we make the error message a bit
562
+ // more verbose to compensate.
563
+ if (!downstream_tls_context.common_tls_context
564
+ .certificate_validation_context.match_subject_alt_names.empty()) {
565
+ errors->AddError("match_subject_alt_names not supported on servers");
543
566
  }
544
567
  }
568
+ // Note: We can't be more specific about the field name for this
569
+ // error, because we don't know which fields they were found in
570
+ // inside of CommonTlsContext, so we make the error message a bit
571
+ // more verbose to compensate.
572
+ if (downstream_tls_context.common_tls_context
573
+ .tls_certificate_provider_instance.instance_name.empty()) {
574
+ errors->AddError(
575
+ "TLS configuration provided but no "
576
+ "tls_certificate_provider_instance found");
577
+ }
545
578
  auto* require_client_certificate =
546
579
  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_require_client_certificate(
547
580
  downstream_tls_context_proto);
548
581
  if (require_client_certificate != nullptr) {
549
582
  downstream_tls_context.require_client_certificate =
550
583
  google_protobuf_BoolValue_value(require_client_certificate);
584
+ if (downstream_tls_context.require_client_certificate &&
585
+ downstream_tls_context.common_tls_context.certificate_validation_context
586
+ .ca_certificate_provider_instance.instance_name.empty()) {
587
+ ValidationErrors::ScopedField field(errors,
588
+ ".require_client_certificate");
589
+ errors->AddError(
590
+ "client certificate required but no certificate "
591
+ "provider instance specified for validation");
592
+ }
551
593
  }
552
594
  auto* require_sni =
553
595
  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_require_sni(
554
596
  downstream_tls_context_proto);
555
597
  if (require_sni != nullptr && google_protobuf_BoolValue_value(require_sni)) {
556
- errors.emplace_back("require_sni: unsupported");
598
+ ValidationErrors::ScopedField field(errors, ".require_sni");
599
+ errors->AddError("field unsupported");
557
600
  }
558
601
  if (envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_ocsp_staple_policy(
559
602
  downstream_tls_context_proto) !=
560
603
  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_LENIENT_STAPLING) {
561
- errors.emplace_back("ocsp_staple_policy: Only LENIENT_STAPLING supported");
562
- }
563
- if (downstream_tls_context.common_tls_context
564
- .tls_certificate_provider_instance.instance_name.empty()) {
565
- errors.emplace_back(
566
- "TLS configuration provided but no "
567
- "tls_certificate_provider_instance found.");
568
- }
569
- if (downstream_tls_context.require_client_certificate &&
570
- downstream_tls_context.common_tls_context.certificate_validation_context
571
- .ca_certificate_provider_instance.instance_name.empty()) {
572
- errors.emplace_back(
573
- "TLS configuration requires client certificates but no certificate "
574
- "provider instance specified for validation.");
575
- }
576
- if (!downstream_tls_context.common_tls_context.certificate_validation_context
577
- .match_subject_alt_names.empty()) {
578
- errors.emplace_back("match_subject_alt_names not supported on servers");
579
- }
580
- // Return result.
581
- if (!errors.empty()) {
582
- return absl::InvalidArgumentError(
583
- absl::StrCat("Errors parsing DownstreamTlsContext: [",
584
- absl::StrJoin(errors, "; "), "]"));
604
+ ValidationErrors::ScopedField field(errors, ".ocsp_staple_policy");
605
+ errors->AddError("value must be LENIENT_STAPLING");
585
606
  }
586
607
  return downstream_tls_context;
587
608
  }
588
609
 
589
- absl::StatusOr<XdsListenerResource::FilterChainMap::CidrRange> CidrRangeParse(
590
- const envoy_config_core_v3_CidrRange* cidr_range_proto) {
610
+ absl::optional<XdsListenerResource::FilterChainMap::CidrRange> CidrRangeParse(
611
+ const envoy_config_core_v3_CidrRange* cidr_range_proto,
612
+ ValidationErrors* errors) {
613
+ ValidationErrors::ScopedField field(errors, ".address_prefix");
591
614
  XdsListenerResource::FilterChainMap::CidrRange cidr_range;
592
615
  std::string address_prefix = UpbStringToStdString(
593
616
  envoy_config_core_v3_CidrRange_address_prefix(cidr_range_proto));
594
617
  auto address = StringToSockaddr(address_prefix, /*port=*/0);
595
- if (!address.ok()) return address.status();
618
+ if (!address.ok()) {
619
+ errors->AddError(address.status().message());
620
+ return absl::nullopt;
621
+ }
596
622
  cidr_range.address = *address;
597
623
  cidr_range.prefix_len = 0;
598
624
  auto* prefix_len_proto =
@@ -610,10 +636,12 @@ absl::StatusOr<XdsListenerResource::FilterChainMap::CidrRange> CidrRangeParse(
610
636
  return cidr_range;
611
637
  }
612
638
 
613
- absl::StatusOr<FilterChain::FilterChainMatch> FilterChainMatchParse(
614
- const envoy_config_listener_v3_FilterChainMatch* filter_chain_match_proto) {
615
- std::vector<std::string> errors;
639
+ absl::optional<FilterChain::FilterChainMatch> FilterChainMatchParse(
640
+ const envoy_config_listener_v3_FilterChainMatch* filter_chain_match_proto,
641
+ ValidationErrors* errors) {
616
642
  FilterChain::FilterChainMatch filter_chain_match;
643
+ const size_t original_error_size = errors->size();
644
+ // destination_port
617
645
  auto* destination_port =
618
646
  envoy_config_listener_v3_FilterChainMatch_destination_port(
619
647
  filter_chain_match_proto);
@@ -621,51 +649,56 @@ absl::StatusOr<FilterChain::FilterChainMatch> FilterChainMatchParse(
621
649
  filter_chain_match.destination_port =
622
650
  google_protobuf_UInt32Value_value(destination_port);
623
651
  }
652
+ // prefix_ranges
624
653
  size_t size = 0;
625
654
  auto* prefix_ranges = envoy_config_listener_v3_FilterChainMatch_prefix_ranges(
626
655
  filter_chain_match_proto, &size);
627
656
  filter_chain_match.prefix_ranges.reserve(size);
628
657
  for (size_t i = 0; i < size; i++) {
629
- auto cidr_range = CidrRangeParse(prefix_ranges[i]);
630
- if (!cidr_range.ok()) {
631
- errors.emplace_back(absl::StrCat("prefix range ", i, ": ",
632
- cidr_range.status().message()));
633
- continue;
658
+ ValidationErrors::ScopedField field(
659
+ errors, absl::StrCat(".prefix_ranges[", i, "]"));
660
+ auto cidr_range = CidrRangeParse(prefix_ranges[i], errors);
661
+ if (cidr_range.has_value()) {
662
+ filter_chain_match.prefix_ranges.push_back(*cidr_range);
634
663
  }
635
- filter_chain_match.prefix_ranges.push_back(*cidr_range);
636
664
  }
665
+ // source_type
637
666
  filter_chain_match.source_type =
638
667
  static_cast<XdsListenerResource::FilterChainMap::ConnectionSourceType>(
639
668
  envoy_config_listener_v3_FilterChainMatch_source_type(
640
669
  filter_chain_match_proto));
670
+ // source_prefix_ranges
641
671
  auto* source_prefix_ranges =
642
672
  envoy_config_listener_v3_FilterChainMatch_source_prefix_ranges(
643
673
  filter_chain_match_proto, &size);
644
674
  filter_chain_match.source_prefix_ranges.reserve(size);
645
675
  for (size_t i = 0; i < size; i++) {
646
- auto cidr_range = CidrRangeParse(source_prefix_ranges[i]);
647
- if (!cidr_range.ok()) {
648
- errors.emplace_back(absl::StrCat("source prefix range ", i, ": ",
649
- cidr_range.status().message()));
650
- continue;
676
+ ValidationErrors::ScopedField field(
677
+ errors, absl::StrCat(".source_prefix_ranges[", i, "]"));
678
+ auto cidr_range = CidrRangeParse(source_prefix_ranges[i], errors);
679
+ if (cidr_range.has_value()) {
680
+ filter_chain_match.source_prefix_ranges.push_back(*cidr_range);
651
681
  }
652
- filter_chain_match.source_prefix_ranges.push_back(*cidr_range);
653
682
  }
683
+ // source_ports
654
684
  auto* source_ports = envoy_config_listener_v3_FilterChainMatch_source_ports(
655
685
  filter_chain_match_proto, &size);
656
686
  filter_chain_match.source_ports.reserve(size);
657
687
  for (size_t i = 0; i < size; i++) {
658
688
  filter_chain_match.source_ports.push_back(source_ports[i]);
659
689
  }
690
+ // server_names
660
691
  auto* server_names = envoy_config_listener_v3_FilterChainMatch_server_names(
661
692
  filter_chain_match_proto, &size);
662
693
  for (size_t i = 0; i < size; i++) {
663
694
  filter_chain_match.server_names.push_back(
664
695
  UpbStringToStdString(server_names[i]));
665
696
  }
697
+ // transport_protocol
666
698
  filter_chain_match.transport_protocol = UpbStringToStdString(
667
699
  envoy_config_listener_v3_FilterChainMatch_transport_protocol(
668
700
  filter_chain_match_proto));
701
+ // application_protocols
669
702
  auto* application_protocols =
670
703
  envoy_config_listener_v3_FilterChainMatch_application_protocols(
671
704
  filter_chain_match_proto, &size);
@@ -674,112 +707,93 @@ absl::StatusOr<FilterChain::FilterChainMatch> FilterChainMatchParse(
674
707
  UpbStringToStdString(application_protocols[i]));
675
708
  }
676
709
  // Return result.
677
- if (!errors.empty()) {
678
- return absl::InvalidArgumentError(
679
- absl::StrCat("errors parsing filter chain match: [",
680
- absl::StrJoin(errors, "; "), "]"));
681
- }
710
+ if (errors->size() != original_error_size) return absl::nullopt;
682
711
  return filter_chain_match;
683
712
  }
684
713
 
685
- absl::StatusOr<FilterChain> FilterChainParse(
714
+ absl::optional<FilterChain> FilterChainParse(
686
715
  const XdsResourceType::DecodeContext& context,
687
716
  const envoy_config_listener_v3_FilterChain* filter_chain_proto,
688
- bool is_v2) {
717
+ ValidationErrors* errors) {
689
718
  FilterChain filter_chain;
690
- std::vector<std::string> errors;
719
+ const size_t original_error_size = errors->size();
720
+ // filter_chain_match
691
721
  auto* filter_chain_match =
692
722
  envoy_config_listener_v3_FilterChain_filter_chain_match(
693
723
  filter_chain_proto);
694
724
  if (filter_chain_match != nullptr) {
695
- auto match = FilterChainMatchParse(filter_chain_match);
696
- if (!match.ok()) {
697
- errors.emplace_back(match.status().message());
698
- } else {
725
+ ValidationErrors::ScopedField field(errors, ".filter_chain_match");
726
+ auto match = FilterChainMatchParse(filter_chain_match, errors);
727
+ if (match.has_value()) {
699
728
  filter_chain.filter_chain_match = std::move(*match);
700
729
  }
701
730
  }
702
- filter_chain.filter_chain_data =
703
- std::make_shared<XdsListenerResource::FilterChainData>();
704
- // Parse the filters list. Currently we only support HttpConnectionManager.
705
- size_t size = 0;
706
- auto* filters =
707
- envoy_config_listener_v3_FilterChain_filters(filter_chain_proto, &size);
708
- if (size != 1) {
709
- errors.push_back(
710
- "FilterChain should have exactly one filter: HttpConnectionManager; no "
711
- "other filter is supported at the moment");
712
- } else {
713
- auto* typed_config =
714
- envoy_config_listener_v3_Filter_typed_config(filters[0]);
715
- if (typed_config == nullptr) {
716
- errors.emplace_back("No typed_config found in filter.");
717
- } else {
718
- absl::string_view type_url = absl::StripPrefix(
719
- UpbStringToAbsl(google_protobuf_Any_type_url(typed_config)),
720
- "type.googleapis.com/");
721
- if (type_url !=
722
- "envoy.extensions.filters.network.http_connection_manager.v3."
723
- "HttpConnectionManager") {
724
- errors.emplace_back(absl::StrCat("Unsupported filter type ", type_url));
725
- } else {
726
- const upb_StringView encoded_http_connection_manager =
727
- google_protobuf_Any_value(typed_config);
728
- const auto* http_connection_manager =
729
- envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse(
730
- encoded_http_connection_manager.data,
731
- encoded_http_connection_manager.size, context.arena);
732
- if (http_connection_manager == nullptr) {
733
- errors.emplace_back(
734
- "Could not parse HttpConnectionManager config from filter "
735
- "typed_config");
736
- } else {
737
- auto hcm = HttpConnectionManagerParse(
738
- /*is_client=*/false, context, http_connection_manager, is_v2);
739
- if (!hcm.ok()) {
740
- errors.emplace_back(hcm.status().message());
741
- } else {
742
- filter_chain.filter_chain_data->http_connection_manager =
743
- std::move(*hcm);
744
- }
745
- }
731
+ // filters
732
+ {
733
+ ValidationErrors::ScopedField field(errors, ".filters");
734
+ filter_chain.filter_chain_data =
735
+ std::make_shared<XdsListenerResource::FilterChainData>();
736
+ size_t size = 0;
737
+ auto* filters =
738
+ envoy_config_listener_v3_FilterChain_filters(filter_chain_proto, &size);
739
+ if (size != 1) {
740
+ errors->AddError(
741
+ "must have exactly one filter (HttpConnectionManager -- "
742
+ "no other filter is supported at the moment)");
743
+ }
744
+ // entries in filters list
745
+ for (size_t i = 0; i < size; ++i) {
746
+ ValidationErrors::ScopedField field(
747
+ errors, absl::StrCat("[", i, "].typed_config"));
748
+ auto* typed_config =
749
+ envoy_config_listener_v3_Filter_typed_config(filters[i]);
750
+ auto extension = ExtractXdsExtension(context, typed_config, errors);
751
+ if (extension.has_value()) {
752
+ filter_chain.filter_chain_data->http_connection_manager =
753
+ HttpConnectionManagerParse(/*is_client=*/false, context,
754
+ std::move(*extension), errors);
746
755
  }
747
756
  }
748
757
  }
758
+ // transport_socket
749
759
  auto* transport_socket =
750
760
  envoy_config_listener_v3_FilterChain_transport_socket(filter_chain_proto);
751
761
  if (transport_socket != nullptr) {
752
- auto downstream_context =
753
- DownstreamTlsContextParse(context, transport_socket);
754
- if (!downstream_context.ok()) {
755
- errors.emplace_back(downstream_context.status().message());
756
- } else {
757
- filter_chain.filter_chain_data->downstream_tls_context =
758
- std::move(*downstream_context);
759
- }
762
+ ValidationErrors::ScopedField field(errors, ".transport_socket");
763
+ filter_chain.filter_chain_data->downstream_tls_context =
764
+ DownstreamTlsContextParse(context, transport_socket, errors);
760
765
  }
761
766
  // Return result.
762
- if (!errors.empty()) {
763
- return absl::InvalidArgumentError(absl::StrCat(
764
- "Errors parsing FilterChain: [", absl::StrJoin(errors, "; "), "]"));
765
- }
767
+ if (errors->size() != original_error_size) return absl::nullopt;
766
768
  return filter_chain;
767
769
  }
768
770
 
769
- absl::StatusOr<std::string> AddressParse(
770
- const envoy_config_core_v3_Address* address_proto) {
771
+ absl::optional<std::string> AddressParse(
772
+ const envoy_config_core_v3_Address* address_proto,
773
+ ValidationErrors* errors) {
774
+ if (address_proto == nullptr) {
775
+ errors->AddError("field not present");
776
+ return absl::nullopt;
777
+ }
778
+ ValidationErrors::ScopedField field(errors, ".socket_address");
771
779
  const auto* socket_address =
772
780
  envoy_config_core_v3_Address_socket_address(address_proto);
773
781
  if (socket_address == nullptr) {
774
- return absl::InvalidArgumentError("Address does not have socket_address");
775
- }
776
- if (envoy_config_core_v3_SocketAddress_protocol(socket_address) !=
777
- envoy_config_core_v3_SocketAddress_TCP) {
778
- return absl::InvalidArgumentError("SocketAddress protocol is not TCP");
782
+ errors->AddError("field not present");
783
+ return absl::nullopt;
784
+ }
785
+ {
786
+ ValidationErrors::ScopedField field(errors, ".protocol");
787
+ if (envoy_config_core_v3_SocketAddress_protocol(socket_address) !=
788
+ envoy_config_core_v3_SocketAddress_TCP) {
789
+ errors->AddError("value must be TCP");
790
+ }
779
791
  }
792
+ ValidationErrors::ScopedField field2(errors, ".port_value");
780
793
  uint32_t port = envoy_config_core_v3_SocketAddress_port_value(socket_address);
781
794
  if (port > 65535) {
782
- return absl::InvalidArgumentError("Invalid port");
795
+ errors->AddError("invalid port");
796
+ return absl::nullopt;
783
797
  }
784
798
  return JoinHostPort(
785
799
  UpbStringToAbsl(
@@ -803,97 +817,103 @@ struct InternalFilterChainMap {
803
817
  DestinationIpMap destination_ip_map;
804
818
  };
805
819
 
806
- absl::Status AddFilterChainDataForSourcePort(
820
+ void AddFilterChainDataForSourcePort(
807
821
  const FilterChain& filter_chain, uint32_t port,
808
- XdsListenerResource::FilterChainMap::SourcePortsMap* ports_map) {
822
+ XdsListenerResource::FilterChainMap::SourcePortsMap* ports_map,
823
+ ValidationErrors* errors) {
809
824
  auto insert_result = ports_map->emplace(
810
825
  port, XdsListenerResource::FilterChainMap::FilterChainDataSharedPtr{
811
826
  filter_chain.filter_chain_data});
812
827
  if (!insert_result.second) {
813
- return absl::InvalidArgumentError(absl::StrCat(
814
- "Duplicate matching rules detected when adding filter chain: ",
828
+ errors->AddError(absl::StrCat(
829
+ "duplicate matching rules detected when adding filter chain: ",
815
830
  filter_chain.filter_chain_match.ToString()));
816
831
  }
817
- return absl::OkStatus();
818
832
  }
819
833
 
820
- absl::Status AddFilterChainDataForSourcePorts(
834
+ void AddFilterChainDataForSourcePorts(
821
835
  const FilterChain& filter_chain,
822
- XdsListenerResource::FilterChainMap::SourcePortsMap* ports_map) {
836
+ XdsListenerResource::FilterChainMap::SourcePortsMap* ports_map,
837
+ ValidationErrors* errors) {
823
838
  if (filter_chain.filter_chain_match.source_ports.empty()) {
824
- return AddFilterChainDataForSourcePort(filter_chain, 0, ports_map);
839
+ AddFilterChainDataForSourcePort(filter_chain, 0, ports_map, errors);
825
840
  } else {
826
841
  for (uint32_t port : filter_chain.filter_chain_match.source_ports) {
827
- absl::Status status =
828
- AddFilterChainDataForSourcePort(filter_chain, port, ports_map);
829
- if (!status.ok()) return status;
842
+ AddFilterChainDataForSourcePort(filter_chain, port, ports_map, errors);
830
843
  }
831
844
  }
832
- return absl::OkStatus();
833
845
  }
834
846
 
835
- absl::Status AddFilterChainDataForSourceIpRange(
847
+ void AddFilterChainDataForSourceIpRange(
836
848
  const FilterChain& filter_chain,
837
- InternalFilterChainMap::SourceIpMap* source_ip_map) {
849
+ InternalFilterChainMap::SourceIpMap* source_ip_map,
850
+ ValidationErrors* errors) {
838
851
  if (filter_chain.filter_chain_match.source_prefix_ranges.empty()) {
839
852
  auto insert_result = source_ip_map->emplace(
840
853
  "", XdsListenerResource::FilterChainMap::SourceIp());
841
- return AddFilterChainDataForSourcePorts(
842
- filter_chain, &insert_result.first->second.ports_map);
854
+ AddFilterChainDataForSourcePorts(
855
+ filter_chain, &insert_result.first->second.ports_map, errors);
843
856
  } else {
844
857
  for (const auto& prefix_range :
845
858
  filter_chain.filter_chain_match.source_prefix_ranges) {
846
859
  auto addr_str = grpc_sockaddr_to_string(&prefix_range.address, false);
847
- if (!addr_str.ok()) return addr_str.status();
860
+ if (!addr_str.ok()) {
861
+ errors->AddError(absl::StrCat(
862
+ "error parsing source IP sockaddr (should not happen): ",
863
+ addr_str.status().message()));
864
+ continue;
865
+ }
848
866
  auto insert_result = source_ip_map->emplace(
849
867
  absl::StrCat(*addr_str, "/", prefix_range.prefix_len),
850
868
  XdsListenerResource::FilterChainMap::SourceIp());
851
869
  if (insert_result.second) {
852
870
  insert_result.first->second.prefix_range.emplace(prefix_range);
853
871
  }
854
- absl::Status status = AddFilterChainDataForSourcePorts(
855
- filter_chain, &insert_result.first->second.ports_map);
856
- if (!status.ok()) return status;
872
+ AddFilterChainDataForSourcePorts(
873
+ filter_chain, &insert_result.first->second.ports_map, errors);
857
874
  }
858
875
  }
859
- return absl::OkStatus();
860
876
  }
861
877
 
862
- absl::Status AddFilterChainDataForSourceType(
878
+ void AddFilterChainDataForSourceType(
863
879
  const FilterChain& filter_chain,
864
- InternalFilterChainMap::DestinationIp* destination_ip) {
880
+ InternalFilterChainMap::DestinationIp* destination_ip,
881
+ ValidationErrors* errors) {
865
882
  GPR_ASSERT(static_cast<unsigned int>(
866
883
  filter_chain.filter_chain_match.source_type) < 3);
867
- return AddFilterChainDataForSourceIpRange(
868
- filter_chain, &destination_ip->source_types_array[static_cast<int>(
869
- filter_chain.filter_chain_match.source_type)]);
884
+ AddFilterChainDataForSourceIpRange(
885
+ filter_chain,
886
+ &destination_ip->source_types_array[static_cast<int>(
887
+ filter_chain.filter_chain_match.source_type)],
888
+ errors);
870
889
  }
871
890
 
872
- absl::Status AddFilterChainDataForApplicationProtocols(
891
+ void AddFilterChainDataForApplicationProtocols(
873
892
  const FilterChain& filter_chain,
874
- InternalFilterChainMap::DestinationIp* destination_ip) {
893
+ InternalFilterChainMap::DestinationIp* destination_ip,
894
+ ValidationErrors* errors) {
875
895
  // Only allow filter chains that do not mention application protocols
876
- if (!filter_chain.filter_chain_match.application_protocols.empty()) {
877
- return absl::OkStatus();
896
+ if (filter_chain.filter_chain_match.application_protocols.empty()) {
897
+ AddFilterChainDataForSourceType(filter_chain, destination_ip, errors);
878
898
  }
879
- return AddFilterChainDataForSourceType(filter_chain, destination_ip);
880
899
  }
881
900
 
882
- absl::Status AddFilterChainDataForTransportProtocol(
901
+ void AddFilterChainDataForTransportProtocol(
883
902
  const FilterChain& filter_chain,
884
- InternalFilterChainMap::DestinationIp* destination_ip) {
903
+ InternalFilterChainMap::DestinationIp* destination_ip,
904
+ ValidationErrors* errors) {
885
905
  const std::string& transport_protocol =
886
906
  filter_chain.filter_chain_match.transport_protocol;
887
907
  // Only allow filter chains with no transport protocol or "raw_buffer"
888
908
  if (!transport_protocol.empty() && transport_protocol != "raw_buffer") {
889
- return absl::OkStatus();
909
+ return;
890
910
  }
891
911
  // If for this configuration, we've already seen filter chains that mention
892
912
  // the transport protocol as "raw_buffer", we will never match filter chains
893
913
  // that do not mention it.
894
914
  if (destination_ip->transport_protocol_raw_buffer_provided &&
895
915
  transport_protocol.empty()) {
896
- return absl::OkStatus();
916
+ return;
897
917
  }
898
918
  if (!transport_protocol.empty() &&
899
919
  !destination_ip->transport_protocol_raw_buffer_provided) {
@@ -903,45 +923,50 @@ absl::Status AddFilterChainDataForTransportProtocol(
903
923
  destination_ip->source_types_array =
904
924
  InternalFilterChainMap::ConnectionSourceTypesArray();
905
925
  }
906
- return AddFilterChainDataForApplicationProtocols(filter_chain,
907
- destination_ip);
926
+ AddFilterChainDataForApplicationProtocols(filter_chain, destination_ip,
927
+ errors);
908
928
  }
909
929
 
910
- absl::Status AddFilterChainDataForServerNames(
930
+ void AddFilterChainDataForServerNames(
911
931
  const FilterChain& filter_chain,
912
- InternalFilterChainMap::DestinationIp* destination_ip) {
932
+ InternalFilterChainMap::DestinationIp* destination_ip,
933
+ ValidationErrors* errors) {
913
934
  // Don't continue adding filter chains with server names mentioned
914
- if (!filter_chain.filter_chain_match.server_names.empty()) {
915
- return absl::OkStatus();
935
+ if (filter_chain.filter_chain_match.server_names.empty()) {
936
+ AddFilterChainDataForTransportProtocol(filter_chain, destination_ip,
937
+ errors);
916
938
  }
917
- return AddFilterChainDataForTransportProtocol(filter_chain, destination_ip);
918
939
  }
919
940
 
920
- absl::Status AddFilterChainDataForDestinationIpRange(
941
+ void AddFilterChainDataForDestinationIpRange(
921
942
  const FilterChain& filter_chain,
922
- InternalFilterChainMap::DestinationIpMap* destination_ip_map) {
943
+ InternalFilterChainMap::DestinationIpMap* destination_ip_map,
944
+ ValidationErrors* errors) {
923
945
  if (filter_chain.filter_chain_match.prefix_ranges.empty()) {
924
946
  auto insert_result = destination_ip_map->emplace(
925
947
  "", InternalFilterChainMap::DestinationIp());
926
- return AddFilterChainDataForServerNames(filter_chain,
927
- &insert_result.first->second);
948
+ AddFilterChainDataForServerNames(filter_chain, &insert_result.first->second,
949
+ errors);
928
950
  } else {
929
951
  for (const auto& prefix_range :
930
952
  filter_chain.filter_chain_match.prefix_ranges) {
931
953
  auto addr_str = grpc_sockaddr_to_string(&prefix_range.address, false);
932
- if (!addr_str.ok()) return addr_str.status();
954
+ if (!addr_str.ok()) {
955
+ errors->AddError(absl::StrCat(
956
+ "error parsing destination IP sockaddr (should not happen): ",
957
+ addr_str.status().message()));
958
+ continue;
959
+ }
933
960
  auto insert_result = destination_ip_map->emplace(
934
961
  absl::StrCat(*addr_str, "/", prefix_range.prefix_len),
935
962
  InternalFilterChainMap::DestinationIp());
936
963
  if (insert_result.second) {
937
964
  insert_result.first->second.prefix_range.emplace(prefix_range);
938
965
  }
939
- absl::Status status = AddFilterChainDataForServerNames(
940
- filter_chain, &insert_result.first->second);
941
- if (!status.ok()) return status;
966
+ AddFilterChainDataForServerNames(filter_chain,
967
+ &insert_result.first->second, errors);
942
968
  }
943
969
  }
944
- return absl::OkStatus();
945
970
  }
946
971
 
947
972
  XdsListenerResource::FilterChainMap BuildFromInternalFilterChainMap(
@@ -963,68 +988,86 @@ XdsListenerResource::FilterChainMap BuildFromInternalFilterChainMap(
963
988
  return filter_chain_map;
964
989
  }
965
990
 
966
- absl::StatusOr<XdsListenerResource::FilterChainMap> BuildFilterChainMap(
967
- const std::vector<FilterChain>& filter_chains) {
991
+ XdsListenerResource::FilterChainMap BuildFilterChainMap(
992
+ const std::vector<FilterChain>& filter_chains, ValidationErrors* errors) {
968
993
  InternalFilterChainMap internal_filter_chain_map;
969
994
  for (const auto& filter_chain : filter_chains) {
970
995
  // Discard filter chain entries that specify destination port
971
996
  if (filter_chain.filter_chain_match.destination_port != 0) continue;
972
- absl::Status status = AddFilterChainDataForDestinationIpRange(
973
- filter_chain, &internal_filter_chain_map.destination_ip_map);
974
- if (!status.ok()) return status;
997
+ AddFilterChainDataForDestinationIpRange(
998
+ filter_chain, &internal_filter_chain_map.destination_ip_map, errors);
975
999
  }
976
1000
  return BuildFromInternalFilterChainMap(&internal_filter_chain_map);
977
1001
  }
978
1002
 
979
1003
  absl::StatusOr<XdsListenerResource> LdsResourceParseServer(
980
1004
  const XdsResourceType::DecodeContext& context,
981
- const envoy_config_listener_v3_Listener* listener, bool is_v2) {
982
- XdsListenerResource lds_update;
983
- lds_update.type = XdsListenerResource::ListenerType::kTcpListener;
984
- auto address =
985
- AddressParse(envoy_config_listener_v3_Listener_address(listener));
986
- if (!address.ok()) return address.status();
987
- lds_update.address = std::move(*address);
988
- const auto* use_original_dst =
989
- envoy_config_listener_v3_Listener_use_original_dst(listener);
990
- if (use_original_dst != nullptr) {
991
- if (google_protobuf_BoolValue_value(use_original_dst)) {
992
- return absl::InvalidArgumentError(
993
- "Field \'use_original_dst\' is not supported.");
1005
+ const envoy_config_listener_v3_Listener* listener) {
1006
+ ValidationErrors errors;
1007
+ XdsListenerResource::TcpListener tcp_listener;
1008
+ // address
1009
+ {
1010
+ ValidationErrors::ScopedField field(&errors, "address");
1011
+ auto address = AddressParse(
1012
+ envoy_config_listener_v3_Listener_address(listener), &errors);
1013
+ if (address.has_value()) tcp_listener.address = std::move(*address);
1014
+ }
1015
+ // use_original_dst
1016
+ {
1017
+ ValidationErrors::ScopedField field(&errors, "use_original_dst");
1018
+ const auto* use_original_dst =
1019
+ envoy_config_listener_v3_Listener_use_original_dst(listener);
1020
+ if (use_original_dst != nullptr &&
1021
+ google_protobuf_BoolValue_value(use_original_dst)) {
1022
+ errors.AddError("field not supported");
994
1023
  }
995
1024
  }
996
- size_t size = 0;
997
- auto* filter_chains =
998
- envoy_config_listener_v3_Listener_filter_chains(listener, &size);
999
- std::vector<FilterChain> parsed_filter_chains;
1000
- parsed_filter_chains.reserve(size);
1001
- for (size_t i = 0; i < size; i++) {
1002
- auto filter_chain = FilterChainParse(context, filter_chains[i], is_v2);
1003
- if (!filter_chain.ok()) return filter_chain.status();
1004
- parsed_filter_chains.push_back(std::move(*filter_chain));
1005
- }
1006
- auto filter_chain_map = BuildFilterChainMap(parsed_filter_chains);
1007
- if (!filter_chain_map.ok()) return filter_chain_map.status();
1008
- lds_update.filter_chain_map = std::move(*filter_chain_map);
1009
- auto* default_filter_chain =
1010
- envoy_config_listener_v3_Listener_default_filter_chain(listener);
1011
- if (default_filter_chain != nullptr) {
1012
- auto filter_chain = FilterChainParse(context, default_filter_chain, is_v2);
1013
- if (!filter_chain.ok()) return filter_chain.status();
1014
- if (filter_chain->filter_chain_data != nullptr) {
1015
- lds_update.default_filter_chain =
1016
- std::move(*filter_chain->filter_chain_data);
1025
+ // filter_chains
1026
+ size_t num_filter_chains = 0;
1027
+ {
1028
+ ValidationErrors::ScopedField field(&errors, "filter_chains");
1029
+ auto* filter_chains = envoy_config_listener_v3_Listener_filter_chains(
1030
+ listener, &num_filter_chains);
1031
+ std::vector<FilterChain> parsed_filter_chains;
1032
+ parsed_filter_chains.reserve(num_filter_chains);
1033
+ for (size_t i = 0; i < num_filter_chains; i++) {
1034
+ ValidationErrors::ScopedField field(&errors, absl::StrCat("[", i, "]"));
1035
+ auto filter_chain = FilterChainParse(context, filter_chains[i], &errors);
1036
+ if (filter_chain.has_value()) {
1037
+ parsed_filter_chains.push_back(std::move(*filter_chain));
1038
+ }
1039
+ }
1040
+ tcp_listener.filter_chain_map =
1041
+ BuildFilterChainMap(parsed_filter_chains, &errors);
1042
+ }
1043
+ // default_filter_chain
1044
+ {
1045
+ ValidationErrors::ScopedField field(&errors, "default_filter_chain");
1046
+ auto* default_filter_chain =
1047
+ envoy_config_listener_v3_Listener_default_filter_chain(listener);
1048
+ if (default_filter_chain != nullptr) {
1049
+ auto filter_chain =
1050
+ FilterChainParse(context, default_filter_chain, &errors);
1051
+ if (filter_chain.has_value() &&
1052
+ filter_chain->filter_chain_data != nullptr) {
1053
+ tcp_listener.default_filter_chain =
1054
+ std::move(*filter_chain->filter_chain_data);
1055
+ }
1056
+ } else if (num_filter_chains == 0) {
1057
+ // Make sure that there is at least one filter chain to use.
1058
+ errors.AddError("must be set if filter_chains is unset");
1017
1059
  }
1018
1060
  }
1019
- if (size == 0 && default_filter_chain == nullptr) {
1020
- return absl::InvalidArgumentError("No filter chain provided.");
1021
- }
1061
+ // Return result.
1062
+ if (!errors.ok()) return errors.status("errors validating server Listener");
1063
+ XdsListenerResource lds_update;
1064
+ lds_update.listener = std::move(tcp_listener);
1022
1065
  return lds_update;
1023
1066
  }
1024
1067
 
1025
1068
  absl::StatusOr<XdsListenerResource> LdsResourceParse(
1026
1069
  const XdsResourceType::DecodeContext& context,
1027
- const envoy_config_listener_v3_Listener* listener, bool is_v2) {
1070
+ const envoy_config_listener_v3_Listener* listener) {
1028
1071
  // Check whether it's a client or server listener.
1029
1072
  const envoy_config_listener_v3_ApiListener* api_listener =
1030
1073
  envoy_config_listener_v3_Listener_api_listener(listener);
@@ -1043,9 +1086,9 @@ absl::StatusOr<XdsListenerResource> LdsResourceParse(
1043
1086
  // If api_listener is present, it's for a client; otherwise, it's
1044
1087
  // for a server.
1045
1088
  if (api_listener != nullptr) {
1046
- return LdsResourceParseClient(context, api_listener, is_v2);
1089
+ return LdsResourceParseClient(context, api_listener);
1047
1090
  }
1048
- return LdsResourceParseServer(context, listener, is_v2);
1091
+ return LdsResourceParseServer(context, listener);
1049
1092
  }
1050
1093
 
1051
1094
  void MaybeLogListener(const XdsResourceType::DecodeContext& context,
@@ -1064,7 +1107,7 @@ void MaybeLogListener(const XdsResourceType::DecodeContext& context,
1064
1107
 
1065
1108
  XdsResourceType::DecodeResult XdsListenerResourceType::Decode(
1066
1109
  const XdsResourceType::DecodeContext& context,
1067
- absl::string_view serialized_resource, bool is_v2) const {
1110
+ absl::string_view serialized_resource) const {
1068
1111
  DecodeResult result;
1069
1112
  // Parse serialized proto.
1070
1113
  auto* resource = envoy_config_listener_v3_Listener_parse(
@@ -1078,7 +1121,7 @@ XdsResourceType::DecodeResult XdsListenerResourceType::Decode(
1078
1121
  // Validate resource.
1079
1122
  result.name =
1080
1123
  UpbStringToStdString(envoy_config_listener_v3_Listener_name(resource));
1081
- auto listener = LdsResourceParse(context, resource, is_v2);
1124
+ auto listener = LdsResourceParse(context, resource);
1082
1125
  if (!listener.ok()) {
1083
1126
  if (GRPC_TRACE_FLAG_ENABLED(*context.tracer)) {
1084
1127
  gpr_log(GPR_ERROR, "[xds_client %p] invalid Listener %s: %s",
@@ -1092,9 +1135,8 @@ XdsResourceType::DecodeResult XdsListenerResourceType::Decode(
1092
1135
  context.client, result.name->c_str(),
1093
1136
  listener->ToString().c_str());
1094
1137
  }
1095
- auto resource = absl::make_unique<ResourceDataSubclass>();
1096
- resource->resource = std::move(*listener);
1097
- result.resource = std::move(resource);
1138
+ result.resource =
1139
+ std::make_unique<XdsListenerResource>(std::move(*listener));
1098
1140
  }
1099
1141
  return result;
1100
1142
  }