支持 IPv6 DNS64 / NAT64 网络的调研

2016/06/12 婷婷 iOS

iOS9 iOS 上架需要 支持IPv6 DNS64 / NAT64网络的调研 。

一 背景

1、 IPv4地址耗尽。

2、 IPv6比IPv4更高效。

  • 2.1 避免了网络地址转换的需求。

  • 2.2 通过简单的IP报文头部格式提供更快的路。

  • 2.3 避免网络碎片。

  • 2.4 避免广播邻居地址解析。

3、 4G网络对IPv6的支持。

4、 多媒体服务兼容IPv6。

5、 继续支持IPv4的运营成本和管理成本较高。

二 调研内容

1、 蜂窝网络利用DNS64和NAT64部署IPv6网络。

Figure 10-2 A cellular network that deploys an IPv6 network with DNS64 and NAT64

Figure 10-1  A cellular network that provides separate IPv4 and IPv6 connectivity

客户端给一个DNS64的服务器发送请求IPv6地址的网络请求,如果找到了IPv6地址,立即返回给客户端,如果未找到IPv6地址,DNS64服务器就会寻找IPv4地址,并通过给IPv4地址就前缀的方式合成IPv4地址并且返回。

当客户端发送给服务器的请求时,发往合成地址的任何IPv6数据包自动由网络通过一个NAT64网关路由。网关执行IPv6-to-IPv4地址和协议转换的请求。它也执行IPv4到IPv6转换来自服务器的响应。

Figure 10-3 DNS64 IPv4 to IPv6 translation process

Figure 10-3  DNS64 IPv4 to IPv6 translation process

2、 常见不支持IPv6的情况

  • 2.1 IP地址写入在协议里,比如:直接嵌套在SIP和FTP协议中。

  • 2.2 IP地址写入在配置文件中。

  • 2.3 网络预测,即在网络连接API中写入IP地址判断蜂窝或者Wi-Fi是否连接。

  • 2.4 使用支持IPv4的低级API。

  • 2.5 使用容量小于或等于32字节的地址存储器。

3、 确保兼容IPv6 DNS64/NAT64

  • 3.1 使用高级的网络框架,比如:

Cocoa URL loading system(NSURLSession, NSURLRequest, and NSURLConnection)、

CFNetwork(CFHostCreateWithName,CFStreamCreatePairWithSocketToCFHost)、

WebKit (此框架适用于web内容展示)

  • 3.2 不要使用明文IP(Don’t Use IP Address Literals):

苹果建议使用:getaddrinfo 和 getnameinfo通过传递hostname和FQDN(完全限定域名)的方式

不要使用:getaddrinfo 和SCNetworkReachabilityCreateWithName通过传递明文IP的方式

注:在iOS9及其之后,NSURLSession和CFNetwork会自动从IPv4地址合成IPv6地址

  • 3.3 使用没有预测的网络连接:

    判断设备是否可路由:

    苹果不建议使用: SCNetworkReachabilityCreateWithAddress 并且传入IP地址

    苹果建议使用: SCNetworkReachabilityCreateWithName 并且传进一个hostname。

    判断蜂窝或者Wi-Fi是否连接:

    苹果不建议使用:SCNetworkReachabilityCreateWithAddress并且IPv4地址

    苹果建议使用: kSCNetworkReachabilityFlagsIsWWAN。

  • 3.4 使用足够存储IPv6地址的地址储存器,比如:sockaddr_storage。

  • 3.5 检查不支持IPv6的低级API:

    注:inet_addr(),inet_aton(),inet_lnaof(),inet_makeaddr(),inet_netof(),inet_network(),inet_ntoa(),inet_ntoa_r(),bindresvport(),getipv4sourcefilter(),setipv4sourcefilter()

修改可兼容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_IPv6
  • 3.6 使用系统的API合成IPv6地址。

    如果在没有主机名的情况下应用需要去连接一个只支持IPv4的服务器,可以使用getaddrinfo函数解析IPv4,如果当前的网络接口并不支持IPv4,但是支持IPv6、NAT64和 DNS64,那么使用这个函数可以得到一个合成的IPv6的地址。

    注:在iOS9.2和OS X10.11.2,getaddrinfo拥有合成地址的功能。

  • 3.7 避免在连接到主机之前解析域名。

    原因:DNS解析可以返回很多IP地址,但是在应用层并不能确定哪一个IP才是连接远程主机的最好连接方式;如果使用域名,就可以去判断哪一个IP才可以链接到主机。

    解决:可以使用例如CFHost或者CFNetService这样支持传入域名的API。

参考文档

Search

    欢迎下载我们的APP

    Table of Contents