grpc 1.74.1 → 1.75.0.pre1
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.
- checksums.yaml +4 -4
- data/Makefile +83 -41
- data/include/grpc/credentials.h +7 -1
- data/src/core/call/client_call.cc +4 -4
- data/src/core/call/filter_fusion.h +1230 -0
- data/src/core/call/metadata.cc +22 -0
- data/src/core/call/metadata.h +24 -2
- data/src/core/channelz/channelz.cc +10 -17
- data/src/core/channelz/channelz.h +58 -19
- data/src/core/channelz/channelz_registry.cc +0 -162
- data/src/core/channelz/channelz_registry.h +14 -7
- data/src/core/channelz/property_list.cc +19 -23
- data/src/core/channelz/property_list.h +3 -1
- data/src/core/channelz/v2tov1/convert.cc +683 -0
- data/src/core/channelz/v2tov1/convert.h +58 -0
- data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
- data/src/core/channelz/v2tov1/legacy_api.h +32 -0
- data/src/core/channelz/v2tov1/property_list.cc +118 -0
- data/src/core/channelz/v2tov1/property_list.h +52 -0
- data/src/core/client_channel/client_channel_filter.cc +5 -4
- data/src/core/client_channel/client_channel_filter.h +2 -2
- data/src/core/client_channel/client_channel_internal.h +2 -1
- data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
- data/src/core/client_channel/subchannel.cc +14 -6
- data/src/core/client_channel/subchannel.h +2 -0
- data/src/core/config/core_configuration.cc +3 -1
- data/src/core/config/core_configuration.h +12 -0
- data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
- data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
- data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
- data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
- data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
- data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
- data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
- data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
- data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
- data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
- data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
- data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
- data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
- data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
- data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
- data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
- data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
- data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
- data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
- data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
- data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
- data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
- data/src/core/filter/auth/auth_filters.h +2 -2
- data/src/core/filter/fused_filters.cc +154 -0
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
- data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
- data/src/core/handshaker/security/secure_endpoint.cc +28 -13
- data/src/core/handshaker/security/secure_endpoint.h +8 -0
- data/src/core/lib/channel/promise_based_filter.cc +15 -25
- data/src/core/lib/channel/promise_based_filter.h +6 -5
- data/src/core/lib/event_engine/ares_resolver.h +3 -1
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
- data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
- data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
- data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
- data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
- data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
- data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
- data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
- data/src/core/lib/experiments/experiments.cc +120 -6
- data/src/core/lib/experiments/experiments.h +46 -3
- data/src/core/lib/iomgr/combiner.cc +1 -1
- data/src/core/lib/iomgr/exec_ctx.h +3 -9
- data/src/core/lib/iomgr/socket_mutator.cc +1 -1
- data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
- data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
- data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
- data/src/core/lib/iomgr/tcp_posix.cc +3 -3
- data/src/core/lib/promise/activity.h +2 -2
- data/src/core/lib/promise/mpsc.cc +8 -8
- data/src/core/lib/promise/party.cc +7 -7
- data/src/core/lib/promise/party.h +4 -4
- data/src/core/lib/promise/poll.h +10 -0
- data/src/core/lib/resource_quota/memory_quota.cc +90 -3
- data/src/core/lib/resource_quota/memory_quota.h +20 -9
- data/src/core/lib/resource_quota/periodic_update.cc +14 -0
- data/src/core/lib/resource_quota/periodic_update.h +8 -0
- data/src/core/lib/resource_quota/resource_quota.cc +15 -4
- data/src/core/lib/resource_quota/resource_quota.h +3 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
- data/src/core/lib/surface/call.cc +5 -5
- data/src/core/lib/surface/call.h +6 -5
- data/src/core/lib/surface/completion_queue.cc +2 -4
- data/src/core/lib/surface/filter_stack_call.cc +1 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.h +3 -3
- data/src/core/load_balancing/endpoint_list.cc +29 -2
- data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
- data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
- data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
- data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
- data/src/core/net/socket_mutator.cc +19 -0
- data/src/core/net/socket_mutator.h +25 -0
- data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
- data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
- data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
- data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
- data/src/core/server/server.cc +1 -1
- data/src/core/server/server_call_tracer_filter.cc +0 -66
- data/src/core/server/server_call_tracer_filter.h +64 -0
- data/src/core/server/server_config_selector_filter.cc +1 -1
- data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
- data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
- data/src/core/telemetry/call_tracer.cc +20 -14
- data/src/core/telemetry/call_tracer.h +22 -17
- data/src/core/telemetry/metrics.h +8 -8
- data/src/core/telemetry/stats_data.cc +151 -151
- data/src/core/telemetry/stats_data.h +87 -87
- data/src/core/transport/auth_context.cc +20 -0
- data/src/core/transport/auth_context.h +4 -0
- data/src/core/transport/auth_context_comparator_registry.h +69 -0
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
- data/src/core/tsi/ssl_transport_security.cc +202 -32
- data/src/core/tsi/ssl_transport_security.h +19 -10
- data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
- data/src/core/tsi/ssl_transport_security_utils.h +4 -0
- data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
- data/src/core/util/latent_see.cc +178 -146
- data/src/core/util/latent_see.h +245 -188
- data/src/core/util/single_set_ptr.h +5 -2
- data/src/core/util/useful.h +91 -0
- data/src/core/util/windows/directory_reader.cc +1 -0
- data/src/core/util/windows/thd.cc +1 -3
- data/src/core/util/work_serializer.cc +1 -1
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
- data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/cares/cares/include/ares.h +925 -460
- data/third_party/cares/cares/include/ares_dns.h +86 -71
- data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
- data/third_party/cares/cares/include/ares_nameser.h +215 -189
- data/third_party/cares/cares/include/ares_version.h +37 -14
- data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
- data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
- data/third_party/cares/cares/src/lib/ares_android.c +216 -164
- data/third_party/cares/cares/src/lib/ares_android.h +25 -14
- data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
- data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
- data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
- data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
- data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
- data/third_party/cares/cares/src/lib/ares_data.c +93 -181
- data/third_party/cares/cares/src/lib/ares_data.h +50 -39
- data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
- data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
- data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
- data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
- data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
- data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
- data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
- data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
- data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
- data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
- data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
- data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
- data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
- data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
- data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
- data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
- data/third_party/cares/cares/src/lib/ares_options.c +418 -332
- data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
- data/third_party/cares/cares/src/lib/ares_private.h +558 -356
- data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
- data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
- data/third_party/cares/cares/src/lib/ares_query.c +126 -121
- data/third_party/cares/cares/src/lib/ares_search.c +564 -262
- data/third_party/cares/cares/src/lib/ares_send.c +264 -93
- data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
- data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
- data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
- data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
- data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
- data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
- data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
- data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
- data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
- data/third_party/cares/cares/src/lib/ares_version.c +29 -4
- data/third_party/cares/cares/src/lib/config-dos.h +88 -89
- data/third_party/cares/cares/src/lib/config-win32.h +122 -77
- data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
- data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
- data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
- data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
- data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
- data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
- data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
- data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
- data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
- data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
- data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
- data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
- data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
- data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
- data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
- data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
- data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
- data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
- data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
- data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
- data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
- data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
- data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
- data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
- data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
- data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
- data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
- data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
- data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
- data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
- data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
- data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
- data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
- data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
- data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
- data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
- data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
- data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
- data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
- data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
- data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
- data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
- data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
- data/third_party/cares/cares/src/lib/windows_port.c +16 -9
- metadata +121 -49
- data/src/core/util/ring_buffer.h +0 -122
- data/third_party/cares/cares/include/ares_rules.h +0 -125
- data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
- data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
- data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
- data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
- data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
- data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
- data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
- data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
- data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
- data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
- data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
- data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
- data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
- data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
- data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
- data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
- data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
- data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
- data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
- data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
- data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
- data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
- data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
- data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
- data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
- data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
- data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
- data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
- data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
- data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
- data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
- data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
- data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
- data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
- data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
- data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
- data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
- data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
- data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
- data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
- data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
- data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
- data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
- data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
- data/third_party/cares/cares/src/lib/setup_once.h +0 -554
- data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -0,0 +1,965 @@
|
|
1
|
+
//
|
2
|
+
//
|
3
|
+
// Copyright 2015 gRPC authors.
|
4
|
+
//
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
// you may not use this file except in compliance with the License.
|
7
|
+
// You may obtain a copy of the License at
|
8
|
+
//
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
//
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
// See the License for the specific language governing permissions and
|
15
|
+
// limitations under the License.
|
16
|
+
//
|
17
|
+
//
|
18
|
+
|
19
|
+
#include <grpc/event_engine/memory_allocator.h>
|
20
|
+
#include <grpc/event_engine/memory_request.h>
|
21
|
+
#include <grpc/slice.h>
|
22
|
+
#include <grpc/slice_buffer.h>
|
23
|
+
#include <grpc/support/alloc.h>
|
24
|
+
#include <grpc/support/atm.h>
|
25
|
+
#include <grpc/support/port_platform.h>
|
26
|
+
#include <grpc/support/sync.h>
|
27
|
+
|
28
|
+
#include <algorithm>
|
29
|
+
#include <atomic>
|
30
|
+
#include <cstddef>
|
31
|
+
#include <cstdint>
|
32
|
+
#include <memory>
|
33
|
+
#include <optional>
|
34
|
+
#include <utility>
|
35
|
+
#include <vector>
|
36
|
+
|
37
|
+
#include "absl/base/thread_annotations.h"
|
38
|
+
#include "absl/functional/any_invocable.h"
|
39
|
+
#include "absl/log/check.h"
|
40
|
+
#include "absl/log/log.h"
|
41
|
+
#include "absl/status/status.h"
|
42
|
+
#include "absl/strings/str_cat.h"
|
43
|
+
#include "absl/strings/string_view.h"
|
44
|
+
#include "absl/types/span.h"
|
45
|
+
#include "src/core/handshaker/security/secure_endpoint.h"
|
46
|
+
#include "src/core/lib/channel/channel_args.h"
|
47
|
+
#include "src/core/lib/debug/trace.h"
|
48
|
+
#include "src/core/lib/experiments/experiments.h"
|
49
|
+
#include "src/core/lib/iomgr/endpoint.h"
|
50
|
+
#include "src/core/lib/iomgr/error.h"
|
51
|
+
#include "src/core/lib/iomgr/event_engine_shims/endpoint.h"
|
52
|
+
#include "src/core/lib/resource_quota/memory_quota.h"
|
53
|
+
#include "src/core/lib/resource_quota/resource_quota.h"
|
54
|
+
#include "src/core/lib/slice/slice.h"
|
55
|
+
#include "src/core/lib/slice/slice_buffer.h"
|
56
|
+
#include "src/core/lib/slice/slice_string_helpers.h"
|
57
|
+
#include "src/core/tsi/transport_security_grpc.h"
|
58
|
+
#include "src/core/tsi/transport_security_interface.h"
|
59
|
+
#include "src/core/util/latent_see.h"
|
60
|
+
#include "src/core/util/orphanable.h"
|
61
|
+
#include "src/core/util/ref_counted.h"
|
62
|
+
#include "src/core/util/ref_counted_ptr.h"
|
63
|
+
#include "src/core/util/string.h"
|
64
|
+
#include "src/core/util/sync.h"
|
65
|
+
|
66
|
+
#define STAGING_BUFFER_SIZE 8192
|
67
|
+
|
68
|
+
namespace grpc_core {
|
69
|
+
namespace {
|
70
|
+
class FrameProtector : public RefCounted<FrameProtector> {
|
71
|
+
public:
|
72
|
+
FrameProtector(tsi_frame_protector* protector,
|
73
|
+
tsi_zero_copy_grpc_protector* zero_copy_protector,
|
74
|
+
grpc_slice* leftover_slices, size_t leftover_nslices,
|
75
|
+
const ChannelArgs& args)
|
76
|
+
: protector_(protector),
|
77
|
+
zero_copy_protector_(zero_copy_protector),
|
78
|
+
memory_owner_(args.GetObject<ResourceQuota>()
|
79
|
+
->memory_quota()
|
80
|
+
->CreateMemoryOwner()),
|
81
|
+
self_reservation_(memory_owner_.MakeReservation(sizeof(*this))) {
|
82
|
+
GRPC_TRACE_LOG(secure_endpoint, INFO)
|
83
|
+
<< "FrameProtector: " << this << " protector: " << protector_
|
84
|
+
<< " zero_copy_protector: " << zero_copy_protector_
|
85
|
+
<< " leftover_nslices: " << leftover_nslices;
|
86
|
+
if (leftover_nslices > 0) {
|
87
|
+
leftover_bytes_ = std::make_unique<SliceBuffer>();
|
88
|
+
for (size_t i = 0; i < leftover_nslices; i++) {
|
89
|
+
leftover_bytes_->Append(Slice(CSliceRef(leftover_slices[i])));
|
90
|
+
}
|
91
|
+
}
|
92
|
+
if (zero_copy_protector_ != nullptr) {
|
93
|
+
read_staging_buffer_ = grpc_empty_slice();
|
94
|
+
write_staging_buffer_ = grpc_empty_slice();
|
95
|
+
} else {
|
96
|
+
read_staging_buffer_ =
|
97
|
+
memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
|
98
|
+
write_staging_buffer_ =
|
99
|
+
memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
~FrameProtector() override {
|
104
|
+
tsi_frame_protector_destroy(protector_);
|
105
|
+
tsi_zero_copy_grpc_protector_destroy(zero_copy_protector_);
|
106
|
+
CSliceUnref(read_staging_buffer_);
|
107
|
+
CSliceUnref(write_staging_buffer_);
|
108
|
+
}
|
109
|
+
|
110
|
+
Mutex* read_mu() ABSL_LOCK_RETURNED(read_mu_) { return &read_mu_; }
|
111
|
+
Mutex* write_mu() ABSL_LOCK_RETURNED(write_mu_) { return &write_mu_; }
|
112
|
+
|
113
|
+
void TraceOp(absl::string_view op, grpc_slice_buffer* slices) {
|
114
|
+
if (GRPC_TRACE_FLAG_ENABLED(secure_endpoint)) {
|
115
|
+
size_t i;
|
116
|
+
if (slices->length < 64) {
|
117
|
+
for (i = 0; i < slices->count; i++) {
|
118
|
+
char* data =
|
119
|
+
grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
120
|
+
LOG(INFO) << op << " " << this << ": " << data;
|
121
|
+
gpr_free(data);
|
122
|
+
}
|
123
|
+
} else {
|
124
|
+
grpc_slice first = GRPC_SLICE_MALLOC(64);
|
125
|
+
grpc_slice_buffer_copy_first_into_buffer(slices, 64,
|
126
|
+
GRPC_SLICE_START_PTR(first));
|
127
|
+
char* data = grpc_dump_slice(first, GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
128
|
+
LOG(INFO) << op << " first:" << this << ": " << data;
|
129
|
+
gpr_free(data);
|
130
|
+
CSliceUnref(first);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
void MaybePostReclaimer() {
|
136
|
+
if (!has_posted_reclaimer_.exchange(true, std::memory_order_relaxed)) {
|
137
|
+
memory_owner_.PostReclaimer(
|
138
|
+
ReclamationPass::kBenign,
|
139
|
+
[self = Ref()](std::optional<ReclamationSweep> sweep) {
|
140
|
+
if (sweep.has_value()) {
|
141
|
+
GRPC_TRACE_LOG(resource_quota, INFO)
|
142
|
+
<< "secure endpoint: benign reclamation to free memory";
|
143
|
+
grpc_slice temp_read_slice;
|
144
|
+
grpc_slice temp_write_slice;
|
145
|
+
|
146
|
+
self->read_mu_.Lock();
|
147
|
+
temp_read_slice =
|
148
|
+
std::exchange(self->read_staging_buffer_, grpc_empty_slice());
|
149
|
+
self->read_mu_.Unlock();
|
150
|
+
|
151
|
+
self->write_mu_.Lock();
|
152
|
+
temp_write_slice = std::exchange(self->write_staging_buffer_,
|
153
|
+
grpc_empty_slice());
|
154
|
+
self->write_mu_.Unlock();
|
155
|
+
|
156
|
+
CSliceUnref(temp_read_slice);
|
157
|
+
CSliceUnref(temp_write_slice);
|
158
|
+
self->has_posted_reclaimer_.store(false,
|
159
|
+
std::memory_order_relaxed);
|
160
|
+
}
|
161
|
+
});
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
void FlushReadStagingBuffer(uint8_t** cur, uint8_t** end)
|
166
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) {
|
167
|
+
grpc_slice_buffer_add_indexed(read_buffer_, read_staging_buffer_);
|
168
|
+
read_staging_buffer_ =
|
169
|
+
memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
|
170
|
+
*cur = GRPC_SLICE_START_PTR(read_staging_buffer_);
|
171
|
+
*end = GRPC_SLICE_END_PTR(read_staging_buffer_);
|
172
|
+
}
|
173
|
+
|
174
|
+
void FinishRead(bool ok) {
|
175
|
+
TraceOp("FinishRead", read_buffer_);
|
176
|
+
// TODO(yangg) experiment with moving this block after read_cb to see if it
|
177
|
+
// helps latency
|
178
|
+
source_buffer_.Clear();
|
179
|
+
if (!ok) grpc_slice_buffer_reset_and_unref(read_buffer_);
|
180
|
+
read_buffer_ = nullptr;
|
181
|
+
}
|
182
|
+
|
183
|
+
absl::Status Unprotect(absl::Status read_status)
|
184
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) {
|
185
|
+
if (shutdown_) {
|
186
|
+
return absl::CancelledError("secure endpoint shutdown");
|
187
|
+
}
|
188
|
+
|
189
|
+
GRPC_LATENT_SEE_SCOPE("unprotect");
|
190
|
+
bool keep_looping = false;
|
191
|
+
tsi_result result = TSI_OK;
|
192
|
+
|
193
|
+
uint8_t* cur = GRPC_SLICE_START_PTR(read_staging_buffer_);
|
194
|
+
uint8_t* end = GRPC_SLICE_END_PTR(read_staging_buffer_);
|
195
|
+
|
196
|
+
if (!read_status.ok()) {
|
197
|
+
grpc_slice_buffer_reset_and_unref(read_buffer_);
|
198
|
+
} else if (zero_copy_protector_ != nullptr) {
|
199
|
+
// Use zero-copy grpc protector to unprotect.
|
200
|
+
int min_progress_size = 1;
|
201
|
+
// Get the size of the last frame which is not yet fully decrypted.
|
202
|
+
// This estimated frame size is stored in ep->min_progress_size which is
|
203
|
+
// passed to the TCP layer to indicate the minimum number of
|
204
|
+
// bytes that need to be read to make meaningful progress. This would
|
205
|
+
// avoid reading of small slices from the network.
|
206
|
+
// TODO(vigneshbabu): Set min_progress_size in the regular
|
207
|
+
// (non-zero-copy) frame protector code path as well.
|
208
|
+
result = tsi_zero_copy_grpc_protector_unprotect(
|
209
|
+
zero_copy_protector_, source_buffer_.c_slice_buffer(), read_buffer_,
|
210
|
+
&min_progress_size);
|
211
|
+
min_progress_size = std::max(1, min_progress_size);
|
212
|
+
min_progress_size_ = result != TSI_OK ? 1 : min_progress_size;
|
213
|
+
} else {
|
214
|
+
// Use frame protector to unprotect.
|
215
|
+
// TODO(yangg) check error, maybe bail out early
|
216
|
+
for (size_t i = 0; i < source_buffer_.Count(); i++) {
|
217
|
+
grpc_slice encrypted = source_buffer_.c_slice_buffer()->slices[i];
|
218
|
+
uint8_t* message_bytes = GRPC_SLICE_START_PTR(encrypted);
|
219
|
+
size_t message_size = GRPC_SLICE_LENGTH(encrypted);
|
220
|
+
|
221
|
+
while (message_size > 0 || keep_looping) {
|
222
|
+
size_t unprotected_buffer_size_written =
|
223
|
+
static_cast<size_t>(end - cur);
|
224
|
+
size_t processed_message_size = message_size;
|
225
|
+
if (IsTsiFrameProtectorWithoutLocksEnabled()) {
|
226
|
+
result = tsi_frame_protector_unprotect(
|
227
|
+
protector_, message_bytes, &processed_message_size, cur,
|
228
|
+
&unprotected_buffer_size_written);
|
229
|
+
} else {
|
230
|
+
protector_mu_.Lock();
|
231
|
+
result = tsi_frame_protector_unprotect(
|
232
|
+
protector_, message_bytes, &processed_message_size, cur,
|
233
|
+
&unprotected_buffer_size_written);
|
234
|
+
protector_mu_.Unlock();
|
235
|
+
}
|
236
|
+
if (result != TSI_OK) {
|
237
|
+
LOG(ERROR) << "Decryption error: " << tsi_result_to_string(result);
|
238
|
+
break;
|
239
|
+
}
|
240
|
+
message_bytes += processed_message_size;
|
241
|
+
message_size -= processed_message_size;
|
242
|
+
cur += unprotected_buffer_size_written;
|
243
|
+
|
244
|
+
if (cur == end) {
|
245
|
+
FlushReadStagingBuffer(&cur, &end);
|
246
|
+
// Force to enter the loop again to extract buffered bytes in
|
247
|
+
// protector. The bytes could be buffered because of running out
|
248
|
+
// of staging_buffer. If this happens at the end of all slices,
|
249
|
+
// doing another unprotect avoids leaving data in the protector.
|
250
|
+
keep_looping = true;
|
251
|
+
} else if (unprotected_buffer_size_written > 0) {
|
252
|
+
keep_looping = true;
|
253
|
+
} else {
|
254
|
+
keep_looping = false;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
if (result != TSI_OK) break;
|
258
|
+
}
|
259
|
+
|
260
|
+
if (cur != GRPC_SLICE_START_PTR(read_staging_buffer_)) {
|
261
|
+
grpc_slice_buffer_add(
|
262
|
+
read_buffer_,
|
263
|
+
grpc_slice_split_head(
|
264
|
+
&read_staging_buffer_,
|
265
|
+
static_cast<size_t>(
|
266
|
+
cur - GRPC_SLICE_START_PTR(read_staging_buffer_))));
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
if (read_status.ok() && result != TSI_OK) {
|
271
|
+
read_status = GRPC_ERROR_CREATE(
|
272
|
+
absl::StrCat("Unwrap failed (", tsi_result_to_string(result), ")"));
|
273
|
+
}
|
274
|
+
|
275
|
+
GRPC_TRACE_LOG(secure_endpoint, INFO)
|
276
|
+
<< "Unprotect: " << this << " read_status: " << read_status;
|
277
|
+
|
278
|
+
return read_status;
|
279
|
+
}
|
280
|
+
|
281
|
+
void BeginRead(grpc_slice_buffer* slices) {
|
282
|
+
read_buffer_ = slices;
|
283
|
+
grpc_slice_buffer_reset_and_unref(read_buffer_);
|
284
|
+
}
|
285
|
+
|
286
|
+
bool MaybeReadLeftoverBytes(
|
287
|
+
grpc_event_engine::experimental::SliceBuffer* dest) {
|
288
|
+
GRPC_TRACE_LOG(secure_endpoint, INFO)
|
289
|
+
<< "ReadLeftoverBytes: " << this
|
290
|
+
<< " leftover_bytes_: " << leftover_bytes_.get();
|
291
|
+
if (leftover_bytes_ == nullptr) {
|
292
|
+
return false;
|
293
|
+
}
|
294
|
+
grpc_slice_buffer_swap(leftover_bytes_->c_slice_buffer(),
|
295
|
+
dest->c_slice_buffer());
|
296
|
+
leftover_bytes_.reset();
|
297
|
+
return true;
|
298
|
+
}
|
299
|
+
|
300
|
+
void SetSourceBuffer(
|
301
|
+
std::unique_ptr<grpc_event_engine::experimental::SliceBuffer>
|
302
|
+
source_buffer) {
|
303
|
+
source_buffer_ = std::move(*source_buffer);
|
304
|
+
source_buffer.reset();
|
305
|
+
}
|
306
|
+
|
307
|
+
int min_progress_size() const { return min_progress_size_; }
|
308
|
+
|
309
|
+
void FlushWriteStagingBuffer(uint8_t** cur, uint8_t** end)
|
310
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(write_mu_) {
|
311
|
+
output_buffer_.AppendIndexed(
|
312
|
+
grpc_event_engine::experimental::Slice(write_staging_buffer_));
|
313
|
+
write_staging_buffer_ =
|
314
|
+
memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
|
315
|
+
*cur = GRPC_SLICE_START_PTR(write_staging_buffer_);
|
316
|
+
*end = GRPC_SLICE_END_PTR(write_staging_buffer_);
|
317
|
+
MaybePostReclaimer();
|
318
|
+
}
|
319
|
+
|
320
|
+
tsi_result Protect(grpc_slice_buffer* slices, int max_frame_size)
|
321
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(write_mu_) {
|
322
|
+
if (shutdown_) return TSI_FAILED_PRECONDITION;
|
323
|
+
|
324
|
+
GRPC_LATENT_SEE_SCOPE("protect");
|
325
|
+
uint8_t* cur = GRPC_SLICE_START_PTR(write_staging_buffer_);
|
326
|
+
uint8_t* end = GRPC_SLICE_END_PTR(write_staging_buffer_);
|
327
|
+
|
328
|
+
output_buffer_.Clear();
|
329
|
+
|
330
|
+
TraceOp("Protect", slices);
|
331
|
+
|
332
|
+
tsi_result result = TSI_OK;
|
333
|
+
if (zero_copy_protector_ != nullptr) {
|
334
|
+
// Use zero-copy grpc protector to protect.
|
335
|
+
// Break the input slices into chunks of size = max_frame_size and call
|
336
|
+
// tsi_zero_copy_grpc_protector_protect on each chunk. This ensures that
|
337
|
+
// the protector cannot create frames larger than the specified
|
338
|
+
// max_frame_size.
|
339
|
+
while (slices->length > static_cast<size_t>(max_frame_size) &&
|
340
|
+
result == TSI_OK) {
|
341
|
+
grpc_slice_buffer_move_first(
|
342
|
+
slices, static_cast<size_t>(max_frame_size),
|
343
|
+
protector_staging_buffer_.c_slice_buffer());
|
344
|
+
result = tsi_zero_copy_grpc_protector_protect(
|
345
|
+
zero_copy_protector_, protector_staging_buffer_.c_slice_buffer(),
|
346
|
+
output_buffer_.c_slice_buffer());
|
347
|
+
}
|
348
|
+
if (result == TSI_OK && slices->length > 0) {
|
349
|
+
result = tsi_zero_copy_grpc_protector_protect(
|
350
|
+
zero_copy_protector_, slices, output_buffer_.c_slice_buffer());
|
351
|
+
}
|
352
|
+
protector_staging_buffer_.Clear();
|
353
|
+
} else {
|
354
|
+
// Use frame protector to protect.
|
355
|
+
for (size_t i = 0; i < slices->count; i++) {
|
356
|
+
grpc_slice plain = slices->slices[i];
|
357
|
+
uint8_t* message_bytes = GRPC_SLICE_START_PTR(plain);
|
358
|
+
size_t message_size = GRPC_SLICE_LENGTH(plain);
|
359
|
+
while (message_size > 0) {
|
360
|
+
size_t protected_buffer_size_to_send = static_cast<size_t>(end - cur);
|
361
|
+
size_t processed_message_size = message_size;
|
362
|
+
if (IsTsiFrameProtectorWithoutLocksEnabled()) {
|
363
|
+
result = tsi_frame_protector_protect(
|
364
|
+
protector_, message_bytes, &processed_message_size, cur,
|
365
|
+
&protected_buffer_size_to_send);
|
366
|
+
} else {
|
367
|
+
protector_mu_.Lock();
|
368
|
+
result = tsi_frame_protector_protect(
|
369
|
+
protector_, message_bytes, &processed_message_size, cur,
|
370
|
+
&protected_buffer_size_to_send);
|
371
|
+
protector_mu_.Unlock();
|
372
|
+
}
|
373
|
+
if (result != TSI_OK) {
|
374
|
+
LOG(ERROR) << "Encryption error: " << tsi_result_to_string(result);
|
375
|
+
break;
|
376
|
+
}
|
377
|
+
message_bytes += processed_message_size;
|
378
|
+
message_size -= processed_message_size;
|
379
|
+
cur += protected_buffer_size_to_send;
|
380
|
+
|
381
|
+
if (cur == end) {
|
382
|
+
FlushWriteStagingBuffer(&cur, &end);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
if (result != TSI_OK) break;
|
386
|
+
}
|
387
|
+
if (result == TSI_OK) {
|
388
|
+
size_t still_pending_size;
|
389
|
+
do {
|
390
|
+
size_t protected_buffer_size_to_send = static_cast<size_t>(end - cur);
|
391
|
+
if (IsTsiFrameProtectorWithoutLocksEnabled()) {
|
392
|
+
result = tsi_frame_protector_protect_flush(
|
393
|
+
protector_, cur, &protected_buffer_size_to_send,
|
394
|
+
&still_pending_size);
|
395
|
+
} else {
|
396
|
+
protector_mu_.Lock();
|
397
|
+
result = tsi_frame_protector_protect_flush(
|
398
|
+
protector_, cur, &protected_buffer_size_to_send,
|
399
|
+
&still_pending_size);
|
400
|
+
protector_mu_.Unlock();
|
401
|
+
}
|
402
|
+
if (result != TSI_OK) break;
|
403
|
+
cur += protected_buffer_size_to_send;
|
404
|
+
if (cur == end) {
|
405
|
+
FlushWriteStagingBuffer(&cur, &end);
|
406
|
+
}
|
407
|
+
} while (still_pending_size > 0);
|
408
|
+
if (cur != GRPC_SLICE_START_PTR(write_staging_buffer_)) {
|
409
|
+
output_buffer_.Append(
|
410
|
+
grpc_event_engine::experimental::Slice(grpc_slice_split_head(
|
411
|
+
&write_staging_buffer_,
|
412
|
+
static_cast<size_t>(
|
413
|
+
cur - GRPC_SLICE_START_PTR(write_staging_buffer_)))));
|
414
|
+
}
|
415
|
+
}
|
416
|
+
}
|
417
|
+
// TODO(yangg) do different things according to the error type?
|
418
|
+
if (result != TSI_OK) output_buffer_.Clear();
|
419
|
+
return result;
|
420
|
+
}
|
421
|
+
|
422
|
+
grpc_event_engine::experimental::SliceBuffer* output_buffer() {
|
423
|
+
return &output_buffer_;
|
424
|
+
}
|
425
|
+
|
426
|
+
void Shutdown() {
|
427
|
+
shutdown_ = true;
|
428
|
+
memory_owner_.Reset();
|
429
|
+
}
|
430
|
+
|
431
|
+
private:
|
432
|
+
struct tsi_frame_protector* const protector_;
|
433
|
+
struct tsi_zero_copy_grpc_protector* const zero_copy_protector_;
|
434
|
+
Mutex mu_;
|
435
|
+
Mutex write_mu_;
|
436
|
+
// The read mutex must be acquired after the write mutex for shutdown
|
437
|
+
// purposes.
|
438
|
+
Mutex read_mu_ ABSL_ACQUIRED_AFTER(write_mu_);
|
439
|
+
Mutex protector_mu_;
|
440
|
+
grpc_slice_buffer* read_buffer_ = nullptr;
|
441
|
+
grpc_event_engine::experimental::SliceBuffer source_buffer_;
|
442
|
+
// saved handshaker leftover data to unprotect.
|
443
|
+
std::unique_ptr<SliceBuffer> leftover_bytes_;
|
444
|
+
// buffers for read and write
|
445
|
+
grpc_slice read_staging_buffer_ ABSL_GUARDED_BY(read_mu_);
|
446
|
+
grpc_slice write_staging_buffer_ ABSL_GUARDED_BY(write_mu_);
|
447
|
+
grpc_event_engine::experimental::SliceBuffer output_buffer_;
|
448
|
+
MemoryOwner memory_owner_;
|
449
|
+
MemoryAllocator::Reservation self_reservation_;
|
450
|
+
std::atomic<bool> has_posted_reclaimer_{false};
|
451
|
+
int min_progress_size_ = 1;
|
452
|
+
SliceBuffer protector_staging_buffer_;
|
453
|
+
bool shutdown_ = false;
|
454
|
+
};
|
455
|
+
} // namespace
|
456
|
+
} // namespace grpc_core
|
457
|
+
|
458
|
+
namespace grpc_event_engine::experimental {
|
459
|
+
namespace {
|
460
|
+
|
461
|
+
class PipelinedSecureEndpoint final : public EventEngine::Endpoint {
|
462
|
+
public:
|
463
|
+
PipelinedSecureEndpoint(
|
464
|
+
std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
|
465
|
+
wrapped_ep,
|
466
|
+
struct tsi_frame_protector* protector,
|
467
|
+
struct tsi_zero_copy_grpc_protector* zero_copy_protector,
|
468
|
+
grpc_slice* leftover_slices, size_t leftover_nslices,
|
469
|
+
const grpc_core::ChannelArgs& channel_args)
|
470
|
+
: impl_(grpc_core::MakeRefCounted<Impl>(
|
471
|
+
std::move(wrapped_ep), protector, zero_copy_protector,
|
472
|
+
leftover_slices, leftover_nslices, channel_args)) {}
|
473
|
+
|
474
|
+
~PipelinedSecureEndpoint() override { impl_->Shutdown(); }
|
475
|
+
|
476
|
+
bool Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer,
|
477
|
+
ReadArgs in_args) override {
|
478
|
+
return impl_->Read(std::move(on_read), buffer, std::move(in_args));
|
479
|
+
}
|
480
|
+
|
481
|
+
bool Write(absl::AnyInvocable<void(absl::Status)> on_writable,
|
482
|
+
SliceBuffer* data, WriteArgs args) override {
|
483
|
+
return impl_->Write(std::move(on_writable), data, std::move(args));
|
484
|
+
}
|
485
|
+
|
486
|
+
const EventEngine::ResolvedAddress& GetPeerAddress() const override {
|
487
|
+
return impl_->GetPeerAddress();
|
488
|
+
}
|
489
|
+
|
490
|
+
const EventEngine::ResolvedAddress& GetLocalAddress() const override {
|
491
|
+
return impl_->GetLocalAddress();
|
492
|
+
}
|
493
|
+
|
494
|
+
void* QueryExtension(absl::string_view id) override {
|
495
|
+
return impl_->QueryExtension(id);
|
496
|
+
}
|
497
|
+
|
498
|
+
std::shared_ptr<TelemetryInfo> GetTelemetryInfo() const override {
|
499
|
+
return std::make_shared<Impl::TelemetryInfo>(impl_->GetTelemetryInfo());
|
500
|
+
}
|
501
|
+
|
502
|
+
private:
|
503
|
+
class Impl : public grpc_core::RefCounted<Impl> {
|
504
|
+
public:
|
505
|
+
class TelemetryInfo : public EventEngine::Endpoint::TelemetryInfo {
|
506
|
+
public:
|
507
|
+
explicit TelemetryInfo(
|
508
|
+
std::shared_ptr<EventEngine::Endpoint::TelemetryInfo>
|
509
|
+
wrapped_telemetry_info)
|
510
|
+
: wrapped_telemetry_info_(std::move(wrapped_telemetry_info)) {}
|
511
|
+
|
512
|
+
std::vector<size_t> AllWriteMetrics() const override {
|
513
|
+
return wrapped_telemetry_info_
|
514
|
+
? wrapped_telemetry_info_->AllWriteMetrics()
|
515
|
+
: std::vector<size_t>{};
|
516
|
+
}
|
517
|
+
|
518
|
+
std::optional<absl::string_view> GetMetricName(
|
519
|
+
size_t key) const override {
|
520
|
+
return wrapped_telemetry_info_
|
521
|
+
? wrapped_telemetry_info_->GetMetricName(key)
|
522
|
+
: std::nullopt;
|
523
|
+
}
|
524
|
+
|
525
|
+
std::optional<size_t> GetMetricKey(
|
526
|
+
absl::string_view name) const override {
|
527
|
+
return wrapped_telemetry_info_
|
528
|
+
? wrapped_telemetry_info_->GetMetricKey(name)
|
529
|
+
: std::nullopt;
|
530
|
+
}
|
531
|
+
|
532
|
+
std::shared_ptr<EventEngine::Endpoint::MetricsSet> GetMetricsSet(
|
533
|
+
absl::Span<const size_t> keys) const override {
|
534
|
+
return wrapped_telemetry_info_
|
535
|
+
? wrapped_telemetry_info_->GetMetricsSet(keys)
|
536
|
+
: nullptr;
|
537
|
+
}
|
538
|
+
|
539
|
+
std::shared_ptr<EventEngine::Endpoint::MetricsSet> GetFullMetricsSet()
|
540
|
+
const override {
|
541
|
+
return wrapped_telemetry_info_
|
542
|
+
? wrapped_telemetry_info_->GetFullMetricsSet()
|
543
|
+
: nullptr;
|
544
|
+
}
|
545
|
+
|
546
|
+
private:
|
547
|
+
std::shared_ptr<EventEngine::Endpoint::TelemetryInfo>
|
548
|
+
wrapped_telemetry_info_;
|
549
|
+
};
|
550
|
+
|
551
|
+
Impl(std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
|
552
|
+
wrapped_ep,
|
553
|
+
struct tsi_frame_protector* protector,
|
554
|
+
struct tsi_zero_copy_grpc_protector* zero_copy_protector,
|
555
|
+
grpc_slice* leftover_slices, size_t leftover_nslices,
|
556
|
+
const grpc_core::ChannelArgs& channel_args)
|
557
|
+
: staging_protected_data_buffer_(std::make_unique<SliceBuffer>()),
|
558
|
+
frame_protector_(protector, zero_copy_protector, leftover_slices,
|
559
|
+
leftover_nslices, channel_args),
|
560
|
+
wrapped_ep_(std::move(wrapped_ep)),
|
561
|
+
event_engine_(channel_args.GetObjectRef<
|
562
|
+
grpc_event_engine::experimental::EventEngine>()) {
|
563
|
+
if (event_engine_ == nullptr) {
|
564
|
+
event_engine_ = GetDefaultEventEngine();
|
565
|
+
}
|
566
|
+
// Kick off the first endpoint read ahead of the first transport read.
|
567
|
+
StartFirstRead();
|
568
|
+
}
|
569
|
+
|
570
|
+
bool Read(absl::AnyInvocable<void(absl::Status)> on_read,
|
571
|
+
SliceBuffer* buffer, ReadArgs args) {
|
572
|
+
GRPC_LATENT_SEE_SCOPE("secure_endpoint read");
|
573
|
+
|
574
|
+
grpc_core::ReleasableMutexLock lock(&read_queue_mu_);
|
575
|
+
// If there's been an error observed asynchronously, then fail out with
|
576
|
+
// that error.
|
577
|
+
if (!unprotecting_.ok()) {
|
578
|
+
event_engine_->Run(
|
579
|
+
[on_read = std::move(on_read),
|
580
|
+
status = unprotecting_.status()]() mutable { on_read(status); });
|
581
|
+
return false;
|
582
|
+
}
|
583
|
+
|
584
|
+
// If we already have some unprotected bytes available, we can just return
|
585
|
+
// those here.
|
586
|
+
if (waiting_for_transport_read_) {
|
587
|
+
waiting_for_transport_read_ = false;
|
588
|
+
if (unprotected_data_buffer_ != nullptr) {
|
589
|
+
*buffer = std::move(*unprotected_data_buffer_);
|
590
|
+
unprotected_data_buffer_.reset();
|
591
|
+
}
|
592
|
+
// We might have been waiting for this transport read before continuing
|
593
|
+
// to unprotect. If we were (the last read completed and there are now
|
594
|
+
// bytes to unprotect), then calling ContinueUnprotect will start
|
595
|
+
// unprotecting these bytes. If we weren't (the last read has not
|
596
|
+
// completed yet), then ContinueUnprotect will just return early and be
|
597
|
+
// called again once that read completes.
|
598
|
+
if (unprotecting_.value()) {
|
599
|
+
lock.Release();
|
600
|
+
event_engine_->Run(
|
601
|
+
[impl = Ref()]() mutable { ContinueUnprotect(std::move(impl)); });
|
602
|
+
}
|
603
|
+
return true;
|
604
|
+
}
|
605
|
+
|
606
|
+
// If we're already unprotecting on another thread, we need to store the
|
607
|
+
// buffer until we have some unprotected bytes to give it.
|
608
|
+
CHECK(on_read_ == nullptr);
|
609
|
+
pending_output_buffer_ = buffer;
|
610
|
+
on_read_ = std::move(on_read);
|
611
|
+
last_read_args_ = std::move(args);
|
612
|
+
return false;
|
613
|
+
}
|
614
|
+
|
615
|
+
bool Write(absl::AnyInvocable<void(absl::Status)> on_writable,
|
616
|
+
SliceBuffer* data, WriteArgs args) {
|
617
|
+
GRPC_LATENT_SEE_SCOPE("secure_endpoint write");
|
618
|
+
tsi_result result;
|
619
|
+
frame_protector_.TraceOp("Write", data->c_slice_buffer());
|
620
|
+
{
|
621
|
+
grpc_core::MutexLock lock(frame_protector_.write_mu());
|
622
|
+
result = frame_protector_.Protect(data->c_slice_buffer(),
|
623
|
+
args.max_frame_size());
|
624
|
+
}
|
625
|
+
if (result != TSI_OK) {
|
626
|
+
event_engine_->Run(
|
627
|
+
[on_writable = std::move(on_writable), result]() mutable {
|
628
|
+
on_writable(GRPC_ERROR_CREATE(absl::StrCat(
|
629
|
+
"Wrap failed (", tsi_result_to_string(result), ")")));
|
630
|
+
});
|
631
|
+
return false;
|
632
|
+
}
|
633
|
+
on_write_ = std::move(on_writable);
|
634
|
+
frame_protector_.TraceOp(
|
635
|
+
"Write", frame_protector_.output_buffer()->c_slice_buffer());
|
636
|
+
return wrapped_ep_->Write(
|
637
|
+
[impl = Ref()](absl::Status status) mutable {
|
638
|
+
auto on_write = std::move(impl->on_write_);
|
639
|
+
impl.reset();
|
640
|
+
on_write(status);
|
641
|
+
},
|
642
|
+
frame_protector_.output_buffer(), std::move(args));
|
643
|
+
}
|
644
|
+
|
645
|
+
const EventEngine::ResolvedAddress& GetPeerAddress() const {
|
646
|
+
return wrapped_ep_->GetPeerAddress();
|
647
|
+
}
|
648
|
+
|
649
|
+
const EventEngine::ResolvedAddress& GetLocalAddress() const {
|
650
|
+
return wrapped_ep_->GetLocalAddress();
|
651
|
+
}
|
652
|
+
|
653
|
+
void* QueryExtension(absl::string_view id) {
|
654
|
+
return wrapped_ep_->QueryExtension(id);
|
655
|
+
}
|
656
|
+
|
657
|
+
void Shutdown() {
|
658
|
+
std::unique_ptr<EventEngine::Endpoint> wrapped_ep;
|
659
|
+
grpc_core::MutexLock write_lock(frame_protector_.write_mu());
|
660
|
+
grpc_core::MutexLock read_lock(frame_protector_.read_mu());
|
661
|
+
grpc_core::MutexLock shutdown_read_lock(&shutdown_read_mu_);
|
662
|
+
wrapped_ep = std::move(wrapped_ep_);
|
663
|
+
frame_protector_.Shutdown();
|
664
|
+
}
|
665
|
+
|
666
|
+
std::shared_ptr<TelemetryInfo> GetTelemetryInfo() const {
|
667
|
+
return std::make_shared<Impl::TelemetryInfo>(
|
668
|
+
wrapped_ep_->GetTelemetryInfo());
|
669
|
+
}
|
670
|
+
|
671
|
+
private:
|
672
|
+
void StartFirstRead() ABSL_LOCKS_EXCLUDED(read_queue_mu_) {
|
673
|
+
grpc_core::ReleasableMutexLock lock(&read_queue_mu_);
|
674
|
+
unprotecting_ = true;
|
675
|
+
CHECK(protected_data_buffer_ == nullptr);
|
676
|
+
CHECK(unprotected_data_buffer_ == nullptr);
|
677
|
+
// First, check if there are any leftover bytes to unprotect. If there
|
678
|
+
// are, we can immediately start unprotecting those bytes.
|
679
|
+
if (frame_protector_.MaybeReadLeftoverBytes(
|
680
|
+
staging_protected_data_buffer_.get())) {
|
681
|
+
MoveStagingIntoProtectedBuffer();
|
682
|
+
lock.Release();
|
683
|
+
// Unprotect inline since we expect a small number of leftover bytes.
|
684
|
+
ContinueUnprotect(Ref());
|
685
|
+
return;
|
686
|
+
}
|
687
|
+
|
688
|
+
// Kick off the first read in another thread.
|
689
|
+
ReadArgs args;
|
690
|
+
args.set_read_hint_bytes(frame_protector_.min_progress_size());
|
691
|
+
lock.Release();
|
692
|
+
event_engine_->Run([impl = Ref(), args = std::move(args)]() mutable {
|
693
|
+
// If the endpoint closed whilst waiting for this callback, then
|
694
|
+
// fail out the read and we're done.
|
695
|
+
grpc_core::ReleasableMutexLock lock(impl->frame_protector_.read_mu());
|
696
|
+
if (impl->wrapped_ep_ == nullptr) {
|
697
|
+
lock.Release();
|
698
|
+
FailReads(std::move(impl),
|
699
|
+
absl::CancelledError("secure endpoint shutdown"));
|
700
|
+
return;
|
701
|
+
}
|
702
|
+
const bool read_finished_immediately = impl->wrapped_ep_->Read(
|
703
|
+
[impl = impl->Ref()](absl::Status status) mutable {
|
704
|
+
FinishFirstRead(std::move(impl), status);
|
705
|
+
},
|
706
|
+
impl->staging_protected_data_buffer_.get(), std::move(args));
|
707
|
+
if (read_finished_immediately) {
|
708
|
+
lock.Release();
|
709
|
+
{
|
710
|
+
grpc_core::MutexLock lock(&impl->read_queue_mu_);
|
711
|
+
impl->frame_protector_.TraceOp(
|
712
|
+
"ReadImm",
|
713
|
+
impl->staging_protected_data_buffer_->c_slice_buffer());
|
714
|
+
impl->MoveStagingIntoProtectedBuffer();
|
715
|
+
}
|
716
|
+
ContinueUnprotect(std::move(impl));
|
717
|
+
}
|
718
|
+
});
|
719
|
+
}
|
720
|
+
|
721
|
+
static void FinishFirstRead(grpc_core::RefCountedPtr<Impl> impl,
|
722
|
+
absl::Status status)
|
723
|
+
ABSL_LOCKS_EXCLUDED(impl->read_queue_mu_) {
|
724
|
+
if (status.ok()) {
|
725
|
+
{
|
726
|
+
grpc_core::MutexLock lock(&impl->read_queue_mu_);
|
727
|
+
impl->frame_protector_.TraceOp(
|
728
|
+
"Read", impl->staging_protected_data_buffer_->c_slice_buffer());
|
729
|
+
impl->MoveStagingIntoProtectedBuffer();
|
730
|
+
}
|
731
|
+
ContinueUnprotect(std::move(impl));
|
732
|
+
return;
|
733
|
+
}
|
734
|
+
FailReads(std::move(impl), status);
|
735
|
+
}
|
736
|
+
|
737
|
+
void MoveStagingIntoProtectedBuffer()
|
738
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_queue_mu_) {
|
739
|
+
protected_data_buffer_ = std::move(staging_protected_data_buffer_);
|
740
|
+
staging_protected_data_buffer_ = std::make_unique<SliceBuffer>();
|
741
|
+
}
|
742
|
+
|
743
|
+
bool ShouldContinueUnprotect()
|
744
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_queue_mu_) {
|
745
|
+
if (unprotecting_.ok() && !unprotecting_.value()) {
|
746
|
+
unprotecting_ = true;
|
747
|
+
return true;
|
748
|
+
}
|
749
|
+
return false;
|
750
|
+
}
|
751
|
+
|
752
|
+
static void FailReads(grpc_core::RefCountedPtr<Impl> impl,
|
753
|
+
absl::Status status)
|
754
|
+
ABSL_LOCKS_EXCLUDED(frame_protector_.read_mu(), read_queue_mu_) {
|
755
|
+
impl->read_queue_mu_.Lock();
|
756
|
+
impl->unprotecting_ = status;
|
757
|
+
auto on_read = std::move(impl->on_read_);
|
758
|
+
impl->read_queue_mu_.Unlock();
|
759
|
+
impl.reset();
|
760
|
+
if (on_read != nullptr) on_read(status);
|
761
|
+
};
|
762
|
+
|
763
|
+
static void ContinueUnprotect(grpc_core::RefCountedPtr<Impl> impl) {
|
764
|
+
GRPC_LATENT_SEE_SCOPE("secure endpoint continue unprotect");
|
765
|
+
ReadArgs args;
|
766
|
+
std::unique_ptr<SliceBuffer> source_buffer;
|
767
|
+
std::unique_ptr<SliceBuffer> read_buffer;
|
768
|
+
absl::Status unprotect_status;
|
769
|
+
absl::AnyInvocable<void(absl::Status)> on_read;
|
770
|
+
|
771
|
+
/*
|
772
|
+
Data passes through the buffers as follows:
|
773
|
+
(1) Data is read into staging buffer.
|
774
|
+
(2) Once ready to be unprotected, data is moved from staging buffer to
|
775
|
+
protected data buffer.
|
776
|
+
(3) Data is passed to frame protector's source buffer and unprotected into
|
777
|
+
read buffer.
|
778
|
+
(4) Unprotected data is passed from read buffer to unprotected data
|
779
|
+
buffer.
|
780
|
+
(5) Lastly, data is optionally passed to pending output buffer if there is
|
781
|
+
currently a pending read.
|
782
|
+
*/
|
783
|
+
while (true) {
|
784
|
+
{
|
785
|
+
grpc_core::ReleasableMutexLock lock(&impl->read_queue_mu_);
|
786
|
+
if (!impl->unprotecting_.ok()) {
|
787
|
+
// Something failed or we're shutting down, so fail reads.
|
788
|
+
auto status = impl->unprotecting_.status();
|
789
|
+
lock.Release();
|
790
|
+
FailReads(std::move(impl), status);
|
791
|
+
return;
|
792
|
+
}
|
793
|
+
|
794
|
+
if (impl->protected_data_buffer_ == nullptr) {
|
795
|
+
// No pending data to unprotect - we're done.
|
796
|
+
impl->unprotecting_ = false;
|
797
|
+
lock.Release();
|
798
|
+
return;
|
799
|
+
}
|
800
|
+
|
801
|
+
// There's more data to unprotect - grab it under the queue lock.
|
802
|
+
source_buffer = std::move(impl->protected_data_buffer_);
|
803
|
+
impl->frame_protector_.TraceOp("data",
|
804
|
+
source_buffer->c_slice_buffer());
|
805
|
+
args = std::move(impl->last_read_args_);
|
806
|
+
args.set_read_hint_bytes(impl->frame_protector_.min_progress_size());
|
807
|
+
}
|
808
|
+
|
809
|
+
// Kick off the next read in another thread while we unprotect in this
|
810
|
+
// thread.
|
811
|
+
impl->event_engine_->Run(
|
812
|
+
[impl = impl->Ref(), args = std::move(args)]() mutable {
|
813
|
+
StartAsyncRead(std::move(impl), std::move(args));
|
814
|
+
});
|
815
|
+
|
816
|
+
{
|
817
|
+
grpc_core::ReleasableMutexLock lock(impl->frame_protector_.read_mu());
|
818
|
+
// Unprotect the bytes.
|
819
|
+
CHECK(read_buffer == nullptr);
|
820
|
+
impl->frame_protector_.SetSourceBuffer(std::move(source_buffer));
|
821
|
+
read_buffer = std::make_unique<SliceBuffer>();
|
822
|
+
impl->frame_protector_.BeginRead(read_buffer->c_slice_buffer());
|
823
|
+
unprotect_status = impl->frame_protector_.Unprotect(absl::OkStatus());
|
824
|
+
impl->frame_protector_.FinishRead(unprotect_status.ok());
|
825
|
+
if (!unprotect_status.ok()) {
|
826
|
+
lock.Release();
|
827
|
+
FailReads(std::move(impl), unprotect_status);
|
828
|
+
return;
|
829
|
+
}
|
830
|
+
}
|
831
|
+
|
832
|
+
impl->read_queue_mu_.Lock();
|
833
|
+
impl->unprotected_data_buffer_ = std::move(read_buffer);
|
834
|
+
// We have a read waiting on this unprotected data - call the
|
835
|
+
// callback and continue in loop.
|
836
|
+
if (impl->on_read_ != nullptr) {
|
837
|
+
*impl->pending_output_buffer_ =
|
838
|
+
std::move(*impl->unprotected_data_buffer_);
|
839
|
+
impl->unprotected_data_buffer_.reset();
|
840
|
+
on_read = std::move(impl->on_read_);
|
841
|
+
impl->read_queue_mu_.Unlock();
|
842
|
+
impl->event_engine_->Run([on_read = std::move(on_read)]() mutable {
|
843
|
+
on_read(absl::OkStatus());
|
844
|
+
});
|
845
|
+
} else {
|
846
|
+
// We're waiting on the next read to read this data. We're done
|
847
|
+
// for now.
|
848
|
+
impl->waiting_for_transport_read_ = true;
|
849
|
+
impl->read_queue_mu_.Unlock();
|
850
|
+
break;
|
851
|
+
}
|
852
|
+
}
|
853
|
+
}
|
854
|
+
|
855
|
+
static void StartAsyncRead(grpc_core::RefCountedPtr<Impl> impl,
|
856
|
+
ReadArgs args)
|
857
|
+
ABSL_LOCKS_EXCLUDED(impl->shutdown_read_mu_, impl->read_queue_mu_) {
|
858
|
+
grpc_core::ReleasableMutexLock lock(&impl->shutdown_read_mu_);
|
859
|
+
if (impl->wrapped_ep_ == nullptr) {
|
860
|
+
lock.Release();
|
861
|
+
FailReads(std::move(impl),
|
862
|
+
absl::CancelledError("secure endpoint shutdown"));
|
863
|
+
return;
|
864
|
+
}
|
865
|
+
const bool read_finished_immediately = impl->wrapped_ep_->Read(
|
866
|
+
[impl = impl->Ref()](absl::Status status) mutable {
|
867
|
+
FinishAsyncRead(std::move(impl), status);
|
868
|
+
},
|
869
|
+
impl->staging_protected_data_buffer_.get(), std::move(args));
|
870
|
+
if (read_finished_immediately) {
|
871
|
+
lock.Release();
|
872
|
+
bool should_unprotect = false;
|
873
|
+
{
|
874
|
+
grpc_core::MutexLock lock(&impl->read_queue_mu_);
|
875
|
+
impl->frame_protector_.TraceOp(
|
876
|
+
"ReadImm",
|
877
|
+
impl->staging_protected_data_buffer_->c_slice_buffer());
|
878
|
+
impl->MoveStagingIntoProtectedBuffer();
|
879
|
+
should_unprotect = impl->ShouldContinueUnprotect();
|
880
|
+
}
|
881
|
+
// We now have data to unprotect so we should continue unprotecting
|
882
|
+
// if not currently doing so.
|
883
|
+
if (should_unprotect) {
|
884
|
+
ContinueUnprotect(std::move(impl));
|
885
|
+
}
|
886
|
+
}
|
887
|
+
}
|
888
|
+
|
889
|
+
static void FinishAsyncRead(grpc_core::RefCountedPtr<Impl> impl,
|
890
|
+
absl::Status status)
|
891
|
+
ABSL_LOCKS_EXCLUDED(impl->read_queue_mu_) {
|
892
|
+
bool should_unprotect = false;
|
893
|
+
{
|
894
|
+
grpc_core::MutexLock lock(&impl->read_queue_mu_);
|
895
|
+
should_unprotect = impl->ShouldContinueUnprotect();
|
896
|
+
if (!status.ok()) {
|
897
|
+
// We rely on ContinueUnprotect to fail the read if the
|
898
|
+
// status is not ok, since we might currently have an
|
899
|
+
// unprotect in progress and we want to return that data
|
900
|
+
// before we fail future reads.
|
901
|
+
impl->unprotecting_ = status;
|
902
|
+
} else {
|
903
|
+
impl->frame_protector_.TraceOp(
|
904
|
+
"Read", impl->staging_protected_data_buffer_->c_slice_buffer());
|
905
|
+
impl->MoveStagingIntoProtectedBuffer();
|
906
|
+
}
|
907
|
+
}
|
908
|
+
// We now have data to unprotect so we should continue unprotecting
|
909
|
+
// if not currently doing so.
|
910
|
+
if (should_unprotect) {
|
911
|
+
ContinueUnprotect(std::move(impl));
|
912
|
+
}
|
913
|
+
}
|
914
|
+
|
915
|
+
grpc_core::Mutex read_queue_mu_;
|
916
|
+
// We have a separate read shutdown lock in order to avoid sharing a lock
|
917
|
+
// between read and unprotect. This way, we can perform reads and
|
918
|
+
// unprotects in parallel. We also must acquire this after both frame
|
919
|
+
// protector mutexes for shutdown purposes.
|
920
|
+
grpc_core::Mutex shutdown_read_mu_
|
921
|
+
ABSL_ACQUIRED_AFTER(frame_protector_.read_mu());
|
922
|
+
bool waiting_for_transport_read_ ABSL_GUARDED_BY(read_queue_mu_) = false;
|
923
|
+
absl::StatusOr<bool> unprotecting_ ABSL_GUARDED_BY(read_queue_mu_) = false;
|
924
|
+
std::unique_ptr<SliceBuffer> unprotected_data_buffer_
|
925
|
+
ABSL_GUARDED_BY(read_queue_mu_);
|
926
|
+
std::unique_ptr<SliceBuffer> staging_protected_data_buffer_;
|
927
|
+
SliceBuffer* pending_output_buffer_ ABSL_GUARDED_BY(read_queue_mu_);
|
928
|
+
std::unique_ptr<SliceBuffer> protected_data_buffer_
|
929
|
+
ABSL_GUARDED_BY(read_queue_mu_);
|
930
|
+
ReadArgs last_read_args_ ABSL_GUARDED_BY(read_queue_mu_);
|
931
|
+
absl::AnyInvocable<void(absl::Status)> on_read_
|
932
|
+
ABSL_GUARDED_BY(read_queue_mu_) = nullptr;
|
933
|
+
// Since writes are currently not pipelined, we don't need to protect this
|
934
|
+
// callback with a mutex.
|
935
|
+
absl::AnyInvocable<void(absl::Status)> on_write_ = nullptr;
|
936
|
+
// Operations to the frame protector are protected by mutexes, so the frame
|
937
|
+
// protector itself does not need to be protected.
|
938
|
+
grpc_core::FrameProtector frame_protector_;
|
939
|
+
// Resetting wrapped endpoint requires holding three different locks, but
|
940
|
+
// other operations using it require holding only one of those locks, so we
|
941
|
+
// don't want any guard annotations on the wrapped_ep_ field.
|
942
|
+
std::unique_ptr<EventEngine::Endpoint> wrapped_ep_;
|
943
|
+
std::shared_ptr<EventEngine> event_engine_;
|
944
|
+
};
|
945
|
+
|
946
|
+
grpc_core::RefCountedPtr<Impl> impl_;
|
947
|
+
};
|
948
|
+
|
949
|
+
} // namespace
|
950
|
+
} // namespace grpc_event_engine::experimental
|
951
|
+
|
952
|
+
grpc_core::OrphanablePtr<grpc_endpoint> grpc_pipelined_secure_endpoint_create(
|
953
|
+
struct tsi_frame_protector* protector,
|
954
|
+
struct tsi_zero_copy_grpc_protector* zero_copy_protector,
|
955
|
+
std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
|
956
|
+
to_wrap,
|
957
|
+
grpc_slice* leftover_slices, const grpc_core::ChannelArgs& channel_args,
|
958
|
+
size_t leftover_nslices) {
|
959
|
+
return grpc_core::OrphanablePtr<grpc_endpoint>(
|
960
|
+
grpc_event_engine::experimental::grpc_event_engine_endpoint_create(
|
961
|
+
std::make_unique<
|
962
|
+
grpc_event_engine::experimental::PipelinedSecureEndpoint>(
|
963
|
+
std::move(to_wrap), protector, zero_copy_protector,
|
964
|
+
leftover_slices, leftover_nslices, channel_args)));
|
965
|
+
}
|