• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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