aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2016-06-07 18:11:37 +0800
committerDaniel Stenberg <daniel@haxx.se>2016-06-07 20:39:05 +0200
commit01a49a7626ee4a226cd0b50d70591ab147d60ee0 (patch)
treeef54a49ff290e8c432570d6dc081ebb6c56f420d
parent9b6d3a662ea81ec3bbb12002ca79fd27d750671e (diff)
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
-rw-r--r--lib/asyn-thread.c11
-rw-r--r--lib/curl_addrinfo.c29
-rw-r--r--lib/curl_addrinfo.h10
-rw-r--r--lib/curl_setup.h9
-rw-r--r--lib/hostip6.c12
5 files changed, 69 insertions, 2 deletions
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 81caedb09..0ca260334 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -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;
}
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 8fa0c84cc..35eb2ddb9 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -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
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index 01f286478..1a681e61e 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -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 */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index d78873fe5..7dcc4c4cd 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -222,6 +222,15 @@
#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,
* winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
diff --git a/lib/hostip6.c b/lib/hostip6.c
index 59bc4e4ac..9d401484a 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -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;