iOS 支持 IPv6

 

蘋果的規定:2016年6月1日提交到App Store必須支持IPv6-only網絡。html

 官方文檔:https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1api

 

大多數應用APP 不須要任何改變,由於IPv6的已經被NSURLSession、CFNetwork、NSURLConnection 支持。安全

 

1、是否須要修改代碼服務器

一、若是線上環境的APP 只使用域名訪問,沒有使用IP地址,而且沒有使用底層socket API ,就不用修改代碼。微信

直接訪問IP地址 主要是用在測試環境中。網絡

大多數app使用的:NSURLSession、NSURLConnection、UIWebView、WKWebView、CFNetwork。因此能夠不用修改網絡代碼,AFNetworking2.x、reachability 這些 都 不用作任何的改變。 app

不過仍是 推薦 你們升級AFNetworking到最新版本,畢竟NSURLConnection早晚要被淘汰。異步

用Swift寫的 就直接用 Alamofire吧。socket

 

二、Reachability不用IP地址,能夠固定寫死爲 線上域名。也能夠用 AFNetworking 的Reachability來判斷網絡鏈接狀態(是異步的,不用輸入域名或IP)。測試

Reachability 最新版本 官方 聲明iOS8以上系統可使用,經測試,iOS 7.0以上系統均可以使用。

 

三、iOS 9.0、OS X 10.11 以上的系統 在IPv6的環境下 是支持IP地址訪問網絡的。因此你們測試機若是是 iOS9.0以上的系統,能夠直接經過IP訪問。這是由於iOS 9.0以後 NSURLSession和CFNetwork能把IPv4的地址 合成IPv6的地址(在DNS64/NAT64網絡環境中)。

iOS 9.0如下的系統 就會報錯,這和是否升級 AFNetworking 沒有關係。就算升級AFNetworking到3.x,也是同樣會報:Error Domain=NSURLErrorDomain Code=-1001 等錯誤。

 

 官方圖片:

 

 

 

四、分享SDK

微信SDK、新浪微博SDK 都更新了版本,並聲明支持IPv6。

可是由於微信自己不支持IPv6,因此即便更新SDK到最新版本,分享到微信時,在微信的APP 仍是會一直顯示網絡沒法鏈接。

測試發現,不更新 這些分享的SDK,也能兼容IPv6。(等微信支持IPv6後,是否必須更新SDK 還不清楚)

友盟分享 官網建議升級SDK,我的也是推薦升級,若是實在不想升,應該也沒問題。

來個小插曲:

上星期友盟新發的5.2版本 的SDK 有 郵件、短信分享崩潰的bug,給他們提出了。他們昨天下午進行了升級。

 

 

 

2、現有APP支持IPv6的狀況

一、絕大多數 都是支持IPv6的,好比:QQ,淘寶、大衆點評。

1.一、由於絕大多數的app 都使用的域名,而不是ip地址。

1.二、而且沒有調用底層的socket api。

1.三、不須要進行DNS查找。


二、極少數app不支持IPv6,好比:微信。

 

 

3、DNS64/ NAT64

 DNS64/ NAT64過渡工做流程:

一、提供獨立的IPv4和IPv6鏈接 的 蜂窩網絡,把IPv4的網絡升級到IPv6

 

上圖只是理想狀態下,升級到IPv6的狀況,可是如今絕大多數都是IPv4的服務器,因此一些大的供應商開始實施DNS64/NAT64 的過分 來支持IPv6.

 

二、部署DNS64/NAT64 IPv6的蜂窩網絡

 

客戶端請求 網站域名,首先會經過DNS64服務器 查詢該域名是否存在 IPv6的地址,若是存在,就返回IPv6的地址。若是不存在,就去查找該域名對應的IPv4地址,並返回。

下面是詳細流程圖:

 

三、DNS64/NAT64 轉換 流程:

DNS64/NAT64 能夠 將IPv4地址 轉換爲IPv6,將IPv6地址解析成IPv4。

IPv4地址 轉換爲IPv6:
客戶端訪問網站域名 ,若是網站只有 IPv4 地址:56.111.211.22,轉成16進制: 38 6F D3 16,該16進製爲IPv6的最後2位:   64:ff9b::386F:D316

 

 

 

4、搭建 IPv6 環境

MAC 的系統爲 OS 10.11 及以上系統。

一、進入MAC 電腦的 「系統偏好設置」--》按住option/alt 鍵--》 點擊 「共享」

 

二、選中「建立NAT64網絡」,而後打開熱點。

三、手機 鏈接 熱點後,查看網絡的 DNS 爲:XX:XX:XX:XX:XX:XX ,說明網絡爲IPv6。

 

下圖爲MAC搭建IPv6 的原理圖:

 

 目前,一個網卡會同時使用這兩張地址;之後 一個網卡僅有IPv6 地址。 兩種設備不能直接訪問,須要DNS64/NAT64 這種 過渡技術才能 互相訪問。

 

5、升級AFNetworking2.X到最新版本

一、將  AFHTTPRequestOperationManager 替換爲:  AFHTTPSessionManager

二、將  AFHTTPRequestOperation  替換爲:NSURLSessionTask

三、若是經過IP訪問,或者容許https證書以外的域名訪問,須要設置 validatesDomainName 爲false。

這個設置是源於 2.5.3版本 以前的安全漏洞(AFNetworking曝SSL漏洞)。

修改完成後可使用了,可是很不安全,這樣黑客能夠獲取 你https 通訊的數據。不管你是用http仍是https,數據必定要加密。。

AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];

manager.securityPolicy = [AFSecurityPolicy defaultPolicy];

manager.securityPolicy.allowInvalidCertificates = YES;  //忽略https證書

manager.securityPolicy.validatesDomainName = NO;    //是否驗證域名

 

 

6、系統兼容IPv6代碼

一、下面的方法 只適用於IPv4,不能兼容IPv6:

  • 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_IPv6


三、使用系統API合成IPv6:

若是你的APP須要鏈接的服務器 只有IPv4地址,沒有域名,能夠用 getaddrinfo 來解決。下面的代碼,將IPv4地址(如:192.0.2.1) 地址轉換爲IPv6地址(如:包含  64:ff9b::192.0.2.1  的struct sockaddr_in6 )

 

#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);

 

歡迎關注個人 今日頭條號 名稱: 雲端夢想科技  

歡迎關注個人 微信公衆號:dreams2999

相關文章
相關標籤/搜索