]> granicus.if.org Git - curl/commitdiff
resolve: add support for IPv6 DNS64/NAT64 Networks on OS X + iOS
authorLuo Jinghua <sunmoon1997@gmail.com>
Tue, 7 Jun 2016 10:11:37 +0000 (18:11 +0800)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 7 Jun 2016 18:39:05 +0000 (20:39 +0200)
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

lib/asyn-thread.c
lib/curl_addrinfo.c
lib/curl_addrinfo.h
lib/curl_setup.h
lib/hostip6.c

index 81caedb091cf2dcd7a4ce388dc266506c620a304..0ca2603349d5567123434b83db7dc2d972ec25f9 100644 (file)
@@ -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 */
@@ -609,7 +613,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
 
 #ifdef CURLRES_IPV6
   /* check if this is an IPv6 address string */
-  if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+  if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
     /* This is an IPv6 address literal */
     return Curl_ip2addr(AF_INET6, &in6, hostname, port);
 
@@ -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;
 }
 
index 8fa0c84cccec4eefef39b510c59a4cb1f8af2400..35eb2ddb96add93ab30cbe3af20b95c7372b83d9 100644 (file)
@@ -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
index 01f2864785d9c6c95db8cc5d8ea8ae3134ff14b5..1a681e61efabb45e87978e61070b360259605259 100644 (file)
@@ -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 */
index d78873fe53a9e1fe6ccf98843ee88baea1939ddb..7dcc4c4cdbfbabbc953c7be385c38f137d0819e4 100644 (file)
 #  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,
index 59bc4e4ac57143b1ff87b809b6737a3bea8769bf..9d401484a3042b4b2b00a8e92c4d04ea4de37a20 100644 (file)
@@ -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;