mirror of https://github.com/grpc/grpc.git
Revert "[ObjC] dns service resolver for cf event engine" (#33964)
Reverts grpc/grpc#33233. This is failing 100% of builds https://source.cloud.google.com/results/invocations/248656d3-15ac-4d42-a2f8-6bec5c411e67/targetspull/33966/head
parent
91e7f223d3
commit
48f455a9a0
24 changed files with 8 additions and 623 deletions
@ -1,222 +0,0 @@ |
||||
// 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 <grpc/support/port_platform.h> |
||||
|
||||
#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<int>(name.length()), name.data(), |
||||
static_cast<int>(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.
|
||||
std::vector<EventEngine::ResolvedAddress> result; |
||||
result.emplace_back(reinterpret_cast<sockaddr*>(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<uint16_t>(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<DNSServiceResolverImpl*>(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
|
||||
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<sockaddr_in*>( |
||||
reinterpret_cast<const sockaddr_in*>(resolved_address.address()))) |
||||
->sin_port = htons(request.port); |
||||
} else if (address->sa_family == AF_INET6) { |
||||
(const_cast<sockaddr_in6*>( |
||||
reinterpret_cast<const sockaddr_in6*>(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); |
||||
} |
||||
|
||||
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<DNSServiceResolverImpl> that{ |
||||
static_cast<DNSServiceResolverImpl*>(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<DNSServiceRef>(sdRef)); |
||||
} |
||||
that->requests_.clear(); |
||||
}); |
||||
} |
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc_event_engine
|
||||
|
||||
#endif // GPR_APPLE
|
@ -1,117 +0,0 @@ |
||||
// 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 <grpc/support/port_platform.h> |
||||
|
||||
#ifdef GPR_APPLE |
||||
|
||||
#include <CoreFoundation/CoreFoundation.h> |
||||
#include <dns_sd.h> |
||||
|
||||
#include "absl/container/flat_hash_map.h" |
||||
|
||||
#include <grpc/event_engine/event_engine.h> |
||||
|
||||
#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<DNSServiceResolverImpl> { |
||||
struct DNSServiceRequest { |
||||
EventEngine::DNSResolver::LookupHostnameCallback on_resolve; |
||||
uint16_t port; |
||||
std::vector<EventEngine::ResolvedAddress> result; |
||||
bool has_ipv4_response = false; |
||||
bool has_ipv6_response = false; |
||||
}; |
||||
|
||||
public: |
||||
explicit DNSServiceResolverImpl(std::shared_ptr<CFEventEngine> 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<CFEventEngine> 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<DNSServiceRef, DNSServiceRequest> requests_ |
||||
ABSL_GUARDED_BY(request_mu_); |
||||
}; |
||||
|
||||
class DNSServiceResolver : public EventEngine::DNSResolver { |
||||
public: |
||||
explicit DNSServiceResolver(std::shared_ptr<CFEventEngine> engine) |
||||
: engine_(std::move(engine)), |
||||
impl_(grpc_core::MakeRefCounted<DNSServiceResolverImpl>( |
||||
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<CFEventEngine> engine_; |
||||
grpc_core::RefCountedPtr<DNSServiceResolverImpl> impl_; |
||||
}; |
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc_event_engine
|
||||
|
||||
#endif // GPR_APPLE
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H
|
Loading…
Reference in new issue