1 // Copyright 2021 The gRPC Authors
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include <grpc/support/port_platform.h>
16 #ifdef GRPC_USE_EVENT_ENGINE
17 #include <grpc/event_engine/event_engine.h>
18 #include "absl/functional/bind_front.h"
20 #include "src/core/lib/address_utils/sockaddr_utils.h"
21 #include "src/core/lib/gprpp/sync.h"
22 #include "src/core/lib/iomgr/error.h"
23 #include "src/core/lib/iomgr/event_engine/iomgr.h"
24 #include "src/core/lib/iomgr/event_engine/promise.h"
25 #include "src/core/lib/iomgr/event_engine/resolved_address_internal.h"
26 #include "src/core/lib/iomgr/resolve_address.h"
27 #include "src/core/lib/iomgr/work_serializer.h"
28 #include "src/core/lib/surface/init.h"
29 #include "src/core/lib/transport/error_utils.h"
32 using ::grpc_event_engine::experimental::CreateGRPCResolvedAddress;
33 using ::grpc_event_engine::experimental::EventEngine;
34 using ::grpc_event_engine::experimental::Promise;
36 /// A fire-and-forget class representing an individual DNS request.
38 /// This provides a place to store the ownership of the DNSResolver object until
39 /// the request is complete.
42 DnsRequest(std::unique_ptr<EventEngine::DNSResolver> dns_resolver,
43 absl::string_view address, absl::string_view default_port,
44 grpc_closure* on_done, grpc_resolved_addresses** addresses)
45 : dns_resolver_(std::move(dns_resolver)),
47 addresses_(addresses) {
48 dns_resolver_->LookupHostname(
49 absl::bind_front(&DnsRequest::OnLookupComplete, this), address,
50 default_port, absl::InfiniteFuture());
54 void OnLookupComplete(
55 absl::StatusOr<std::vector<EventEngine::ResolvedAddress>> addresses) {
56 grpc_core::ExecCtx exec_ctx;
57 // Convert addresses to iomgr form.
58 *addresses_ = static_cast<grpc_resolved_addresses*>(
59 gpr_malloc(sizeof(grpc_resolved_addresses)));
60 (*addresses_)->naddrs = addresses->size();
61 (*addresses_)->addrs = static_cast<grpc_resolved_address*>(
62 gpr_malloc(sizeof(grpc_resolved_address) * addresses->size()));
63 for (size_t i = 0; i < addresses->size(); ++i) {
64 (*addresses_)->addrs[i] = CreateGRPCResolvedAddress((*addresses)[i]);
66 grpc_closure* cb = cb_;
68 grpc_core::Closure::Run(DEBUG_LOCATION, cb,
69 absl_status_to_grpc_error(addresses.status()));
72 std::unique_ptr<EventEngine::DNSResolver> dns_resolver_;
74 grpc_resolved_addresses** addresses_;
77 void resolve_address(const char* addr, const char* default_port,
78 grpc_pollset_set* /* interested_parties */,
79 grpc_closure* on_done,
80 grpc_resolved_addresses** addresses) {
81 auto dns_resolver = grpc_iomgr_event_engine()->GetDNSResolver();
82 if (!dns_resolver.ok()) {
83 grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done,
84 absl_status_to_grpc_error(dns_resolver.status()));
87 new DnsRequest(std::move(*dns_resolver), addr, default_port, on_done,
91 void blocking_handle_async_resolve_done(void* arg, grpc_error_handle error) {
92 static_cast<Promise<grpc_error_handle>*>(arg)->Set(std::move(error));
95 grpc_error* blocking_resolve_address(const char* name, const char* default_port,
96 grpc_resolved_addresses** addresses) {
98 Promise<grpc_error_handle> evt;
99 GRPC_CLOSURE_INIT(&on_done, blocking_handle_async_resolve_done, &evt,
100 grpc_schedule_on_exec_ctx);
101 resolve_address(name, default_port, nullptr, &on_done, addresses);
107 grpc_address_resolver_vtable grpc_event_engine_resolver_vtable{
108 resolve_address, blocking_resolve_address};
110 #endif // GRPC_USE_EVENT_ENGINE