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 ) {
15- for (int i = 0 ; i < d -> io_events_count ; i ++ ) {
15+ for (unsigned i = 0 ; i < d -> io_events_count ; i ++ ) {
1616 if (d -> io_events [i ].fd == sock ) {
1717 return & d -> io_events [i ];
1818 }
@@ -35,7 +35,7 @@ static void sock_state_cb(void *data, int fd, int read, int write) {
3535 // reserve and start new event on unused slot
3636 io_event_ptr = get_io_event (d , 0 );
3737 if (!io_event_ptr ) {
38- FLOG ("c-ares needed more IO event handler, than the number of provided nameservers: %d " , d -> io_events_count );
38+ FLOG ("c-ares needed more IO event handler, than the number of provided nameservers: %u " , d -> io_events_count );
3939 }
4040 DLOG ("Reserved new io event: %p" , io_event_ptr );
4141 // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
@@ -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- 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 );
@@ -97,18 +120,23 @@ static ev_tstamp get_timeout(dns_poller_t *d)
97120 struct timeval tv ;
98121 struct timeval * tvp = ares_timeout (d -> ares , & max_tv , & tv );
99122 // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
100- ev_tstamp after = tvp -> tv_sec + tvp -> tv_usec * 1e-6 ;
101- return after ? after : 0.1 ;
123+ ev_tstamp after = ( double ) tvp -> tv_sec + ( double ) tvp -> tv_usec * 1e-6 ;
124+ return after > 0.1 ? after : 0.1 ;
102125}
103126
104127static void timer_cb (struct ev_loop __attribute__((unused )) * loop ,
105128 ev_timer * w , int __attribute__((unused )) revents ) {
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!
@@ -170,8 +205,8 @@ void dns_poller_init(dns_poller_t *d, struct ev_loop *loop,
170205 d -> timer .data = d ;
171206 ev_timer_start (d -> loop , & d -> timer );
172207
173- int nameservers = 1 ;
174- for (int i = 0 ; bootstrap_dns [i ]; i ++ ) {
208+ unsigned nameservers = 1 ;
209+ for (unsigned i = 0 ; bootstrap_dns [i ]; i ++ ) {
175210 if (bootstrap_dns [i ] == ',' ) {
176211 nameservers ++ ;
177212 }
@@ -181,7 +216,7 @@ void dns_poller_init(dns_poller_t *d, struct ev_loop *loop,
181216 if (!d -> io_events ) {
182217 FLOG ("Out of mem" );
183218 }
184- for (int i = 0 ; i < nameservers ; i ++ ) {
219+ for (unsigned i = 0 ; i < nameservers ; i ++ ) {
185220 d -> io_events [i ].data = d ;
186221 }
187222 d -> io_events_count = nameservers ;
0 commit comments