Lines Matching +full:c +full:- +full:ares

8  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
21 * SPDX-License-Identifier: curl
28 * Only for ares-enabled builds
67 #include <ares.h>
68 #include <ares_version.h> /* really old c-ares did not include this by
72 /* c-ares 1.5.0 or later, the callback proto is modified */
102 int num_pending; /* number of outstanding c-ares requests */
103 struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
113 obtaining a "definitive" one. For old c-ares without getaddrinfo.
115 This is intended to equal the c-ares default timeout. cURL always uses that
116 default value. Unfortunately, c-ares does not expose its default timeout in
128 * Curl_resolver_global_init() - the generic low-level asynchronous name
130 * environment. Initializes ares library.
147 * Deinitializes ares library.
170 * Called from curl_easy_init() -> Curl_open() to initialize resolver
171 * URL-state specific environment ('resolver' member of the UrlState
183 if c ares < 1.20.0: curl set timeout to CARES_TIMEOUT_PER_ATTEMPT (2s) in Curl_resolver_init()
185 if c-ares >= 1.20.0 it already has the timeout to 2s, curl does not need in Curl_resolver_init()
188 if c-ares >= 1.24.0, user can set the timeout via /etc/resolv.conf to in Curl_resolver_init()
189 overwrite c-ares' timeout. in Curl_resolver_init()
206 ares channel before returning error! */ in Curl_resolver_init()
212 * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
213 * URL-state specific environment ('resolver' member of the UrlState
214 * structure). Destroys the ares channel.
224 * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
226 * 'from' ares channel and passes the resulting channel to the 'to' pointer.
242 * Cancel all possibly still on-going resolves for this connection.
247 if(data->state.async.resolver) in Curl_resolver_cancel()
248 ares_cancel((ares_channel)data->state.async.resolver); in Curl_resolver_cancel()
249 destroy_async_data(&data->state.async); in Curl_resolver_cancel()
253 * We are equivalent to Curl_resolver_cancel() for the c-ares resolver. We
268 if(async->tdata) { in destroy_async_data()
269 struct thread_data *res = async->tdata; in destroy_async_data()
271 if(res->temp_ai) { in destroy_async_data()
272 Curl_freeaddrinfo(res->temp_ai); in destroy_async_data()
273 res->temp_ai = NULL; in destroy_async_data()
277 async->tdata = NULL; in destroy_async_data()
284 * with ares. The caller must make sure that this function is only called when
285 * we have a working ares channel.
287 * Returns: sockets-in-use-bitmap
295 int max = ares_getsock((ares_channel)data->state.async.resolver, in Curl_resolver_getsock()
298 ares_timeout((ares_channel)data->state.async.resolver, &maxtime, &timebuf); in Curl_resolver_getsock()
307 * 1) Ask ares what sockets it currently plays with, then
308 * 2) wait for the timeout period to check for action on ares' sockets.
309 * 3) tell ares to act on all the sockets marked as "with action"
311 * return number of sockets it worked on, or -1 on error
323 bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks, in waitperform()
346 return -1; in waitperform()
353 above, as otherwise the ares name resolve will not timeout! */ in waitperform()
354 ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD, in waitperform()
359 ares_process_fd((ares_channel)data->state.async.resolver, in waitperform()
370 * name resolve request has completed. It should also make sure to time-out if
378 struct thread_data *res = data->state.async.tdata; in Curl_resolver_is_resolved()
392 && res->num_pending in Curl_resolver_is_resolved()
393 /* This is only set to non-zero if the timer was started. */ in Curl_resolver_is_resolved()
394 && (res->happy_eyeballs_dns_time.tv_sec in Curl_resolver_is_resolved()
395 || res->happy_eyeballs_dns_time.tv_usec) in Curl_resolver_is_resolved()
396 && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time) in Curl_resolver_is_resolved()
401 &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time)); in Curl_resolver_is_resolved()
403 /* Cancel the raw c-ares request, which will fire query_completed_cb() with in Curl_resolver_is_resolved()
405 leave us with res->num_pending == 0, which is perfect for the next in Curl_resolver_is_resolved()
407 ares_cancel((ares_channel)data->state.async.resolver); in Curl_resolver_is_resolved()
408 DEBUGASSERT(res->num_pending == 0); in Curl_resolver_is_resolved()
412 if(res && !res->num_pending) { in Curl_resolver_is_resolved()
413 (void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai); in Curl_resolver_is_resolved()
414 /* temp_ai ownership is moved to the connection, so we need not free-up in Curl_resolver_is_resolved()
416 res->temp_ai = NULL; in Curl_resolver_is_resolved()
418 if(!data->state.async.dns) in Curl_resolver_is_resolved()
421 *dns = data->state.async.dns; in Curl_resolver_is_resolved()
423 destroy_async_data(&data->state.async); in Curl_resolver_is_resolved()
435 * 'entry' MUST be non-NULL.
438 * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
453 connclose(data->conn, "Timed out before name resolve started"); in Curl_resolver_wait_resolv()
474 tvp = ares_timeout((ares_channel)data->state.async.resolver, &store, &tv); in Curl_resolver_wait_resolv()
476 /* use the timeout period ares returned to us above if less than one in Curl_resolver_wait_resolv()
479 if(!tvp->tv_sec) in Curl_resolver_wait_resolv()
480 timeout_ms = (timediff_t)(tvp->tv_usec/1000); in Curl_resolver_wait_resolv()
488 if(result || data->state.async.done) in Curl_resolver_wait_resolv()
497 timeout -= 1; /* always deduct at least 1 */ in Curl_resolver_wait_resolv()
499 timeout = -1; in Curl_resolver_wait_resolv()
501 timeout -= timediff; in Curl_resolver_wait_resolv()
508 /* failure, so we cancel the ares operation */ in Curl_resolver_wait_resolv()
509 ares_cancel((ares_channel)data->state.async.resolver); in Curl_resolver_wait_resolv()
514 *entry = data->state.async.dns; in Curl_resolver_wait_resolv()
519 connclose(data->conn, "c-ares resolve failed"); in Curl_resolver_wait_resolv()
534 if(res->temp_ai && res->temp_ai->ai_family == PF_INET6) { in compound_results()
537 struct Curl_addrinfo *temp_ai_tail = res->temp_ai; in compound_results()
539 while(temp_ai_tail->ai_next) in compound_results()
540 temp_ai_tail = temp_ai_tail->ai_next; in compound_results()
542 temp_ai_tail->ai_next = ai; in compound_results()
549 while(ai_tail->ai_next) in compound_results()
550 ai_tail = ai_tail->ai_next; in compound_results()
552 ai_tail->ai_next = res->temp_ai; in compound_results()
553 res->temp_ai = ai; in compound_results()
558 * ares_query_completed_cb() is the callback that ares will call when
560 * when using ares, is completed either successfully or with failure.
577 /* when this ares handle is getting destroyed, the 'arg' pointer may not in query_completed_cb()
581 res = data->state.async.tdata; in query_completed_cb()
583 res->num_pending--; in query_completed_cb()
586 struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port); in query_completed_cb()
592 if(res->last_status != ARES_SUCCESS) in query_completed_cb()
593 res->last_status = status; in query_completed_cb()
600 if(res->num_pending in query_completed_cb()
601 /* Only these c-ares status values count as "definitive" for these in query_completed_cb()
606 requests), local or network conditions, non-definitive server in query_completed_cb()
611 DEBUGASSERT(res->num_pending == 1); in query_completed_cb()
632 the first place. Without modifying c-ares, we cannot know exactly in query_completed_cb()
639 c-ares query timeout. That is enough time for a typical parallel in query_completed_cb()
643 c-ares timeout (5 seconds) plus the round trip time for the successful in query_completed_cb()
644 request, which seems bearable. The downside is that c-ares might race in query_completed_cb()
648 c-ares retry cycle each request is. in query_completed_cb()
650 res->happy_eyeballs_dns_time = Curl_now(); in query_completed_cb()
657 /* c-ares 1.16.0 or later */
660 * ares2addr() converts an address list provided by c-ares to an internal
671 for(ai = node; ai != NULL; ai = ai->ai_next) { in ares2addr()
675 /* settle family-specific sockaddr structure size. */ in ares2addr()
676 if(ai->ai_family == AF_INET) in ares2addr()
679 else if(ai->ai_family == AF_INET6) in ares2addr()
686 if(!ai->ai_addr || !(ai->ai_addrlen > 0)) in ares2addr()
690 if((size_t)ai->ai_addrlen < ss_size) in ares2addr()
702 ca->ai_flags = ai->ai_flags; in ares2addr()
703 ca->ai_family = ai->ai_family; in ares2addr()
704 ca->ai_socktype = ai->ai_socktype; in ares2addr()
705 ca->ai_protocol = ai->ai_protocol; in ares2addr()
706 ca->ai_addrlen = (curl_socklen_t)ss_size; in ares2addr()
707 ca->ai_addr = NULL; in ares2addr()
708 ca->ai_canonname = NULL; in ares2addr()
709 ca->ai_next = NULL; in ares2addr()
711 ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); in ares2addr()
712 memcpy(ca->ai_addr, ai->ai_addr, ss_size); in ares2addr()
720 calast->ai_next = ca; in ares2addr()
737 struct thread_data *res = data->state.async.tdata; in addrinfo_cb()
740 res->temp_ai = ares2addr(result->nodes); in addrinfo_cb()
741 res->last_status = CURL_ASYNC_SUCCESS; in addrinfo_cb()
744 res->num_pending--; in addrinfo_cb()
749 * Curl_resolver_getaddrinfo() - when using ares
767 strcpy(res->hostname, hostname); in Curl_resolver_getaddrinfo()
768 data->state.async.hostname = res->hostname; in Curl_resolver_getaddrinfo()
769 data->state.async.port = port; in Curl_resolver_getaddrinfo()
770 data->state.async.done = FALSE; /* not done */ in Curl_resolver_getaddrinfo()
771 data->state.async.status = 0; /* clear */ in Curl_resolver_getaddrinfo()
772 data->state.async.dns = NULL; /* clear */ in Curl_resolver_getaddrinfo()
773 data->state.async.tdata = res; in Curl_resolver_getaddrinfo()
775 /* initial status - failed */ in Curl_resolver_getaddrinfo()
776 res->last_status = ARES_ENOTFOUND; in Curl_resolver_getaddrinfo()
785 if((data->conn->ip_version != CURL_IPRESOLVE_V4) && in Curl_resolver_getaddrinfo()
787 /* The stack seems to be IPv6-enabled */ in Curl_resolver_getaddrinfo()
788 if(data->conn->ip_version == CURL_IPRESOLVE_V6) in Curl_resolver_getaddrinfo()
795 hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ? in Curl_resolver_getaddrinfo()
798 * accordingly to save a call to getservbyname in inside C-Ares in Curl_resolver_getaddrinfo()
802 res->num_pending = 1; in Curl_resolver_getaddrinfo()
803 ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname, in Curl_resolver_getaddrinfo()
809 if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) { in Curl_resolver_getaddrinfo()
810 /* The stack seems to be IPv6-enabled */ in Curl_resolver_getaddrinfo()
811 res->num_pending = 2; in Curl_resolver_getaddrinfo()
814 ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, in Curl_resolver_getaddrinfo()
816 ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, in Curl_resolver_getaddrinfo()
822 res->num_pending = 1; in Curl_resolver_getaddrinfo()
825 ares_gethostbyname((ares_channel)data->state.async.resolver, in Curl_resolver_getaddrinfo()
842 * from ares library, which will cause any and all queries to fail. in Curl_set_dns_servers()
844 * any changes to c-ares. This lets c-ares use its defaults, which in Curl_set_dns_servers()
852 ares_result = ares_set_servers_ports_csv(data->state.async.resolver, in Curl_set_dns_servers()
855 ares_result = ares_set_servers_csv(data->state.async.resolver, servers); in Curl_set_dns_servers()
872 #else /* too old c-ares version! */ in Curl_set_dns_servers()
886 ares_set_local_dev((ares_channel)data->state.async.resolver, interf); in Curl_set_dns_interface()
889 #else /* c-ares version too old! */ in Curl_set_dns_interface()
912 ares_set_local_ip4((ares_channel)data->state.async.resolver, in Curl_set_dns_local_ip4()
916 #else /* c-ares version too old! */ in Curl_set_dns_local_ip4()
940 ares_set_local_ip6((ares_channel)data->state.async.resolver, a6); in Curl_set_dns_local_ip6()
943 #else /* c-ares version too old! */ in Curl_set_dns_local_ip6()