36713026820252a8b35d2ecb0ea3d1fee8210fd5
[platform/upstream/grpc.git] / src / core / lib / iomgr / event_engine / resolver.cc
1 // Copyright 2021 The gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include <grpc/support/port_platform.h>
15
16 #ifdef GRPC_USE_EVENT_ENGINE
17 #include <grpc/event_engine/event_engine.h>
18 #include "absl/functional/bind_front.h"
19
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"
30
31 namespace {
32 using ::grpc_event_engine::experimental::CreateGRPCResolvedAddress;
33 using ::grpc_event_engine::experimental::EventEngine;
34 using ::grpc_event_engine::experimental::Promise;
35
36 /// A fire-and-forget class representing an individual DNS request.
37 ///
38 /// This provides a place to store the ownership of the DNSResolver object until
39 /// the request is complete.
40 class DnsRequest {
41  public:
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)),
46         cb_(on_done),
47         addresses_(addresses) {
48     dns_resolver_->LookupHostname(
49         absl::bind_front(&DnsRequest::OnLookupComplete, this), address,
50         default_port, absl::InfiniteFuture());
51   }
52
53  private:
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]);
65     }
66     grpc_closure* cb = cb_;
67     delete this;
68     grpc_core::Closure::Run(DEBUG_LOCATION, cb,
69                             absl_status_to_grpc_error(addresses.status()));
70   }
71
72   std::unique_ptr<EventEngine::DNSResolver> dns_resolver_;
73   grpc_closure* cb_;
74   grpc_resolved_addresses** addresses_;
75 };
76
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()));
85     return;
86   }
87   new DnsRequest(std::move(*dns_resolver), addr, default_port, on_done,
88                  addresses);
89 }
90
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));
93 }
94
95 grpc_error* blocking_resolve_address(const char* name, const char* default_port,
96                                      grpc_resolved_addresses** addresses) {
97   grpc_closure on_done;
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);
102   return evt.Get();
103 }
104
105 }  // namespace
106
107 grpc_address_resolver_vtable grpc_event_engine_resolver_vtable{
108     resolve_address, blocking_resolve_address};
109
110 #endif  // GRPC_USE_EVENT_ENGINE