ares: ask for both IPv4 and IPv6 addresses
Make the c-ares resolver code ask for both IPv4 and IPv6 addresses when IPv6 is enabled. This is a workaround for the missing ares_getaddrinfo() and is a lot easier to implement. Note that as long as c-ares returns IPv4 addresses when IPv6 addresses were requested but missing, this will cause a host's IPv4 addresses to occur twice in the DNS cache. URL: http://curl.haxx.se/mail/lib-2010-12/0041.html
This commit is contained in:
Родитель
bcfb9ea34c
Коммит
8ab137b2bc
|
@ -398,13 +398,30 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = bufp;
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
conn->async.temp_ai = NULL; /* clear */
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||
(ares_host_callback)ares_query_completed_cb, conn);
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
if(family == PF_UNSPEC) {
|
||||
conn->async.num_pending = 2;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
||||
ares_query_completed_cb, conn);
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET6,
|
||||
ares_query_completed_cb, conn);
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
{
|
||||
conn->async.num_pending = 1;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||
ares_query_completed_cb, conn);
|
||||
}
|
||||
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -95,6 +95,20 @@ CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
|||
if(ai) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
Curl_addrinfo *ai_tail = ai;
|
||||
|
||||
while (ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = conn->async.temp_ai;
|
||||
conn->async.temp_ai = ai;
|
||||
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
#endif
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
|
@ -110,9 +124,48 @@ CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
|||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
else
|
||||
else {
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
if(--conn->async.num_pending > 0) {
|
||||
/* We are not done yet. Clean up and return.
|
||||
This function will be called again. */
|
||||
if(conn->async.temp_ai)
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
else
|
||||
{
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
|
||||
if(conn->async.temp_ai) {
|
||||
/* We are done, and while this latest request
|
||||
failed, some previous results exist. */
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = Curl_cache_addr(data, conn->async.temp_ai,
|
||||
conn->async.hostname,
|
||||
conn->async.port);
|
||||
if(!dns) {
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn->async.dns = dns;
|
||||
|
||||
|
|
|
@ -479,6 +479,8 @@ struct Curl_async {
|
|||
bool done; /* set TRUE when the lookup is complete */
|
||||
int status; /* if done is TRUE, this is the status from the callback */
|
||||
void *os_specific; /* 'struct thread_data' for Windows */
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче