How to resolve IP address on host using c-ares?

This is what I have done so far. It compiles, but it segfaults when I try to run it.

#include <iostream> #include <netdb.h> #include <arpa/inet.h> #include <ares.h> void dns_callback (void* arg, int status, int timeouts, struct hostent* host) { std::cout << host->h_name << "\n"; } int main(int argc, char **argv) { struct in_addr ip; char *arg; inet_aton(argv[1], &ip); ares_channel channel; ares_gethostbyaddr(channel, &ip, 4, AF_INET, dns_callback, arg); sleep(15); return 0; } 
+6
c ++ linux dns
source share
1 answer

You should at least initialize ares_channel before using it

  if(ares_init(&channel) != ARES_SUCCESS) { //handle error } 

You also need an event loop to handle events in the ares file descriptors and ares_process is called to handle these events (most often you'd integrate this into your application's event loop) There is nothing magical about ares, it does not use threads to handle async, so it’s just calls sleep (15); doesn't allow ares to run in the background

Your callback should also check the status variable, you cannot access host->h_name if the search failed.

Full example:

 #include <time.h> #include <iostream> #include <netdb.h> #include <arpa/inet.h> #include <ares.h> void dns_callback (void* arg, int status, int timeouts, struct hostent* host) { if(status == ARES_SUCCESS) std::cout << host->h_name << "\n"; else std::cout << "lookup failed: " << status << '\n'; } void main_loop(ares_channel &channel) { int nfds, count; fd_set readers, writers; timeval tv, *tvp; while (1) { FD_ZERO(&readers); FD_ZERO(&writers); nfds = ares_fds(channel, &readers, &writers); if (nfds == 0) break; tvp = ares_timeout(channel, NULL, &tv); count = select(nfds, &readers, &writers, NULL, tvp); ares_process(channel, &readers, &writers); } } int main(int argc, char **argv) { struct in_addr ip; int res; if(argc < 2 ) { std::cout << "usage: " << argv[0] << " ip.address\n"; return 1; } inet_aton(argv[1], &ip); ares_channel channel; if((res = ares_init(&channel)) != ARES_SUCCESS) { std::cout << "ares feiled: " << res << '\n'; return 1; } ares_gethostbyaddr(channel, &ip, sizeof ip, AF_INET, dns_callback, NULL); main_loop(channel); return 0; } 
  $ g ++ -Wall test_ares.cpp -lcares
  $ ./a.out 8.8.8.8
 google-public-dns-a.google.com
+11
source share

All Articles