diff --git a/CMakeLists.txt b/CMakeLists.txt index dc941c0820c..5ad4e0c981a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2159,6 +2159,7 @@ add_library(grpc src/core/lib/event_engine/ares_resolver.cc src/core/lib/event_engine/cf_engine/cf_engine.cc src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/default_event_engine.cc src/core/lib/event_engine/default_event_engine_factory.cc @@ -2868,6 +2869,7 @@ add_library(grpc_unsecure src/core/lib/event_engine/ares_resolver.cc src/core/lib/event_engine/cf_engine/cf_engine.cc src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/default_event_engine.cc src/core/lib/event_engine/default_event_engine_factory.cc @@ -4406,6 +4408,7 @@ add_library(grpc_authorization_provider src/core/lib/event_engine/ares_resolver.cc src/core/lib/event_engine/cf_engine/cf_engine.cc src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/default_event_engine.cc src/core/lib/event_engine/default_event_engine_factory.cc @@ -12485,6 +12488,7 @@ add_executable(frame_test src/core/lib/event_engine/ares_resolver.cc src/core/lib/event_engine/cf_engine/cf_engine.cc src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/default_event_engine.cc src/core/lib/event_engine/default_event_engine_factory.cc diff --git a/Makefile b/Makefile index f1a04b993b0..7e39779d5a1 100644 --- a/Makefile +++ b/Makefile @@ -1440,6 +1440,7 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/ares_resolver.cc \ src/core/lib/event_engine/cf_engine/cf_engine.cc \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \ + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/default_event_engine.cc \ src/core/lib/event_engine/default_event_engine_factory.cc \ @@ -2002,6 +2003,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/event_engine/ares_resolver.cc \ src/core/lib/event_engine/cf_engine/cf_engine.cc \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \ + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/default_event_engine.cc \ src/core/lib/event_engine/default_event_engine_factory.cc \ diff --git a/Package.swift b/Package.swift index b712cd822d9..56699d86e08 100644 --- a/Package.swift +++ b/Package.swift @@ -1069,6 +1069,8 @@ let package = Package( "src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc", "src/core/lib/event_engine/cf_engine/cfstream_endpoint.h", "src/core/lib/event_engine/cf_engine/cftype_unique_ref.h", + "src/core/lib/event_engine/cf_engine/dns_service_resolver.cc", + "src/core/lib/event_engine/cf_engine/dns_service_resolver.h", "src/core/lib/event_engine/channel_args_endpoint_config.cc", "src/core/lib/event_engine/channel_args_endpoint_config.h", "src/core/lib/event_engine/common_closures.h", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 607b4493de8..93759c1d0a8 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -687,6 +687,7 @@ libs: - src/core/lib/event_engine/cf_engine/cf_engine.h - src/core/lib/event_engine/cf_engine/cfstream_endpoint.h - src/core/lib/event_engine/cf_engine/cftype_unique_ref.h + - src/core/lib/event_engine/cf_engine/dns_service_resolver.h - src/core/lib/event_engine/channel_args_endpoint_config.h - src/core/lib/event_engine/common_closures.h - src/core/lib/event_engine/default_event_engine.h @@ -1501,6 +1502,7 @@ libs: - src/core/lib/event_engine/ares_resolver.cc - src/core/lib/event_engine/cf_engine/cf_engine.cc - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/default_event_engine.cc - src/core/lib/event_engine/default_event_engine_factory.cc @@ -2084,6 +2086,7 @@ libs: - src/core/lib/event_engine/cf_engine/cf_engine.h - src/core/lib/event_engine/cf_engine/cfstream_endpoint.h - src/core/lib/event_engine/cf_engine/cftype_unique_ref.h + - src/core/lib/event_engine/cf_engine/dns_service_resolver.h - src/core/lib/event_engine/channel_args_endpoint_config.h - src/core/lib/event_engine/common_closures.h - src/core/lib/event_engine/default_event_engine.h @@ -2505,6 +2508,7 @@ libs: - src/core/lib/event_engine/ares_resolver.cc - src/core/lib/event_engine/cf_engine/cf_engine.cc - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/default_event_engine.cc - src/core/lib/event_engine/default_event_engine_factory.cc @@ -3592,6 +3596,7 @@ libs: - src/core/lib/event_engine/cf_engine/cf_engine.h - src/core/lib/event_engine/cf_engine/cfstream_endpoint.h - src/core/lib/event_engine/cf_engine/cftype_unique_ref.h + - src/core/lib/event_engine/cf_engine/dns_service_resolver.h - src/core/lib/event_engine/channel_args_endpoint_config.h - src/core/lib/event_engine/common_closures.h - src/core/lib/event_engine/default_event_engine.h @@ -3892,6 +3897,7 @@ libs: - src/core/lib/event_engine/ares_resolver.cc - src/core/lib/event_engine/cf_engine/cf_engine.cc - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/default_event_engine.cc - src/core/lib/event_engine/default_event_engine_factory.cc @@ -8127,6 +8133,7 @@ targets: - src/core/lib/event_engine/cf_engine/cf_engine.h - src/core/lib/event_engine/cf_engine/cfstream_endpoint.h - src/core/lib/event_engine/cf_engine/cftype_unique_ref.h + - src/core/lib/event_engine/cf_engine/dns_service_resolver.h - src/core/lib/event_engine/channel_args_endpoint_config.h - src/core/lib/event_engine/common_closures.h - src/core/lib/event_engine/default_event_engine.h @@ -8409,6 +8416,7 @@ targets: - src/core/lib/event_engine/ares_resolver.cc - src/core/lib/event_engine/cf_engine/cf_engine.cc - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc + - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/default_event_engine.cc - src/core/lib/event_engine/default_event_engine_factory.cc diff --git a/config.m4 b/config.m4 index 7963168b683..93a4b2c5b50 100644 --- a/config.m4 +++ b/config.m4 @@ -522,6 +522,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/event_engine/ares_resolver.cc \ src/core/lib/event_engine/cf_engine/cf_engine.cc \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \ + src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/default_event_engine.cc \ src/core/lib/event_engine/default_event_engine_factory.cc \ diff --git a/config.w32 b/config.w32 index e8412bdeb19..6de00278ef0 100644 --- a/config.w32 +++ b/config.w32 @@ -487,6 +487,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\event_engine\\ares_resolver.cc " + "src\\core\\lib\\event_engine\\cf_engine\\cf_engine.cc " + "src\\core\\lib\\event_engine\\cf_engine\\cfstream_endpoint.cc " + + "src\\core\\lib\\event_engine\\cf_engine\\dns_service_resolver.cc " + "src\\core\\lib\\event_engine\\channel_args_endpoint_config.cc " + "src\\core\\lib\\event_engine\\default_event_engine.cc " + "src\\core\\lib\\event_engine\\default_event_engine_factory.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0ff4a859756..d9590738516 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -758,6 +758,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/cf_engine/cf_engine.h', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h', 'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.h', 'src/core/lib/event_engine/channel_args_endpoint_config.h', 'src/core/lib/event_engine/common_closures.h', 'src/core/lib/event_engine/default_event_engine.h', @@ -1807,6 +1808,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/cf_engine/cf_engine.h', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h', 'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.h', 'src/core/lib/event_engine/channel_args_endpoint_config.h', 'src/core/lib/event_engine/common_closures.h', 'src/core/lib/event_engine/default_event_engine.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1f7ee059f52..c6f4811efe8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1170,6 +1170,8 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h', 'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.h', 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/channel_args_endpoint_config.h', 'src/core/lib/event_engine/common_closures.h', @@ -2542,6 +2544,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/cf_engine/cf_engine.h', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h', 'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.h', 'src/core/lib/event_engine/channel_args_endpoint_config.h', 'src/core/lib/event_engine/common_closures.h', 'src/core/lib/event_engine/default_event_engine.h', diff --git a/grpc.gemspec b/grpc.gemspec index 8eecc38bea7..d3d4df3b6cc 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1075,6 +1075,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc ) s.files += %w( src/core/lib/event_engine/cf_engine/cfstream_endpoint.h ) s.files += %w( src/core/lib/event_engine/cf_engine/cftype_unique_ref.h ) + s.files += %w( src/core/lib/event_engine/cf_engine/dns_service_resolver.cc ) + s.files += %w( src/core/lib/event_engine/cf_engine/dns_service_resolver.h ) s.files += %w( src/core/lib/event_engine/channel_args_endpoint_config.cc ) s.files += %w( src/core/lib/event_engine/channel_args_endpoint_config.h ) s.files += %w( src/core/lib/event_engine/common_closures.h ) diff --git a/grpc.gyp b/grpc.gyp index 9a53deff7e9..4ac488d26ea 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -744,6 +744,7 @@ 'src/core/lib/event_engine/ares_resolver.cc', 'src/core/lib/event_engine/cf_engine/cf_engine.cc', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/default_event_engine.cc', 'src/core/lib/event_engine/default_event_engine_factory.cc', @@ -1245,6 +1246,7 @@ 'src/core/lib/event_engine/ares_resolver.cc', 'src/core/lib/event_engine/cf_engine/cf_engine.cc', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/default_event_engine.cc', 'src/core/lib/event_engine/default_event_engine_factory.cc', @@ -1766,6 +1768,7 @@ 'src/core/lib/event_engine/ares_resolver.cc', 'src/core/lib/event_engine/cf_engine/cf_engine.cc', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/default_event_engine.cc', 'src/core/lib/event_engine/default_event_engine_factory.cc', diff --git a/package.xml b/package.xml index 00f44d11922..3a8afe9b3fd 100644 --- a/package.xml +++ b/package.xml @@ -1057,6 +1057,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index cda8d1c32ee..cf94603020d 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2123,13 +2123,18 @@ grpc_cc_library( srcs = [ "lib/event_engine/cf_engine/cf_engine.cc", "lib/event_engine/cf_engine/cfstream_endpoint.cc", + "lib/event_engine/cf_engine/dns_service_resolver.cc", ], hdrs = [ "lib/event_engine/cf_engine/cf_engine.h", "lib/event_engine/cf_engine/cfstream_endpoint.h", "lib/event_engine/cf_engine/cftype_unique_ref.h", + "lib/event_engine/cf_engine/dns_service_resolver.h", + ], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings:str_format", ], - external_deps = ["absl/strings:str_format"], deps = [ "event_engine_common", "event_engine_tcp_socket_utils", @@ -2145,6 +2150,7 @@ grpc_cc_library( "strerror", "//:event_engine_base_hdrs", "//:gpr", + "//:parse_address", "//:ref_counted_ptr", "//:sockaddr_utils", ], diff --git a/src/core/lib/event_engine/cf_engine/cf_engine.cc b/src/core/lib/event_engine/cf_engine/cf_engine.cc index f835e64a21e..af0b7248d19 100644 --- a/src/core/lib/event_engine/cf_engine/cf_engine.cc +++ b/src/core/lib/event_engine/cf_engine/cf_engine.cc @@ -22,6 +22,7 @@ #include "src/core/lib/event_engine/cf_engine/cf_engine.h" #include "src/core/lib/event_engine/cf_engine/cfstream_endpoint.h" +#include "src/core/lib/event_engine/cf_engine/dns_service_resolver.h" #include "src/core/lib/event_engine/posix_engine/timer_manager.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/thread_pool/thread_pool.h" @@ -156,9 +157,14 @@ bool CFEventEngine::CancelConnectInternal(ConnectionHandle handle, bool CFEventEngine::IsWorkerThread() { grpc_core::Crash("unimplemented"); } absl::StatusOr> -CFEventEngine::GetDNSResolver( - const DNSResolver::ResolverOptions& /* options */) { - grpc_core::Crash("unimplemented"); +CFEventEngine::GetDNSResolver(const DNSResolver::ResolverOptions& options) { + if (!options.dns_server.empty()) { + return absl::InvalidArgumentError( + "CFEventEngine does not support custom DNS servers"); + } + + return std::make_unique( + std::static_pointer_cast(shared_from_this())); } void CFEventEngine::Run(EventEngine::Closure* closure) { diff --git a/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc b/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc new file mode 100644 index 00000000000..6e30f478ffc --- /dev/null +++ b/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc @@ -0,0 +1,229 @@ +// Copyright 2023 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#ifdef GPR_APPLE + +#include "absl/strings/str_format.h" + +#include "src/core/lib/address_utils/parse_address.h" +#include "src/core/lib/event_engine/cf_engine/dns_service_resolver.h" +#include "src/core/lib/event_engine/posix_engine/lockfree_event.h" +#include "src/core/lib/event_engine/tcp_socket_utils.h" +#include "src/core/lib/event_engine/trace.h" +#include "src/core/lib/gprpp/host_port.h" + +namespace grpc_event_engine { +namespace experimental { + +void DNSServiceResolverImpl::LookupHostname( + EventEngine::DNSResolver::LookupHostnameCallback on_resolve, + absl::string_view name, absl::string_view default_port) { + GRPC_EVENT_ENGINE_DNS_TRACE( + "DNSServiceResolverImpl::LookupHostname: name: %.*s, default_port: %.*s, " + "this: %p", + static_cast(name.length()), name.data(), + static_cast(default_port.length()), default_port.data(), this); + + absl::string_view host; + absl::string_view port_string; + if (!grpc_core::SplitHostPort(name, &host, &port_string)) { + engine_->Run([on_resolve = std::move(on_resolve), + status = absl::InvalidArgumentError( + absl::StrCat("Unparseable name: ", name))]() mutable { + on_resolve(status); + }); + return; + } + GPR_ASSERT(!host.empty()); + if (port_string.empty()) { + if (default_port.empty()) { + engine_->Run([on_resolve = std::move(on_resolve), + status = absl::InvalidArgumentError(absl::StrFormat( + "No port in name %s or default_port argument", + name))]() mutable { on_resolve(std::move(status)); }); + return; + } + port_string = default_port; + } + + int port = 0; + if (port_string == "http") { + port = 80; + } else if (port_string == "https") { + port = 443; + } else if (!absl::SimpleAtoi(port_string, &port)) { + engine_->Run([on_resolve = std::move(on_resolve), + status = absl::InvalidArgumentError(absl::StrCat( + "Failed to parse port in name: ", name))]() mutable { + on_resolve(std::move(status)); + }); + return; + } + + // TODO(yijiem): Change this when refactoring code in + // src/core/lib/address_utils to use EventEngine::ResolvedAddress. + grpc_resolved_address addr; + const std::string hostport = grpc_core::JoinHostPort(host, port); + if (grpc_parse_ipv4_hostport(hostport.c_str(), &addr, + /*log_errors=*/false) || + grpc_parse_ipv6_hostport(hostport.c_str(), &addr, + /*log_errors=*/false)) { + // Early out if the target is an ipv4 or ipv6 literal, otherwise dns service + // responses with kDNSServiceErr_NoSuchRecord + std::vector result; + result.emplace_back(reinterpret_cast(addr.addr), addr.len); + engine_->Run([on_resolve = std::move(on_resolve), + result = std::move(result)]() mutable { + on_resolve(std::move(result)); + }); + return; + } + + DNSServiceRef sdRef; + auto host_string = std::string{host}; + auto error = DNSServiceGetAddrInfo( + &sdRef, kDNSServiceFlagsTimeout | kDNSServiceFlagsReturnIntermediates, 0, + kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, host_string.c_str(), + &DNSServiceResolverImpl::ResolveCallback, this /* do not Ref */); + + if (error != kDNSServiceErr_NoError) { + engine_->Run([on_resolve = std::move(on_resolve), + status = absl::UnknownError(absl::StrFormat( + "DNSServiceGetAddrInfo failed with error:%d", + error))]() mutable { on_resolve(std::move(status)); }); + return; + } + + grpc_core::ReleasableMutexLock lock(&request_mu_); + + error = DNSServiceSetDispatchQueue(sdRef, queue_); + if (error != kDNSServiceErr_NoError) { + engine_->Run([on_resolve = std::move(on_resolve), + status = absl::UnknownError(absl::StrFormat( + "DNSServiceSetDispatchQueue failed with error:%d", + error))]() mutable { on_resolve(std::move(status)); }); + return; + } + + requests_.try_emplace( + sdRef, DNSServiceRequest{ + std::move(on_resolve), static_cast(port), {}}); +} + +/* static */ +void DNSServiceResolverImpl::ResolveCallback( + DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, + DNSServiceErrorType errorCode, const char* hostname, + const struct sockaddr* address, uint32_t ttl, void* context) { + GRPC_EVENT_ENGINE_DNS_TRACE( + "DNSServiceResolverImpl::ResolveCallback: sdRef: %p, flags: %x, " + "interface: %d, errorCode: %d, hostname: %s, addressFamily: %d, ttl: " + "%d, " + "this: %p", + sdRef, flags, interfaceIndex, errorCode, hostname, address->sa_family, + ttl, context); + + // no need to increase refcount here, since ResolveCallback and Shutdown is + // called from the serial queue and it is guarenteed that it won't be called + // after the sdRef is deallocated + auto that = static_cast(context); + + grpc_core::ReleasableMutexLock lock(&that->request_mu_); + auto request_it = that->requests_.find(sdRef); + GPR_ASSERT(request_it != that->requests_.end()); + auto& request = request_it->second; + + if (errorCode != kDNSServiceErr_NoError && + errorCode != kDNSServiceErr_NoSuchRecord) { + request.on_resolve(absl::UnknownError(absl::StrFormat( + "address lookup failed for %s: errorCode: %d", hostname, errorCode))); + that->requests_.erase(request_it); + DNSServiceRefDeallocate(sdRef); + return; + } + + // set received ipv4 or ipv6 response, even for kDNSServiceErr_NoSuchRecord to + // mark that the response for the stack is received, it is possible that the + // one stack receives some results and the other stack gets + // kDNSServiceErr_NoSuchRecord error. + if (address->sa_family == AF_INET) { + request.has_ipv4_response = true; + } else if (address->sa_family == AF_INET6) { + request.has_ipv6_response = true; + } + + // collect results if there is no error (not kDNSServiceErr_NoSuchRecord) + if (errorCode == kDNSServiceErr_NoError) { + request.result.emplace_back(address, address->sa_len); + auto& resolved_address = request.result.back(); + if (address->sa_family == AF_INET) { + (const_cast( + reinterpret_cast(resolved_address.address()))) + ->sin_port = htons(request.port); + } else if (address->sa_family == AF_INET6) { + (const_cast( + reinterpret_cast(resolved_address.address()))) + ->sin6_port = htons(request.port); + } + + GRPC_EVENT_ENGINE_DNS_TRACE( + "DNSServiceResolverImpl::ResolveCallback: " + "sdRef: %p, hostname: %s, addressPort: %s, this: %p", + sdRef, hostname, + ResolvedAddressToString(resolved_address).value_or("ERROR").c_str(), + context); + } + + // received both ipv4 and ipv6 responses, and no more responses (e.g. multiple + // IP addresses for a domain name) are coming, finish `LookupHostname` resolve + // with the collected results. + if (!(flags & kDNSServiceFlagsMoreComing) && request.has_ipv4_response && + request.has_ipv6_response) { + if (request.result.empty()) { + request.on_resolve(absl::NotFoundError(absl::StrFormat( + "address lookup failed for %s: Domain name not found", hostname))); + } else { + request.on_resolve(std::move(request.result)); + } + that->requests_.erase(request_it); + DNSServiceRefDeallocate(sdRef); + } +} + +void DNSServiceResolverImpl::Shutdown() { + dispatch_async_f(queue_, Ref().release(), [](void* thatPtr) { + grpc_core::RefCountedPtr that{ + static_cast(thatPtr)}; + grpc_core::MutexLock lock(&that->request_mu_); + for (auto& kv : that->requests_) { + auto& sdRef = kv.first; + auto& request = kv.second; + GRPC_EVENT_ENGINE_DNS_TRACE( + "DNSServiceResolverImpl::Shutdown sdRef: %p, this: %p", sdRef, + thatPtr); + + request.on_resolve( + absl::CancelledError("DNSServiceResolverImpl::Shutdown")); + DNSServiceRefDeallocate(static_cast(sdRef)); + } + that->requests_.clear(); + }); +} + +} // namespace experimental +} // namespace grpc_event_engine + +#endif // GPR_APPLE diff --git a/src/core/lib/event_engine/cf_engine/dns_service_resolver.h b/src/core/lib/event_engine/cf_engine/dns_service_resolver.h new file mode 100644 index 00000000000..00a55a30500 --- /dev/null +++ b/src/core/lib/event_engine/cf_engine/dns_service_resolver.h @@ -0,0 +1,117 @@ +// Copyright 2023 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H +#include + +#ifdef GPR_APPLE + +#include +#include + +#include "absl/container/flat_hash_map.h" + +#include + +#include "src/core/lib/event_engine/cf_engine/cf_engine.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" + +namespace grpc_event_engine { +namespace experimental { + +class DNSServiceResolverImpl + : public grpc_core::RefCounted { + struct DNSServiceRequest { + EventEngine::DNSResolver::LookupHostnameCallback on_resolve; + uint16_t port; + std::vector result; + bool has_ipv4_response = false; + bool has_ipv6_response = false; + }; + + public: + explicit DNSServiceResolverImpl(std::shared_ptr engine) + : engine_(std::move((engine))) {} + ~DNSServiceResolverImpl() override { + GPR_ASSERT(requests_.empty()); + dispatch_release(queue_); + } + + void Shutdown(); + + void LookupHostname( + EventEngine::DNSResolver::LookupHostnameCallback on_resolve, + absl::string_view name, absl::string_view default_port); + + private: + static void ResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* hostname, + const struct sockaddr* address, uint32_t ttl, + void* context); + + private: + std::shared_ptr engine_; + // DNSServiceSetDispatchQueue requires a serial dispatch queue + dispatch_queue_t queue_ = + dispatch_queue_create("dns_service_resolver", nullptr); + grpc_core::Mutex request_mu_; + absl::flat_hash_map requests_ + ABSL_GUARDED_BY(request_mu_); +}; + +class DNSServiceResolver : public EventEngine::DNSResolver { + public: + explicit DNSServiceResolver(std::shared_ptr engine) + : engine_(std::move(engine)), + impl_(grpc_core::MakeRefCounted( + std::move((engine_)))) {} + + ~DNSServiceResolver() override { impl_->Shutdown(); } + + void LookupHostname( + EventEngine::DNSResolver::LookupHostnameCallback on_resolve, + absl::string_view name, absl::string_view default_port) override { + impl_->LookupHostname(std::move(on_resolve), name, default_port); + }; + + void LookupSRV(EventEngine::DNSResolver::LookupSRVCallback on_resolve, + absl::string_view /* name */) override { + engine_->Run([on_resolve = std::move(on_resolve)]() mutable { + on_resolve(absl::UnimplementedError( + "The DNS Service resolver does not support looking up SRV records")); + }); + } + + void LookupTXT(EventEngine::DNSResolver::LookupTXTCallback on_resolve, + absl::string_view /* name */) override { + engine_->Run([on_resolve = std::move(on_resolve)]() mutable { + on_resolve(absl::UnimplementedError( + "The DNS Service resolver does not support looking up TXT records")); + }); + } + + private: + std::shared_ptr engine_; + grpc_core::RefCountedPtr impl_; +}; + +} // namespace experimental +} // namespace grpc_event_engine + +#endif // GPR_APPLE + +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H diff --git a/src/objective-c/tests/BUILD b/src/objective-c/tests/BUILD index 9eef39eaba6..d5544d6cdf2 100644 --- a/src/objective-c/tests/BUILD +++ b/src/objective-c/tests/BUILD @@ -334,20 +334,36 @@ grpc_objc_ios_unit_test( ) grpc_objc_testing_library( - name = "EventEngineTests-lib", - srcs = glob(["EventEngineTests/*.mm"]), + name = "EventEngineClientTests-lib", + srcs = ["EventEngineTests/CFEventEngineClientTests.mm"], # defines = ["GRPC_IOS_EVENT_ENGINE_CLIENT=1"], deps = [ "//src/core:cf_event_engine", "//test/core/event_engine/test_suite/posix:oracle_event_engine_posix", "//test/core/event_engine/test_suite/tests:client", + ], +) + +grpc_objc_testing_library( + name = "EventEngineUnitTests-lib", + srcs = ["EventEngineTests/CFEventEngineUnitTests.mm"], + defines = ["GRPC_IOS_EVENT_ENGINE_CLIENT=1"], + deps = [ + "//src/core:cf_event_engine", + "//test/core/event_engine/cf:cf_engine_unit_test_lib", + "//test/core/event_engine/test_suite/tests:dns", "//test/core/event_engine/test_suite/tests:timer", ], ) grpc_objc_ios_unit_test( - name = "EventEngineTests", - deps = [":EventEngineTests-lib"], + name = "EventEngineClientTests", + deps = [":EventEngineClientTests-lib"], +) + +grpc_objc_ios_unit_test( + name = "EventEngineUnitTests", + deps = [":EventEngineUnitTests-lib"], ) # Note that bazel currently doesn't support running tvos_unit_test diff --git a/src/objective-c/tests/EventEngineTests/CFEventEngineTests.mm b/src/objective-c/tests/EventEngineTests/CFEventEngineClientTests.mm similarity index 94% rename from src/objective-c/tests/EventEngineTests/CFEventEngineTests.mm rename to src/objective-c/tests/EventEngineTests/CFEventEngineClientTests.mm index 2f32a409314..c5a4e1c9cef 100644 --- a/src/objective-c/tests/EventEngineTests/CFEventEngineTests.mm +++ b/src/objective-c/tests/EventEngineTests/CFEventEngineClientTests.mm @@ -24,7 +24,6 @@ #include "test/core/event_engine/test_suite/event_engine_test_framework.h" #include "test/core/event_engine/test_suite/posix/oracle_event_engine_posix.h" #include "test/core/event_engine/test_suite/tests/client_test.h" -#include "test/core/event_engine/test_suite/tests/timer_test.h" #include "test/core/util/test_config.h" @interface EventEngineTimerTests : XCTestCase @@ -51,7 +50,6 @@ return std::make_unique(); }; SetEventEngineFactories(factory, oracle_factory); - grpc_event_engine::experimental::InitTimerTests(); grpc_event_engine::experimental::InitClientTests(); // TODO(ctiller): EventEngine temporarily needs grpc to be initialized first // until we clear out the iomgr shutdown code. diff --git a/src/objective-c/tests/EventEngineTests/CFEventEngineUnitTests.mm b/src/objective-c/tests/EventEngineTests/CFEventEngineUnitTests.mm new file mode 100644 index 00000000000..d81b25aa8c3 --- /dev/null +++ b/src/objective-c/tests/EventEngineTests/CFEventEngineUnitTests.mm @@ -0,0 +1,61 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#include + +#include "src/core/lib/event_engine/cf_engine/cf_engine.h" +#include "test/core/event_engine/test_suite/event_engine_test_framework.h" +#include "test/core/event_engine/test_suite/tests/dns_test.h" +#include "test/core/event_engine/test_suite/tests/timer_test.h" +#include "test/core/util/test_config.h" + +@interface EventEngineTimerTests : XCTestCase +@end + +@implementation EventEngineTimerTests + +- (void)testAll { + NSArray *arguments = [NSProcessInfo processInfo].arguments; + int argc = (int)arguments.count; + char **argv = static_cast(alloca((sizeof(char *) * (argc + 1)))); + for (int index = 0; index < argc; index++) { + argv[index] = const_cast([arguments[index] UTF8String]); + } + argv[argc] = NULL; + + testing::InitGoogleTest(&argc, (char **)argv); + grpc::testing::TestEnvironment env(&argc, (char **)argv); + + auto factory = []() { + return std::make_unique(); + }; + SetEventEngineFactories(factory, nullptr); + grpc_event_engine::experimental::InitTimerTests(); + grpc_event_engine::experimental::InitDNSTests(); + // TODO(ctiller): EventEngine temporarily needs grpc to be initialized first + // until we clear out the iomgr shutdown code. + grpc_init(); + int r = RUN_ALL_TESTS(); + grpc_shutdown(); + + XCTAssertEqual(r, 0); +} + +@end diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 3a03e18ac08..76fbcce089e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -496,6 +496,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/event_engine/ares_resolver.cc', 'src/core/lib/event_engine/cf_engine/cf_engine.cc', 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/default_event_engine.cc', 'src/core/lib/event_engine/default_event_engine_factory.cc', diff --git a/test/core/event_engine/cf/BUILD b/test/core/event_engine/cf/BUILD index 9bc735bc860..244df0d8860 100644 --- a/test/core/event_engine/cf/BUILD +++ b/test/core/event_engine/cf/BUILD @@ -12,10 +12,32 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_test") +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test") licenses(["notice"]) +grpc_cc_library( + name = "cf_engine_unit_test_lib", + testonly = True, + srcs = ["cf_engine_test.cc"], + external_deps = ["gtest"], + language = "C++", + tags = [ + "no_linux", + "no_windows", + ], + visibility = [ + "//src/objective-c/tests:__subpackages__", + "//test:__subpackages__", + ], + deps = [ + "//:gpr_platform", + "//src/core:cf_event_engine", + "//test/core/util:grpc_test_util", + ], + alwayslink = 1, +) + grpc_cc_test( name = "cf_engine_test", timeout = "short", diff --git a/test/core/event_engine/cf/cf_engine_test.cc b/test/core/event_engine/cf/cf_engine_test.cc index f50b40f82fa..ae9e540b359 100644 --- a/test/core/event_engine/cf/cf_engine_test.cc +++ b/test/core/event_engine/cf/cf_engine_test.cc @@ -19,6 +19,8 @@ #include #include "absl/status/status.h" +#include "absl/strings/str_format.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include @@ -80,6 +82,215 @@ TEST(CFEventEngineTest, TestConnectionCancelled) { client_signal.WaitForNotification(); } +namespace { +std::vector ResolvedAddressesToStrings( + const std::vector addresses) { + std::vector ip_strings; + std::transform(addresses.cbegin(), addresses.cend(), + std::back_inserter(ip_strings), [](auto const& address) { + return ResolvedAddressToString(address).value_or("ERROR"); + }); + return ip_strings; +} +} // namespace + +TEST(CFEventEngineTest, TestCreateDNSResolver) { + grpc_core::MemoryQuota memory_quota("cf_engine_test"); + auto cf_engine = std::make_shared(); + + EXPECT_TRUE(cf_engine->GetDNSResolver({}).status().ok()); + EXPECT_TRUE(cf_engine->GetDNSResolver({.dns_server = ""}).status().ok()); + EXPECT_EQ( + cf_engine->GetDNSResolver({.dns_server = "8.8.8.8"}).status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ( + cf_engine->GetDNSResolver({.dns_server = "8.8.8.8:53"}).status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ( + cf_engine->GetDNSResolver({.dns_server = "invalid"}).status().code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(CFEventEngineTest, TestResolveLocalhost) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT(ResolvedAddressesToStrings(result.value()), + testing::UnorderedElementsAre("127.0.0.1:80", "[::1]:80")); + + resolve_signal.Notify(); + }, + "localhost", "80"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveRemote) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT(ResolvedAddressesToStrings(result.value()), + testing::UnorderedElementsAre("127.0.0.1:80", "[::1]:80")); + + resolve_signal.Notify(); + }, + "localtest.me:80", "443"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveIPv4Remote) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT(ResolvedAddressesToStrings(result.value()), + testing::IsSubsetOf( + {"1.2.3.4:80", "[64:ff9b::102:304]:80" /*NAT64*/})); + + resolve_signal.Notify(); + }, + "1.2.3.4.nip.io:80", ""); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveIPv6Remote) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT( + ResolvedAddressesToStrings(result.value()), + testing::UnorderedElementsAre("[2607:f8b0:400a:801::1002]:80")); + + resolve_signal.Notify(); + }, + "2607-f8b0-400a-801--1002.sslip.io.", "80"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveIPv4Literal) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT(ResolvedAddressesToStrings(result.value()), + testing::UnorderedElementsAre("1.2.3.4:443")); + + resolve_signal.Notify(); + }, + "1.2.3.4", "https"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveIPv6Literal) { + grpc_core::Notification resolve_signal; + + auto cf_engine = std::make_shared(); + auto dns_resolver = cf_engine->GetDNSResolver({}); + + dns_resolver.value()->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT( + ResolvedAddressesToStrings(result.value()), + testing::UnorderedElementsAre("[2607:f8b0:400a:801::1002]:443")); + + resolve_signal.Notify(); + }, + "[2607:f8b0:400a:801::1002]", "443"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveNoRecord) { + grpc_core::Notification resolve_signal; + auto cf_engine = std::make_shared(); + auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value(); + + dns_resolver->LookupHostname( + [&resolve_signal](auto result) { + EXPECT_EQ(result.status().code(), absl::StatusCode::kNotFound); + + resolve_signal.Notify(); + }, + "nonexisting-target.dns-test.event-engine.", "443"); + + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveCanceled) { + grpc_core::Notification resolve_signal; + auto cf_engine = std::make_shared(); + auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value(); + + dns_resolver->LookupHostname( + [&resolve_signal](auto result) { + // query may have already finished before canceling, only verity the + // code if status is not ok + if (!result.status().ok()) { + EXPECT_EQ(result.status().code(), absl::StatusCode::kCancelled); + } + + resolve_signal.Notify(); + }, + "dont-care-since-wont-be-resolved.localtest.me", "443"); + + dns_resolver.reset(); + resolve_signal.WaitForNotification(); +} + +TEST(CFEventEngineTest, TestResolveMany) { + std::atomic times{10}; + grpc_core::Notification resolve_signal; + auto cf_engine = std::make_shared(); + auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value(); + + for (int i = times; i >= 1; --i) { + dns_resolver->LookupHostname( + [&resolve_signal, ×, i](auto result) { + EXPECT_TRUE(result.status().ok()); + EXPECT_THAT( + ResolvedAddressesToStrings(result.value()), + testing::IsSubsetOf( + {absl::StrFormat("100.0.0.%d:443", i), + absl::StrFormat("[64:ff9b::6400:%x]:443", i) /*NAT64*/})); + + if (--times == 0) { + resolve_signal.Notify(); + } + }, + absl::StrFormat("100.0.0.%d.nip.io", i), "443"); + } + + resolve_signal.WaitForNotification(); +} + } // namespace experimental } // namespace grpc_event_engine diff --git a/test/core/event_engine/test_suite/BUILD b/test/core/event_engine/test_suite/BUILD index cc485a4d9a2..385aa7bb6a2 100644 --- a/test/core/event_engine/test_suite/BUILD +++ b/test/core/event_engine/test_suite/BUILD @@ -96,6 +96,7 @@ grpc_cc_test( grpc_cc_test( name = "cf_event_engine_test", srcs = ["cf_event_engine_test.cc"], + copts = ["-DGRPC_IOS_EVENT_ENGINE_CLIENT=1"], tags = [ "no_linux", "no_windows", diff --git a/test/core/event_engine/test_suite/cf_event_engine_test.cc b/test/core/event_engine/test_suite/cf_event_engine_test.cc index 1d222514cb6..8372e448358 100644 --- a/test/core/event_engine/test_suite/cf_event_engine_test.cc +++ b/test/core/event_engine/test_suite/cf_event_engine_test.cc @@ -37,8 +37,6 @@ int main(int argc, char** argv) { SetEventEngineFactories(factory, oracle_factory); grpc_event_engine::experimental::InitTimerTests(); grpc_event_engine::experimental::InitClientTests(); - // TODO(vigneshbabu): remove when the experiment is over - grpc_core::ForceEnableExperiment("event_engine_client", true); // TODO(ctiller): EventEngine temporarily needs grpc to be initialized first // until we clear out the iomgr shutdown code. grpc_init(); diff --git a/test/core/event_engine/test_suite/tests/dns_test.cc b/test/core/event_engine/test_suite/tests/dns_test.cc index cbd48e26bc7..5149959c82b 100644 --- a/test/core/event_engine/test_suite/tests/dns_test.cc +++ b/test/core/event_engine/test_suite/tests/dns_test.cc @@ -102,6 +102,7 @@ MATCHER(StatusCodeEq, "") { class EventEngineDNSTest : public EventEngineTest { protected: static void SetUpTestSuite() { +#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT std::string test_records_path = kDNSTestRecordGroupsYamlPath; std::string dns_server_path = kDNSServerRelPath; std::string dns_resolver_path = kDNSResolverRelPath; @@ -143,12 +144,15 @@ class EventEngineDNSTest : public EventEngineTest { int status = health_check.Join(); // TODO(yijiem): make this portable for Windows ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0); +#endif // GRPC_IOS_EVENT_ENGINE_CLIENT } static void TearDownTestSuite() { +#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT dns_server_.server_process->Interrupt(); dns_server_.server_process->Join(); delete dns_server_.server_process; +#endif // GRPC_IOS_EVENT_ENGINE_CLIENT } std::unique_ptr CreateDefaultDNSResolver() { @@ -194,6 +198,9 @@ class EventEngineDNSTest : public EventEngineTest { EventEngineDNSTest::DNSServer EventEngineDNSTest::dns_server_; +// TODO(hork): implement XFAIL for resolvers that don't support TXT or SRV +#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT + TEST_F(EventEngineDNSTest, QueryNXHostname) { auto dns_resolver = CreateDefaultDNSResolver(); dns_resolver->LookupHostname( @@ -365,6 +372,7 @@ TEST_F(EventEngineDNSTest, TestCancelActiveDNSQuery) { dns_resolver.reset(); dns_resolver_signal_.WaitForNotification(); } +#endif // GRPC_IOS_EVENT_ENGINE_CLIENT #define EXPECT_SUCCESS() \ do { \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ab7809664f8..637de7d2295 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2072,6 +2072,8 @@ src/core/lib/event_engine/cf_engine/cf_engine.h \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.h \ src/core/lib/event_engine/cf_engine/cftype_unique_ref.h \ +src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \ +src/core/lib/event_engine/cf_engine/dns_service_resolver.h \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/channel_args_endpoint_config.h \ src/core/lib/event_engine/common_closures.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index d5b0b9258ab..17607e9339a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1850,6 +1850,8 @@ src/core/lib/event_engine/cf_engine/cf_engine.h \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \ src/core/lib/event_engine/cf_engine/cfstream_endpoint.h \ src/core/lib/event_engine/cf_engine/cftype_unique_ref.h \ +src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \ +src/core/lib/event_engine/cf_engine/dns_service_resolver.h \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/channel_args_endpoint_config.h \ src/core/lib/event_engine/common_closures.h \ diff --git a/tools/internal_ci/macos/grpc_objc_bazel_test.sh b/tools/internal_ci/macos/grpc_objc_bazel_test.sh index 3ed4556dd99..fc82aee4aca 100644 --- a/tools/internal_ci/macos/grpc_objc_bazel_test.sh +++ b/tools/internal_ci/macos/grpc_objc_bazel_test.sh @@ -61,7 +61,8 @@ TEST_TARGETS=( #//src/objective-c/tests:CronetTests #//src/objective-c/tests:PerfTests //src/objective-c/tests:CFStreamTests - //src/objective-c/tests:EventEngineTests + # Needs oracle engine, which doesn't work with GRPC_IOS_EVENT_ENGINE_CLIENT=1 + //src/objective-c/tests:EventEngineClientTests //src/objective-c/tests:tvtests_build_test # codegen plugin tests //src/objective-c/tests:objc_codegen_plugin_test @@ -128,6 +129,7 @@ EVENT_ENGINE_TEST_TARGETS=( //src/objective-c/tests:InteropTestsRemote //src/objective-c/tests:MacTests //src/objective-c/tests:UnitTests + //src/objective-c/tests:EventEngineUnitTests //src/objective-c/tests:tvtests_build_test )