diff options
author | Daniel Stenberg <daniel@haxx.se> | 2008-07-09 18:39:49 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2008-07-09 18:39:49 +0000 |
commit | 0cd8840dbaf662ee59573be86fe6550a1b5cbf97 (patch) | |
tree | afeeb1408ce03e1848e9ed2c6593cf5cc2aba587 /lib/hostares.c | |
parent | d4b253ba3ec87e1d703910bdb278d142e6e6abf8 (diff) |
- 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.
Diffstat (limited to 'lib/hostares.c')
-rw-r--r-- | lib/hostares.c | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/lib/hostares.c b/lib/hostares.c index b6de83027..231235242 100644 --- a/lib/hostares.c +++ b/lib/hostares.c @@ -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 */ |