原文地址:http://www.skyfox.org/ios-app-support-ipv6-dns64-nat64.html
IPV4地址枯竭迫在眉睫,越來(lái)越多的企業(yè)和移動(dòng)電話運(yùn)營(yíng)商都在部署IPv6 DNS64和NAT64網(wǎng)絡(luò)。一個(gè)DNS64 / NAT64 IPv6-only 網(wǎng)絡(luò)是繼續(xù)提供轉(zhuǎn)化訪問(wèn)IPv4的內(nèi)容。根據(jù)您的應(yīng)用程序的性質(zhì),過(guò)渡有不同的含義:
如果您正在編寫一個(gè)客戶端應(yīng)用程序使用高級(jí)網(wǎng)絡(luò)api,如NSURLSession和CFNetwork框架,并且使用域名鏈接,你不需要改變?nèi)魏螙|西為您的應(yīng)用程序使用IPv6地址。如果你的鏈接未使用域名,你現(xiàn)在應(yīng)該使用它了。查看Avoid Resolving DNS Names Before Connecting to a Host學(xué)習(xí)怎么做,有關(guān). CFNetwork的更多信息, 查看CFNetwork Framework Reference.
如果你在寫一個(gè)服務(wù)器端應(yīng)用程序或其他低級(jí)的網(wǎng)絡(luò)應(yīng)用程序,你需要確保你的套接字代碼與IPv4和IPv6地址正常工作。Refer toRFC4038: Application Aspects of IPv6 Transition.
一.是什么驅(qū)使我們采用 IPv6
主要的網(wǎng)絡(luò)服務(wù)提供者,包括美國(guó)主要移動(dòng)運(yùn)營(yíng)商正在積極推廣和部署IPv6。這是由于各種各樣的因素。
IPv4 地址耗盡
幾十年來(lái),世界已經(jīng)知道IPv4地址最終將枯竭。無(wú)類域間路由等技術(shù)(CIDR)和網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)幫助拖延不可避免的。然而,1月31日,2011年,頂級(jí)的互聯(lián)網(wǎng)地址分配機(jī)構(gòu)(IANA)IPv4地址正式精疲力竭。美國(guó)互聯(lián)網(wǎng)號(hào)碼注冊(cè)機(jī)構(gòu)(ARIN)預(yù)計(jì)將在2015年夏天用完IPv4地址----這有一個(gè)一個(gè)倒計(jì)時(shí)。
IPv6比IPv4更加高效
除了解決IPv4的耗盡問(wèn)題,IPv6比IPv4更高效。例如,IPv6:
避免了網(wǎng)絡(luò)地址轉(zhuǎn)換的需要(NAT)
通過(guò)使用簡(jiǎn)化的頭提供了更快的路由通過(guò)網(wǎng)絡(luò)
防止網(wǎng)絡(luò)碎片
避免廣播鄰居地址解析
4G 部署
第四代移動(dòng)通信技術(shù)(4G)是基于分組僅進(jìn)行切換。由于IPv4地址的供應(yīng)量有限,對(duì)IPv6的支持是必需的,為了4G部署的可擴(kuò)展性。
多媒體服務(wù)的兼容性
IP多媒體核心網(wǎng)絡(luò)子系統(tǒng)(IMS)允許一些服務(wù),如多媒體短信消息和語(yǔ)音/ LTE(VoLTE) 通過(guò) IP傳送。一些服務(wù)提供商使用的IMS兼容IPv6 only。
成本
繼續(xù)支持遺留的IPv4網(wǎng)絡(luò),服務(wù)提供者引發(fā)了額外的操作和管理成本,而行業(yè)正在繼續(xù)遷移到IPv6。
DNS64 / NAT64過(guò)渡工作流
為了幫助延緩IPv4地址的枯竭,NAT在很多IPv4網(wǎng)絡(luò)中實(shí)現(xiàn)。雖然這種解決方案暫時(shí)的有效,它證明了昂貴和脆弱。如今,隨著越來(lái)越多的客戶使用IPv6,供應(yīng)商必須現(xiàn)在同時(shí)支持IPv4和IPv6。這是一個(gè)高昂代價(jià)。
一個(gè)蜂窩網(wǎng)絡(luò),提供單獨(dú)的IPv4和IPv6連接
理想情況下,提供者想放棄支持IPv4網(wǎng)絡(luò)。然而,這樣做防止了客戶訪問(wèn)IPv4服務(wù)器,它代表的是互聯(lián)網(wǎng)的重要部分。為了解決這個(gè)問(wèn)題,大多數(shù)網(wǎng)絡(luò)提供商實(shí)現(xiàn)DNS64 / NAT64過(guò)渡工作流。通過(guò)過(guò)渡轉(zhuǎn)換,能使 IPv6-only 網(wǎng)絡(luò)繼續(xù)提供訪問(wèn)IPv4內(nèi)容。
蜂窩網(wǎng)絡(luò)部署IPv6網(wǎng)絡(luò)DNS64和NAT64
在這種類型的工作流中,客戶端發(fā)送DNS查詢一個(gè)DNS64服務(wù)器,從DNS服務(wù)器請(qǐng)求IPv6地址。當(dāng)發(fā)現(xiàn)IPv6地址,它立即傳回客戶機(jī)。然而,當(dāng)一個(gè)IPv6地址找不到的時(shí)候,DNS64服務(wù)器請(qǐng)求一個(gè)IPv4地址代替。然后DNS64服務(wù)器通過(guò)IPv4地址的前綴生成一個(gè)IPv6地址,并將傳回客戶端。在這方面,客戶總是收到一個(gè)IPv6-ready地址。見(jiàn)圖3。
圖3 DNS64 IPv4與IPv6翻譯過(guò)程
當(dāng)客戶端發(fā)送一個(gè)請(qǐng)求到服務(wù)器,任何IPv6合成地址發(fā)送的數(shù)據(jù)包通過(guò)NAT64網(wǎng)關(guān)自動(dòng)路由的網(wǎng)絡(luò)。網(wǎng)關(guān)執(zhí)行IPv6-to-IPv4地址和協(xié)議轉(zhuǎn)換的請(qǐng)求。它還執(zhí)行IPv4-to-IPv6來(lái)自服務(wù)器的響應(yīng)的轉(zhuǎn)換。參見(jiàn)圖4。
圖4 DNS64 / NAT64過(guò)渡解決方案的工作流程
IPv6和Appstore的審核要求
一個(gè)應(yīng)用程序提交上架到Appstore 兼容IPv6 DNS64 / NAT64網(wǎng)絡(luò)將是必需的,至關(guān)重要的是,應(yīng)用程序應(yīng)該保證兼容性。好消息是,大多數(shù)應(yīng)用程序已經(jīng)兼容IPv6。對(duì)于這些應(yīng)用,定期回歸測(cè)試你的應(yīng)用也是必要的。應(yīng)用程序不兼容ipv6 DNS64 / NAT64網(wǎng)絡(luò)上操作時(shí)可能會(huì)遇到問(wèn)題。幸運(yùn)的是,解決這些問(wèn)題通常是相當(dāng)簡(jiǎn)單的,在本章中討論。
6月1日以后所有iOS應(yīng)用必須支持IPv6-only網(wǎng)絡(luò)
支持IPv6的常見(jiàn)障礙
有些情況下會(huì)阻礙一個(gè)應(yīng)用程序支持IPv6。接下來(lái)的小節(jié)描述如何解決這些問(wèn)題。
嵌入在協(xié)議的IP地址。許多通信協(xié)議,如會(huì)話初始化協(xié)議(SIP),文件傳輸協(xié)議(FTP)的WebSockets,和點(diǎn)對(duì)點(diǎn)協(xié)議(P2PP),包括IP地址文字協(xié)議消息。例如,FTP命令參數(shù)數(shù)據(jù)端口DATA PORT和被動(dòng)PASSIVE的交換信息,包括IP地址文字。同樣,IP地址文字可能出現(xiàn)在SIP header字段的值,例如,To,From,Contact,Record-Route, andVia。看Use High-Level Networking Frameworks和Don’t Use IP Address Literals.
嵌入到配置文件的IP地址。配置文件經(jīng)常包含IP地址。Don’t Use IP Address Literals.。
網(wǎng)絡(luò)連通性預(yù)檢。許多應(yīng)用程序試圖通過(guò)使用IP地址和相應(yīng)API,主動(dòng)檢查網(wǎng)絡(luò)連接或一個(gè)活躍的WI-FI連接,。查看Connect Without Preflight.
使用低級(jí)網(wǎng)絡(luò)API。一些應(yīng)用程序直接與套接字和其他原始網(wǎng)絡(luò)api進(jìn)行交互,如gethostbyname,gethostbyname2, 與inet_aton。這些API很容易濫用或者他們只支持IPv4,例如:解析主機(jī)名AF_INET地址族, 而不是AF_UNSPEC地址族。查看Use High-Level Networking Frameworks.
使用小地址族的儲(chǔ)存容器。一些應(yīng)用程序和網(wǎng)絡(luò)庫(kù)使用地址存儲(chǔ)容器uint32_t,in_addr, 與sockaddr_in32位或者更小。查看Use Appropriately Sized Storage Containers.
確保IPv6的DNS64/NAT64兼容性
堅(jiān)持以下原則,以確保您的應(yīng)用程序的IPv6 DNS64/ NAT64的兼容性。
使用高級(jí)網(wǎng)絡(luò)框架
需要聯(lián)網(wǎng)的應(yīng)用程序可以在高級(jí)別聯(lián)網(wǎng)框架或低級(jí)別的POSIX socket API來(lái)構(gòu)建。在大多數(shù)情況下,高級(jí)別框架是足夠的。他們有能力,易于使用,并且不容易比低級(jí)別的API遇到常見(jiàn)的陷阱。
網(wǎng)絡(luò)框架和API層
WebKit。這個(gè)框架提供了一組類,用于顯示在窗口的網(wǎng)頁(yè)內(nèi)容,并實(shí)現(xiàn)了瀏覽器的功能,如以下鏈接,管理后臺(tái)轉(zhuǎn)發(fā)列表和管理的頁(yè)面的歷史記錄最近訪問(wèn)過(guò)的。 WebKit的簡(jiǎn)化加載網(wǎng)頁(yè),也就是說(shuō),異步請(qǐng)求從HTTP服務(wù)器的網(wǎng)頁(yè)內(nèi)容,其中反應(yīng)可能逐步到來(lái),以隨機(jī)順序,或部分由于網(wǎng)絡(luò)錯(cuò)誤的復(fù)雜過(guò)程。欲了解更多信息,請(qǐng)參閱WebKit Framework Reference.。
Cocoa URL loading system。這個(gè)系統(tǒng)是在沒(méi)有提供明確的IP地址發(fā)送和接收網(wǎng)絡(luò)上的數(shù)據(jù)的最簡(jiǎn)單的方法。數(shù)據(jù)的發(fā)送和使用幾類之一,如NSURLSession,NSURLRequest和NSURLConnection,與NSURL對(duì)象一起工作。 NSURL對(duì)象可以讓你的應(yīng)用程序處理URL和它們引用的資源。方法和傳遞一個(gè)URL說(shuō)明:通過(guò)調(diào)用initWithString創(chuàng)建NSURL對(duì)象。調(diào)用checkResourceIsReachableAndReturnError:在NSURL類的方法來(lái)檢查主機(jī)是否可達(dá)。欲了解更多信息,請(qǐng)參閱URL Session Programming Guide.
CFNetwork。這個(gè)核心服務(wù)框架提供抽象的網(wǎng)絡(luò)協(xié)議,這使得它易于進(jìn)行各種網(wǎng)絡(luò)任務(wù),如與BSD sockets工作,解析DNS主機(jī),并與HTTP / HTTPS工作。要定位沒(méi)有明確的IP地址的主機(jī),調(diào)用CFHostCreateWithName方法。要打開(kāi)對(duì)TCP sockets的主機(jī),調(diào)用CFStreamCreatePairWithSocketToCFHost方法。欲了解更多信息,請(qǐng)參見(jiàn)CFNetwork ConceptsinCFNetwork Programming Guide.
如果您確實(shí)需要低級(jí)別的Socket API的應(yīng)用,遵循RFC4038指南RFC4038: Application Aspects of IPv6 Transition.
不要使用IP地址
確保你不是通過(guò)IPv4地址 點(diǎn)符號(hào)的文字API ,如getaddrinfo和SCNetworkReachabilityCreateWithName等。相反,使用高級(jí)網(wǎng)絡(luò)框架和address-agnostic版本的api,比如getaddrinfogetnameinfo,通過(guò)主機(jī)名或完全限定域名(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會(huì)在本地自動(dòng)合成IPv6 從IPv4文本在本地DNS64/ NAT64網(wǎng)絡(luò)設(shè)備上。不過(guò),你還是應(yīng)該努力擺脫使用IP地址的代碼。
連接而無(wú)需預(yù)檢
可達(dá)性的API(見(jiàn)SCNetworkReachability Reference)明確連接問(wèn)題后,用于診斷目的。許多應(yīng)用程序不正確地使用這些API主動(dòng)檢查通過(guò)調(diào)用SCNetworkReachabilityCreateWithAddress方法,并傳遞給它的0.0.0.0IPv4地址,這表明網(wǎng)絡(luò)上有一個(gè)路由器。然而,路由器的存在并不能保證一個(gè)因特網(wǎng)連接是否存在。一般情況下,避免預(yù)檢網(wǎng)絡(luò)可達(dá)性。只嘗試做一個(gè)連接,并從容地處理失敗。如果你必須檢查網(wǎng)絡(luò)的可用性,避免調(diào)用SCNetwoSCNetworkReachabilityCreateWithAddress方法。調(diào)用SCNetworkReachabilityCreateWithName方法,并傳遞給它一個(gè)主機(jī)名代替。
有些應(yīng)用程序還通過(guò)SCNetworkReachabilityCreateWithAddress方法 一個(gè)IPv4169.254.0.0,自分配的鏈路本地地址的,以檢查活躍的Wi-Fi連接。要檢查Wi-Fi或蜂窩連接,查找網(wǎng)絡(luò)可達(dá)性標(biāo)志使用kSCNetworkReachabilityFlagsIsWWAN代替。
使用適當(dāng)大小的存儲(chǔ)容器
使用地址存儲(chǔ)容器,如sockaddr_storage,存儲(chǔ)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的等價(jià)方法去處理。
IPv4IPv6
AF_INETAF_INET6
PF_INETPF_INET6
struct in_addrstruct in_addr6
struct sockaddr_instruct sockaddr_in6
kDNSServiceProtocol_IPv4kDNSServiceProtocol_IPv
使用系統(tǒng)API來(lái)合成IPv6地址
使用getaddrinfo解決一個(gè)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方法然而,它不兼容老系統(tǒng)版本。查閱:getaddrinfo(3) Mac OS X Developer Tools Manual Page
定期測(cè)試IPv6 DNS64 / NAT64兼容性
最簡(jiǎn)單的方法來(lái)測(cè)試你的應(yīng)用是否兼容IPv6 DNS64 / NAT64
在mac上建立一個(gè)本地IPv6 DNS64 / NAT64網(wǎng)絡(luò)。你可以從你的其他設(shè)備連接到這個(gè)網(wǎng)絡(luò)用于測(cè)試目的。參見(jiàn)圖
重要提示:IPv6的DNS64/NAT64網(wǎng)絡(luò)設(shè)置選項(xiàng)在OS X10.11及更高版本可用。此外,基于Mac的IPv6 DNS64/NAT64網(wǎng)絡(luò)是與已經(jīng)執(zhí)行了RFC6106支持客戶端設(shè)備兼容:對(duì)于DNS配置IPv6路由器廣告選項(xiàng)。如果您的測(cè)試設(shè)備不是iOS或OS X設(shè)備,請(qǐng)確保它支持RFC。需要注意的是,不同于服務(wù)提供商部署DNS64/ NAT64工作流程,一臺(tái)Mac,基于IPv6 DNS64/ NAT64總是產(chǎn)生合成的IPv6地址。因此,它不能提供本地網(wǎng)絡(luò)的外部訪問(wèn)
使用你的MAC建立本地的IPv6 Wi-Fi 網(wǎng)絡(luò)
確認(rèn)你的MAC連接到了互聯(lián)網(wǎng),并且不是通過(guò)Wi-Fi.
從Dock中運(yùn)行系統(tǒng)首選項(xiàng)
按住Option按鍵并且同時(shí)點(diǎn)擊共享 ,不要松開(kāi)Option按鍵
打開(kāi)設(shè)置 共享選項(xiàng)
從共享服務(wù)中選擇互聯(lián)網(wǎng)分享選項(xiàng)
配置互聯(lián)網(wǎng)共享
釋放Option按鍵
選中 創(chuàng)建NAT64網(wǎng)絡(luò)復(fù)選框
打開(kāi)本地的IPv6 NAT64 網(wǎng)絡(luò)
選擇一個(gè)提供互聯(lián)網(wǎng)鏈接的網(wǎng)絡(luò)接口, 例如雷電網(wǎng)卡
選擇一個(gè)網(wǎng)絡(luò)接口共享
選擇Wi-Fi 復(fù)選框.
打開(kāi)通過(guò) Wi-Fi共享
點(diǎn)擊 Wi-Fi 選項(xiàng), 配置網(wǎng)絡(luò)名稱與密碼等信息
訪問(wèn)WI-FI設(shè)置選項(xiàng)
設(shè)置本地WI-FI
選擇互聯(lián)網(wǎng)共享復(fù)選框,開(kāi)啟你的本地網(wǎng)絡(luò)
開(kāi)啟互聯(lián)網(wǎng)共享
當(dāng)提示確認(rèn)開(kāi)始分享的時(shí)候,點(diǎn)擊開(kāi)始
開(kāi)始分享
一旦共享處于活動(dòng)狀態(tài),你應(yīng)該看到一個(gè)綠色的狀態(tài)指示燈,Internet共享標(biāo)簽:開(kāi)。在無(wú)線網(wǎng)絡(luò)菜單中,您還將看到一個(gè)小的,淡淡的箭頭朝上,表明互聯(lián)網(wǎng)共享已啟用。你現(xiàn)在有一個(gè)IPv6NAT64網(wǎng)絡(luò),并可以從其他設(shè)備,以測(cè)試你的應(yīng)用程序連接到它。
互聯(lián)網(wǎng)共享標(biāo)識(shí)