你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> NAT64網絡下合成IPv6地址

NAT64網絡下合成IPv6地址

編輯:IOS開發基礎

最近公司的App不能提交到App Store了。因為,我們的app無法支持NAT64網絡環境。蘋果還算是比較人性化,給出了解決方案 Supporting IPv6 DNS64/NAT64 Networks。這篇文章說得很詳細,大致意思就是盡量使用域名而不是ip地址訪問服務器,主要調用了 getaddrinfo 這個方法。他會根據你給的選項及當前所處的網絡環境,返回一個ip地址列表。當然如果是NAT64網絡,也會包含ipv6地址(如果域名綁定了ipv6地址,則返回服務器的ipv6地址;如果服務器只有ipv4地址,則它會自動幫你合成一個ipv6地址)。這樣會省去你很多麻煩。

我們的app直接使用low-level BSD socket api通過tcp協議直接與後台服務器通信。服務器只有ipv4地址,並且沒有綁定域名。剛開始我們嘗試使用蘋果給出的示例代碼解決該問題:

50.png

51.png

看起來很簡單: 將我們想要合成的ipv4地址、端口及選項傳給getaddrinfo就可以得到一個地址鏈表;然後,我們測試地址的連通性,在其中找到一個可用的。

但是,經過測試發現,getaddrinfo針對域名可以工作,但是對於ipv4地址卻不能合成ipv6地址。這非常奇怪,我查閱了兩份關於IPv6的RFC文檔: RFC4038: Application Aspects of IPv6 Transition和rfc7050: Discovery of the IPv6 Prefix Used for IPv6 Address Synthesis;也在蘋果官方論壇上咨詢了,他們給的答復是可以正常工作,並且建議使用域名。。。但是我這邊確實是不可以的啊,相同的代碼,而且後台服務器也沒域名。在申請到新域名之前,作為過渡方案,沒辦法,只能另辟蹊徑了。

前面提到 getaddrinfo 對於域名可以正確地工作。我們為什麼不利用這一點呢?

原理

首先先針對一個比較知名的域名調用getaddrinfo得到ip地址列表,然後針對地址列表進行進一步處理,用我們的ip地址替換ip地址列表中的地址。在rfc7050: Discovery of the IPv6 Prefix Used for IPv6 Address Synthesis這篇文章中,提到了一個非常特殊的域名 ipv4only.arpa., 該域名只綁定了兩個ipv4地址。這非常好,因為我們無需擔心挑選的域名綁定了ipv6地址,給我們處理地址列時帶來不便,增加了問題的復雜度。所以,我們的思路是:

1.首先調用getaddrinfo對 ipv4only.arpa. 進行解析,得到地址列表;

2.對地址列表進一步進行處理:

  • ipv4地址,直接進行處理;

  • ipv6地址,將高4個字節替換成我們的ip地址。

刪除其中的重復項。

實現

函數參數與getaddrinfo一致。但是,hostname是ipv4地址字符串,servname是端口數字字符串。函數聲明如下:

52.png

1.獲取地址列表

53.png

需要注意的是,這裡servname傳遞的是"http"。事實證明,傳遞一個任意的端口數字字符串也是可以的,並不影響地址的解析。

2.地址替換
地址替換需要注意的是,不同的地址會有不同的替換方法:ipv4直接替換;ipv6只替換地址的高4個字節。代碼如下:

56.png

3.消除重復項
因為 ipv4only.arpa. 綁定了兩個ipv4地址,所以經過第二步的替換後,出現了重復項。所以,我們需要稍微處理下。本質上就是對一個鏈表做刪除重復項操作。

57.png

原理其實很簡單。全部代碼見 GitHub。

討論

雖然,我們解決了該問題,但是這只是一個過渡方案。還是應該像蘋果建議的那樣,申請一個域名,這會降低問題的復雜度。另外,服務器最好分配一個IPv6地址,畢竟IPv6是大勢所趨。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved