cURL / Mailing Lists / curl-library / Single Mail

curl-library

debians ipv6/c-ares patch

From: Andreas Schuldei <andreas+curllib_at_schuldei.org>
Date: Tue, 8 Jul 2008 00:29:58 +0200

hi!

attached please find the patch that the debian curl package would for
nitting together c-ares and curl for ipv6 usage. It is largely based on
work by Phil Blundell <pb_at_reciva.com>. one known issue found when
uploading a curl package with this to experimental is the fact that it
curl will do ipv6 lookups even if -4 for ipv4 usage is specified.

Index: trunk/lib/hostares.c
===================================================================
--- trunk.orig/lib/hostares.c 2008-06-25 21:59:03.000000000 +0200
+++ trunk/lib/hostares.c 2008-06-25 22:10:40.000000000 +0200
@@ -297,6 +297,62 @@
   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 = alloca (sizeof (struct namebuf6) + strlen(hostname));
+
+
+ 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_name = &buf->hostname[0];
+ h->h_aliases = NULL;
+
+ /* 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);
+
+ return ai;
+}
+#endif /* CURLRES_IPV6 */
+
+
+
 /*
  * Curl_getaddrinfo() - when using ares
  *
@@ -313,7 +369,10 @@
   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 +380,15 @@
     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);
+ }
+
+ family = PF_INET6;
+#endif /* CURLRES_IPV6 */
+
   bufp = strdup(hostname);
 
   if(bufp) {
@@ -332,7 +400,7 @@
     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 */
Index: trunk/lib/hostip4.c
===================================================================
--- trunk.orig/lib/hostip4.c 2008-06-25 21:59:03.000000000 +0200
+++ trunk/lib/hostip4.c 2008-06-25 22:10:10.000000000 +0200
@@ -346,6 +346,9 @@
   Curl_addrinfo *prevai = NULL;
   Curl_addrinfo *firstai = NULL;
   struct sockaddr_in *addr;
+#if (defined(ENABLE_IPV6) && defined(USE_ARES)) /* CURLRES_IPV6 */
+ struct sockaddr_in6 *addr6;
+#endif /* CURLRES_IPV6 */
   int i;
   struct in_addr *curr;
 
@@ -355,7 +358,13 @@
 
   for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]) != NULL; i++) {
 
- ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in));
+ int ss_size = sizeof (struct sockaddr_in);
+#if (defined(ENABLE_IPV6) && defined(USE_ARES)) /* CURLRES_IPV6 */
+ if (he->h_addrtype == AF_INET6)
+ ss_size = sizeof (struct sockaddr_in6);
+#endif /* CURLRES_IPV6 */
+
+ ai = calloc(1, sizeof(Curl_addrinfo) + ss_size);
 
     if(!ai)
       break;
@@ -368,13 +377,13 @@
       /* make the previous entry point to this */
       prevai->ai_next = ai;
 
- ai->ai_family = AF_INET; /* we only support this */
+ ai->ai_family = he->h_addrtype;
 
     /* we return all names as STREAM, so when using this address for TFTP
        the type must be ignored and conn->socktype be used instead! */
     ai->ai_socktype = SOCK_STREAM;
 
- ai->ai_addrlen = sizeof(struct sockaddr_in);
+ ai->ai_addrlen = ss_size;
     /* make the ai_addr point to the address immediately following this struct
        and use that area to store the address */
     ai->ai_addr = (struct sockaddr *) ((char*)ai + sizeof(Curl_addrinfo));
@@ -384,11 +393,25 @@
 
     /* leave the rest of the struct filled with zero */
 
- addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
+ switch (ai->ai_family) {
+ case AF_INET:
+ addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
+
+ memcpy((char *)&(addr->sin_addr), curr, sizeof(struct in_addr));
+ addr->sin_family = (unsigned short)(he->h_addrtype);
+ addr->sin_port = htons((unsigned short)port);
+ break;
 
- memcpy((char *)&(addr->sin_addr), curr, sizeof(struct in_addr));
- addr->sin_family = (unsigned short)(he->h_addrtype);
- addr->sin_port = htons((unsigned short)port);
+#if (defined(ENABLE_IPV6) && defined(USE_ARES)) /* CURLRES_IPV6 */
+ case AF_INET6:
+ addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */
+
+ memcpy((char *)&(addr6->sin6_addr), curr, sizeof(struct in6_addr));
+ addr6->sin6_family = (unsigned short)(he->h_addrtype);
+ addr6->sin6_port = htons((unsigned short)port);
+ break;
+#endif /* CURLRES_IPV6 */
+ }
 
     prevai = ai;
   }
Index: trunk/lib/hostip.h
===================================================================
--- trunk.orig/lib/hostip.h 2008-06-25 21:59:03.000000000 +0200
+++ trunk/lib/hostip.h 2008-06-25 22:10:10.000000000 +0200
@@ -104,6 +104,10 @@
  */
 #ifdef CURLRES_IPV6
 typedef struct addrinfo Curl_addrinfo;
+#ifdef CURLRES_ARES
+Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in,
+ const char *hostname, int port);
+#endif
 #else
 /* OK, so some ipv4-only include tree probably have the addrinfo struct, but
    to work even on those that don't, we provide our own look-alike! */
Received on 2008-07-07