summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/asyn-ares.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/asyn-ares.c')
-rw-r--r--Utilities/cmcurl/lib/asyn-ares.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index c885ade..33edba1 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -113,6 +115,7 @@ struct thread_data {
#ifndef HAVE_CARES_GETADDRINFO
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
#endif
+ char hostname[1];
};
/* How long we are willing to wait for additional parallel responses after
@@ -250,8 +253,6 @@ void Curl_resolver_kill(struct Curl_easy *data)
*/
static void destroy_async_data(struct Curl_async *async)
{
- free(async->hostname);
-
if(async->tdata) {
struct thread_data *res = async->tdata;
if(res) {
@@ -263,8 +264,6 @@ static void destroy_async_data(struct Curl_async *async)
}
async->tdata = NULL;
}
-
- async->hostname = NULL;
}
/*
@@ -306,7 +305,7 @@ int Curl_resolver_getsock(struct Curl_easy *data,
* 2) wait for the timeout period to check for action on ares' sockets.
* 3) tell ares to act on all the sockets marked as "with action"
*
- * return number of sockets it worked on
+ * return number of sockets it worked on, or -1 on error
*/
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
@@ -338,8 +337,11 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
break;
}
- if(num)
+ if(num) {
nfds = Curl_poll(pfd, num, timeout_ms);
+ if(nfds < 0)
+ return -1;
+ }
else
nfds = 0;
@@ -376,7 +378,8 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
DEBUGASSERT(dns);
*dns = NULL;
- waitperform(data, 0);
+ if(waitperform(data, 0) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
#ifndef HAVE_CARES_GETADDRINFO
/* Now that we've checked for any last minute results above, see if there are
@@ -475,7 +478,8 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
else
timeout_ms = 1000;
- waitperform(data, timeout_ms);
+ if(waitperform(data, timeout_ms) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
result = Curl_resolver_is_resolved(data, entry);
if(result || data->state.async.done)
@@ -742,7 +746,7 @@ static void addrinfo_cb(void *arg, int status, int timeouts,
* Curl_resolver_getaddrinfo() - when using ares
*
* Returns name information about the given hostname and port number. If
- * successful, the 'hostent' is returned and the forth argument will point to
+ * successful, the 'hostent' is returned and the fourth argument will point to
* memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
@@ -751,25 +755,18 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
int port,
int *waitp)
{
- char *bufp;
-
+ struct thread_data *res = NULL;
+ size_t namelen = strlen(hostname);
*waitp = 0; /* default to synchronous response */
- bufp = strdup(hostname);
- if(bufp) {
- struct thread_data *res = NULL;
- free(data->state.async.hostname);
- data->state.async.hostname = bufp;
+ res = calloc(sizeof(struct thread_data) + namelen, 1);
+ if(res) {
+ strcpy(res->hostname, hostname);
+ data->state.async.hostname = res->hostname;
data->state.async.port = port;
data->state.async.done = FALSE; /* not done */
data->state.async.status = 0; /* clear */
data->state.async.dns = NULL; /* clear */
- res = calloc(sizeof(struct thread_data), 1);
- if(!res) {
- free(data->state.async.hostname);
- data->state.async.hostname = NULL;
- return NULL;
- }
data->state.async.tdata = res;
/* initial status - failed */
@@ -782,13 +779,17 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
int pf = PF_INET;
memset(&hints, 0, sizeof(hints));
#ifdef CURLRES_IPV6
- if(Curl_ipv6works(data))
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
/* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
#endif /* CURLRES_IPV6 */
hints.ai_family = pf;
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
SOCK_STREAM : SOCK_DGRAM;
+ /* Since the service is a numerical one, set the hint flags
+ * accordingly to save a call to getservbyname in inside C-Ares
+ */
+ hints.ai_flags = ARES_AI_NUMERICSERV;
msnprintf(service, sizeof(service), "%d", port);
res->num_pending = 1;
ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname,
@@ -797,7 +798,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
#else
#ifdef HAVE_CARES_IPV6
- if(Curl_ipv6works(data)) {
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
/* The stack seems to be IPv6-enabled */
res->num_pending = 2;