aboutsummaryrefslogtreecommitdiff
path: root/lib/hostares.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-07-09 18:39:49 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-07-09 18:39:49 +0000
commit0cd8840dbaf662ee59573be86fe6550a1b5cbf97 (patch)
treeafeeb1408ce03e1848e9ed2c6593cf5cc2aba587 /lib/hostares.c
parentd4b253ba3ec87e1d703910bdb278d142e6e6abf8 (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.c88
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 */