IPv6客戶端訪問IPv4服務器原理
首先,這個是無法直接訪問的,必須網絡的提供商支持過渡技術。
第一步:DNS 污染
例如我們想要訪問 example.com ,假設這個網站只有 IPv4 地址(93.184.216.34,用16進制表示為 5d b8 d8 22) 那么,被“污染”的DNS返回的 IP 地址是 64:ff9b::5db8:d822。 其中 `64:ff9b::/96`是IANA分配用于DNS64的前綴。
第二步:IPv6 轉 IPv4
訪問 64:ff9b::5db8:d822 時,IPv6 包頭被替換為 IPv4 包頭,繼續訪問。 同時回來的數據包會被做反向處理。
微信的DNS查詢,使用的 HTTP 協議自己封裝的,這樣在 IPv4 網絡下可以避免相當多的問題。 如圖,微信直接查詢 A 記錄,即使我的設備在 IPv6-ONLY 的網絡環境下。 因此,微信就跪掉
應用如何支持IPV6-Only?
對于如何支持IPV6-Only,官方給出了如下幾點標準:(這里就不對其進行解釋了,大家看上面的參考鏈接即可)
1. Use High-Level Networking Frameworks;
2. Don’t Use IP Address Literals;
3. Check Source Code for IPv6 DNS64/NAT64 Incompatibilities;
4. Use System APIs to Synthesize IPv6 Addresses;
NSURLConnection是否支持IPV6?
官方的這句話讓我們疑惑頓生:
*** using high-level networking APIs such as NSURLSession and the CFNetwork frameworks and you connect by name, you should not need to change anything for your app to work with IPv6 addresses***
只說了NSURLSession和CFNetwork的API不需要改變,但是并沒有提及到NSURLConnection。 從上文的參考資料中,我們看到NSURLSession、NSURLConnection同屬于Cocoa的url loading system,可以猜測出NSURLConnection在ios9上是支持IPV6的。
應用里面的API網絡請求,大家一般都會選擇AFNetworking進行請求發送,由于歷史原因,應用的代碼基本上都深度引用了AFHTTPRequestOperation類,所以目前API網絡請求均需要通過NSURLConnection發送出去,所以必須確認NSURLConnection是否支持IPV6. 經過測試,NSURLConnection在最新的iOS9系統上是支持IPV6的。
Cocoa的URL Loading System從iOS哪個版本開始支持IPV6?
目前我們的應用最低版本還需要支持iOS7,雖然蘋果只要求最新版本支持IPV6-Only,但是出于對用戶負責的態度,我們仍然需要搞清楚在低版本上URL Loading System的API是否支持IPV6.
(to fix me, make some experiments)待續~~~
Reachability是否需要修改支持IPV6?
我們可以查到應用中大量使用了Reachability進行網絡狀態判斷,但是在里面卻使用了IPV4的專用API。
在Pods:Reachability中
AF_INET Files:Reachability.m
struct sockaddr_in Files:Reachability.h , Reachability.m
那Reachability應該如何支持IPV6呢?
(1)目前Github的開源庫Reachability的最新版本是3.2,蘋果也出了一個Support IPV6 的Reachability的官方樣例,我們比較了一下源碼,跟Github上的Reachability沒有什么差異。
(2)我們通常都是通過一個0.0.0.0 (ZeroAddress)去開啟網絡狀態監控,經過我們測試,在iOS9以上的系統上IPV4和IPV6網絡環境均能夠正常使用;但是在iOS8上IPV4和IPV6相互切換的時候無法監控到網絡狀態的變化,可能是因為蘋果在iOS8上還并沒有對IPV6進行相關支持相關。(但是這仍然滿足蘋果要求在最新系統版本上支持IPV6的網絡)。
(3)當大家都在要求Reachability添加對于IPV6的支持,其實蘋果在iOS9以上對Zero Address進行了特別處理,官方發言是這樣的:
reachabilityForInternetConnection: This monitors the address 0.0.0.0,
which reachability treats as a special token that causes it to actually
monitor the general routing status of the device, both IPv4 and IPv6.
+ (instancetype)reachabilityForInternetConnection {
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
return [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress];
}
綜上所述,Reachability不需要做任何修改,在iOS9上就可以支持IPV6和IPV4,但是在iOS9以下會存在bug,但是蘋果審核并不關心。
評論
查看更多