Commit 01a49a76 authored by Luo Jinghua's avatar Luo Jinghua Committed by Daniel Stenberg
Browse files

resolve: add support for IPv6 DNS64/NAT64 Networks on OS X + iOS

Use getaddrinfo() to resolve the IPv4 address literal on iOS/Mac OS X.
If the current network interface doesn’t support IPv4, but supports
IPv6, NAT64, and DNS64.

Closes #866
Fixes #863
parent 9b6d3a66
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -279,6 +279,9 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
    if(tsd->sock_error == 0)
      tsd->sock_error = RESOLVER_ENOMEM;
  }
  else {
    Curl_addrinfo_set_port(tsd->res, tsd->port);
  }

  Curl_mutex_acquire(tsd->mtx);
  if(tsd->done) {
@@ -602,6 +605,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,

  *waitp = 0; /* default to synchronous response */

#ifndef USE_RESOLVE_ON_IPS
  /* First check if this is an IPv4 address string */
  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
    /* This is a dotted IP address 123.123.123.123-style */
@@ -633,6 +637,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
    pf = PF_INET;

#endif /* CURLRES_IPV6 */
#endif /* USE_RESOLVE_ON_IPS */

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = pf;
@@ -656,6 +661,10 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
          hostname, port, Curl_strerror(conn, SOCKERRNO));
    return NULL;
  }
  else {
    Curl_addrinfo_set_port(res, port);
  }

  return res;
}

+29 −0
Original line number Diff line number Diff line
@@ -563,3 +563,32 @@ curl_dogetaddrinfo(const char *hostname,
}
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */

#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
/*
 * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
 * 10.11.5.
 */
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
{
  Curl_addrinfo *ca;
  struct sockaddr_in *addr;
#ifdef ENABLE_IPV6
  struct sockaddr_in6 *addr6;
#endif
  for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
    switch (ca->ai_family) {
    case AF_INET:
      addr = (void *)ca->ai_addr; /* storage area for this info */
      addr->sin_port = htons((unsigned short)port);
      break;

#ifdef ENABLE_IPV6
    case AF_INET6:
      addr6 = (void *)ca->ai_addr; /* storage area for this info */
      addr6->sin6_port = htons((unsigned short)port);
      break;
#endif
    }
  }
}
#endif
+9 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -99,4 +99,12 @@ curl_dogetaddrinfo(const char *hostname,
                   int line, const char *source);
#endif

#ifdef HAVE_GETADDRINFO
#ifdef USE_RESOLVE_ON_IPS
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
#else
#define Curl_addrinfo_set_port(x,y)
#endif
#endif

#endif /* HEADER_CURL_ADDRINFO_H */
+9 −0
Original line number Diff line number Diff line
@@ -221,6 +221,15 @@
#  include "setup-vms.h"
#endif

/*
 * Use getaddrinfo to resolve the IPv4 address literal. If the current network
 * interface doesn’t support IPv4, but supports IPv6, NAT64, and DNS64,
 * performing this task will result in a synthesized IPv6 address.
 */
#ifdef  __APPLE__
#define USE_RESOLVE_ON_IPS 1
#endif

/*
 * Include header files for windows builds before redefining anything.
 * Use this preprocessor block only to include or exclude windows.h,
+12 −0
Original line number Diff line number Diff line
@@ -167,7 +167,9 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
  int error;
  char sbuf[12];
  char *sbufptr = NULL;
#ifndef USE_RESOLVE_ON_IPS
  char addrbuf[128];
#endif
  int pf;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
  struct SessionHandle *data = conn->data;
@@ -196,11 +198,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
  hints.ai_family = pf;
  hints.ai_socktype = conn->socktype;

#ifndef USE_RESOLVE_ON_IPS
  /*
   * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from
   * an IPv4 address on iOS and Mac OS X.
   */
  if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
     (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
    /* the given address is numerical only, prevent a reverse lookup */
    hints.ai_flags = AI_NUMERICHOST;
  }
#endif

  if(port) {
    snprintf(sbuf, sizeof(sbuf), "%d", port);
@@ -213,6 +221,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
    return NULL;
  }

  if(port) {
    Curl_addrinfo_set_port(res, port);
  }

  dump_addrinfo(conn, res);

  return res;