※HTML5 Advent Calendar 2015への投稿ですが全然htmlネタじゃないです
※まだ調査中の部分があるので、後で追記します
#目的
iOSアプリのIPv6対応
iOSネイティブWebRTCアプリでAppRTCDemoを使ってる場合にSTUNだとP2Pのコネクションが通らないので調査
#前提:iOSアプリにおけるIPv6対応について
参考:下記
http://qiita.com/shao1555/items/4433803419dfc72bf80b
2016年初頭にアプリをIPv6に対応しないとApple審査に通らなくなるとのこと
#調査内容
上記の記事にあるように、El CapitanのMacでIPv6 only Networkを構築
システム環境設定→共有をoptionクリック→create nat64 networkにチェックを入れてインターネット共有スタート
立ち上げたEl CapitanをwifiポイントにしてiOS9端末でアクセス
→テストしたいアプリ起動して動作に問題がなければ審査通る
#調査内容 For WebRTC
自分の作ってるアプリでは現状STUNのみでP2P通信を実現してる(サーバーリソース使いたくない)
iOSのWebViewだとWebRTC対応してないので、AppRTCDemoを組み込んだ自分のサンプルをiOS端末で動かす
→P2P通信が失敗する!
※最新のライブラリバージョンじゃなかったので後日最新バージョンでも試してみます
iOSのAppRTCDemoは下記とか使ってやってます
https://github.com/pristineio/webrtc-build-scripts
#Apple審査におけるNAT64/DNS64の環境について
なぜIPv6 Only NetworkでP2Pが繋がらないのか、結局まだ原因は分かっていないのですが(できたら後日追記します)そもそもIPv6対応ってなんなのか?というところを調べていたので内容を書いていきます
##IPv6 Only Networkとは
Apple公式
DNS64/NAT64に対応したネットワーク環境のことです。
DNS64/NAT64は上記公式ページの図Figure 10-3にあるように、IPv6のDNSリクエストクエリ(example.apple.com)を発行した際、下記のような動作をするようです
→example.apple.comのIPv6アドレス(AAAAレコード)が存在するかチェック
→存在すればIPv6アドレス(AAAAレコード)を返す
→存在しなければexample.apple.comのIPv4アドレス(Aレコード)が存在するかチェック
→存在すればIPv4アドレス(Aレコード)をIPv6アドレス(AAAAレコード)に変換したものを返す
##IPv6 Only Networkの挙動
例えばIPv4アドレス直打ちでAFNetwork越しにHTTPリクエスト叩いたら普通にレスポンス返ってきた。
IPv6アドレスしか使えないのかと思ったけど、NAT64/DNS64はドメインのDNSクエリを変換するだけなので、そこは通らなくなるわけではないようです
やはり問題になるのはinet_aton, gethostbyname等のIPv4だけでしか動かないAPIを使っている場合のみのよう
※↑、別記事でまとめました→IPv6 only Network上での通信周り挙動について
##WebRTCxSTUNxIPv6 only networkで動かない原因
結論:ビルドしたライブラリ内部のSTUNクライアントあたりがうまくいってない
シグナリングはつつがなく行われてるように見えるんだけど、IPv6 only networkにつないでる端末からだけSTUNサーバー(rfc5766-turn-server)にログが流れてこなかった。
IPv6 only networkだとSTUNが通らない?っていうのを確かめる為、
下記のクライアント入れてSTUNが効かないのか試してみた
https://github.com/soulfly/STUN-iOS
IPv4のままだけど、STUN Port: xx.xx.xx.xxって返ってきた
→STUNのポート取得はIPv6 only networkでも問題ない
→STUNサーバーへのリクエスト部分で、使っちゃいけない関数使われてる?
ていうのが調査結果でした。
該当のコード箇所はAppRTCDemoでも使われてるライブラリのメソッド呼んでるだけで、
RTCICEServer *ICEServer = [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:urlString]
username:@"hoge"
password:@"huga"];
RTCPeerConnection *peerConnection = [self.peerConnectionFactory peerConnectionWithICEServers:servers
constraints:mediaConstraints
delegate:self];
こんな感じでpeerConnection作ってcreateOfferとかすると通常はSTUNサーバーにアクセスが来る。ここから先は今の自分にはちょっと解析しきれないので…調査はここでストップしてます。
以上