苹果:6月1日后所有iOS应用必须支持IPv6-only网络
IPV4地址枯竭迫在眉睫,越来越多的企业和移动电话运营商都在部署IPv6 DNS64和NAT64网络。一个DNS64 / NAT64 IPv6-only 网络是继续提供转化访问IPv4的内容。根据您的应用程序的性质,过渡有不同的含义:
- 如果您正在编写一个客户端应用程序使用高级网络api,如NSURLSession和CFNetwork框架,并且使用域名链接,你不需要改变任何东西为您的应用程序使用IPv6地址。如果你的链接未使用域名,你现在应该使用它了。查看 Avoid Resolving DNS Names Before Connecting to a Host 学习怎么做,有关. CFNetwork的更多信息, 查看 CFNetwork Framework Reference.
- 如果你在写一个服务器端应用程序或其他低级的网络应用程序,你需要确保你的套接字代码与IPv4和IPv6地址正常工作。Refer to RFC4038: Application Aspects of IPv6 Transition.
一.是什么驱使我们采用 IPv6
主要的网络服务提供者,包括美国主要移动运营商正在积极推广和部署IPv6。这是由于各种各样的因素。
IPv4 地址耗尽
几十年来,世界已经知道IPv4地址最终将枯竭。无类域间路由等技术(CIDR)和网络地址转换(NAT)帮助拖延不可避免的。然而,1月31日,2011年,顶级的互联网地址分配机构(IANA)IPv4地址正式精疲力竭。美国互联网号码注册机构(ARIN)预计将在2015年夏天用完IPv4地址----这有一个一个倒计时。
IPv6比IPv4更加高效
除了解决IPv4的耗尽问题,IPv6比IPv4更高效。例如,IPv6:
- 避免了网络地址转换的需要(NAT)
- 通过使用简化的头提供了更快的路由通过网络
- 防止网络碎片
- 避免广播邻居地址解析
4G 部署
第四代移动通信技术(4G)是基于分组仅进行切换。由于IPv4地址的供应量有限,对IPv6的支持是必需的,为了4G部署的可扩展性。
多媒体服务的兼容性
IP多媒体核心网络子系统(IMS)允许一些服务,如多媒体短信消息和语音/ LTE(VoLTE) 通过 IP传送。一些服务提供商使用的IMS兼容IPv6 only。
成本
继续支持遗留的IPv4网络,服务提供者引发了额外的操作和管理成本,而行业正在继续迁移到IPv6。
DNS64 / NAT64过渡工作流
为了帮助延缓IPv4地址的枯竭,NAT在很多IPv4网络中实现。虽然这种解决方案暂时的有效,它证明了昂贵和脆弱。如今,随着越来越多的客户使用IPv6,供应商必须现在同时支持IPv4和IPv6。这是一个高昂代价。
一个蜂窝网络,提供单独的IPv4和IPv6连接
IPv6-only环境的原理
理想情况下,提供者想放弃支持IPv4网络。然而,这样做防止了客户访问IPv4服务器,它代表的是互联网的重要部分。为了解决这个问题,大多数网络提供商实现DNS64 / NAT64过渡工作流。通过过渡转换,能使 IPv6-only 网络继续提供访问IPv4内容。
首先需要明确一点,在App Store审核APP的IPv6-only的环境下也是可以正常访问IPv4的服务的,只是首先由DNS64将解析出来的IPv4地址转成兼容的IPv6地址,然后访问IPv4服务时通过NAT64网关对IPv4和IPv6进行NAT,并不需要客户有实际的IPv6服务。如下图所示:
蜂窝网络部署IPv6网络DNS64和NAT64
DNS64原理
在这种类型的工作流中,客户端发送DNS查询一个DNS64服务器,从DNS服务器请求IPv6地址。当发现IPv6地址,它立即传回客户机。然而,当一个IPv6地址找不到的时候,DNS64服务器请求一个IPv4地址代替。然后DNS64服务器通过IPv4地址的前缀生成一个IPv6地址,并将传回客户端。在这方面,客户总是收到一个IPv6-ready地址。见图3。
图3 DNS64 IPv4与IPv6解析流程
NAT64原理
当客户端发送一个请求到服务器,任何IPv6合成地址发送的数据包通过NAT64网关自动路由的网络。网关执行IPv6-to-IPv4地址和协议转换的请求。它还执行IPv4-to-IPv6来自服务器的响应的转换。参见图4。
图4 DNS64 / NAT64过渡解决方案的工作流程
IPv6和Appstore的审核要求
一个应用程序提交上架到Appstore 兼容IPv6 DNS64 / NAT64网络将是必需的,至关重要的是,应用程序应该保证兼容性。好消息是,大多数应用程序已经兼容IPv6。对于这些应用,定期回归测试你的应用也是必要的。应用程序不兼容ipv6 DNS64 / NAT64网络上操作时可能会遇到问题。幸运的是,解决这些问题通常是相当简单的,在本章中讨论。
6月1日以后所有iOS应用必须支持IPv6-only网络
支持IPv6的常见障碍
有些情况下会阻碍一个应用程序支持IPv6。接下来的小节描述如何解决这些问题。
- 嵌入在协议的IP地址。许多通信协议,如会话初始化协议(SIP),文件传输协议(FTP)的WebSockets,和点对点协议(P2PP),包括IP地址文字协议消息。例如,FTP命令参数数据端口
DATA PORT
和被动PASSIVE
的交换信息,包括IP地址文字。同样,IP地址文字可能出现在SIP header字段的值,例如,To
,From
,Contact
,Record-Route
, andVia
。看 Use High-Level Networking Frameworks 和 Don’t Use IP Address Literals. - 嵌入到配置文件的IP地址。配置文件经常包含IP地址。 Don’t Use IP Address Literals.。
- 网络连通性预检。许多应用程序试图通过使用IP地址和相应API,主动检查网络连接或一个活跃的WI-FI连接,。查看 Connect Without Preflight.
- 使用低级网络API。一些应用程序直接与套接字和其他原始网络api进行交互,如
gethostbyname
,gethostbyname2
, 与inet_aton
。这些API很容易滥用或者他们只支持IPv4,例如:解析主机名AF_INET
地址族, 而不是AF_UNSPEC
地址族。查看 Use High-Level Networking Frameworks. - 使用小地址族的储存容器。一些应用程序和网络库使用地址存储容器
uint32_t
,in_addr
, 与sockaddr_in
32位或者更小。查看 Use Appropriately Sized Storage Containers.
确保IPv6的DNS64/ NAT64兼容性
坚持以下原则,以确保您的应用程序的IPv6 DNS64/ NAT64的兼容性。
使用高级网络框架
需要联网的应用程序可以在高级别联网框架或低级别的POSIX socket API来构建。在大多数情况下,高级别框架是足够的。他们有能力,易于使用,并且不容易比低级别的API遇到常见的陷阱。
网络框架和API层
- WebKit。这个框架提供了一组类,用于显示在窗口的网页内容,并实现了浏览器的功能,如以下链接,管理后台转发列表和管理的页面的历史记录最近访问过的。 WebKit的简化加载网页,也就是说,异步请求从HTTP服务器的网页内容,其中反应可能逐步到来,以随机顺序,或部分由于网络错误的复杂过程。欲了解更多信息,请参阅WebKit Framework Reference.。
- Cocoa URL loading system。这个系统是在没有提供明确的IP地址发送和接收网络上的数据的最简单的方法。数据的发送和使用几类之一,如NSURLSession,NSURLRequest和NSURLConnection,与NSURL对象一起工作。 NSURL对象可以让你的应用程序处理URL和它们引用的资源。方法和传递一个URL说明:通过调用initWithString创建NSURL对象。调用checkResourceIsReachableAndReturnError:在NSURL类的方法来检查主机是否可达。欲了解更多信息,请参阅 URL Session Programming Guide.
- CFNetwork。这个核心服务框架提供抽象的网络协议,这使得它易于进行各种网络任务,如与BSD sockets工作,解析DNS主机,并与HTTP / HTTPS工作。要定位没有明确的IP地址的主机,调用CFHostCreateWithName方法。要打开对TCP sockets的主机,调用CFStreamCreatePairWithSocketToCFHost方法。欲了解更多信息,请参见 CFNetwork Concepts in CFNetwork Programming Guide.
如果您确实需要低级别的Socket API的应用,遵循RFC4038指南 RFC4038: Application Aspects of IPv6 Transition.
不要使用IP地址
确保你不是通过IPv4地址 点符号的文字API ,如getaddrinfo
和SCNetworkReachabilityCreateWithName
等。相反,使用高级网络框架和address-agnostic版本的api,比如getaddrinfo
getnameinfo
,通过主机名或完全限定域名(fqdn)。查阅getaddrinfo(3) Mac OS X Developer Tools Manual Page
和getnameinfo(3) Mac OS X Developer Tools Manual Page
.
注意:在iOS9和OS X10.11及更高版本,NSURLSession
和CFNetwork
会在本地自动合成IPv6 从IPv4文本 在本地DNS64/ NAT64网络设备上。不过,你还是应该努力摆脱使用IP地址的代码。
连接而无需预检
可达性的API(见 SCNetworkReachability Reference)明确连接问题后,用于诊断目的。许多应用程序不正确地使用这些API主动检查通过调用SCNetworkReachabilityCreateWithAddress方法,并传递给它的0.0.0.0
IPv4地址,这表明网络上有一个路由器。然而,路由器的存在并不能保证一个因特网连接是否存在。一般情况下,避免预检网络可达性。只尝试做一个连接,并从容地处理失败。如果你必须检查网络的可用性,避免调用SCNetwoSCNetworkReachabilityCreateWithAddress
方法。调用SCNetworkReachabilityCreateWithName
方法,并传递给它一个主机名代替。
有些应用程序还通过SCNetworkReachabilityCreateWithAddress
方法 一个IPv4 169.254.0.0
,自分配的链路本地地址的,以检查活跃的Wi-Fi连接。要检查Wi-Fi或蜂窝连接,查找网络可达性标志使用kSCNetworkReachabilityFlagsIsWWAN
代替。
使用适当大小的存储容器
使用地址存储容器,如sockaddr_storage,存储IPv6足够大。
检查源代码IPv6 DNS64 / NAT64不兼容
检查并消除IPv4-specific api,如:
inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
inet_ntoa_r()
bindresvport()
getipv4sourcefilter()
setipv4sourcefilter()
如果您的代码有以下IPv4类型,确保使用IPv6的等价方法去处理。
IPv4 | IPv6 |
---|---|
AF_INET |
AF_INET6 |
PF_INET |
PF_INET6 |
struct in_addr |
struct in_addr6 |
struct sockaddr_in |
struct sockaddr_in6 |
kDNSServiceProtocol_IPv4 |
kDNSServiceProtocol_IPv |
使用系统API来合成IPv6地址
使用getaddrinfo解决一个IPv4地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <err.h> uint8_t ipv4[4] = {192, 0, 2, 1}; struct addrinfo hints, *res, *res0; int error, s; const char *cause = NULL; char ipv4_str_buf[INET_ADDRSTRLEN] = { 0 }; const char *ipv4_str = inet_ntop(AF_INET, &ipv4, ipv4_str_buf, sizeof(ipv4_str_buf)); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_DEFAULT; error = getaddrinfo(ipv4_str, "http", &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /*NOTREACHED*/ } s = -1; for (res = res0; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { cause = "socket"; continue; } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { cause = "connect"; close(s); s = -1; continue; } break; /* okay we got one */ } if (s < 0) { err(1, "%s", cause); /*NOTREACHED*/ } freeaddrinfo(res0); |
注意:合成IPv6地址的能力添加在iOS 9.2和OS X 10.11.2中的 getaddrinfo方法
然而,它不兼容老系统版本。查阅:getaddrinfo(3) Mac OS X Developer Tools Manual Page
定期测试IPv6 DNS64 / NAT64兼容性
最简单的方法来测试你的应用是否兼容IPv6 DNS64 / NAT64
在mac上建立一个本地IPv6 DNS64 / NAT64网络。你可以从你的其他设备连接到这个网络用于测试目的。参见图
重要提示:IPv6的DNS64/ NAT64网络设置选项在OS X10.11及更高版本可用。此外,基于Mac的IPv6 DNS64/ NAT64网络是与已经执行了RFC6106支持客户端设备兼容:对于DNS配置IPv6路由器广告选项。如果您的测试设备不是iOS或OS X设备,请确保它支持RFC。需要注意的是,不同于服务提供商部署DNS64/ NAT64工作流程,一台Mac,基于IPv6 DNS64/ NAT64总是产生合成的IPv6地址。因此,它不能提供本地网络的外部访问
使用你的MAC建立本地的IPv6 Wi-Fi 网络
- 确认你的MAC连接到了互联网,并且不是通过Wi-Fi.
- 从Dock中运行系统首选项
-
按住Option按键并且同时点击共享 ,不要松开Option按键
-
从共享服务中选择互联网分享选项
- 释放Option按键
-
选中 创建NAT64网络复选框
-
选择一个提供互联网链接的网络接口, 例如雷电网卡
-
选择Wi-Fi 复选框.
-
点击 Wi-Fi 选项, 配置网络名称与密码等信息
-
选择互联网共享复选框,开启你的本地网络
-
当提示确认开始分享的时候,点击开始
一旦共享处于活动状态,你应该看到一个绿色的状态指示灯,Internet共享标签:开。在无线网络菜单中,您还将看到一个小的,淡淡的箭头朝上,表明互联网共享已启用。你现在有一个IPv6 NAT64网络,并可以从其他设备,以测试你的应用程序连接到它。
互联网共享标识
测试成功了。你以为就没问题了?这里提交依然可能被拒,手机和 Mac 之间是 IPv6 连接没错,但 Mac 和你的服务器之间还是 IPv4 连接。
测试服务器的IPv6兼容性
苹果表示服务器不必须支持 IPv6,但是有一点苹果没有指出来,那就是,虽然你的服务器不用支持 IPv6,但是必须正确响应 IPv6 的 DNS 查询
在现在这种IPv4和IPV6混用的情况下,你也可以使用dig命令的AAAA的选项查询主机的IPv6 AAAA记录,终端执行:
1 |
dig +nocmd +nostats example.com AAAA |
例如检测apple.com:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Jakey-mini:~ Jakey$ dig +nocmd +nostats www.apple.com AAAA ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54941 ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 13, ADDITIONAL: 1 ;; QUESTION SECTION: ;www.apple.com. IN AAAA ;; ANSWER SECTION: www.apple.com. 1287 IN CNAME www.apple.com.edgekey.net. www.apple.com.edgekey.net. 226 IN CNAME www.apple.com.edgekey.net.globalredir.akadns.net. www.apple.com.edgekey.net.globalredir.akadns.net. 1807 IN CNAME e6858.dsce9.akamaiedge.net. e6858.dsce9.akamaiedge.net. 30 IN AAAA 2600:140b:10:1a3::1aca e6858.dsce9.akamaiedge.net. 30 IN AAAA 2600:140b:10:1b5::1aca ;; AUTHORITY SECTION: akamaiedge.net. 7858 IN NS ns2-194.akamaiedge.net. akamaiedge.net. 7858 IN NS la6.akamaiedge.net. akamaiedge.net. 7858 IN NS ns6-194.akamaiedge.net. akamaiedge.net. 7858 IN NS ns1-1.akamaiedge.net. akamaiedge.net. 7858 IN NS la7.akamaiedge.net. akamaiedge.net. 7858 IN NS ns3-194.akamaiedge.net. akamaiedge.net. 7858 IN NS lar6.akamaiedge.net. akamaiedge.net. 7858 IN NS lar2.akamaiedge.net. akamaiedge.net. 7858 IN NS ns5-194.akamaiedge.net. akamaiedge.net. 7858 IN NS ns4-194.akamaiedge.net. akamaiedge.net. 7858 IN NS ns7-194.akamaiedge.net. akamaiedge.net. 7858 IN NS la1.akamaiedge.net. akamaiedge.net. 7858 IN NS la3.akamaiedge.net. ;; ADDITIONAL SECTION: la1.akamaiedge.net. 7858 IN A 184.26.161.192 |
如果返回的 status 为 NOERROR,说明服务器DNS解析兼容了IPv6查询。
如果返回的是其他的响应,尤其是 SERVFAIL 的情况,那就证明DNS 配置出现了问题,直到稳定返回 NOERROR 为止。
原文链接: Supporting IPv6 DNS64/NAT64 Networks
转载请注明:天狐博客 » 适配iOS应用兼容IPv6 DNS64/NAT64网络