Pia の NAT トラバーサルの参考情報について説明します。
ルータの NAT のポートマッピングやフィルタリングの仕様によって NAT タイプが決まります。
uint8_t mappingType = nn::pia::inet::NexFacade::GetInstance()->GetNatPropertyMapping();
uint8_t filteringType = nn::pia::inet::NexFacade::GetInstance()->GetNatPropertyFiltering(); uint32_t portIncrement = nn::pia::inet::NexFacade::GetInstance()->GetNatPropertyPortIncrement(); |
mapping | |
---|---|
1 | EIM (Endpoint Independent Mapping) |
2 | EDM (Endpoint Dependent Mapping, Symmetric) |
filtering | |
---|---|
1 | PIF (Port Independent Filtering) |
2 | PDF (Port Dependent Filtering) |
NAT タイプのマッピングが EDM (Endpoint Dependent Mapping)のルータを「EDM ルータ」と表記します。EDM ルータが1台以上使用されている回線を「EDM 回線」と表記します。EDM 回線は全世界で約 8 %前後(任天堂での調査)存在しています。
ポートインクリメントとは、EDM ルータが端末ごとに割り当てる WAN 側ポート番号の増加量(差分)になります。ポートインクリメントが1の場合1ずつ増加し、-1の場合1ずつ減少することを示します。
NAT タイプは本体メニューの接続テストを行った際に表示されるサポートコードで確認することもできます。サポートコードは 5 桁の数字で表されるコードで、上位 3 桁は NAT タイプを示し、下位 2 桁は NAT タイプ判定処理の結果コードを示します。各桁の数値の意味については NEX プログラミングマニュアルの「NAT タイプ確認方法」の項を参照してください。
NAT トラバーサルに失敗した場合、 session::Session::JoinSessionAsync() の非同期処理結果として session::Session::GetJoinSessionResult() から取得できる値が次のいずれかのエラーを返します。
エラー定数 | エラーコード | 内容 |
---|---|---|
ResultStationConnectionNatTraversalFailedUnknown | 0510 | マッピング種別が不明の回線で NAT トラバーサルに失敗した場合のエラー |
ResultNatTraversalFailedBothEim | 0513 | EIM 同士で NAT トラバーサルに失敗した場合のエラー |
ResultNatTraversalFailedBothEdm | 0514 | EDM 同士で NAT トラバーサルに失敗した場合のエラー |
ResultNatTraversalFailedLocalEimRemoteEdm | 0515 | 自分は EIM で、相手が EDM で NAT トラバーサルに失敗した場合のエラー |
ResultNatTraversalFailedLocalEdmRemoteEim | 0516 | 自分は EDM で、相手が EIM で NAT トラバーサルに失敗した場合のエラー |
ResultNatTraversalRequestTimeout | 0521 | NAT トラバーサル相手に送ったリクエストに対して一定期間に相手から返答がなく、タイムアウトした場合のエラー |
Pia の NAT トラバーサルの制限について、ネットワーク構成ごとに説明します。
Pia では、ポート予測時のポートインクリメントを常に1として扱うことでポートインクリメントの誤判定の影響を回避し、EDM 回線の NAT トラバーサル成功確率を改善しています。そのため、ポートインクリメントが1以外の EDM 回線の端末と他の回線の端末では NAT トラバーサルに失敗します。ポートインクリメントが1以外の EDM ルータの割合はごく稀かとなっています。
同一回線(同一のグローバルIPを使用している回線)の中の、並列接続したルータ同士はお互いに NAT トラバーサル処理のパケットが届かないため、NAT トラバーサルに失敗します。
例:
次の NAT21 と NAT22 は NAT トラバーサルに失敗します。
Internet - NAT1 - NAT21
| - NAT22
Pia では、直列接続したルータ同士の NAT トラバーサルはサポートしています。
例:
次の NAT1 と NAT2、NAT2 と NAT3、NAT1 と NAT3 の間の NAT トラバーサルは通常成功します。
Internet - NAT1 - NAT2 - NAT3
同じ EDM ルータの LAN 内の複数の端末が、他の回線のセッションホストに同時に参加する場合、ポート予測に失敗し、NAT トラバーサルに失敗することがあります。数秒程度以上タイミングをずらして参加すればポート予測失敗確率は低減されます。
逆に、同じ EDM ルータの LAN 内の複数の端末が存在するセッションに後から参加する場合、Pia では通常成功します。
例:
次の Station2 と Station3 が同時に参加した場合、NAT トラバーサルに失敗することがあります。
Internet - NAT - Station1 (セッションホスト)
Internet - EDM - Station2
|- Station3
TTL 値 4 のパケットが届く相手のルータの SPI 機能が有効になっている場合、NAT テーブル更新用のパケットが届くことで SPI 機能が働いてしまうため、NAT トラバーサルに失敗することがあります。
SPI 機能が有効設定になっているルータから 4 段以上直列に接続したルータの端末は、NAT テーブル更新用の TTL 値 4 のパケットが SPI 機能が有効になっているルータの WAN 側に届かないため、 NAT トラバーサルに失敗することがあります。
プライベートセパレータ機能が有効設定になっているルータに接続した端末間では直接通信が遮断されてしまうため、NAT トラバーサルに失敗します。
開発に使用している回線が EDM の場合、次の点を参考にしてください。
開発に使用しているルータが EDM であることがわかった場合、そのルータを EIM のルータに置き換えることで EDM を避けることができます。しかし、インターネット接続業者の CTU(終端装置) で EDM のものが存在しており、その場合は 置き換えることができないため、EDM を避けることはできません。
EDM 回線であっても、同じルータ内でのみ P2P 接続を行う場合は、NAT トラバーサルは行われないため、NAT トラバーサルに失敗することはなくなります。
EDM 回線と他の回線の間で P2P 接続を行う場合は、通信状況によっては NAT トラバーサル失敗によるエラーが起きます。次の点に注意することで失敗確率を減らすことができます。
TypeA、TypeB、TypeC の組み合わせについては Pia リリース時に検証されています。
TypeD、TypeF については Pia の NAT トラバーサル機能ではサポートしておらず、NAT トラバーサルに失敗しますが、動作停止などの致命的問題が起きないことが保証されています。
アプリケーションの開発時には普及率の高い TypeA または TypeB の回線でデバッグを行うことを推奨します。
ただし、これらの回線を使用している場合、NAT トラバーサルに失敗する確率は低いため、アプリケーションで適切にエラーハンドリングできているか確認することが困難となります。このような用途のために、Pia では NAT トラバーサル処理を意図的に失敗させるデバッグ機能を用意しています。
詳細は 4.3. デバッグ支援 - NAT トラバーサル失敗エミュレーション を参照ください。