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 "src/core/lib/iomgr/resolve_address.h"
20 #include <grpc/grpc.h>
21 #include <grpc/support/alloc.h>
22 #include <grpc/support/log.h>
23 #include <grpc/support/sync.h>
24 #include <grpc/support/time.h>
25
26 #include <string.h>
27
28 #include "src/core/lib/gpr/env.h"
29 #include "src/core/lib/gpr/string.h"
30 #include "src/core/lib/iomgr/executor.h"
31 #include "src/core/lib/iomgr/iomgr.h"
32 #include "test/core/util/cmdline.h"
33 #include "test/core/util/test_config.h"
34
test_deadline(void)35 static gpr_timespec test_deadline(void) {
36 return grpc_timeout_seconds_to_deadline(100);
37 }
38
39 typedef struct args_struct {
40 gpr_event ev;
41 grpc_resolved_addresses* addrs;
42 gpr_atm done_atm;
43 gpr_mu* mu;
44 grpc_pollset* pollset;
45 grpc_pollset_set* pollset_set;
46 } args_struct;
47
do_nothing(void * arg,grpc_error * error)48 static void do_nothing(void* arg, grpc_error* error) {}
49
args_init(args_struct * args)50 void args_init(args_struct* args) {
51 gpr_event_init(&args->ev);
52 args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
53 grpc_pollset_init(args->pollset, &args->mu);
54 args->pollset_set = grpc_pollset_set_create();
55 grpc_pollset_set_add_pollset(args->pollset_set, args->pollset);
56 args->addrs = nullptr;
57 gpr_atm_rel_store(&args->done_atm, 0);
58 }
59
args_finish(args_struct * args)60 void args_finish(args_struct* args) {
61 GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
62 grpc_resolved_addresses_destroy(args->addrs);
63 grpc_pollset_set_del_pollset(args->pollset_set, args->pollset);
64 grpc_pollset_set_destroy(args->pollset_set);
65 grpc_closure do_nothing_cb;
66 GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr,
67 grpc_schedule_on_exec_ctx);
68 gpr_mu_lock(args->mu);
69 grpc_pollset_shutdown(args->pollset, &do_nothing_cb);
70 gpr_mu_unlock(args->mu);
71 // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
72 grpc_core::ExecCtx::Get()->Flush();
73 grpc_pollset_destroy(args->pollset);
74 gpr_free(args->pollset);
75 }
76
n_sec_deadline(int seconds)77 static grpc_millis n_sec_deadline(int seconds) {
78 return grpc_timespec_to_millis_round_up(
79 grpc_timeout_seconds_to_deadline(seconds));
80 }
81
poll_pollset_until_request_done(args_struct * args)82 static void poll_pollset_until_request_done(args_struct* args) {
83 grpc_core::ExecCtx exec_ctx;
84 grpc_millis deadline = n_sec_deadline(10);
85 while (true) {
86 bool done = gpr_atm_acq_load(&args->done_atm) != 0;
87 if (done) {
88 break;
89 }
90 grpc_millis time_left = deadline - grpc_core::ExecCtx::Get()->Now();
91 gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64, done, time_left);
92 GPR_ASSERT(time_left >= 0);
93 grpc_pollset_worker* worker = nullptr;
94 gpr_mu_lock(args->mu);
95 GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(args->pollset, &worker,
96 n_sec_deadline(1)));
97 gpr_mu_unlock(args->mu);
98 grpc_core::ExecCtx::Get()->Flush();
99 }
100 gpr_event_set(&args->ev, (void*)1);
101 }
102
must_succeed(void * argsp,grpc_error * err)103 static void must_succeed(void* argsp, grpc_error* err) {
104 args_struct* args = static_cast<args_struct*>(argsp);
105 GPR_ASSERT(err == GRPC_ERROR_NONE);
106 GPR_ASSERT(args->addrs != nullptr);
107 GPR_ASSERT(args->addrs->naddrs > 0);
108 gpr_atm_rel_store(&args->done_atm, 1);
109 gpr_mu_lock(args->mu);
110 GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr));
111 gpr_mu_unlock(args->mu);
112 }
113
must_fail(void * argsp,grpc_error * err)114 static void must_fail(void* argsp, grpc_error* err) {
115 args_struct* args = static_cast<args_struct*>(argsp);
116 GPR_ASSERT(err != GRPC_ERROR_NONE);
117 gpr_atm_rel_store(&args->done_atm, 1);
118 gpr_mu_lock(args->mu);
119 GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr));
120 gpr_mu_unlock(args->mu);
121 }
122
test_localhost(void)123 static void test_localhost(void) {
124 grpc_core::ExecCtx exec_ctx;
125 args_struct args;
126 args_init(&args);
127 grpc_resolve_address(
128 "localhost:1", nullptr, args.pollset_set,
129 GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx),
130 &args.addrs);
131 grpc_core::ExecCtx::Get()->Flush();
132 poll_pollset_until_request_done(&args);
133 args_finish(&args);
134 }
135
test_default_port(void)136 static void test_default_port(void) {
137 grpc_core::ExecCtx exec_ctx;
138 args_struct args;
139 args_init(&args);
140 grpc_resolve_address(
141 "localhost", "1", args.pollset_set,
142 GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx),
143 &args.addrs);
144 grpc_core::ExecCtx::Get()->Flush();
145 poll_pollset_until_request_done(&args);
146 args_finish(&args);
147 }
148
test_non_numeric_default_port(void)149 static void test_non_numeric_default_port(void) {
150 grpc_core::ExecCtx exec_ctx;
151 args_struct args;
152 args_init(&args);
153 grpc_resolve_address(
154 "localhost", "https", args.pollset_set,
155 GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx),
156 &args.addrs);
157 grpc_core::ExecCtx::Get()->Flush();
158 poll_pollset_until_request_done(&args);
159 args_finish(&args);
160 }
161
test_missing_default_port(void)162 static void test_missing_default_port(void) {
163 grpc_core::ExecCtx exec_ctx;
164 args_struct args;
165 args_init(&args);
166 grpc_resolve_address(
167 "localhost", nullptr, args.pollset_set,
168 GRPC_CLOSURE_CREATE(must_fail, &args, grpc_schedule_on_exec_ctx),
169 &args.addrs);
170 grpc_core::ExecCtx::Get()->Flush();
171 poll_pollset_until_request_done(&args);
172 args_finish(&args);
173 }
174
test_ipv6_with_port(void)175 static void test_ipv6_with_port(void) {
176 grpc_core::ExecCtx exec_ctx;
177 args_struct args;
178 args_init(&args);
179 grpc_resolve_address(
180 "[2001:db8::1]:1", nullptr, args.pollset_set,
181 GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx),
182 &args.addrs);
183 grpc_core::ExecCtx::Get()->Flush();
184 poll_pollset_until_request_done(&args);
185 args_finish(&args);
186 }
187
test_ipv6_without_port(void)188 static void test_ipv6_without_port(void) {
189 const char* const kCases[] = {
190 "2001:db8::1",
191 "2001:db8::1.2.3.4",
192 "[2001:db8::1]",
193 };
194 unsigned i;
195 for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
196 grpc_core::ExecCtx exec_ctx;
197 args_struct args;
198 args_init(&args);
199 grpc_resolve_address(
200 kCases[i], "80", args.pollset_set,
201 GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx),
202 &args.addrs);
203 grpc_core::ExecCtx::Get()->Flush();
204 poll_pollset_until_request_done(&args);
205 args_finish(&args);
206 }
207 }
208
test_invalid_ip_addresses(void)209 static void test_invalid_ip_addresses(void) {
210 const char* const kCases[] = {
211 "293.283.1238.3:1",
212 "[2001:db8::11111]:1",
213 };
214 unsigned i;
215 for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
216 grpc_core::ExecCtx exec_ctx;
217 args_struct args;
218 args_init(&args);
219 grpc_resolve_address(
220 kCases[i], nullptr, args.pollset_set,
221 GRPC_CLOSURE_CREATE(must_fail, &args, grpc_schedule_on_exec_ctx),
222 &args.addrs);
223 grpc_core::ExecCtx::Get()->Flush();
224 poll_pollset_until_request_done(&args);
225 args_finish(&args);
226 }
227 }
228
test_unparseable_hostports(void)229 static void test_unparseable_hostports(void) {
230 const char* const kCases[] = {
231 "[", "[::1", "[::1]bad", "[1.2.3.4]", "[localhost]", "[localhost]:1",
232 };
233 unsigned i;
234 for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
235 grpc_core::ExecCtx exec_ctx;
236 args_struct args;
237 args_init(&args);
238 grpc_resolve_address(
239 kCases[i], "1", args.pollset_set,
240 GRPC_CLOSURE_CREATE(must_fail, &args, grpc_schedule_on_exec_ctx),
241 &args.addrs);
242 grpc_core::ExecCtx::Get()->Flush();
243 poll_pollset_until_request_done(&args);
244 args_finish(&args);
245 }
246 }
247
main(int argc,char ** argv)248 int main(int argc, char** argv) {
249 // First set the resolver type based off of --resolver
250 const char* resolver_type = nullptr;
251 gpr_cmdline* cl = gpr_cmdline_create("resolve address test");
252 gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)",
253 &resolver_type);
254 gpr_cmdline_parse(cl, argc, argv);
255 const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER");
256 if (cur_resolver != nullptr && strlen(cur_resolver) != 0) {
257 gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s",
258 cur_resolver);
259 }
260 if (gpr_stricmp(resolver_type, "native") == 0) {
261 gpr_setenv("GRPC_DNS_RESOLVER", "native");
262 } else if (gpr_stricmp(resolver_type, "ares") == 0) {
263 #ifndef GRPC_UV
264 gpr_setenv("GRPC_DNS_RESOLVER", "ares");
265 #endif
266 } else {
267 gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native");
268 abort();
269 }
270 // Run the test.
271 grpc_test_init(argc, argv);
272 grpc_init();
273 {
274 grpc_core::ExecCtx exec_ctx;
275 test_localhost();
276 test_default_port();
277 test_non_numeric_default_port();
278 test_missing_default_port();
279 test_ipv6_with_port();
280 test_ipv6_without_port();
281 if (gpr_stricmp(resolver_type, "ares") != 0) {
282 // These tests can trigger DNS queries to the nearby nameserver
283 // that need to come back in order for the test to succeed.
284 // c-ares is prone to not using the local system caches that the
285 // native getaddrinfo implementations take advantage of, so running
286 // these unit tests under c-ares risks flakiness.
287 test_invalid_ip_addresses();
288 test_unparseable_hostports();
289 }
290 grpc_executor_shutdown();
291 }
292 gpr_cmdline_destroy(cl);
293
294 grpc_shutdown();
295 return 0;
296 }
297