grpc_ares_wrapper.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2016 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 
20 
21 #include <algorithm>
22 #include <vector>
23 
25 
26 // IWYU pragma: no_include <arpa/nameser.h>
27 // IWYU pragma: no_include <inttypes.h>
28 // IWYU pragma: no_include <netdb.h>
29 // IWYU pragma: no_include <netinet/in.h>
30 // IWYU pragma: no_include <stdlib.h>
31 // IWYU pragma: no_include <sys/socket.h>
32 
33 #if GRPC_ARES == 1
34 
35 #include <string.h>
36 #include <sys/types.h> // IWYU pragma: keep
37 
38 #include <string>
39 #include <utility>
40 
42 #include <ares.h>
43 
44 #include "absl/container/inlined_vector.h"
45 #include "absl/memory/memory.h"
46 #include "absl/status/status.h"
47 #include "absl/status/statusor.h"
48 #include "absl/strings/str_cat.h"
49 #include "absl/strings/str_format.h"
50 
52 #include <grpc/support/alloc.h>
53 #include <grpc/support/log.h>
55 #include <grpc/support/sync.h>
56 
68 #include "src/core/lib/iomgr/nameser.h" // IWYU pragma: keep
71 
74 
76  "cares_address_sorting");
77 
78 grpc_core::TraceFlag grpc_trace_cares_resolver(false, "cares_resolver");
79 
80 typedef struct fd_node {
81  /* default constructor exists only for linked list manipulation */
82  fd_node() : ev_driver(nullptr) {}
83 
84  explicit fd_node(grpc_ares_ev_driver* ev_driver) : ev_driver(ev_driver) {}
85 
87  grpc_ares_ev_driver* const ev_driver;
95  struct fd_node* next ABSL_GUARDED_BY(&grpc_ares_request::mu);
96 
98  grpc_core::GrpcPolledFd* grpc_polled_fd
101  bool readable_registered ABSL_GUARDED_BY(&grpc_ares_request::mu);
103  bool writable_registered ABSL_GUARDED_BY(&grpc_ares_request::mu);
105  bool already_shutdown ABSL_GUARDED_BY(&grpc_ares_request::mu);
106 } fd_node;
107 
108 struct grpc_ares_ev_driver {
110 
117 
119  fd_node* fds ABSL_GUARDED_BY(&grpc_ares_request::mu);
121  bool shutting_down ABSL_GUARDED_BY(&grpc_ares_request::mu);
123  grpc_ares_request* const request;
125  std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory
128  int query_timeout_ms ABSL_GUARDED_BY(&grpc_ares_request::mu);
134  grpc_timer ares_backup_poll_alarm ABSL_GUARDED_BY(&grpc_ares_request::mu);
136  grpc_closure on_ares_backup_poll_alarm_locked
138 };
139 
140 // TODO(apolcyn): make grpc_ares_hostbyname_request a sub-class
141 // of GrpcAresQuery.
142 typedef struct grpc_ares_hostbyname_request {
146  grpc_ares_request* parent_request;
148  char* host;
150  uint16_t port;
152  bool is_balancer;
154  const char* qtype;
155 } grpc_ares_hostbyname_request;
156 
157 static void grpc_ares_request_ref_locked(grpc_ares_request* r)
159 static void grpc_ares_request_unref_locked(grpc_ares_request* r)
161 
162 // TODO(apolcyn): as a part of C++-ification, find a way to
163 // organize per-query and per-resolution information in such a way
164 // that doesn't involve allocating a number of different data
165 // structures.
166 class GrpcAresQuery {
167  public:
168  explicit GrpcAresQuery(grpc_ares_request* r, const std::string& name)
169  : r_(r), name_(name) {
170  grpc_ares_request_ref_locked(r_);
171  }
172 
173  ~GrpcAresQuery() { grpc_ares_request_unref_locked(r_); }
174 
175  grpc_ares_request* parent_request() { return r_; }
176 
177  const std::string& name() { return name_; }
178 
179  private:
180  /* the top level request instance */
181  grpc_ares_request* r_;
183  const std::string name_;
184 };
185 
186 static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
187  grpc_ares_ev_driver* ev_driver)
189  GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
190  ev_driver);
191  gpr_ref(&ev_driver->refs);
192  return ev_driver;
193 }
194 
195 static void grpc_ares_complete_request_locked(grpc_ares_request* r)
197 
198 static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver)
200  GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
201  ev_driver);
202  if (gpr_unref(&ev_driver->refs)) {
203  GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
204  ev_driver);
205  GPR_ASSERT(ev_driver->fds == nullptr);
206  ares_destroy(ev_driver->channel);
207  grpc_ares_complete_request_locked(ev_driver->request);
208  delete ev_driver;
209  }
210 }
211 
212 static void fd_node_destroy_locked(fd_node* fdn)
214  GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
215  fdn->grpc_polled_fd->GetName());
216  GPR_ASSERT(!fdn->readable_registered);
217  GPR_ASSERT(!fdn->writable_registered);
218  GPR_ASSERT(fdn->already_shutdown);
219  delete fdn->grpc_polled_fd;
220  delete fdn;
221 }
222 
223 static void fd_node_shutdown_locked(fd_node* fdn, const char* reason)
225  if (!fdn->already_shutdown) {
226  fdn->already_shutdown = true;
227  fdn->grpc_polled_fd->ShutdownLocked(
229  }
230 }
231 
232 void grpc_ares_ev_driver_on_queries_complete_locked(
233  grpc_ares_ev_driver* ev_driver)
235  // We mark the event driver as being shut down.
236  // grpc_ares_notify_on_event_locked will shut down any remaining
237  // fds.
238  ev_driver->shutting_down = true;
239  grpc_timer_cancel(&ev_driver->query_timeout);
240  grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm);
241  grpc_ares_ev_driver_unref(ev_driver);
242 }
243 
244 void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver)
246  ev_driver->shutting_down = true;
247  fd_node* fn = ev_driver->fds;
248  while (fn != nullptr) {
249  fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
250  fn = fn->next;
251  }
252 }
253 
254 // Search fd in the fd_node list head. This is an O(n) search, the max possible
255 // value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
256 static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as)
258  fd_node phony_head;
259  phony_head.next = *head;
260  fd_node* node = &phony_head;
261  while (node->next != nullptr) {
262  if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
263  fd_node* ret = node->next;
264  node->next = node->next->next;
265  *head = phony_head.next;
266  return ret;
267  }
268  node = node->next;
269  }
270  return nullptr;
271 }
272 
273 static grpc_core::Timestamp calculate_next_ares_backup_poll_alarm(
274  grpc_ares_ev_driver* driver)
276  // An alternative here could be to use ares_timeout to try to be more
277  // accurate, but that would require using "struct timeval"'s, which just makes
278  // things a bit more complicated. So just poll every second, as suggested
279  // by the c-ares code comments.
280  grpc_core::Duration until_next_ares_backup_poll_alarm =
283  "request:%p ev_driver=%p. next ares process poll time in "
284  "%" PRId64 " ms",
285  driver->request, driver, until_next_ares_backup_poll_alarm.millis());
286  return grpc_core::ExecCtx::Get()->Now() + until_next_ares_backup_poll_alarm;
287 }
288 
289 static void on_timeout(void* arg, grpc_error_handle error) {
290  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
291  grpc_core::MutexLock lock(&driver->request->mu);
293  "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
294  "err=%s",
295  driver->request, driver, driver->shutting_down,
297  if (!driver->shutting_down && GRPC_ERROR_IS_NONE(error)) {
298  grpc_ares_ev_driver_shutdown_locked(driver);
299  }
300  grpc_ares_ev_driver_unref(driver);
301 }
302 
303 static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver)
305 
306 /* In case of non-responsive DNS servers, dropped packets, etc., c-ares has
307  * intelligent timeout and retry logic, which we can take advantage of by
308  * polling ares_process_fd on time intervals. Overall, the c-ares library is
309  * meant to be called into and given a chance to proceed name resolution:
310  * a) when fd events happen
311  * b) when some time has passed without fd events having happened
312  * For the latter, we use this backup poller. Also see
313  * https://github.com/grpc/grpc/pull/17688 description for more details. */
314 static void on_ares_backup_poll_alarm(void* arg, grpc_error_handle error) {
315  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
316  grpc_core::MutexLock lock(&driver->request->mu);
318  "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. "
319  "driver->shutting_down=%d. "
320  "err=%s",
321  driver->request, driver, driver->shutting_down,
323  if (!driver->shutting_down && GRPC_ERROR_IS_NONE(error)) {
324  fd_node* fdn = driver->fds;
325  while (fdn != nullptr) {
326  if (!fdn->already_shutdown) {
328  "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; "
329  "ares_process_fd. fd=%s",
330  driver->request, driver, fdn->grpc_polled_fd->GetName());
331  ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
332  ares_process_fd(driver->channel, as, as);
333  }
334  fdn = fdn->next;
335  }
336  if (!driver->shutting_down) {
337  // InvalidateNow to avoid getting stuck re-initializing this timer
338  // in a loop while draining the currently-held WorkSerializer.
339  // Also see https://github.com/grpc/grpc/issues/26079.
341  grpc_core::Timestamp next_ares_backup_poll_alarm =
342  calculate_next_ares_backup_poll_alarm(driver);
343  grpc_ares_ev_driver_ref(driver);
344  GRPC_CLOSURE_INIT(&driver->on_ares_backup_poll_alarm_locked,
345  on_ares_backup_poll_alarm, driver,
346  grpc_schedule_on_exec_ctx);
347  grpc_timer_init(&driver->ares_backup_poll_alarm,
348  next_ares_backup_poll_alarm,
349  &driver->on_ares_backup_poll_alarm_locked);
350  }
351  grpc_ares_notify_on_event_locked(driver);
352  }
353  grpc_ares_ev_driver_unref(driver);
354 }
355 
356 static void on_readable(void* arg, grpc_error_handle error) {
357  fd_node* fdn = static_cast<fd_node*>(arg);
358  grpc_core::MutexLock lock(&fdn->ev_driver->request->mu);
359  GPR_ASSERT(fdn->readable_registered);
360  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
361  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
362  fdn->readable_registered = false;
363  GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
364  fdn->grpc_polled_fd->GetName());
365  if (GRPC_ERROR_IS_NONE(error)) {
366  do {
367  ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
368  } while (fdn->grpc_polled_fd->IsFdStillReadableLocked());
369  } else {
370  // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
371  // timed out. The pending lookups made on this ev_driver will be cancelled
372  // by the following ares_cancel() and the on_done callbacks will be invoked
373  // with a status of ARES_ECANCELLED. The remaining file descriptors in this
374  // ev_driver will be cleaned up in the follwing
375  // grpc_ares_notify_on_event_locked().
376  ares_cancel(ev_driver->channel);
377  }
378  grpc_ares_notify_on_event_locked(ev_driver);
379  grpc_ares_ev_driver_unref(ev_driver);
380 }
381 
382 static void on_writable(void* arg, grpc_error_handle error) {
383  fd_node* fdn = static_cast<fd_node*>(arg);
384  grpc_core::MutexLock lock(&fdn->ev_driver->request->mu);
385  GPR_ASSERT(fdn->writable_registered);
386  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
387  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
388  fdn->writable_registered = false;
389  GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
390  fdn->grpc_polled_fd->GetName());
391  if (GRPC_ERROR_IS_NONE(error)) {
392  ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
393  } else {
394  // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
395  // timed out. The pending lookups made on this ev_driver will be cancelled
396  // by the following ares_cancel() and the on_done callbacks will be invoked
397  // with a status of ARES_ECANCELLED. The remaining file descriptors in this
398  // ev_driver will be cleaned up in the follwing
399  // grpc_ares_notify_on_event_locked().
400  ares_cancel(ev_driver->channel);
401  }
402  grpc_ares_notify_on_event_locked(ev_driver);
403  grpc_ares_ev_driver_unref(ev_driver);
404 }
405 
406 // Get the file descriptors used by the ev_driver's ares channel, register
407 // driver_closure with these filedescriptors.
408 static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver)
410  fd_node* new_list = nullptr;
411  if (!ev_driver->shutting_down) {
413  int socks_bitmask =
414  ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
415  for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
416  if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
417  ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
418  fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
419  // Create a new fd_node if sock[i] is not in the fd_node list.
420  if (fdn == nullptr) {
421  fdn = new fd_node(ev_driver);
422  fdn->grpc_polled_fd =
423  ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
424  socks[i], ev_driver->pollset_set);
425  GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
426  fdn->grpc_polled_fd->GetName());
427  fdn->readable_registered = false;
428  fdn->writable_registered = false;
429  fdn->already_shutdown = false;
430  }
431  fdn->next = new_list;
432  new_list = fdn;
433  // Register read_closure if the socket is readable and read_closure has
434  // not been registered with this socket.
435  if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
436  !fdn->readable_registered) {
437  grpc_ares_ev_driver_ref(ev_driver);
438  GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
439  ev_driver->request,
440  fdn->grpc_polled_fd->GetName());
441  GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable, fdn,
442  grpc_schedule_on_exec_ctx);
443  fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
444  fdn->readable_registered = true;
445  }
446  // Register write_closure if the socket is writable and write_closure
447  // has not been registered with this socket.
448  if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
449  !fdn->writable_registered) {
450  GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
451  ev_driver->request,
452  fdn->grpc_polled_fd->GetName());
453  grpc_ares_ev_driver_ref(ev_driver);
454  GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
455  grpc_schedule_on_exec_ctx);
456  GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
457  grpc_schedule_on_exec_ctx);
458  fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
459  &fdn->write_closure);
460  fdn->writable_registered = true;
461  }
462  }
463  }
464  }
465  // Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
466  // are therefore no longer in use, so they can be shut down and removed from
467  // the list.
468  while (ev_driver->fds != nullptr) {
469  fd_node* cur = ev_driver->fds;
470  ev_driver->fds = ev_driver->fds->next;
471  fd_node_shutdown_locked(cur, "c-ares fd shutdown");
472  if (!cur->readable_registered && !cur->writable_registered) {
473  fd_node_destroy_locked(cur);
474  } else {
475  cur->next = new_list;
476  new_list = cur;
477  }
478  }
479  ev_driver->fds = new_list;
480 }
481 
482 void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver)
484  grpc_ares_notify_on_event_locked(ev_driver);
485  // Initialize overall DNS resolution timeout alarm
487  ev_driver->query_timeout_ms == 0
489  : grpc_core::Duration::Milliseconds(ev_driver->query_timeout_ms);
491  "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
492  "%" PRId64 " ms",
493  ev_driver->request, ev_driver, timeout.millis());
494  grpc_ares_ev_driver_ref(ev_driver);
495  GRPC_CLOSURE_INIT(&ev_driver->on_timeout_locked, on_timeout, ev_driver,
496  grpc_schedule_on_exec_ctx);
497  grpc_timer_init(&ev_driver->query_timeout,
499  &ev_driver->on_timeout_locked);
500  // Initialize the backup poll alarm
501  grpc_core::Timestamp next_ares_backup_poll_alarm =
502  calculate_next_ares_backup_poll_alarm(ev_driver);
503  grpc_ares_ev_driver_ref(ev_driver);
504  GRPC_CLOSURE_INIT(&ev_driver->on_ares_backup_poll_alarm_locked,
505  on_ares_backup_poll_alarm, ev_driver,
506  grpc_schedule_on_exec_ctx);
507  grpc_timer_init(&ev_driver->ares_backup_poll_alarm,
508  next_ares_backup_poll_alarm,
509  &ev_driver->on_ares_backup_poll_alarm_locked);
510 }
511 
512 static void noop_inject_channel_config(ares_channel /*channel*/) {}
513 
515  noop_inject_channel_config;
516 
517 grpc_error_handle grpc_ares_ev_driver_create_locked(
518  grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
519  int query_timeout_ms, grpc_ares_request* request)
521  *ev_driver = new grpc_ares_ev_driver(request);
523  memset(&opts, 0, sizeof(opts));
524  opts.flags |= ARES_FLAG_STAYOPEN;
525  int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
526  grpc_ares_test_only_inject_config((*ev_driver)->channel);
527  GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
528  if (status != ARES_SUCCESS) {
530  "Failed to init ares channel. C-ares error: ", ares_strerror(status)));
531  delete *ev_driver;
532  return err;
533  }
534  gpr_ref_init(&(*ev_driver)->refs, 1);
535  (*ev_driver)->pollset_set = pollset_set;
536  (*ev_driver)->fds = nullptr;
537  (*ev_driver)->shutting_down = false;
538  (*ev_driver)->polled_fd_factory =
539  grpc_core::NewGrpcPolledFdFactory(&(*ev_driver)->request->mu);
540  (*ev_driver)
541  ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
542  (*ev_driver)->query_timeout_ms = query_timeout_ms;
543  return GRPC_ERROR_NONE;
544 }
545 
546 static void log_address_sorting_list(const grpc_ares_request* r,
547  const ServerAddressList& addresses,
548  const char* input_output_str) {
549  for (size_t i = 0; i < addresses.size(); i++) {
550  auto addr_str = grpc_sockaddr_to_string(&addresses[i].address(), true);
552  "(c-ares resolver) request:%p c-ares address sorting: %s[%" PRIuPTR
553  "]=%s",
554  r, input_output_str, i,
555  addr_str.ok() ? addr_str->c_str()
556  : addr_str.status().ToString().c_str());
557  }
558 }
559 
561  ServerAddressList* addresses) {
563  log_address_sorting_list(r, *addresses, "input");
564  }
565  address_sorting_sortable* sortables = static_cast<address_sorting_sortable*>(
566  gpr_zalloc(sizeof(address_sorting_sortable) * addresses->size()));
567  for (size_t i = 0; i < addresses->size(); ++i) {
568  sortables[i].user_data = &(*addresses)[i];
569  memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr,
570  (*addresses)[i].address().len);
571  sortables[i].dest_addr.len = (*addresses)[i].address().len;
572  }
573  address_sorting_rfc_6724_sort(sortables, addresses->size());
574  ServerAddressList sorted;
575  sorted.reserve(addresses->size());
576  for (size_t i = 0; i < addresses->size(); ++i) {
577  sorted.emplace_back(*static_cast<ServerAddress*>(sortables[i].user_data));
578  }
579  gpr_free(sortables);
580  *addresses = std::move(sorted);
582  log_address_sorting_list(r, *addresses, "output");
583  }
584 }
585 
586 static void grpc_ares_request_ref_locked(grpc_ares_request* r)
588  r->pending_queries++;
589 }
590 
591 static void grpc_ares_request_unref_locked(grpc_ares_request* r)
593  r->pending_queries--;
594  if (r->pending_queries == 0u) {
595  grpc_ares_ev_driver_on_queries_complete_locked(r->ev_driver);
596  }
597 }
598 
599 void grpc_ares_complete_request_locked(grpc_ares_request* r)
601  /* Invoke on_done callback and destroy the
602  request */
603  r->ev_driver = nullptr;
604  ServerAddressList* addresses = r->addresses_out->get();
605  if (addresses != nullptr) {
607  GRPC_ERROR_UNREF(r->error);
608  r->error = GRPC_ERROR_NONE;
609  // TODO(apolcyn): allow c-ares to return a service config
610  // with no addresses along side it
611  }
612  if (r->balancer_addresses_out != nullptr) {
613  ServerAddressList* balancer_addresses = r->balancer_addresses_out->get();
614  if (balancer_addresses != nullptr) {
615  grpc_cares_wrapper_address_sorting_sort(r, balancer_addresses);
616  }
617  }
618  grpc_core::ExecCtx::Run(DEBUG_LOCATION, r->on_done, r->error);
619 }
620 
621 /* Note that the returned object takes a reference to qtype, so
622  * qtype must outlive it. */
623 static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
624  grpc_ares_request* parent_request, const char* host, uint16_t port,
625  bool is_balancer, const char* qtype)
626  ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_request->mu) {
628  "request:%p create_hostbyname_request_locked host:%s port:%d "
629  "is_balancer:%d qtype:%s",
630  parent_request, host, port, is_balancer, qtype);
631  grpc_ares_hostbyname_request* hr = new grpc_ares_hostbyname_request();
632  hr->parent_request = parent_request;
633  hr->host = gpr_strdup(host);
634  hr->port = port;
635  hr->is_balancer = is_balancer;
636  hr->qtype = qtype;
637  grpc_ares_request_ref_locked(parent_request);
638  return hr;
639 }
640 
641 static void destroy_hostbyname_request_locked(grpc_ares_hostbyname_request* hr)
642  ABSL_EXCLUSIVE_LOCKS_REQUIRED(hr->parent_request->mu) {
643  grpc_ares_request_unref_locked(hr->parent_request);
644  gpr_free(hr->host);
645  delete hr;
646 }
647 
648 static void on_hostbyname_done_locked(void* arg, int status, int /*timeouts*/,
649  struct hostent* hostent)
651  // This callback is invoked from the c-ares library, so disable thread safety
652  // analysis. Note that we are guaranteed to be holding r->mu, though.
653  grpc_ares_hostbyname_request* hr =
654  static_cast<grpc_ares_hostbyname_request*>(arg);
655  grpc_ares_request* r = hr->parent_request;
656  if (status == ARES_SUCCESS) {
658  "request:%p on_hostbyname_done_locked qtype=%s host=%s ARES_SUCCESS", r,
659  hr->qtype, hr->host);
660  std::unique_ptr<ServerAddressList>* address_list_ptr =
661  hr->is_balancer ? r->balancer_addresses_out : r->addresses_out;
662  if (*address_list_ptr == nullptr) {
663  *address_list_ptr = absl::make_unique<ServerAddressList>();
664  }
665  ServerAddressList& addresses = **address_list_ptr;
666  for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) {
668  if (hr->is_balancer) {
670  const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), hr->host));
671  }
673  nullptr, args_to_add.data(), args_to_add.size());
674  switch (hostent->h_addrtype) {
675  case AF_INET6: {
676  size_t addr_len = sizeof(struct sockaddr_in6);
677  struct sockaddr_in6 addr;
678  memset(&addr, 0, addr_len);
679  memcpy(&addr.sin6_addr, hostent->h_addr_list[i],
680  sizeof(struct in6_addr));
681  addr.sin6_family = static_cast<unsigned char>(hostent->h_addrtype);
682  addr.sin6_port = hr->port;
683  addresses.emplace_back(&addr, addr_len, args);
684  char output[INET6_ADDRSTRLEN];
685  ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
687  "request:%p c-ares resolver gets a AF_INET6 result: \n"
688  " addr: %s\n port: %d\n sin6_scope_id: %d\n",
689  r, output, ntohs(hr->port), addr.sin6_scope_id);
690  break;
691  }
692  case AF_INET: {
693  size_t addr_len = sizeof(struct sockaddr_in);
694  struct sockaddr_in addr;
695  memset(&addr, 0, addr_len);
696  memcpy(&addr.sin_addr, hostent->h_addr_list[i],
697  sizeof(struct in_addr));
698  addr.sin_family = static_cast<unsigned char>(hostent->h_addrtype);
699  addr.sin_port = hr->port;
700  addresses.emplace_back(&addr, addr_len, args);
701  char output[INET_ADDRSTRLEN];
702  ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
704  "request:%p c-ares resolver gets a AF_INET result: \n"
705  " addr: %s\n port: %d\n",
706  r, output, ntohs(hr->port));
707  break;
708  }
709  }
710  }
711  } else {
712  std::string error_msg = absl::StrFormat(
713  "C-ares status is not ARES_SUCCESS qtype=%s name=%s is_balancer=%d: %s",
714  hr->qtype, hr->host, hr->is_balancer, ares_strerror(status));
715  GRPC_CARES_TRACE_LOG("request:%p on_hostbyname_done_locked: %s", r,
716  error_msg.c_str());
718  r->error = grpc_error_add_child(error, r->error);
719  }
720  destroy_hostbyname_request_locked(hr);
721 }
722 
723 static void on_srv_query_done_locked(void* arg, int status, int /*timeouts*/,
724  unsigned char* abuf,
726  // This callback is invoked from the c-ares library, so disable thread safety
727  // analysis. Note that we are guaranteed to be holding r->mu, though.
728  GrpcAresQuery* q = static_cast<GrpcAresQuery*>(arg);
729  grpc_ares_request* r = q->parent_request();
730  if (status == ARES_SUCCESS) {
732  "request:%p on_srv_query_done_locked name=%s ARES_SUCCESS", r,
733  q->name().c_str());
734  struct ares_srv_reply* reply;
735  const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
736  GRPC_CARES_TRACE_LOG("request:%p ares_parse_srv_reply: %d", r,
737  parse_status);
738  if (parse_status == ARES_SUCCESS) {
739  for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
740  srv_it = srv_it->next) {
741  if (grpc_ares_query_ipv6()) {
742  grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
743  r, srv_it->host, htons(srv_it->port), true /* is_balancer */,
744  "AAAA");
745  ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
746  on_hostbyname_done_locked, hr);
747  }
748  grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
749  r, srv_it->host, htons(srv_it->port), true /* is_balancer */, "A");
750  ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
751  on_hostbyname_done_locked, hr);
752  grpc_ares_notify_on_event_locked(r->ev_driver);
753  }
754  }
755  if (reply != nullptr) {
756  ares_free_data(reply);
757  }
758  } else {
759  std::string error_msg = absl::StrFormat(
760  "C-ares status is not ARES_SUCCESS qtype=SRV name=%s: %s", q->name(),
762  GRPC_CARES_TRACE_LOG("request:%p on_srv_query_done_locked: %s", r,
763  error_msg.c_str());
765  r->error = grpc_error_add_child(error, r->error);
766  }
767  delete q;
768 }
769 
770 static const char g_service_config_attribute_prefix[] = "grpc_config=";
771 
772 static void on_txt_done_locked(void* arg, int status, int /*timeouts*/,
773  unsigned char* buf,
775  // This callback is invoked from the c-ares library, so disable thread safety
776  // analysis. Note that we are guaranteed to be holding r->mu, though.
777  GrpcAresQuery* q = static_cast<GrpcAresQuery*>(arg);
778  std::unique_ptr<GrpcAresQuery> query_deleter(q);
779  grpc_ares_request* r = q->parent_request();
780  const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1;
781  struct ares_txt_ext* result = nullptr;
782  struct ares_txt_ext* reply = nullptr;
784  if (status != ARES_SUCCESS) goto fail;
785  GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked name=%s ARES_SUCCESS", r,
786  q->name().c_str());
788  if (status != ARES_SUCCESS) goto fail;
789  // Find service config in TXT record.
790  for (result = reply; result != nullptr; result = result->next) {
791  if (result->record_start &&
792  memcmp(result->txt, g_service_config_attribute_prefix, prefix_len) ==
793  0) {
794  break;
795  }
796  }
797  // Found a service config record.
798  if (result != nullptr) {
799  size_t service_config_len = result->length - prefix_len;
800  *r->service_config_json_out =
801  static_cast<char*>(gpr_malloc(service_config_len + 1));
802  memcpy(*r->service_config_json_out, result->txt + prefix_len,
803  service_config_len);
804  for (result = result->next; result != nullptr && !result->record_start;
805  result = result->next) {
806  *r->service_config_json_out = static_cast<char*>(
807  gpr_realloc(*r->service_config_json_out,
808  service_config_len + result->length + 1));
809  memcpy(*r->service_config_json_out + service_config_len, result->txt,
810  result->length);
811  service_config_len += result->length;
812  }
813  (*r->service_config_json_out)[service_config_len] = '\0';
814  GRPC_CARES_TRACE_LOG("request:%p found service config: %s", r,
815  *r->service_config_json_out);
816  }
817  // Clean up.
818  ares_free_data(reply);
819  return;
820 fail:
821  std::string error_msg =
822  absl::StrFormat("C-ares status is not ARES_SUCCESS qtype=TXT name=%s: %s",
823  q->name(), ares_strerror(status));
824  GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked %s", r,
825  error_msg.c_str());
827  r->error = grpc_error_add_child(error, r->error);
828 }
829 
830 void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
831  grpc_ares_request* r, const char* dns_server, const char* name,
832  const char* default_port, grpc_pollset_set* interested_parties,
833  int query_timeout_ms) ABSL_EXCLUSIVE_LOCKS_REQUIRED(r->mu) {
835  grpc_ares_hostbyname_request* hr = nullptr;
836  /* parse name, splitting it into host and port parts */
837  std::string host;
840  if (host.empty()) {
842  GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
844  goto error_cleanup;
845  } else if (port.empty()) {
846  if (default_port == nullptr || strlen(default_port) == 0) {
848  GRPC_ERROR_CREATE_FROM_STATIC_STRING("no port in name"),
850  goto error_cleanup;
851  }
852  port = default_port;
853  }
854  error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
855  query_timeout_ms, r);
856  if (!GRPC_ERROR_IS_NONE(error)) goto error_cleanup;
857  // If dns_server is specified, use it.
858  if (dns_server != nullptr && dns_server[0] != '\0') {
859  GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server);
861  if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) {
862  r->dns_server_addr.family = AF_INET;
863  struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(addr.addr);
864  memcpy(&r->dns_server_addr.addr.addr4, &in->sin_addr,
865  sizeof(struct in_addr));
866  r->dns_server_addr.tcp_port = grpc_sockaddr_get_port(&addr);
867  r->dns_server_addr.udp_port = grpc_sockaddr_get_port(&addr);
869  false /* log_errors */)) {
870  r->dns_server_addr.family = AF_INET6;
871  struct sockaddr_in6* in6 =
872  reinterpret_cast<struct sockaddr_in6*>(addr.addr);
873  memcpy(&r->dns_server_addr.addr.addr6, &in6->sin6_addr,
874  sizeof(struct in6_addr));
875  r->dns_server_addr.tcp_port = grpc_sockaddr_get_port(&addr);
876  r->dns_server_addr.udp_port = grpc_sockaddr_get_port(&addr);
877  } else {
879  GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
881  goto error_cleanup;
882  }
883  int status =
884  ares_set_servers_ports(r->ev_driver->channel, &r->dns_server_addr);
885  if (status != ARES_SUCCESS) {
887  "C-ares status is not ARES_SUCCESS: ", ares_strerror(status)));
888  goto error_cleanup;
889  }
890  }
891  r->pending_queries = 1;
892  if (grpc_ares_query_ipv6()) {
893  hr = create_hostbyname_request_locked(r, host.c_str(),
894  grpc_strhtons(port.c_str()),
895  /*is_balancer=*/false, "AAAA");
896  ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
897  on_hostbyname_done_locked, hr);
898  }
899  hr = create_hostbyname_request_locked(r, host.c_str(),
900  grpc_strhtons(port.c_str()),
901  /*is_balancer=*/false, "A");
902  ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
903  on_hostbyname_done_locked, hr);
904  if (r->balancer_addresses_out != nullptr) {
905  /* Query the SRV record */
906  std::string service_name = absl::StrCat("_grpclb._tcp.", host);
907  GrpcAresQuery* srv_query = new GrpcAresQuery(r, service_name);
908  ares_query(r->ev_driver->channel, service_name.c_str(), ns_c_in, ns_t_srv,
909  on_srv_query_done_locked, srv_query);
910  }
911  if (r->service_config_json_out != nullptr) {
912  std::string config_name = absl::StrCat("_grpc_config.", host);
913  GrpcAresQuery* txt_query = new GrpcAresQuery(r, config_name);
914  ares_search(r->ev_driver->channel, config_name.c_str(), ns_c_in, ns_t_txt,
915  on_txt_done_locked, txt_query);
916  }
917  grpc_ares_ev_driver_start_locked(r->ev_driver);
918  grpc_ares_request_unref_locked(r);
919  return;
920 
921 error_cleanup:
923 }
924 
925 static bool inner_resolve_as_ip_literal_locked(
926  const char* name, const char* default_port,
927  std::unique_ptr<grpc_core::ServerAddressList>* addrs, std::string* host,
928  std::string* port, std::string* hostport) {
929  if (!grpc_core::SplitHostPort(name, host, port)) {
931  "Failed to parse %s to host:port while attempting to resolve as ip "
932  "literal.",
933  name);
934  return false;
935  }
936  if (port->empty()) {
937  if (default_port == nullptr || strlen(default_port) == 0) {
939  "No port or default port for %s while attempting to resolve as "
940  "ip literal.",
941  name);
942  return false;
943  }
944  *port = default_port;
945  }
947  *hostport = grpc_core::JoinHostPort(*host, atoi(port->c_str()));
948  if (grpc_parse_ipv4_hostport(hostport->c_str(), &addr,
949  false /* log errors */) ||
950  grpc_parse_ipv6_hostport(hostport->c_str(), &addr,
951  false /* log errors */)) {
952  GPR_ASSERT(*addrs == nullptr);
953  *addrs = absl::make_unique<ServerAddressList>();
954  (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */);
955  return true;
956  }
957  return false;
958 }
959 
960 static bool resolve_as_ip_literal_locked(
961  const char* name, const char* default_port,
962  std::unique_ptr<grpc_core::ServerAddressList>* addrs) {
963  std::string host;
965  std::string hostport;
966  bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs,
967  &host, &port, &hostport);
968  return out;
969 }
970 
971 static bool target_matches_localhost_inner(const char* name, std::string* host,
972  std::string* port) {
973  if (!grpc_core::SplitHostPort(name, host, port)) {
974  gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name);
975  return false;
976  }
977  return gpr_stricmp(host->c_str(), "localhost") == 0;
978 }
979 
980 static bool target_matches_localhost(const char* name) {
981  std::string host;
983  return target_matches_localhost_inner(name, &host, &port);
984 }
985 
986 #ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY
987 static bool inner_maybe_resolve_localhost_manually_locked(
988  const grpc_ares_request* r, const char* name, const char* default_port,
989  std::unique_ptr<grpc_core::ServerAddressList>* addrs, std::string* host,
990  std::string* port) {
992  if (host->empty()) {
994  "Failed to parse %s into host:port during manual localhost "
995  "resolution check.",
996  name);
997  return false;
998  }
999  if (port->empty()) {
1000  if (default_port == nullptr || strlen(default_port) == 0) {
1002  "No port or default port for %s during manual localhost "
1003  "resolution check.",
1004  name);
1005  return false;
1006  }
1007  *port = default_port;
1008  }
1009  if (gpr_stricmp(host->c_str(), "localhost") == 0) {
1010  GPR_ASSERT(*addrs == nullptr);
1011  *addrs = absl::make_unique<grpc_core::ServerAddressList>();
1012  uint16_t numeric_port = grpc_strhtons(port->c_str());
1013  // Append the ipv6 loopback address.
1014  struct sockaddr_in6 ipv6_loopback_addr;
1015  memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr));
1016  ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1;
1017  ipv6_loopback_addr.sin6_family = AF_INET6;
1018  ipv6_loopback_addr.sin6_port = numeric_port;
1019  (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
1020  nullptr /* args */);
1021  // Append the ipv4 loopback address.
1022  struct sockaddr_in ipv4_loopback_addr;
1023  memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr));
1024  ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f;
1025  ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01;
1026  ipv4_loopback_addr.sin_family = AF_INET;
1027  ipv4_loopback_addr.sin_port = numeric_port;
1028  (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
1029  nullptr /* args */);
1030  // Let the address sorter figure out which one should be tried first.
1032  return true;
1033  }
1034  return false;
1035 }
1036 
1037 static bool grpc_ares_maybe_resolve_localhost_manually_locked(
1038  const grpc_ares_request* r, const char* name, const char* default_port,
1039  std::unique_ptr<grpc_core::ServerAddressList>* addrs) {
1040  std::string host;
1041  std::string port;
1042  return inner_maybe_resolve_localhost_manually_locked(r, name, default_port,
1043  addrs, &host, &port);
1044 }
1045 #else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */
1046 static bool grpc_ares_maybe_resolve_localhost_manually_locked(
1047  const grpc_ares_request* /*r*/, const char* /*name*/,
1048  const char* /*default_port*/,
1049  std::unique_ptr<grpc_core::ServerAddressList>* /*addrs*/) {
1050  return false;
1051 }
1052 #endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */
1053 
1054 static grpc_ares_request* grpc_dns_lookup_ares_impl(
1055  const char* dns_server, const char* name, const char* default_port,
1056  grpc_pollset_set* interested_parties, grpc_closure* on_done,
1057  std::unique_ptr<grpc_core::ServerAddressList>* addrs,
1058  std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
1059  char** service_config_json, int query_timeout_ms) {
1061  grpc_core::MutexLock lock(&r->mu);
1062  r->ev_driver = nullptr;
1063  r->on_done = on_done;
1064  r->addresses_out = addrs;
1065  r->balancer_addresses_out = balancer_addrs;
1066  r->service_config_json_out = service_config_json;
1068  "request:%p c-ares grpc_dns_lookup_ares_impl name=%s, "
1069  "default_port=%s",
1070  r, name, default_port);
1071  // Early out if the target is an ipv4 or ipv6 literal.
1072  if (resolve_as_ip_literal_locked(name, default_port, addrs)) {
1073  grpc_ares_complete_request_locked(r);
1074  return r;
1075  }
1076  // Early out if the target is localhost and we're on Windows.
1077  if (grpc_ares_maybe_resolve_localhost_manually_locked(r, name, default_port,
1078  addrs)) {
1079  grpc_ares_complete_request_locked(r);
1080  return r;
1081  }
1082  // Don't query for SRV and TXT records if the target is "localhost", so
1083  // as to cut down on lookups over the network, especially in tests:
1084  // https://github.com/grpc/proposal/pull/79
1085  if (target_matches_localhost(name)) {
1086  r->balancer_addresses_out = nullptr;
1087  r->service_config_json_out = nullptr;
1088  }
1089  // Look up name using c-ares lib.
1090  grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
1091  r, dns_server, name, default_port, interested_parties, query_timeout_ms);
1092  return r;
1093 }
1094 
1095 grpc_ares_request* (*grpc_dns_lookup_ares)(
1096  const char* dns_server, const char* name, const char* default_port,
1097  grpc_pollset_set* interested_parties, grpc_closure* on_done,
1098  std::unique_ptr<grpc_core::ServerAddressList>* addrs,
1099  std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
1100  char** service_config_json,
1101  int query_timeout_ms) = grpc_dns_lookup_ares_impl;
1102 
1103 static void grpc_cancel_ares_request_impl(grpc_ares_request* r) {
1104  GPR_ASSERT(r != nullptr);
1105  grpc_core::MutexLock lock(&r->mu);
1106  GRPC_CARES_TRACE_LOG("request:%p grpc_cancel_ares_request ev_driver:%p", r,
1107  r->ev_driver);
1108  if (r->ev_driver != nullptr) {
1109  grpc_ares_ev_driver_shutdown_locked(r->ev_driver);
1110  }
1111 }
1112 
1114  grpc_cancel_ares_request_impl;
1115 
1116 // ares_library_init and ares_library_cleanup are currently no-op except under
1117 // Windows. Calling them may cause race conditions when other parts of the
1118 // binary calls these functions concurrently.
1119 #ifdef GPR_WINDOWS
1122  if (status != ARES_SUCCESS) {
1124  absl::StrCat("ares_library_init failed: ", ares_strerror(status)));
1125  }
1126  return GRPC_ERROR_NONE;
1127 }
1128 
1129 void grpc_ares_cleanup(void) { ares_library_cleanup(); }
1130 #else
1132 void grpc_ares_cleanup(void) {}
1133 #endif // GPR_WINDOWS
1134 
1135 #endif /* GRPC_ARES == 1 */
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
address_sorting_sortable
Definition: address_sorting.h:58
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
ares_inet_ntop
const CARES_EXTERN char * ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size)
Definition: inet_ntop.c:56
grpc_trace_cares_resolver
grpc_core::TraceFlag grpc_trace_cares_resolver
address_sorting.h
address_sorting_sortable::dest_addr
address_sorting_address dest_addr
Definition: address_sorting.h:60
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
sockaddr_utils.h
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
ares_options
Definition: ares.h:259
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
ares_library_init
CARES_EXTERN int ares_library_init(int flags)
Definition: ares_library_init.c:133
nameser.h
absl::InlinedVector::emplace_back
reference emplace_back(Args &&... args)
Definition: abseil-cpp/absl/container/inlined_vector.h:675
memset
return memset(p, 0, total)
ares_query
CARES_EXTERN void ares_query(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg)
Definition: ares_query.c:105
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
dns_server
Definition: dns_server.py:1
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
ares.h
grpc_ares_cleanup
void grpc_ares_cleanup(void)
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
string.h
benchmark.request
request
Definition: benchmark.py:77
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
grpc_core::Timestamp
Definition: src/core/lib/gprpp/time.h:62
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
ns_c_in
@ ns_c_in
Definition: nameser.h:34
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
GRPC_CARES_TRACE_LOG
#define GRPC_CARES_TRACE_LOG(format,...)
Definition: grpc_ares_wrapper.h:47
grpc_core::ServerAddress
Definition: server_address.h:49
error_ref_leak.err
err
Definition: error_ref_leak.py:35
on_timeout
void on_timeout(uv_timer_t *req)
Definition: libuv/docs/code/uvwget/main.c:97
grpc_resolved_address
Definition: resolved_address.h:34
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
cstest_report.opts
opts
Definition: cstest_report.py:81
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
ARES_GETSOCK_MAXNUM
#define ARES_GETSOCK_MAXNUM
Definition: ares.h:209
address_sorting_address::len
size_t len
Definition: address_sorting.h:52
grpc_core::SplitHostPort
bool SplitHostPort(absl::string_view name, absl::string_view *host, absl::string_view *port)
Definition: host_port.cc:88
ABSL_GUARDED_BY
#define ABSL_GUARDED_BY(x)
Definition: abseil-cpp/absl/base/thread_annotations.h:62
status
absl::Status status
Definition: rls.cc:251
grpc_ares_query_ipv6
bool grpc_ares_query_ipv6()
ARES_LIB_INIT_ALL
#define ARES_LIB_INIT_ALL
Definition: ares.h:217
setup.name
name
Definition: setup.py:542
grpc_channel_arg_string_create
grpc_arg grpc_channel_arg_string_create(char *name, char *value)
Definition: channel_args.cc:476
ares_srv_reply
Definition: ares.h:539
resolved_address.h
name_
const std::string name_
Definition: priority.cc:233
grpc_timer
Definition: iomgr/timer.h:33
grpc_sockaddr_to_string
absl::StatusOr< std::string > grpc_sockaddr_to_string(const grpc_resolved_address *resolved_addr, bool normalize)
Definition: sockaddr_utils.cc:194
sockaddr.h
grpc_ares_ev_driver.h
ARES_GETSOCK_READABLE
#define ARES_GETSOCK_READABLE(bits, num)
Definition: ares.h:210
grpc_channel_args
Definition: grpc_types.h:132
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
ARES_OPT_FLAGS
#define ARES_OPT_FLAGS
Definition: ares.h:153
gpr_refcount
Definition: impl/codegen/sync_generic.h:39
gen_build_yaml.struct
def struct(**kwargs)
Definition: test/core/end2end/gen_build_yaml.py:30
grpc_error_set_str
grpc_error_handle grpc_error_set_str(grpc_error_handle src, grpc_error_strs which, absl::string_view str)
Definition: error.cc:650
ares_txt_ext
Definition: ares.h:561
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
GRPC_ERROR_STR_TARGET_ADDRESS
@ GRPC_ERROR_STR_TARGET_ADDRESS
peer that we were trying to communicate when this error occurred
Definition: error.h:117
grpc_types.h
grpc_cares_wrapper_address_sorting_sort
void grpc_cares_wrapper_address_sorting_sort(const grpc_ares_request *request, grpc_core::ServerAddressList *addresses)
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
absl::Milliseconds
constexpr Duration Milliseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:415
string_util.h
GRPC_ARG_DEFAULT_AUTHORITY
#define GRPC_ARG_DEFAULT_AUTHORITY
Definition: grpc_types.h:251
grpc_error_add_child
grpc_error_handle grpc_error_add_child(grpc_error_handle src, grpc_error_handle child)
Definition: error.cc:678
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
refs
std::vector< CordRep * > refs
Definition: cordz_info_statistics_test.cc:81
parse_address.h
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
ns_t_srv
@ ns_t_srv
Definition: nameser.h:78
grpc_trace_cares_address_sorting
grpc_core::TraceFlag grpc_trace_cares_address_sorting
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
ares_cancel
CARES_EXTERN void ares_cancel(ares_channel channel)
Definition: ares_cancel.c:26
sockaddr_in6
Definition: ares_ipv6.h:25
gpr_realloc
GPRAPI void * gpr_realloc(void *p, size_t size)
Definition: alloc.cc:56
generate-asm-lcov.fn
fn
Definition: generate-asm-lcov.py:146
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc_ares_wrapper.h
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
ABSL_EXCLUSIVE_LOCKS_REQUIRED
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: abseil-cpp/absl/base/thread_annotations.h:145
grpc_ares_request::mu
grpc_core::Mutex mu
Definition: grpc_ares_wrapper.h:59
grpc_core::fail
Poll< absl::StatusOr< std::tuple< T... > > > fail()
Definition: try_join_test.cc:45
grpc_core::JoinHostPort
std::string JoinHostPort(absl::string_view host, int port)
Definition: host_port.cc:32
arg
Definition: cmdline.cc:40
time.h
grpc_parse_ipv6_hostport
bool grpc_parse_ipv6_hostport(absl::string_view hostport, grpc_resolved_address *addr, bool log_errors)
Definition: parse_address.cc:198
grpc_strhtons
uint16_t grpc_strhtons(const char *port)
Definition: parse_address.cc:311
absl::InlinedVector::data
pointer data() noexcept
Definition: abseil-cpp/absl/container/inlined_vector.h:302
gpr_stricmp
int gpr_stricmp(const char *a, const char *b)
Definition: string.cc:282
error.h
ARES_FLAG_STAYOPEN
#define ARES_FLAG_STAYOPEN
Definition: ares.h:146
host_port.h
absl::InlinedVector::size
size_type size() const noexcept
Definition: abseil-cpp/absl/container/inlined_vector.h:270
address_sorting_sortable::user_data
void * user_data
Definition: address_sorting.h:62
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_core::ServerAddressList
std::vector< ServerAddress > ServerAddressList
Definition: server_address.h:120
ns_t_txt
@ ns_t_txt
Definition: nameser.h:61
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
ares_srv_reply::next
struct ares_srv_reply * next
Definition: ares.h:540
ares_strerror
const CARES_EXTERN char * ares_strerror(int code)
Definition: ares_strerror.c:21
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
grpc_core::TraceFlag
Definition: debug/trace.h:63
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
grpc_ares_request
Definition: grpc_ares_wrapper.h:56
ares_getsock
CARES_EXTERN int ares_getsock(ares_channel channel, ares_socket_t *socks, int numsocks)
Definition: ares_getsock.c:20
ARES_SOCKET_BAD
#define ARES_SOCKET_BAD
Definition: ares.h:230
address_sorting_rfc_6724_sort
void address_sorting_rfc_6724_sort(address_sorting_sortable *sortables, size_t sortables_len)
Definition: address_sorting.c:349
memory_diff.cur
def cur
Definition: memory_diff.py:83
grpc_timer_cancel
void grpc_timer_cancel(grpc_timer *timer)
Definition: iomgr/timer.cc:36
grpc_sockaddr_get_port
int grpc_sockaddr_get_port(const grpc_resolved_address *resolved_addr)
Definition: sockaddr_utils.cc:303
ares_channeldata
Definition: ares_private.h:266
grpc_core::Duration::millis
constexpr int64_t millis() const
Definition: src/core/lib/gprpp/time.h:208
ares_free_data
CARES_EXTERN void ares_free_data(void *dataptr)
Definition: ares_data.c:41
debug_location.h
ares_set_servers_ports
CARES_EXTERN int ares_set_servers_ports(ares_channel channel, struct ares_addr_port_node *servers)
Definition: ares_options.c:195
ares_search
CARES_EXTERN void ares_search(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg)
Definition: ares_search.c:47
grpc_error_std_string
std::string grpc_error_std_string(grpc_error_handle error)
Definition: error.cc:944
ares_library_cleanup
CARES_EXTERN void ares_library_cleanup(void)
Definition: ares_library_init.c:171
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
ares_destroy
CARES_EXTERN void ares_destroy(ares_channel channel)
Definition: ares_destroy.c:43
GRPC_ERROR_CREATE_FROM_CPP_STRING
#define GRPC_ERROR_CREATE_FROM_CPP_STRING(desc)
Definition: error.h:297
alloc.h
next
AllocList * next[kMaxLevel]
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:100
ares_socket_t
int ares_socket_t
Definition: ares.h:229
fix_build_deps.r
r
Definition: fix_build_deps.py:491
ARES_GETSOCK_WRITABLE
#define ARES_GETSOCK_WRITABLE(bits, num)
Definition: ares.h:211
grpc_core::Duration::Seconds
static constexpr Duration Seconds(int64_t seconds)
Definition: src/core/lib/gprpp/time.h:151
grpc_ares_ev_driver
struct grpc_ares_ev_driver grpc_ares_ev_driver
Definition: grpc_ares_wrapper.h:54
arg
struct arg arg
exec_ctx.h
grpc_timer_init
void grpc_timer_init(grpc_timer *timer, grpc_core::Timestamp deadline, grpc_closure *closure)
Definition: iomgr/timer.cc:31
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_core::ExecCtx::Run
static void Run(const DebugLocation &location, grpc_closure *closure, grpc_error_handle error)
Definition: exec_ctx.cc:98
grpc_core::GrpcPolledFd
Definition: grpc_ares_ev_driver.h:42
ares_parse_txt_reply_ext
CARES_EXTERN int ares_parse_txt_reply_ext(const unsigned char *abuf, int alen, struct ares_txt_ext **txt_out)
Definition: ares_parse_txt_reply.c:210
ares_parse_srv_reply
CARES_EXTERN int ares_parse_srv_reply(const unsigned char *abuf, int alen, struct ares_srv_reply **srv_out)
Definition: ares_parse_srv_reply.c:38
channel_args.h
timer.h
absl::str_format_internal::LengthMod::q
@ q
sockaddr_in6::sin6_addr
struct ares_in6_addr sin6_addr
Definition: ares_ipv6.h:30
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
grpc_parse_ipv4_hostport
bool grpc_parse_ipv4_hostport(absl::string_view hostport, grpc_resolved_address *addr, bool log_errors)
Definition: parse_address.cc:146
ares_init_options
CARES_EXTERN int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask)
Definition: ares_init.c:103
Duration
Definition: bloaty/third_party/protobuf/src/google/protobuf/duration.pb.h:69
grpc_ares_init
grpc_error_handle grpc_ares_init(void)
gpr_ref_init
GPRAPI void gpr_ref_init(gpr_refcount *r, int n)
Definition: sync.cc:86
grpc_core::ExecCtx::Now
Timestamp Now()
Definition: exec_ctx.cc:90
absl::InlinedVector
Definition: abseil-cpp/absl/container/inlined_vector.h:69
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
gpr_unref
GPRAPI int gpr_unref(gpr_refcount *r)
Definition: sync.cc:103
grpc_error
Definition: error_internal.h:42
grpc_core::NewGrpcPolledFdFactory
std::unique_ptr< GrpcPolledFdFactory > NewGrpcPolledFdFactory(Mutex *mu)
grpc_core::Duration
Definition: src/core/lib/gprpp/time.h:122
sync.h
grpc_closure
Definition: closure.h:56
grpc_cancel_ares_request
void(* grpc_cancel_ares_request)(grpc_ares_request *request)
gpr_ref
GPRAPI void gpr_ref(gpr_refcount *r)
Definition: sync.cc:88
grpc_ares_test_only_inject_config
void(* grpc_ares_test_only_inject_config)(ares_channel channel)
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
ares_gethostbyname
CARES_EXTERN void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg)
Definition: ares_gethostbyname.c:75
timeout
uv_timer_t timeout
Definition: libuv/docs/code/uvwget/main.c:9
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
grpc_channel_args_copy_and_add
grpc_channel_args * grpc_channel_args_copy_and_add(const grpc_channel_args *src, const grpc_arg *to_add, size_t num_to_add)
Definition: channel_args.cc:224
grpc_core::Duration::Infinity
static constexpr Duration Infinity()
Definition: src/core/lib/gprpp/time.h:139
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
ares_process_fd
CARES_EXTERN void ares_process_fd(ares_channel channel, ares_socket_t read_fd, ares_socket_t write_fd)
Definition: ares_process.c:142
grpc_core::ExecCtx::InvalidateNow
void InvalidateNow()
Definition: exec_ctx.h:188
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
ABSL_NO_THREAD_SAFETY_ANALYSIS
#define ABSL_NO_THREAD_SAFETY_ANALYSIS
Definition: abseil-cpp/absl/base/thread_annotations.h:280
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:44