grpc 1.73.0 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +38 -17
  3. data/include/grpc/create_channel_from_endpoint.h +54 -0
  4. data/include/grpc/credentials.h +11 -5
  5. data/include/grpc/event_engine/event_engine.h +74 -17
  6. data/include/grpc/grpc_posix.h +20 -1
  7. data/include/grpc/impl/channel_arg_names.h +2 -4
  8. data/include/grpc/module.modulemap +1 -0
  9. data/include/grpc/support/json.h +24 -0
  10. data/src/core/call/interception_chain.h +7 -11
  11. data/src/core/channelz/channel_trace.cc +213 -115
  12. data/src/core/channelz/channel_trace.h +380 -86
  13. data/src/core/channelz/channelz.cc +270 -181
  14. data/src/core/channelz/channelz.h +168 -55
  15. data/src/core/channelz/channelz_registry.cc +2 -1
  16. data/src/core/channelz/channelz_registry.h +24 -0
  17. data/src/core/channelz/property_list.cc +357 -0
  18. data/src/core/channelz/property_list.h +202 -0
  19. data/src/core/channelz/ztrace_collector.h +3 -2
  20. data/src/core/client_channel/backup_poller.cc +17 -2
  21. data/src/core/client_channel/client_channel.cc +17 -28
  22. data/src/core/client_channel/client_channel_filter.cc +19 -29
  23. data/src/core/client_channel/config_selector.h +8 -2
  24. data/src/core/client_channel/dynamic_filters.cc +5 -6
  25. data/src/core/client_channel/dynamic_filters.h +1 -1
  26. data/src/core/client_channel/global_subchannel_pool.cc +4 -1
  27. data/src/core/client_channel/retry_filter.cc +21 -27
  28. data/src/core/client_channel/retry_filter.h +10 -7
  29. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
  30. data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
  31. data/src/core/client_channel/retry_interceptor.cc +30 -44
  32. data/src/core/client_channel/retry_interceptor.h +18 -17
  33. data/src/core/client_channel/retry_throttle.cc +46 -61
  34. data/src/core/client_channel/retry_throttle.h +17 -39
  35. data/src/core/client_channel/subchannel.cc +43 -19
  36. data/src/core/client_channel/subchannel.h +8 -0
  37. data/src/core/config/config_vars.cc +2 -0
  38. data/src/core/config/core_configuration.cc +1 -0
  39. data/src/core/config/core_configuration.h +11 -0
  40. data/src/core/credentials/call/call_creds_registry.h +125 -0
  41. data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
  42. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
  43. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
  44. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
  45. data/src/core/credentials/call/jwt_util.cc +70 -0
  46. data/src/core/credentials/call/jwt_util.h +32 -0
  47. data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
  48. data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
  49. data/src/core/credentials/transport/ssl/ssl_credentials.cc +0 -1
  50. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
  51. data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
  52. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
  53. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
  54. data/src/core/ext/filters/http/client_authority_filter.cc +2 -4
  55. data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
  56. data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
  57. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
  58. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
  59. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +162 -115
  60. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
  61. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
  62. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
  63. data/src/core/ext/transport/chttp2/transport/flow_control.h +22 -17
  64. data/src/core/ext/transport/chttp2/transport/frame.cc +10 -0
  65. data/src/core/ext/transport/chttp2/transport/frame.h +2 -2
  66. data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
  67. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
  69. data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
  71. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
  72. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
  73. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
  74. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
  75. data/src/core/ext/transport/chttp2/transport/http2_settings.h +19 -22
  76. data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
  77. data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
  78. data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
  79. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
  80. data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
  81. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
  82. data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
  83. data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
  84. data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
  85. data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
  86. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -4
  87. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
  88. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
  89. data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
  90. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
  91. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
  93. data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
  94. data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
  95. data/src/core/ext/transport/chttp2/transport/writing.cc +37 -11
  96. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
  97. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
  98. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
  99. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
  100. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
  101. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
  102. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
  103. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
  104. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
  105. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
  106. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
  107. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
  108. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
  109. data/src/core/filter/auth/auth_filters.h +0 -25
  110. data/src/core/filter/auth/client_auth_filter.cc +0 -118
  111. data/src/core/filter/filter_args.h +9 -23
  112. data/src/core/handshaker/handshaker.cc +23 -14
  113. data/src/core/handshaker/handshaker.h +3 -0
  114. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
  115. data/src/core/handshaker/security/legacy_secure_endpoint.cc +6 -5
  116. data/src/core/handshaker/security/secure_endpoint.cc +70 -25
  117. data/src/core/handshaker/security/security_handshaker.cc +4 -1
  118. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
  119. data/src/core/lib/channel/channel_args.cc +15 -0
  120. data/src/core/lib/channel/channel_args.h +3 -0
  121. data/src/core/lib/channel/channel_stack.cc +22 -23
  122. data/src/core/lib/channel/channel_stack.h +9 -7
  123. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
  124. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
  125. data/src/core/lib/channel/promise_based_filter.h +5 -5
  126. data/src/core/lib/debug/trace_impl.h +0 -1
  127. data/src/core/lib/event_engine/ares_resolver.cc +165 -46
  128. data/src/core/lib/event_engine/ares_resolver.h +48 -2
  129. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -1
  130. data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
  131. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +2 -6
  132. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
  133. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
  134. data/src/core/lib/event_engine/event_engine.cc +7 -0
  135. data/src/core/lib/event_engine/extensions/channelz.h +10 -6
  136. data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
  137. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
  138. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
  139. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
  140. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
  141. data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
  142. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
  143. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
  144. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
  145. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
  146. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
  147. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
  148. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +145 -92
  149. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
  150. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +333 -116
  151. data/src/core/lib/event_engine/posix_engine/posix_engine.h +61 -18
  152. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
  153. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
  154. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
  155. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
  156. data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
  157. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
  158. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
  159. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
  160. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
  161. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
  162. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
  163. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
  164. data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
  165. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
  166. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
  167. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
  168. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
  169. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
  170. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
  171. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
  172. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
  173. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
  174. data/src/core/lib/event_engine/shim.cc +9 -0
  175. data/src/core/lib/event_engine/shim.h +3 -0
  176. data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
  177. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
  178. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
  179. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
  180. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
  181. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
  182. data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
  183. data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
  184. data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
  185. data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
  186. data/src/core/lib/experiments/experiments.cc +45 -93
  187. data/src/core/lib/experiments/experiments.h +21 -51
  188. data/src/core/lib/iomgr/endpoint.cc +4 -3
  189. data/src/core/lib/iomgr/endpoint.h +7 -4
  190. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
  191. data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
  192. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
  193. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
  194. data/src/core/lib/iomgr/tcp_posix.cc +12 -6
  195. data/src/core/lib/iomgr/tcp_windows.cc +3 -2
  196. data/src/core/lib/promise/activity.h +1 -0
  197. data/src/core/lib/promise/arena_promise.h +23 -7
  198. data/src/core/lib/promise/detail/promise_factory.h +10 -0
  199. data/src/core/lib/promise/detail/promise_like.h +118 -11
  200. data/src/core/lib/promise/detail/promise_variant.h +50 -0
  201. data/src/core/lib/promise/detail/seq_state.h +687 -548
  202. data/src/core/lib/promise/if.h +20 -0
  203. data/src/core/lib/promise/inter_activity_latch.h +147 -0
  204. data/src/core/lib/promise/inter_activity_mutex.h +547 -0
  205. data/src/core/lib/promise/loop.h +65 -3
  206. data/src/core/lib/promise/map.h +24 -0
  207. data/src/core/lib/promise/match_promise.h +103 -0
  208. data/src/core/lib/promise/mpsc.cc +425 -0
  209. data/src/core/lib/promise/mpsc.h +490 -0
  210. data/src/core/lib/promise/party.cc +50 -1
  211. data/src/core/lib/promise/party.h +66 -1
  212. data/src/core/lib/promise/race.h +31 -0
  213. data/src/core/lib/promise/seq.h +4 -1
  214. data/src/core/lib/promise/status_flag.h +7 -0
  215. data/src/core/lib/promise/try_seq.h +4 -1
  216. data/src/core/lib/promise/wait_set.cc +28 -0
  217. data/src/core/lib/promise/wait_set.h +86 -0
  218. data/src/core/lib/resource_quota/arena.h +19 -0
  219. data/src/core/lib/slice/slice.h +5 -0
  220. data/src/core/lib/surface/channel_create.cc +88 -13
  221. data/src/core/lib/surface/channel_create.h +4 -0
  222. data/src/core/lib/surface/channel_init.cc +164 -47
  223. data/src/core/lib/surface/channel_init.h +64 -1
  224. data/src/core/lib/surface/filter_stack_call.cc +18 -9
  225. data/src/core/lib/surface/init.cc +6 -15
  226. data/src/core/lib/surface/legacy_channel.cc +3 -5
  227. data/src/core/lib/surface/legacy_channel.h +3 -1
  228. data/src/core/lib/surface/version.cc +2 -2
  229. data/src/core/lib/transport/promise_endpoint.cc +110 -0
  230. data/src/core/lib/transport/promise_endpoint.h +307 -0
  231. data/src/core/load_balancing/child_policy_handler.cc +2 -4
  232. data/src/core/load_balancing/delegating_helper.h +2 -3
  233. data/src/core/load_balancing/health_check_client.cc +1 -5
  234. data/src/core/load_balancing/lb_policy.h +1 -3
  235. data/src/core/load_balancing/oob_backend_metric.cc +1 -5
  236. data/src/core/load_balancing/pick_first/pick_first.cc +3 -0
  237. data/src/core/load_balancing/xds/cds.cc +10 -1
  238. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
  239. data/src/core/resolver/xds/xds_config.cc +6 -3
  240. data/src/core/resolver/xds/xds_config.h +9 -4
  241. data/src/core/resolver/xds/xds_dependency_manager.cc +21 -6
  242. data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
  243. data/src/core/resolver/xds/xds_resolver.cc +31 -11
  244. data/src/core/server/server.cc +83 -12
  245. data/src/core/server/server.h +21 -2
  246. data/src/core/server/xds_server_config_fetcher.cc +63 -25
  247. data/src/core/service_config/service_config.h +1 -1
  248. data/src/core/service_config/service_config_impl.h +1 -1
  249. data/src/core/telemetry/context_list_entry.cc +38 -0
  250. data/src/core/telemetry/context_list_entry.h +42 -12
  251. data/src/core/telemetry/stats_data.cc +233 -207
  252. data/src/core/telemetry/stats_data.h +250 -153
  253. data/src/core/telemetry/tcp_tracer.h +1 -1
  254. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
  255. data/src/core/tsi/fake_transport_security.cc +17 -0
  256. data/src/core/tsi/ssl_transport_security.cc +2 -0
  257. data/src/core/tsi/transport_security_grpc.cc +8 -0
  258. data/src/core/tsi/transport_security_grpc.h +15 -0
  259. data/src/core/util/backoff.cc +1 -5
  260. data/src/core/util/backoff.h +1 -0
  261. data/src/core/util/down_cast.h +1 -1
  262. data/src/core/util/function_signature.h +15 -1
  263. data/src/core/util/http_client/httpcli.cc +12 -5
  264. data/src/core/util/http_client/httpcli.h +4 -1
  265. data/src/core/util/latent_see.h +8 -5
  266. data/src/core/util/log.cc +4 -0
  267. data/src/core/util/memory_usage.h +268 -0
  268. data/src/core/util/per_cpu.cc +2 -0
  269. data/src/core/util/per_cpu.h +7 -0
  270. data/src/core/util/shared_bit_gen.h +20 -0
  271. data/src/core/util/single_set_ptr.h +2 -2
  272. data/src/core/util/upb_utils.h +42 -0
  273. data/src/core/util/uri.cc +3 -2
  274. data/src/core/util/useful.h +53 -2
  275. data/src/core/util/wait_for_single_owner.cc +31 -0
  276. data/src/core/util/wait_for_single_owner.h +24 -0
  277. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
  278. data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
  279. data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
  280. data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
  281. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  282. data/src/core/xds/grpc/xds_http_filter.h +7 -0
  283. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
  284. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
  285. data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
  286. data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
  287. data/src/core/xds/grpc/xds_server_grpc.h +10 -2
  288. data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
  289. data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
  290. data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
  291. data/src/core/xds/xds_client/xds_client.cc +26 -5
  292. data/src/ruby/ext/grpc/extconf.rb +2 -0
  293. data/src/ruby/ext/grpc/rb_call.c +1 -8
  294. data/src/ruby/ext/grpc/rb_channel.c +72 -568
  295. data/src/ruby/ext/grpc/rb_channel.h +0 -3
  296. data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
  297. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
  298. data/src/ruby/ext/grpc/rb_grpc.c +9 -5
  299. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  300. data/src/ruby/ext/grpc/rb_loader.c +0 -4
  301. data/src/ruby/ext/grpc/rb_server.c +31 -50
  302. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
  303. data/src/ruby/lib/grpc/version.rb +1 -1
  304. data/src/ruby/spec/core_spec.rb +22 -0
  305. data/src/ruby/spec/generic/active_call_spec.rb +1 -1
  306. data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
  307. data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
  308. data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
  309. data/third_party/abseil-cpp/absl/base/config.h +20 -129
  310. data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  311. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  312. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  313. data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
  314. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  315. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
  316. data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
  317. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
  318. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
  319. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  320. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
  321. data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
  322. data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
  323. data/third_party/abseil-cpp/absl/base/options.h +3 -80
  324. data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
  325. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  326. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  327. data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
  328. data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
  329. data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
  330. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
  331. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
  332. data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
  333. data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
  334. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
  335. data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
  336. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
  337. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
  338. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
  339. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
  340. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
  341. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
  342. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
  343. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
  344. data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
  345. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  346. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
  347. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
  348. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
  349. data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
  350. data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
  351. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  352. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
  353. data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  354. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  355. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  356. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
  357. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  358. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
  359. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  360. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  361. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  362. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  363. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
  364. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  365. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  366. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
  367. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
  368. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  369. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
  370. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  371. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  372. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
  373. data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
  374. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  375. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
  376. data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
  377. data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
  378. data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
  379. data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
  380. data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
  381. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
  382. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  383. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  384. data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
  385. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
  386. data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
  387. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
  388. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
  389. data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
  390. data/third_party/abseil-cpp/absl/log/check.h +2 -1
  391. data/third_party/abseil-cpp/absl/log/globals.h +4 -5
  392. data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  393. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
  394. data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
  395. data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  396. data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
  397. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
  398. data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
  399. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  400. data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
  401. data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
  402. data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
  403. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  404. data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
  405. data/third_party/abseil-cpp/absl/log/log.h +48 -35
  406. data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
  407. data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
  408. data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
  409. data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
  410. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
  411. data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  412. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
  413. data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
  414. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
  415. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
  416. data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
  417. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
  418. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  419. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
  420. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  421. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  422. data/third_party/abseil-cpp/absl/random/random.h +88 -53
  423. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  424. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
  425. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  426. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
  427. data/third_party/abseil-cpp/absl/status/status.cc +4 -8
  428. data/third_party/abseil-cpp/absl/status/status.h +8 -8
  429. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  430. data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
  431. data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
  432. data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
  433. data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
  434. data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
  435. data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
  436. data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
  437. data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
  438. data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  439. data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  440. data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
  441. data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
  442. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  443. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
  444. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  445. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
  446. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  447. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  448. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  449. data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  450. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  451. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  452. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  453. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  454. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  455. data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
  456. data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
  457. data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
  458. data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
  459. data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
  460. data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
  461. data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
  462. data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
  463. data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
  464. data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
  465. data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
  466. data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
  467. data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  468. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  469. data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  470. data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  471. data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  472. data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  473. data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  474. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
  475. data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
  476. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  477. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
  478. data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
  479. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  480. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
  481. data/third_party/abseil-cpp/absl/time/time.h +20 -15
  482. data/third_party/abseil-cpp/absl/types/optional.h +7 -747
  483. data/third_party/abseil-cpp/absl/types/span.h +13 -11
  484. data/third_party/abseil-cpp/absl/types/variant.h +5 -784
  485. data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
  486. metadata +72 -20
  487. data/src/core/lib/event_engine/forkable.cc +0 -105
  488. data/src/core/lib/event_engine/forkable.h +0 -67
  489. data/src/core/lib/iomgr/python_util.h +0 -46
  490. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  491. data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
  492. data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
  493. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  494. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  495. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  496. data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  497. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  498. data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
  499. data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
@@ -0,0 +1,1083 @@
1
+ // Copyright 2025 The gRPC Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include <grpc/event_engine/event_engine.h>
16
+ #include <grpc/support/port_platform.h>
17
+
18
+ #include "src/core/lib/event_engine/posix_engine/posix_interface.h"
19
+ #include "src/core/lib/iomgr/port.h"
20
+
21
+ #if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
22
+ #include <fcntl.h>
23
+
24
+ #include "src/core/util/strerror.h"
25
+ #endif // defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
26
+
27
+ #ifdef GRPC_POSIX_SOCKET
28
+
29
+ #include <sys/types.h>
30
+
31
+ #include <cerrno>
32
+ #include <cstdint>
33
+ #include <utility>
34
+
35
+ #include "absl/cleanup/cleanup.h"
36
+ #include "absl/log/log.h"
37
+ #include "absl/status/status.h"
38
+ #include "absl/strings/str_cat.h"
39
+ #include "absl/strings/str_replace.h"
40
+ #include "absl/strings/string_view.h"
41
+ #include "src/core/lib/event_engine/posix_engine/file_descriptor_collection.h"
42
+ #include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h"
43
+ #include "src/core/lib/event_engine/tcp_socket_utils.h"
44
+ #include "src/core/util/crash.h" // IWYU pragma: keep
45
+ #include "src/core/util/status_helper.h"
46
+
47
+ #ifdef GRPC_POSIX_SOCKET_UTILS_COMMON
48
+ #include <arpa/inet.h> // IWYU pragma: keep
49
+ #ifdef GRPC_LINUX_TCP_H
50
+ #include <linux/tcp.h>
51
+ #else
52
+ #include <netinet/in.h> // IWYU pragma: keep
53
+ #include <netinet/tcp.h>
54
+ #endif // GRPC_LINUX_TCP_H
55
+ #include <sys/ioctl.h>
56
+ #include <sys/socket.h>
57
+ #include <unistd.h>
58
+ #endif // GRPC_POSIX_SOCKET_UTILS_COMMON
59
+
60
+ #ifdef GRPC_LINUX_EVENTFD
61
+ #include <sys/eventfd.h>
62
+ #endif
63
+
64
+ // File needs to be compilable on all platforms. These macros will produce stubs
65
+ // if specific feature is not available in specific environment
66
+ #ifdef GRPC_LINUX_EPOLL
67
+ #include <sys/epoll.h>
68
+ #endif // GRPC_LINUX_EPOLL
69
+
70
+ #if GPR_LINUX == 1
71
+ // For Linux, it will be detected to support TCP_USER_TIMEOUT
72
+ #ifndef TCP_USER_TIMEOUT
73
+ #define TCP_USER_TIMEOUT 18
74
+ #endif
75
+ #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
76
+ #else
77
+ // For non-Linux, TCP_USER_TIMEOUT will be used if TCP_USER_TIMEOUT is defined.
78
+ #ifdef TCP_USER_TIMEOUT
79
+ #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
80
+ #else
81
+ #define TCP_USER_TIMEOUT 0
82
+ #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT -1
83
+ #endif // TCP_USER_TIMEOUT
84
+ #endif // GPR_LINUX == 1
85
+
86
+ #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
87
+
88
+ #endif // GRPC_POSIX_SOCKET
89
+
90
+ namespace grpc_event_engine::experimental {
91
+
92
+ #if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_POSIX_SOCKET)
93
+ namespace {
94
+
95
+ // Templated Fn to make it easier to compile on all platforms.
96
+ template <typename Fn, typename... Args>
97
+ PosixErrorOr<int64_t> Int64Wrap(bool correct_gen, int fd, const Fn& fn,
98
+ Args&&... args) {
99
+ if (!correct_gen) return PosixError::WrongGeneration();
100
+ auto result = std::invoke(fn, fd, std::forward<Args>(args)...);
101
+ if (result < 0) return PosixError::Error(errno);
102
+ return result;
103
+ }
104
+
105
+ // Set a socket to non blocking mode
106
+ absl::Status SetSocketNonBlocking(int fd, int non_blocking) {
107
+ int oldflags = fcntl(fd, F_GETFL, 0);
108
+ if (oldflags < 0) {
109
+ return absl::Status(absl::StatusCode::kInternal,
110
+ absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
111
+ }
112
+
113
+ if (non_blocking) {
114
+ oldflags |= O_NONBLOCK;
115
+ } else {
116
+ oldflags &= ~O_NONBLOCK;
117
+ }
118
+
119
+ if (fcntl(fd, F_SETFL, oldflags) != 0) {
120
+ return absl::Status(absl::StatusCode::kInternal,
121
+ absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
122
+ }
123
+ return absl::OkStatus();
124
+ }
125
+
126
+ } // namespace
127
+ #endif // defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_POSIX_SOCKET)
128
+
129
+ #ifdef GRPC_POSIX_SOCKET
130
+
131
+ namespace {
132
+
133
+ // This way if constexpr can be used and also macro nesting is not needed
134
+ #ifdef GRPC_LINUX_ERRQUEUE
135
+ constexpr bool kLinuxErrqueue = true;
136
+ #else // GRPC_LINUX_ERRQUEUE
137
+ constexpr bool kLinuxErrqueue = false;
138
+ #endif // GRPC_LINUX_ERRQUEUE
139
+
140
+ // The default values for TCP_USER_TIMEOUT are currently configured to be in
141
+ // line with the default values of KEEPALIVE_TIMEOUT as proposed in
142
+ // https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md
143
+ int kDefaultClientUserTimeoutMs = 20000;
144
+ int kDefaultServerUserTimeoutMs = 20000;
145
+ bool kDefaultClientUserTimeoutEnabled = false;
146
+ bool kDefaultServerUserTimeoutEnabled = true;
147
+
148
+ // Whether the socket supports TCP_USER_TIMEOUT option.
149
+ // (0: don't know, 1: support, -1: not support)
150
+ std::atomic<int> g_socket_supports_tcp_user_timeout(
151
+ SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT);
152
+
153
+ absl::Status ErrorForFd(
154
+ int fd, const experimental::EventEngine::ResolvedAddress& addr) {
155
+ if (fd >= 0) return absl::OkStatus();
156
+ const char* addr_str = reinterpret_cast<const char*>(addr.address());
157
+ return absl::Status(absl::StatusCode::kInternal,
158
+ absl::StrCat("socket: ", grpc_core::StrError(errno),
159
+ std::string(addr_str, addr.size())));
160
+ }
161
+
162
+ int CreateSocket(std::function<int(int, int, int)> socket_factory, int family,
163
+ int type, int protocol) {
164
+ int res = socket_factory != nullptr ? socket_factory(family, type, protocol)
165
+ : socket(family, type, protocol);
166
+ if (res < 0 && errno == EMFILE) {
167
+ int saved_errno = errno;
168
+ LOG_EVERY_N_SEC(ERROR, 10)
169
+ << "socket(" << family << ", " << type << ", " << protocol
170
+ << ") returned " << res << " with error: |"
171
+ << grpc_core::StrError(errno)
172
+ << "|. This process might not have a sufficient file descriptor limit "
173
+ "for the number of connections grpc wants to open (which is "
174
+ "generally a function of the number of grpc channels, the lb policy "
175
+ "of each channel, and the number of backends each channel is load "
176
+ "balancing across).";
177
+ errno = saved_errno;
178
+ }
179
+ return res;
180
+ }
181
+
182
+ // Tries to set the socket's receive buffer to given size.
183
+ absl::Status SetSocketRcvBuf(int fd, int buffer_size_bytes) {
184
+ return 0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size_bytes,
185
+ sizeof(buffer_size_bytes))
186
+ ? absl::OkStatus()
187
+ : absl::Status(absl::StatusCode::kInternal,
188
+ absl::StrCat("setsockopt(SO_RCVBUF): ",
189
+ grpc_core::StrError(errno)));
190
+ }
191
+
192
+ // get max listen queue size on linux
193
+ int InitMaxAcceptQueueSize() {
194
+ int n = SOMAXCONN;
195
+ char buf[64];
196
+ FILE* fp = fopen("/proc/sys/net/core/somaxconn", "r");
197
+ int max_accept_queue_size;
198
+ if (fp == nullptr) {
199
+ // 2.4 kernel.
200
+ return SOMAXCONN;
201
+ }
202
+ if (fgets(buf, sizeof buf, fp)) {
203
+ char* end;
204
+ long i = strtol(buf, &end, 10);
205
+ if (i > 0 && i <= INT_MAX && end && *end == '\n') {
206
+ n = static_cast<int>(i);
207
+ }
208
+ }
209
+ fclose(fp);
210
+ max_accept_queue_size = n;
211
+
212
+ if (max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
213
+ LOG(INFO) << "Suspiciously small accept queue (" << max_accept_queue_size
214
+ << ") will probably lead to connection drops";
215
+ }
216
+ return max_accept_queue_size;
217
+ }
218
+
219
+ int GetMaxAcceptQueueSize() {
220
+ static const int kMaxAcceptQueueSize = InitMaxAcceptQueueSize();
221
+ return kMaxAcceptQueueSize;
222
+ }
223
+
224
+ // Set a socket to close on exec
225
+ absl::Status SetSocketCloexec(int fd, int close_on_exec) {
226
+ int oldflags = fcntl(fd, F_GETFD, 0);
227
+ if (oldflags < 0) {
228
+ return absl::Status(absl::StatusCode::kInternal,
229
+ absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
230
+ }
231
+
232
+ if (close_on_exec) {
233
+ oldflags |= FD_CLOEXEC;
234
+ } else {
235
+ oldflags &= ~FD_CLOEXEC;
236
+ }
237
+
238
+ if (fcntl(fd, F_SETFD, oldflags) != 0) {
239
+ return absl::Status(absl::StatusCode::kInternal,
240
+ absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
241
+ }
242
+
243
+ return absl::OkStatus();
244
+ }
245
+
246
+ // set a socket to reuse old addresses
247
+ absl::Status SetSocketOption(int fd, int level, int option, int value,
248
+ absl::string_view debug_label) {
249
+ int val = (value != 0);
250
+ int newval;
251
+ socklen_t intlen = sizeof(newval);
252
+ if (0 != setsockopt(fd, level, option, &val, sizeof(val))) {
253
+ return absl::Status(absl::StatusCode::kInternal,
254
+ absl::StrCat("setsockopt(", debug_label,
255
+ "): ", grpc_core::StrError(errno)));
256
+ }
257
+ if (0 != getsockopt(fd, level, option, &newval, &intlen)) {
258
+ return absl::Status(absl::StatusCode::kInternal,
259
+ absl::StrCat("setsockopt(", debug_label,
260
+ "): ", grpc_core::StrError(errno)));
261
+ }
262
+ if ((newval != 0) != val) {
263
+ return absl::Status(absl::StatusCode::kInternal,
264
+ absl::StrCat("Failed to set ", debug_label));
265
+ }
266
+
267
+ return absl::OkStatus();
268
+ }
269
+
270
+ // set a socket to reuse old ports
271
+ absl::Status SetSocketReusePort(int fd, GRPC_UNUSED int reuse) {
272
+ #ifndef SO_REUSEPORT
273
+ return absl::Status(absl::StatusCode::kInternal,
274
+ "SO_REUSEPORT unavailable on compiling system");
275
+ #else
276
+ return SetSocketOption(fd, SOL_SOCKET, SO_REUSEPORT, 1, "SO_REUSEPORT");
277
+ #endif
278
+ }
279
+
280
+ // Set Differentiated Services Code Point (DSCP)
281
+ absl::Status SetSocketDscp(int fdesc, int dscp) {
282
+ if (dscp == PosixTcpOptions::kDscpNotSet) {
283
+ return absl::OkStatus();
284
+ }
285
+ // The TOS/TrafficClass byte consists of following bits:
286
+ // | 7 6 5 4 3 2 | 1 0 |
287
+ // | DSCP | ECN |
288
+ int newval = dscp << 2;
289
+ int val;
290
+ socklen_t intlen = sizeof(val);
291
+ // Get ECN bits from current IP_TOS value unless IPv6 only
292
+ if (0 == getsockopt(fdesc, IPPROTO_IP, IP_TOS, &val, &intlen)) {
293
+ newval |= (val & 0x3);
294
+ if (0 != setsockopt(fdesc, IPPROTO_IP, IP_TOS, &newval, sizeof(newval))) {
295
+ return absl::Status(
296
+ absl::StatusCode::kInternal,
297
+ absl::StrCat("setsockopt(IP_TOS): ", grpc_core::StrError(errno)));
298
+ }
299
+ }
300
+ // Get ECN from current Traffic Class value if IPv6 is available
301
+ if (0 == getsockopt(fdesc, IPPROTO_IPV6, IPV6_TCLASS, &val, &intlen)) {
302
+ newval |= (val & 0x3);
303
+ if (0 !=
304
+ setsockopt(fdesc, IPPROTO_IPV6, IPV6_TCLASS, &newval, sizeof(newval))) {
305
+ return absl::Status(absl::StatusCode::kInternal,
306
+ absl::StrCat("setsockopt(IPV6_TCLASS): ",
307
+ grpc_core::StrError(errno)));
308
+ }
309
+ }
310
+ return absl::OkStatus();
311
+ }
312
+
313
+ // Set a socket to use zerocopy
314
+ absl::Status SetSocketZeroCopy(int fd) {
315
+ #ifdef GRPC_LINUX_ERRQUEUE
316
+ return SetSocketOption(fd, SOL_SOCKET, SO_ZEROCOPY, 1, "SO_ZEROCOPY");
317
+ #else // GRPC_LINUX_ERRQUEUE
318
+ return absl::Status(absl::StatusCode::kInternal,
319
+ absl::StrCat("setsockopt(SO_ZEROCOPY): ",
320
+ grpc_core::StrError(ENOSYS).c_str()));
321
+ #endif // GRPC_LINUX_ERRQUEUE
322
+ }
323
+
324
+ // Set TCP_USER_TIMEOUT
325
+ void TrySetSocketTcpUserTimeout(int fd, const PosixTcpOptions& options,
326
+ bool is_client) {
327
+ if (g_socket_supports_tcp_user_timeout.load() < 0) {
328
+ return;
329
+ }
330
+ bool enable = is_client ? kDefaultClientUserTimeoutEnabled
331
+ : kDefaultServerUserTimeoutEnabled;
332
+ int timeout =
333
+ is_client ? kDefaultClientUserTimeoutMs : kDefaultServerUserTimeoutMs;
334
+ if (options.keep_alive_time_ms > 0) {
335
+ enable = options.keep_alive_time_ms != INT_MAX;
336
+ }
337
+ if (options.keep_alive_timeout_ms > 0) {
338
+ timeout = options.keep_alive_timeout_ms;
339
+ }
340
+ if (enable) {
341
+ int newval;
342
+ socklen_t len = sizeof(newval);
343
+ // If this is the first time to use TCP_USER_TIMEOUT, try to check
344
+ // if it is available.
345
+ if (g_socket_supports_tcp_user_timeout.load() == 0) {
346
+ if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
347
+ // This log is intentionally not protected behind a flag, so that
348
+ // users know that TCP_USER_TIMEOUT is not being used.
349
+ GRPC_TRACE_LOG(tcp, INFO)
350
+ << "TCP_USER_TIMEOUT is not available. TCP_USER_TIMEOUT "
351
+ "won't be used thereafter";
352
+ g_socket_supports_tcp_user_timeout.store(-1);
353
+ } else {
354
+ GRPC_TRACE_LOG(tcp, INFO)
355
+ << "TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be "
356
+ "used thereafter";
357
+ g_socket_supports_tcp_user_timeout.store(1);
358
+ }
359
+ }
360
+ if (g_socket_supports_tcp_user_timeout.load() > 0) {
361
+ if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
362
+ sizeof(timeout))) {
363
+ LOG(ERROR) << "setsockopt(TCP_USER_TIMEOUT) "
364
+ << grpc_core::StrError(errno);
365
+ return;
366
+ }
367
+ if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
368
+ LOG(ERROR) << "getsockopt(TCP_USER_TIMEOUT) "
369
+ << grpc_core::StrError(errno);
370
+ return;
371
+ }
372
+ if (newval != timeout) {
373
+ // Do not fail on failing to set TCP_USER_TIMEOUT
374
+ LOG(ERROR) << "Failed to set TCP_USER_TIMEOUT";
375
+ return;
376
+ }
377
+ }
378
+ }
379
+ }
380
+
381
+ absl::StatusOr<int> InternalCreateDualStackSocket(
382
+ std::function<int(int, int, int)> socket_factory,
383
+ const experimental::EventEngine::ResolvedAddress& addr, int type,
384
+ int protocol, EventEnginePosixInterface::DSMode& dsmode) {
385
+ const sockaddr* sock_addr = addr.address();
386
+ int family = sock_addr->sa_family;
387
+ int newfd;
388
+ if (family == AF_INET6) {
389
+ if (IsIpv6LoopbackAvailable()) {
390
+ newfd = CreateSocket(socket_factory, family, type, protocol);
391
+ } else {
392
+ newfd = -1;
393
+ errno = EAFNOSUPPORT;
394
+ }
395
+ // Check if we've got a valid dualstack socket.
396
+ if (newfd > 0 && SetSocketDualStack(newfd)) {
397
+ dsmode = EventEnginePosixInterface::DSMode::DSMODE_DUALSTACK;
398
+ return newfd;
399
+ }
400
+ // If this isn't an IPv4 address, then return whatever we've
401
+ // got.
402
+ if (!ResolvedAddressIsV4Mapped(addr, nullptr)) {
403
+ if (newfd < 0) {
404
+ return ErrorForFd(newfd, addr);
405
+ }
406
+ dsmode = EventEnginePosixInterface::DSMode::DSMODE_IPV6;
407
+ return newfd;
408
+ }
409
+ // Fall back to AF_INET.
410
+ if (newfd >= 0) {
411
+ close(newfd);
412
+ }
413
+ family = AF_INET;
414
+ }
415
+ dsmode = family == AF_INET ? EventEnginePosixInterface::DSMode::DSMODE_IPV4
416
+ : EventEnginePosixInterface::DSMode::DSMODE_NONE;
417
+ newfd = CreateSocket(socket_factory, family, type, protocol);
418
+ if (newfd < 0) {
419
+ return ErrorForFd(newfd, addr);
420
+ }
421
+ return newfd;
422
+ }
423
+
424
+ absl::Status InternalSetSocketNoSigpipeIfPossible(GRPC_UNUSED int fd) {
425
+ #ifdef GRPC_HAVE_SO_NOSIGPIPE
426
+ return SetSocketOption(fd, SOL_SOCKET, SO_NOSIGPIPE, 1, "SO_NOSIGPIPE");
427
+ #else // GRPC_HAVE_SO_NOSIGPIPE
428
+ return absl::OkStatus();
429
+ #endif // GRPC_HAVE_SO_NOSIGPIPE
430
+ }
431
+
432
+ absl::Status InternalApplySocketMutatorInOptions(
433
+ int fd, grpc_fd_usage usage, const PosixTcpOptions& options) {
434
+ if (options.socket_mutator == nullptr) {
435
+ return absl::OkStatus();
436
+ }
437
+ if (!grpc_socket_mutator_mutate_fd(options.socket_mutator, fd, usage)) {
438
+ return absl::Status(absl::StatusCode::kInternal,
439
+ "grpc_socket_mutator failed.");
440
+ }
441
+ return absl::OkStatus();
442
+ }
443
+
444
+ } // namespace
445
+
446
+ bool IsSocketReusePortSupported() {
447
+ static bool kSupportSoReusePort = []() -> bool {
448
+ EventEnginePosixInterface posix_interface;
449
+ auto s = posix_interface.Socket(AF_INET, SOCK_STREAM, 0);
450
+ if (!s.ok()) {
451
+ // This might be an ipv6-only environment in which case
452
+ // 'socket(AF_INET,..)' call would fail. Try creating IPv6 socket in
453
+ // that case
454
+ s = posix_interface.Socket(AF_INET6, SOCK_STREAM, 0);
455
+ }
456
+ if (s.ok()) {
457
+ bool result =
458
+ SetSocketReusePort(posix_interface.GetFd(s.value()).value(), 1).ok();
459
+ posix_interface.Close(s.value());
460
+ return result;
461
+ } else {
462
+ return false;
463
+ }
464
+ }();
465
+ return kSupportSoReusePort;
466
+ }
467
+
468
+ #ifdef GRPC_ENABLE_FORK_SUPPORT
469
+
470
+ void EventEnginePosixInterface::AdvanceGeneration() {
471
+ if (!IsEventEngineForkEnabled()) {
472
+ grpc_core::Crash(
473
+ "Fork support is disabled but AdvanceGeneration was called");
474
+ }
475
+ for (int fd : descriptors_.ClearAndReturnRawDescriptors()) {
476
+ if (fd > 0) {
477
+ close(fd);
478
+ }
479
+ }
480
+ descriptors_ = FileDescriptorCollection(descriptors_.generation() + 1);
481
+ }
482
+
483
+ #endif // GRPC_ENABLE_FORK_SUPPORT
484
+
485
+ FileDescriptor EventEnginePosixInterface::Adopt(int fd) {
486
+ return descriptors_.Add(fd);
487
+ }
488
+
489
+ PosixErrorOr<int> EventEnginePosixInterface::GetFd(const FileDescriptor& fd) {
490
+ if (!IsCorrectGeneration(fd)) {
491
+ return PosixError::WrongGeneration();
492
+ }
493
+ return fd.fd();
494
+ }
495
+
496
+ //
497
+ // ---- Socket/FD Creation Factories ----
498
+ //
499
+
500
+ absl::StatusOr<EventEnginePosixInterface::PosixSocketCreateResult>
501
+ EventEnginePosixInterface::CreateAndPrepareTcpClientSocket(
502
+ const PosixTcpOptions& options,
503
+ const EventEngine::ResolvedAddress& target_addr) {
504
+ EventEnginePosixInterface::DSMode dsmode;
505
+ EventEngine::ResolvedAddress mapped_target_addr;
506
+
507
+ // Use dualstack sockets where available. Set mapped to v6 or v4 mapped to
508
+ // v6.
509
+ if (!ResolvedAddressToV4Mapped(target_addr, &mapped_target_addr)) {
510
+ // addr is v4 mapped to v6 or just v6.
511
+ mapped_target_addr = target_addr;
512
+ }
513
+ absl::StatusOr<FileDescriptor> socket_fd = CreateDualStackSocket(
514
+ nullptr, mapped_target_addr, SOCK_STREAM, 0, dsmode);
515
+ if (!socket_fd.ok()) {
516
+ return socket_fd.status();
517
+ }
518
+
519
+ if (dsmode == DSMode::DSMODE_IPV4) {
520
+ // Original addr is either v4 or v4 mapped to v6. Set mapped_addr to v4.
521
+ if (!ResolvedAddressIsV4Mapped(target_addr, &mapped_target_addr)) {
522
+ mapped_target_addr = target_addr;
523
+ }
524
+ }
525
+ auto error =
526
+ PrepareTcpClientSocket(socket_fd->fd(), mapped_target_addr, options);
527
+ if (!error.ok()) {
528
+ return error;
529
+ }
530
+ return PosixSocketCreateResult{*socket_fd, mapped_target_addr};
531
+ }
532
+
533
+ absl::StatusOr<FileDescriptor> EventEnginePosixInterface::CreateDualStackSocket(
534
+ std::function<int(int, int, int)> socket_factory,
535
+ const experimental::EventEngine::ResolvedAddress& addr, int type,
536
+ int protocol, DSMode& dsmode) {
537
+ auto fd = InternalCreateDualStackSocket(std::move(socket_factory), addr, type,
538
+ protocol, dsmode);
539
+ if (!fd.ok()) {
540
+ return std::move(fd).status();
541
+ }
542
+ return descriptors_.Add(*fd);
543
+ }
544
+
545
+ #ifdef GRPC_LINUX_EPOLL
546
+ #ifdef GRPC_LINUX_EPOLL_CREATE1
547
+
548
+ PosixErrorOr<FileDescriptor>
549
+ EventEnginePosixInterface::EpollCreateAndCloexec() {
550
+ auto fd = RegisterPosixResult(epoll_create1(EPOLL_CLOEXEC));
551
+ if (!fd.ok()) {
552
+ LOG(ERROR) << "epoll_create1 unavailable";
553
+ }
554
+ return fd;
555
+ }
556
+
557
+ #else // GRPC_LINUX_EPOLL_CREATE1
558
+
559
+ PosixErrorOr<FileDescriptor>
560
+ EventEnginePosixInterface::EpollCreateAndCloexec() {
561
+ auto fd = RegisterPosixResult(epoll_create(MAX_EPOLL_EVENTS));
562
+ if (!fd.ok()) {
563
+ LOG(ERROR) << "epoll_create unavailable";
564
+ return fd;
565
+ } else if (fcntl(fd->value(), F_SETFD, FD_CLOEXEC) != 0) {
566
+ LOG(ERROR) << "fcntl following epoll_create failed";
567
+ return PosixError::Error(errno);
568
+ }
569
+ return fd;
570
+ }
571
+
572
+ #endif // GRPC_LINUX_EPOLL_CREATE1
573
+ #else // GRPC_LINUX_EPOLL
574
+
575
+ PosixErrorOr<FileDescriptor>
576
+ EventEnginePosixInterface::EpollCreateAndCloexec() {
577
+ grpc_core::Crash("Not supported");
578
+ }
579
+
580
+ #endif // GRPC_LINUX_EPOLL
581
+
582
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Socket(int domain,
583
+ int type,
584
+ int protocol) {
585
+ return RegisterPosixResult(socket(domain, type, protocol));
586
+ }
587
+
588
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept(
589
+ const FileDescriptor& sockfd, struct sockaddr* addr, socklen_t* addrlen) {
590
+ if (!IsCorrectGeneration(sockfd)) {
591
+ return PosixError::WrongGeneration();
592
+ }
593
+ return RegisterPosixResult(accept(sockfd.fd(), addr, addrlen));
594
+ }
595
+
596
+ #ifdef GRPC_POSIX_SOCKETUTILS
597
+
598
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept4(
599
+ const FileDescriptor& sockfd,
600
+ grpc_event_engine::experimental::EventEngine::ResolvedAddress& addr,
601
+ int nonblock, int cloexec) {
602
+ int flags;
603
+ EventEngine::ResolvedAddress peer_addr;
604
+ socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
605
+ auto fd = Accept(sockfd, const_cast<sockaddr*>(peer_addr.address()), &len);
606
+ if (!fd.ok()) {
607
+ return fd;
608
+ }
609
+ int raw_fd = fd->fd();
610
+ if (nonblock) {
611
+ flags = fcntl(raw_fd, F_GETFL, 0);
612
+ if (flags < 0) goto close_and_error;
613
+ if (fcntl(raw_fd, F_SETFL, flags | O_NONBLOCK) != 0) goto close_and_error;
614
+ }
615
+ if (cloexec) {
616
+ flags = fcntl(raw_fd, F_GETFD, 0);
617
+ if (flags < 0) goto close_and_error;
618
+ if (fcntl(raw_fd, F_SETFD, flags | FD_CLOEXEC) != 0) goto close_and_error;
619
+ }
620
+ addr = EventEngine::ResolvedAddress(peer_addr.address(), len);
621
+ return fd;
622
+
623
+ close_and_error:
624
+ Close(*fd);
625
+ return PosixError::Error(errno);
626
+ }
627
+
628
+ #else // GRPC_POSIX_SOCKETUTILS
629
+
630
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept4(
631
+ const FileDescriptor& sockfd,
632
+ grpc_event_engine::experimental::EventEngine::ResolvedAddress& addr,
633
+ int nonblock, int cloexec) {
634
+ if (!IsCorrectGeneration(sockfd)) {
635
+ return PosixError::WrongGeneration();
636
+ }
637
+ int flags = 0;
638
+ flags |= nonblock ? SOCK_NONBLOCK : 0;
639
+ flags |= cloexec ? SOCK_CLOEXEC : 0;
640
+ EventEngine::ResolvedAddress peer_addr;
641
+ socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
642
+ PosixErrorOr<FileDescriptor> ret = RegisterPosixResult(accept4(
643
+ sockfd.fd(), const_cast<sockaddr*>(peer_addr.address()), &len, flags));
644
+ if (ret.ok()) {
645
+ addr = EventEngine::ResolvedAddress(peer_addr.address(), len);
646
+ }
647
+ return ret;
648
+ }
649
+
650
+ #endif // GRPC_POSIX_SOCKETUTILS
651
+
652
+ PosixError EventEnginePosixInterface::Connect(const FileDescriptor& sockfd,
653
+ const struct sockaddr* addr,
654
+ socklen_t addrlen) {
655
+ return PosixResultWrap(
656
+ sockfd, [&](int sockfd) { return connect(sockfd, addr, addrlen); });
657
+ }
658
+
659
+ PosixErrorOr<int64_t> EventEnginePosixInterface::RecvMsg(
660
+ const FileDescriptor& fd, struct msghdr* message, int flags) {
661
+ return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), recvmsg, message, flags);
662
+ }
663
+
664
+ PosixErrorOr<int64_t> EventEnginePosixInterface::SendMsg(
665
+ const FileDescriptor& fd, const struct msghdr* message, int flags) {
666
+ return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), sendmsg, message, flags);
667
+ }
668
+
669
+ PosixError EventEnginePosixInterface::Shutdown(const FileDescriptor& fd,
670
+ int how) {
671
+ return PosixResultWrap(fd, [&](int fd) { return shutdown(fd, how); });
672
+ }
673
+
674
+ absl::Status EventEnginePosixInterface::ApplySocketMutatorInOptions(
675
+ const FileDescriptor& fd, grpc_fd_usage usage,
676
+ const PosixTcpOptions& options) {
677
+ if (!IsCorrectGeneration(fd)) {
678
+ return absl::InternalError("ApplySocketMutatorInOptions: wrong generation");
679
+ }
680
+ return InternalApplySocketMutatorInOptions(fd.fd(), usage, options);
681
+ }
682
+
683
+ void EventEnginePosixInterface::ConfigureDefaultTcpUserTimeout(bool enable,
684
+ int timeout,
685
+ bool is_client) {
686
+ if (is_client) {
687
+ kDefaultClientUserTimeoutEnabled = enable;
688
+ if (timeout > 0) {
689
+ kDefaultClientUserTimeoutMs = timeout;
690
+ }
691
+ } else {
692
+ kDefaultServerUserTimeoutEnabled = enable;
693
+ if (timeout > 0) {
694
+ kDefaultServerUserTimeoutMs = timeout;
695
+ }
696
+ }
697
+ }
698
+
699
+ int EventEnginePosixInterface::ConfigureSocket(const FileDescriptor& fd,
700
+ int type) {
701
+ if (!IsCorrectGeneration(fd)) {
702
+ return -1;
703
+ }
704
+ #define RETURN_IF_ERROR(expr) \
705
+ if (!(expr).ok()) { \
706
+ return -1; \
707
+ }
708
+ RETURN_IF_ERROR(SetSocketNonBlocking(fd.fd(), 1));
709
+ RETURN_IF_ERROR(SetSocketCloexec(fd.fd(), 1));
710
+ if (type == SOCK_STREAM) {
711
+ RETURN_IF_ERROR(
712
+ SetSocketOption(fd.fd(), IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
713
+ }
714
+ return 0;
715
+ }
716
+
717
+ PosixError EventEnginePosixInterface::GetSockOpt(const FileDescriptor& fd,
718
+ int level, int optname,
719
+ void* optval, void* optlen) {
720
+ return PosixResultWrap(fd, [&](int fd) {
721
+ return getsockopt(fd, level, optname, optval,
722
+ static_cast<socklen_t*>(optlen));
723
+ });
724
+ }
725
+
726
+ // Bind to "::" to get a port number not used by any address.
727
+ absl::StatusOr<int> EventEnginePosixInterface::GetUnusedPort() {
728
+ EventEngine::ResolvedAddress wild = ResolvedAddressMakeWild6(0);
729
+ DSMode dsmode;
730
+ auto fd =
731
+ InternalCreateDualStackSocket(nullptr, wild, SOCK_STREAM, 0, dsmode);
732
+ GRPC_RETURN_IF_ERROR(fd.status());
733
+ if (dsmode == DSMode::DSMODE_IPV4) {
734
+ wild = ResolvedAddressMakeWild4(0);
735
+ }
736
+ if (bind(*fd, wild.address(), wild.size()) != 0) {
737
+ close(*fd);
738
+ return absl::FailedPreconditionError(
739
+ absl::StrCat("bind(GetUnusedPort): ", std::strerror(errno)));
740
+ }
741
+ socklen_t len = wild.size();
742
+ if (getsockname(*fd, const_cast<sockaddr*>(wild.address()), &len) != 0) {
743
+ close(*fd);
744
+ return absl::FailedPreconditionError(
745
+ absl::StrCat("getsockname(GetUnusedPort): ", std::strerror(errno)));
746
+ }
747
+ close(*fd);
748
+ int port = ResolvedAddressGetPort(wild);
749
+ if (port <= 0) {
750
+ return absl::FailedPreconditionError("Bad port");
751
+ }
752
+ return port;
753
+ }
754
+
755
+ PosixError EventEnginePosixInterface::Ioctl(const FileDescriptor& fd, int op,
756
+ void* arg) {
757
+ return PosixResultWrap(fd, [&](int fd) { return ioctl(fd, op, arg); });
758
+ }
759
+
760
+ absl::StatusOr<EventEngine::ResolvedAddress>
761
+ EventEnginePosixInterface::LocalAddress(const FileDescriptor& fd) {
762
+ if (!IsCorrectGeneration(fd)) {
763
+ return absl::InternalError(
764
+ "getsockname: file descriptor from wrong generation");
765
+ }
766
+ EventEngine::ResolvedAddress addr;
767
+ socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
768
+ if (getsockname(fd.fd(), const_cast<sockaddr*>(addr.address()), &len) < 0) {
769
+ return absl::InternalError(
770
+ absl::StrCat("getsockname:", grpc_core::StrError(errno)));
771
+ }
772
+ return EventEngine::ResolvedAddress(addr.address(), len);
773
+ }
774
+
775
+ absl::StatusOr<std::string> EventEnginePosixInterface::LocalAddressString(
776
+ const FileDescriptor& fd) {
777
+ auto status = LocalAddress(fd);
778
+ if (!status.ok()) {
779
+ return status.status();
780
+ }
781
+ return ResolvedAddressToNormalizedString((*status));
782
+ }
783
+
784
+ absl::StatusOr<EventEngine::ResolvedAddress>
785
+ EventEnginePosixInterface::PeerAddress(const FileDescriptor& fd) {
786
+ if (!IsCorrectGeneration(fd)) {
787
+ return absl::InternalError("getpeername: wrong file descriptor generation");
788
+ }
789
+ EventEngine::ResolvedAddress addr;
790
+ socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
791
+ if (getpeername(fd.fd(), const_cast<sockaddr*>(addr.address()), &len) < 0) {
792
+ return absl::InternalError(
793
+ absl::StrCat("getpeername:", grpc_core::StrError(errno)));
794
+ }
795
+ return EventEngine::ResolvedAddress(addr.address(), len);
796
+ }
797
+
798
+ absl::StatusOr<std::string> EventEnginePosixInterface::PeerAddressString(
799
+ const FileDescriptor& fd) {
800
+ auto status = PeerAddress(fd);
801
+ if (!status.ok()) {
802
+ return status.status();
803
+ }
804
+ return ResolvedAddressToNormalizedString((*status));
805
+ }
806
+
807
+ absl::StatusOr<EventEngine::ResolvedAddress>
808
+ EventEnginePosixInterface::PrepareListenerSocket(
809
+ const FileDescriptor& fd, const PosixTcpOptions& options,
810
+ const EventEngine::ResolvedAddress& address) {
811
+ if (!IsCorrectGeneration(fd)) {
812
+ return absl::InternalError("PrepareListenerSocket: wrong generation");
813
+ }
814
+ int f = fd.fd();
815
+ if (IsSocketReusePortSupported() && options.allow_reuse_port &&
816
+ address.address()->sa_family != AF_UNIX &&
817
+ !ResolvedAddressIsVSock(address)) {
818
+ GRPC_RETURN_IF_ERROR(SetSocketReusePort(f, 1));
819
+ }
820
+
821
+ GRPC_RETURN_IF_ERROR(SetSocketNonBlocking(f, 1));
822
+ GRPC_RETURN_IF_ERROR(SetSocketCloexec(f, 1));
823
+
824
+ if (address.address()->sa_family != AF_UNIX &&
825
+ !ResolvedAddressIsVSock(address)) {
826
+ GRPC_RETURN_IF_ERROR(
827
+ SetSocketOption(f, IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
828
+ GRPC_RETURN_IF_ERROR(
829
+ SetSocketOption(f, SOL_SOCKET, SO_REUSEADDR, 1, "SO_REUSEADDR"));
830
+ GRPC_RETURN_IF_ERROR(SetSocketDscp(f, options.dscp));
831
+ TrySetSocketTcpUserTimeout(f, options, false);
832
+ }
833
+ GRPC_RETURN_IF_ERROR(InternalSetSocketNoSigpipeIfPossible(f));
834
+ GRPC_RETURN_IF_ERROR(InternalApplySocketMutatorInOptions(
835
+ f, GRPC_FD_SERVER_LISTENER_USAGE, options));
836
+ if (kLinuxErrqueue && !SetSocketZeroCopy(f).ok()) {
837
+ // it's not fatal, so just log it.
838
+ VLOG(2) << "Node does not support SO_ZEROCOPY, continuing.";
839
+ }
840
+ if (bind(f, address.address(), address.size()) < 0) {
841
+ auto sockaddr_str = ResolvedAddressToString(address);
842
+ if (!sockaddr_str.ok()) {
843
+ LOG(ERROR) << "Could not convert sockaddr to string: "
844
+ << sockaddr_str.status();
845
+ sockaddr_str = "<unparsable>";
846
+ }
847
+ sockaddr_str = absl::StrReplaceAll(*sockaddr_str, {{"\0", "@"}});
848
+ return absl::FailedPreconditionError(
849
+ absl::StrCat("Error in bind for address '", *sockaddr_str,
850
+ "': ", std::strerror(errno)));
851
+ }
852
+ if (listen(f, GetMaxAcceptQueueSize()) < 0) {
853
+ return absl::FailedPreconditionError(
854
+ absl::StrCat("Error in listen: ", std::strerror(errno)));
855
+ }
856
+ socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
857
+ EventEngine::ResolvedAddress sockname_temp;
858
+ if (getsockname(f, const_cast<sockaddr*>(sockname_temp.address()), &len) <
859
+ 0) {
860
+ return absl::FailedPreconditionError(
861
+ absl::StrCat("Error in getsockname: ", std::strerror(errno)));
862
+ }
863
+ return sockname_temp;
864
+ }
865
+
866
+ // Set a socket using a grpc_socket_mutator
867
+ absl::Status EventEnginePosixInterface::SetSocketMutator(
868
+ const FileDescriptor& fd, grpc_fd_usage usage,
869
+ grpc_socket_mutator* mutator) {
870
+ CHECK(mutator);
871
+ if (!IsCorrectGeneration(fd)) {
872
+ return absl::InternalError("SetSocketMutator: FD has a wrong generation");
873
+ }
874
+ if (!grpc_socket_mutator_mutate_fd(mutator, fd.fd(), usage)) {
875
+ return absl::Status(absl::StatusCode::kInternal,
876
+ "grpc_socket_mutator failed.");
877
+ }
878
+ return absl::OkStatus();
879
+ }
880
+
881
+ absl::Status EventEnginePosixInterface::SetSocketNoSigpipeIfPossible(
882
+ const FileDescriptor& fd) {
883
+ if (!IsCorrectGeneration(fd)) {
884
+ return absl::OkStatus();
885
+ }
886
+ return InternalSetSocketNoSigpipeIfPossible(fd.fd());
887
+ }
888
+
889
+ PosixErrorOr<int64_t> EventEnginePosixInterface::SetSockOpt(
890
+ const FileDescriptor& fd, int level, int optname, uint32_t optval) {
891
+ if (!IsCorrectGeneration(fd)) {
892
+ return PosixError::WrongGeneration();
893
+ }
894
+ if (setsockopt(fd.fd(), level, optname, &optval, sizeof(optval)) < 0) {
895
+ return PosixError::Error(errno);
896
+ }
897
+ return optval;
898
+ }
899
+
900
+ #ifdef GRPC_LINUX_EVENTFD
901
+
902
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::EventFd(int initval,
903
+ int flags) {
904
+ return RegisterPosixResult(eventfd(initval, flags));
905
+ }
906
+
907
+ PosixError EventEnginePosixInterface::EventFdRead(const FileDescriptor& fd) {
908
+ return PosixResultWrap(fd, [](int fd) {
909
+ eventfd_t value;
910
+ return eventfd_read(fd, &value);
911
+ });
912
+ }
913
+
914
+ PosixError EventEnginePosixInterface::EventFdWrite(const FileDescriptor& fd) {
915
+ return PosixResultWrap(fd, [](int fd) { return eventfd_write(fd, 1); });
916
+ }
917
+
918
+ #else // GRPC_LINUX_EVENTFD
919
+
920
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::EventFd(int initval,
921
+ int flags) {
922
+ grpc_core::Crash("EventFD not supported");
923
+ }
924
+
925
+ PosixError EventEnginePosixInterface::EventFdRead(const FileDescriptor& fd) {
926
+ grpc_core::Crash("Not implemented");
927
+ }
928
+
929
+ PosixError EventEnginePosixInterface::EventFdWrite(const FileDescriptor& fd) {
930
+ grpc_core::Crash("Not implemented");
931
+ }
932
+
933
+ #endif // GRPC_LINUX_EVENTFD
934
+
935
+ //
936
+ // Epoll
937
+ //
938
+ #ifdef GRPC_LINUX_EPOLL
939
+
940
+ PosixError EventEnginePosixInterface::EpollCtlDel(const FileDescriptor& epfd,
941
+ const FileDescriptor& fd) {
942
+ if (!IsCorrectGeneration(epfd) || !IsCorrectGeneration(fd)) {
943
+ return PosixError::WrongGeneration();
944
+ }
945
+ epoll_event phony_event;
946
+ int result = epoll_ctl(epfd.fd(), EPOLL_CTL_DEL, fd.fd(), &phony_event);
947
+ if (result < 0) {
948
+ return PosixError::Error(errno);
949
+ }
950
+ return PosixError::Ok();
951
+ }
952
+
953
+ PosixError EventEnginePosixInterface::EpollCtlAdd(const FileDescriptor& epfd,
954
+ bool writable,
955
+ const FileDescriptor& fd,
956
+ void* data) {
957
+ epoll_event event;
958
+ event.events = static_cast<uint32_t>(EPOLLIN | EPOLLET);
959
+ if (writable) {
960
+ event.events |= EPOLLOUT;
961
+ }
962
+ event.data.ptr = data;
963
+ if (!IsCorrectGeneration(epfd) || !IsCorrectGeneration(fd)) {
964
+ return PosixError::WrongGeneration();
965
+ }
966
+ int result = epoll_ctl(epfd.fd(), EPOLL_CTL_ADD, fd.fd(), &event);
967
+ if (result < 0) {
968
+ return PosixError::Error(errno);
969
+ }
970
+ return PosixError::Ok();
971
+ }
972
+
973
+ #endif // GRPC_LINUX_EPOLL
974
+
975
+ absl::Status EventEnginePosixInterface::PrepareTcpClientSocket(
976
+ int fd, const EventEngine::ResolvedAddress& addr,
977
+ const PosixTcpOptions& options) {
978
+ bool close_fd = true;
979
+ auto sock_cleanup = absl::MakeCleanup([&close_fd, &fd]() -> void {
980
+ if (close_fd && fd > 0) {
981
+ close(fd);
982
+ }
983
+ });
984
+ GRPC_RETURN_IF_ERROR(SetSocketNonBlocking(fd, 1));
985
+ GRPC_RETURN_IF_ERROR(SetSocketCloexec(fd, 1));
986
+ if (options.tcp_receive_buffer_size != options.kReadBufferSizeUnset) {
987
+ GRPC_RETURN_IF_ERROR(SetSocketRcvBuf(fd, options.tcp_receive_buffer_size));
988
+ }
989
+ if (addr.address()->sa_family != AF_UNIX && !ResolvedAddressIsVSock(addr)) {
990
+ // If its not a unix socket or vsock address.
991
+ GRPC_RETURN_IF_ERROR(
992
+ SetSocketOption(fd, IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
993
+ GRPC_RETURN_IF_ERROR(
994
+ SetSocketOption(fd, SOL_SOCKET, SO_REUSEADDR, 1, "SO_REUSEADDR"));
995
+ GRPC_RETURN_IF_ERROR(SetSocketDscp(fd, options.dscp));
996
+ TrySetSocketTcpUserTimeout(fd, options, true);
997
+ }
998
+ GRPC_RETURN_IF_ERROR(InternalSetSocketNoSigpipeIfPossible(fd));
999
+ GRPC_RETURN_IF_ERROR(InternalApplySocketMutatorInOptions(
1000
+ fd, GRPC_FD_CLIENT_CONNECTION_USAGE, options));
1001
+ // No errors. Set close_fd to false to ensure the socket is
1002
+ // not closed.
1003
+ close_fd = false;
1004
+ return absl::OkStatus();
1005
+ }
1006
+
1007
+ PosixError EventEnginePosixInterface::PosixResultWrap(
1008
+ const FileDescriptor& wrapped,
1009
+ const absl::AnyInvocable<int(int) const>& fn) const {
1010
+ if (!IsCorrectGeneration(wrapped)) {
1011
+ return PosixError::WrongGeneration();
1012
+ }
1013
+ int result = fn(wrapped.fd());
1014
+ if (result < 0) {
1015
+ return PosixError::Error(errno);
1016
+ }
1017
+ return PosixError::Ok();
1018
+ }
1019
+
1020
+ PosixErrorOr<FileDescriptor> EventEnginePosixInterface::RegisterPosixResult(
1021
+ int result) {
1022
+ if (result < 0) {
1023
+ return PosixError::Error(errno);
1024
+ }
1025
+ return descriptors_.Add(result);
1026
+ }
1027
+
1028
+ #endif // GRPC_POSIX_SOCKET
1029
+
1030
+ #if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
1031
+
1032
+ void EventEnginePosixInterface::Close(const FileDescriptor& fd) {
1033
+ if (descriptors_.Remove(fd)) {
1034
+ close(fd.fd());
1035
+ }
1036
+ }
1037
+
1038
+ bool EventEnginePosixInterface::IsCorrectGeneration(
1039
+ const FileDescriptor& fd) const {
1040
+ (void)fd; // Always used now
1041
+ #ifdef GRPC_ENABLE_FORK_SUPPORT
1042
+ if (IsEventEngineForkEnabled()) {
1043
+ return descriptors_.generation() == fd.generation();
1044
+ }
1045
+ #endif // GRPC_ENABLE_FORK_SUPPORT
1046
+ return true;
1047
+ }
1048
+
1049
+ absl::StatusOr<std::pair<FileDescriptor, FileDescriptor> >
1050
+ EventEnginePosixInterface::Pipe() {
1051
+ int pipefd[2];
1052
+ int r = pipe(pipefd);
1053
+ if (0 != r) {
1054
+ return absl::Status(absl::StatusCode::kInternal,
1055
+ absl::StrCat("pipe: ", grpc_core::StrError(errno)));
1056
+ }
1057
+ auto status = SetSocketNonBlocking(pipefd[0], 1);
1058
+ if (status.ok()) {
1059
+ status = SetSocketNonBlocking(pipefd[1], 1);
1060
+ }
1061
+ if (status.ok()) {
1062
+ return std::pair(descriptors_.Add(pipefd[0]), descriptors_.Add(pipefd[1]));
1063
+ }
1064
+ close(pipefd[0]);
1065
+ close(pipefd[1]);
1066
+ return status;
1067
+ }
1068
+
1069
+ PosixErrorOr<int64_t> EventEnginePosixInterface::Read(const FileDescriptor& fd,
1070
+ absl::Span<char> buf) {
1071
+ return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), read, buf.data(),
1072
+ buf.size());
1073
+ }
1074
+
1075
+ PosixErrorOr<int64_t> EventEnginePosixInterface::Write(const FileDescriptor& fd,
1076
+ absl::Span<char> buf) {
1077
+ return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), write, buf.data(),
1078
+ buf.size());
1079
+ }
1080
+
1081
+ #endif // defined (GRPC_POSIX_WAKEUP_FD) || defined (GRPC_LINUX_EVENTFD)
1082
+
1083
+ } // namespace grpc_event_engine::experimental