77static void sock_cb (struct ev_loop __attribute__((unused )) * loop ,
88 ev_io * w , int revents ) {
99 dns_poller_t * d = (dns_poller_t * )w -> data ;
10- ares_process_fd (d -> ares , (revents & EV_READ ) ? w -> fd : ARES_SOCKET_BAD ,
11- (revents & EV_WRITE ) ? w -> fd : ARES_SOCKET_BAD );
10+ ares_process_fd (d -> ares , (revents & EV_READ ) ? w -> fd : ARES_SOCKET_BAD ,
11+ (revents & EV_WRITE ) ? w -> fd : ARES_SOCKET_BAD );
1212}
1313
1414static struct ev_io * get_io_event (dns_poller_t * d , int sock ) {
@@ -44,21 +44,43 @@ static void sock_state_cb(void *data, int fd, int read, int write) {
4444 ev_io_start (d -> loop , io_event_ptr );
4545}
4646
47- static char * get_addr_listing (char * * addr_list , const int af ) {
47+ static char * get_addr_listing (struct ares_addrinfo_node * nodes ) {
4848 char * list = (char * )calloc (1 , POLLER_ADDR_LIST_SIZE );
49- char * pos = list ;
5049 if (list == NULL ) {
5150 FLOG ("Out of mem" );
5251 }
53- for (int i = 0 ; addr_list [i ]; i ++ ) {
54- const char * res = ares_inet_ntop (af , addr_list [i ], pos ,
55- (ares_socklen_t )(list + POLLER_ADDR_LIST_SIZE - 1 - pos ));
52+ char * pos = list ;
53+ unsigned ipv4 = 0 ;
54+ unsigned ipv6 = 0 ;
55+
56+ for (struct ares_addrinfo_node * node = nodes ; node != NULL ; node = node -> ai_next ) {
57+ const char * res = NULL ;
58+
59+ if (node -> ai_family == AF_INET ) {
60+ res = ares_inet_ntop (AF_INET , (const void * )& ((struct sockaddr_in * )node -> ai_addr )-> sin_addr ,
61+ pos , (ares_socklen_t )(list + POLLER_ADDR_LIST_SIZE - 1 - pos ));
62+ ipv4 ++ ;
63+ } else if (node -> ai_family == AF_INET6 ) {
64+ res = ares_inet_ntop (AF_INET6 , (const void * )& ((struct sockaddr_in6 * )node -> ai_addr )-> sin6_addr ,
65+ pos , (ares_socklen_t )(list + POLLER_ADDR_LIST_SIZE - 1 - pos ));
66+ ipv6 ++ ;
67+ } else {
68+ WLOG ("Unhandled address family: %d" , node -> ai_family );
69+ continue ;
70+ }
71+
5672 if (res != NULL ) {
5773 pos += strlen (pos );
5874 * pos = ',' ;
5975 pos ++ ;
76+ } else {
77+ DLOG ("Not enough space left for further IP addresses" ); // test with POLLER_ADDR_LIST_SIZE = 10 value
78+ break ;
6079 }
6180 }
81+
82+ DLOG ("Received %u IPv4 and %u IPv6 addresses" , ipv4 , ipv6 );
83+
6284 if (pos == list ) {
6385 free ((void * )list );
6486 list = NULL ;
@@ -69,19 +91,20 @@ static char *get_addr_listing(char** addr_list, const int af) {
6991}
7092
7193static void ares_cb (void * arg , int status , int __attribute__((unused )) timeouts ,
72- struct hostent * h ) {
94+ struct ares_addrinfo * result ) {
7395 dns_poller_t * d = (dns_poller_t * )arg ;
7496 d -> request_ongoing = 0 ;
7597 ev_tstamp interval = 5 ; // retry by default after some time
7698
7799 if (status != ARES_SUCCESS ) {
78100 WLOG ("DNS lookup of '%s' failed: %s" , d -> hostname , ares_strerror (status ));
79- } else if (!h || h -> h_length < 1 ) {
101+ } else if (!result || result -> nodes == NULL ) {
80102 WLOG ("No hosts found for '%s'" , d -> hostname );
81103 } else {
82104 interval = d -> polling_interval ;
83- d -> cb (d -> hostname , d -> cb_data , get_addr_listing (h -> h_addr_list , h -> h_addrtype ));
105+ d -> cb (d -> hostname , d -> cb_data , get_addr_listing (result -> nodes ));
84106 }
107+ ares_freeaddrinfo (result );
85108
86109 if (status != ARES_EDESTRUCTION ) {
87110 DLOG ("DNS poll interval changed to: %.0lf" , interval );
@@ -106,9 +129,14 @@ static void timer_cb(struct ev_loop __attribute__((unused)) *loop,
106129 dns_poller_t * d = (dns_poller_t * )w -> data ;
107130
108131 if (d -> request_ongoing ) {
109- // process query timeouts
110- DLOG ("Processing DNS queries" );
132+ DLOG ("Processing DNS query timeouts" );
133+ #if ARES_VERSION_MAJOR >= 1 && ARES_VERSION_MINOR >= 34
134+ ares_process_fds (d -> ares , NULL , 0 , ARES_PROCESS_FLAG_NONE );
135+ #elif ARES_VERSION_MAJOR >= 1 && ARES_VERSION_MINOR >= 28
136+ ares_process_fd (d -> ares , ARES_SOCKET_BAD , ARES_SOCKET_BAD );
137+ #else
111138 ares_process (d -> ares , NULL , NULL );
139+ #endif
112140 } else {
113141 DLOG ("Starting DNS query" );
114142 // Cancel any pending queries before making new ones. c-ares can't be depended on to
@@ -117,7 +145,14 @@ static void timer_cb(struct ev_loop __attribute__((unused)) *loop,
117145 // free memory tied up by any "zombie" queries.
118146 ares_cancel (d -> ares );
119147 d -> request_ongoing = 1 ;
120- ares_gethostbyname (d -> ares , d -> hostname , d -> family , ares_cb , d );
148+
149+ struct ares_addrinfo_hints hints ;
150+ memset (& hints , 0 , sizeof (hints )); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
151+ hints .ai_flags = ARES_AI_CANONNAME ;
152+ hints .ai_family = d -> family ;
153+ hints .ai_socktype = SOCK_STREAM ;
154+
155+ ares_getaddrinfo (d -> ares , d -> hostname , "https" , & hints , ares_cb , d );
121156 }
122157
123158 if (d -> request_ongoing ) { // need to re-check, it might change!
0 commit comments