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 */ | 
