From 00c0b1b7076ebc24735071f587f9501c1595a02b Mon Sep 17 00:00:00 2001
From: James Yonan <james@openvpn.net>
Date: Mon, 19 Mar 2018 11:24:10 +0800
Subject: [PATCH] Added Apple NAT64 support when both ASIO_HAS_GETADDRINFO and
 ASIO_APPLE_NAT64 ar defined

* When calling getaddrinfo(), Apple recommends to set
  AI_DEFAULT flags in hint.

* iOS bug workaround: sometimes iOS getaddrinfo() returns a
  non-zero scope ID for non-link-local addresses.
  Workaround by forcing scope ID to 0 for non-link-local
  addresses.
---
 asio/include/asio/detail/impl/socket_ops.ipp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/asio/include/asio/detail/impl/socket_ops.ipp b/asio/include/asio/detail/impl/socket_ops.ipp
index ad203b74..b17a60ed 100644
--- a/asio/include/asio/detail/impl/socket_ops.ipp
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
@@ -3339,6 +3339,23 @@ asio::error_code getaddrinfo(const char* host,
 # endif
 #elif !defined(ASIO_HAS_GETADDRINFO)
   int error = getaddrinfo_emulation(host, service, &hints, result);
+  return ec = translate_addrinfo_error(error);
+#elif defined(ASIO_HAS_GETADDRINFO) && defined(ASIO_APPLE_NAT64)
+  // For NAT64 compatibility, Apple recommends to set AI_DEFAULT flags
+  addrinfo_type new_hints = hints;
+  new_hints.ai_flags |= AI_DEFAULT;
+  int error = ::getaddrinfo(host, service, &new_hints, result);
+
+  // iOS bug workaround: sometimes iOS getaddrinfo() returns a non-zero scope ID
+  // for non-link-local addresses.  Workaround by forcing scope ID to 0 for
+  // non-link-local addresses.
+  if (!error && (*result)->ai_family == AF_INET6)
+  {
+    sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr;
+    if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr)))
+      a6->sin6_scope_id = 0;
+  }
+
   return ec = translate_addrinfo_error(error);
 #else
   int error = ::getaddrinfo(host, service, &hints, result);
-- 
2.21.0

