原文地址:http://www.skyfox.org/ios-app-support-ipv6-dns64-nat64.html
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 toRFC4038: 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连接
理想情况下,提供者想放弃支持IPv4网络。然而,这样做防止了客户访问IPv4服务器,它代表的是互联网的重要部分。为了解决这个问题,大多数网络提供商实现DNS64 / NAT64过渡工作流。通过过渡转换,能使 IPv6-only 网络继续提供访问IPv4内容。
蜂窝网络部署IPv6网络DNS64和NAT64
在这种类型的工作流中,客户端发送DNS查询一个DNS64服务器,从DNS服务器请求IPv6地址。当发现IPv6地址,它立即传回客户机。然而,当一个IPv6地址找不到的时候,DNS64服务器请求一个IPv4地址代替。然后DNS64服务器通过IPv4地址的前缀生成一个IPv6地址,并将传回客户端。在这方面,客户总是收到一个IPv6-ready地址。见图3。
图3 DNS64 IPv4与IPv6翻译过程
当客户端发送一个请求到服务器,任何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_in32位或者更小。查看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 ConceptsinCFNetwork Programming Guide.
如果您确实需要低级别的Socket API的应用,遵循RFC4038指南RFC4038: Application Aspects of IPv6 Transition.
不要使用IP地址
确保你不是通过IPv4地址 点符号的文字API ,如getaddrinfo和SCNetworkReachabilityCreateWithName等。相反,使用高级网络框架和address-agnostic版本的api,比如getaddrinfogetnameinfo,通过主机名或完全限定域名(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.0IPv4地址,这表明网络上有一个路由器。然而,路由器的存在并不能保证一个因特网连接是否存在。一般情况下,避免预检网络可达性。只尝试做一个连接,并从容地处理失败。如果你必须检查网络的可用性,避免调用SCNetwoSCNetworkReachabilityCreateWithAddress方法。调用SCNetworkReachabilityCreateWithName方法,并传递给它一个主机名代替。
有些应用程序还通过SCNetworkReachabilityCreateWithAddress方法 一个IPv4169.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的等价方法去处理。
IPv4IPv6
AF_INETAF_INET6
PF_INETPF_INET6
struct in_addrstruct in_addr6
struct sockaddr_instruct sockaddr_in6
kDNSServiceProtocol_IPv4kDNSServiceProtocol_IPv
使用系统API来合成IPv6地址
使用getaddrinfo解决一个IPv4地址
#include
#include
#include
#include
uint8_tipv4[4]={192,0,2,1};
structaddrinfohints,*res,*res0;
interror,s;
constchar*cause=NULL;
charipv4_str_buf[INET_ADDRSTRLEN]={0};
constchar*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网络复选框
打开本地的IPv6 NAT64 网络
选择一个提供互联网链接的网络接口, 例如雷电网卡
选择一个网络接口共享
选择Wi-Fi 复选框.
打开通过 Wi-Fi共享
点击 Wi-Fi 选项, 配置网络名称与密码等信息
访问WI-FI设置选项
设置本地WI-FI
选择互联网共享复选框,开启你的本地网络
开启互联网共享
当提示确认开始分享的时候,点击开始
开始分享
一旦共享处于活动状态,你应该看到一个绿色的状态指示灯,Internet共享标签:开。在无线网络菜单中,您还将看到一个小的,淡淡的箭头朝上,表明互联网共享已启用。你现在有一个IPv6NAT64网络,并可以从其他设备,以测试你的应用程序连接到它。
互联网共享标识