- Andreas Schuldei improved Phil Blundell's patch for IPv6 using c-ares, and I

edited it slightly. Now you should be able to use IPv6 addresses fine even
  with libcurl built to use c-ares.
This commit is contained in:
Daniel Stenberg
2008-07-09 18:39:49 +00:00
parent d4b253ba3e
commit 0cd8840dba
6 changed files with 214 additions and 95 deletions

View File

@@ -297,6 +297,70 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
return rc;
}
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
/*
* Curl_ip2addr6() takes an ipv6 internet address as input parameter
* together with a pointer to the string version of the address, and it
* returns a Curl_addrinfo chain filled in correctly with information for this
* address/host.
*
* The input parameters ARE NOT checked for validity but they are expected
* to have been checked already when this is called.
*/
Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in,
const char *hostname, int port)
{
Curl_addrinfo *ai;
#if defined(VMS) && defined(__INITIAL_POINTER_SIZE) && \
(__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h;
struct in6_addr *addrentry;
struct namebuf6 {
struct hostent hostentry;
char *h_addr_list[2];
struct in6_addr addrentry;
char hostname[1];
};
struct namebuf6 *buf = malloc(sizeof (struct namebuf6) + strlen(hostname));
if(!buf)
return NULL;
h = &buf->hostentry;
h->h_addr_list = &buf->h_addr_list[0];
addrentry = &buf->addrentry;
memcpy(addrentry, in, sizeof (*in));
h->h_addr_list[0] = (char*)addrentry;
h->h_addr_list[1] = NULL; /* terminate list of entries */
h->h_name = &buf->hostname[0];
h->h_aliases = NULL;
h->h_addrtype = AF_INET6;
/* Now store the dotted version of the address */
strcpy (h->h_name, hostname);
#if defined(VMS) && defined(__INITIAL_POINTER_SIZE) && \
(__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port);
free(buf);
return ai;
}
#endif /* CURLRES_IPV6 */
/*
* Curl_getaddrinfo() - when using ares
*
@@ -313,7 +377,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
char *bufp;
struct SessionHandle *data = conn->data;
in_addr_t in = inet_addr(hostname);
int family = PF_INET;
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
struct in6_addr in6;
#endif /* CURLRES_IPV6 */
*waitp = FALSE;
if(in != CURL_INADDR_NONE) {
@@ -321,6 +388,23 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
return Curl_ip2addr(in, hostname, port);
}
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
if (inet_pton (AF_INET6, hostname, &in6) > 0) {
/* This must be an IPv6 address literal. */
return Curl_ip2addr6(&in6, hostname, port);
}
switch(data->set.ip_version) {
case CURL_IPRESOLVE_V4:
family = PF_INET;
break;
default: /* by default we try ipv6, as PF_UNSPEC isn't supported by (c-)ares */
case CURL_IPRESOLVE_V6:
family = PF_INET6;
break;
}
#endif /* CURLRES_IPV6 */
bufp = strdup(hostname);
if(bufp) {
@@ -332,7 +416,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
conn->async.dns = NULL; /* clear */
/* areschannel is already setup in the Curl_open() function */
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
ares_gethostbyname(data->state.areschannel, hostname, family,
(ares_host_callback)Curl_addrinfo4_callback, conn);
*waitp = TRUE; /* please wait for the response */