38
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nintendo Switch の「NATタイプ」判定条件

Last updated at Posted at 2020-04-26

Nintendo Switch には、「接続テスト」の結果表示に「NAT タイプ」という欄があり、このタイプ判定をみることで、インターネット経由でのマルチプレイに支障がない環境かどうかを確認することができます。任天堂の公式 FAQ によれば、タイプ A・B は比較的良好、タイプ C・D は「最適ではない」、タイプ F は通信対戦不可、となっており、それぞれ NAT トラバーサル(NAT 越え)のしやすさに対応していると考えられます。

しかし、このタイプの判定基準は公開されておらず、ルーターの設定項目を手探りで変えてゆくしかない状況になっています。そこで本記事では、ネットワーク(ファイアウォール)の状態がどの NAT タイプに対応しているかを調査しました。また、任意の NAT タイプを再現する方法も掲載しています。

結論(判定基準)

通信のしやすさは、 A > B > C > D となっていました。文字通りですね。

  • UDP パケットの送受信ができなければ、タイプ F。
  • Endpoint-Independent Mapping が満たされているとき、
  • 満たされていないとき(Address-Dependent Mapping または Address and Port-Dependent Mapping のとき)、
    • 外部ポート番号の割り当てが予測可能ならば、タイプ C。
    • そうでないならば、タイプ D。

マッピングとフィルタリングの定義は RFC4787日本語訳) か、文中にリンクした @iwashi86 さんのスライドを参照してください。なお、 RFC3489 による古い分類でいうと、タイプ A が "Full Cone" または "Restricted Cone" で、タイプ B が "Port Restricted Cone"、タイプ C・D が "Symmetric" に相当します。

これだけだと分かりにくいと思うので、Nintendo Switch 実機が接続テストの際に行う動作を示します。

また、 https://github.com/yokoyama10/nintendo-switch-nat-type に、それぞれの NAT タイプを再現することができるスクリプトを掲載しました。このスクリプトは、Nintendo Switch からの UDP パケットを一度受信し、任天堂のサーバーにプロキシしています。いろいろ遊んでみましょう。

Nintendo Switch での判定の流れ

  1. ホスト A の Port 33334 に UDP パケットを送信する。送るのみで、パケットは帰ってこない。
  2. ホスト A の Port 10025 に UDP パケットを送信する。このとき、変換後の外部ポート番号を a1 とする。返信パケットが送られてくる。
  3. ホスト B の Port 10025 に UDP パケットを送信する。このとき、変換後の外部ポート番号を b1 とする。返信パケットが送られてくる。
  4. ホスト A の Port 50920 からポート a1 宛に、UDP パケットが送られてくる。

この一連の動作を2度繰り返し、2度目の外部ポート番号を、それぞれ a2, b2 とします(通信ができない F 判定の場合はさらにリトライ)。なお、1. での Port 33334 への通信は、拒否やフィルタしても判定に影響を及ぼさないようです。

ホスト名 IPアドレス
ホスト A nncs1-lp1.n.n.srv.nintendo.net 52.199.66.160
13.112.35.82
ホスト B nncs2-lp1.n.n.srv.nintendo.net 54.64.157.221
52.193.120.207

タイプ A・B の場合

a1 == b1 が成り立っています。
さらに、 4. での Port 50920 からのパケットが受信できた場合はタイプ A となり、受信できなかった場合はタイプ B。

通信相手によらず外部ポート番号が同じタイプ A・B では、任天堂のサーバーがまず外部ポート番号を観測し、それを相手に通知することで、相互通信を確立できます。

タイプ C・D の場合

a1 != b1 が成り立っています。
さらに、 (a2 - a1) == (b2 - b1) のとき(ポート番号の差が予測可能なとき)タイプ C となり、そうでないときはタイプ D。(この基準は、タイプ A・B の判定には影響を与えません)

タイプ C のようにポート番号が予測可能なとき、通信相手の使用ポートを当てずっぽうで決めて通信を開始することで、相互通信を確立できる可能性があります。(とはいえ、ここで確認されているような同一ホスト間での予測可能性だけでは、あまり意味がない気がしますが...)

iptables での設定方法

iptables による Linux ルーターで、各 NAT タイプを再現する設定方法を示します。基本的な設定方法は別文献を参照してください。

タイプ A

  • UDP ポート (1024--65535) を Nintendo Switch に転送するように設定します。
EXTIF=ppp0  # インターネットに繋がっている NIC の名前
NINTENDO_IPADDR=192.168.0.177  # Nintendo Switch のローカル IP アドレス
iptables -t nat -I PREROUTING -i ${EXTIF} -p udp --dport 1024:65535 -j DNAT --to-destination ${NINTENDO_IPADDR}
iptables -t filter -I FORWARD -i ${EXTIF} -p udp --dport 1024:65535 -j ACCEPT

タイプ B

iptables で普通に設定した IP マスカレーディングは、タイプBになります。
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
スプラトゥーン2のナワバリバトルは快適にプレイ可能です。

タイプ C

iptables での再現手段が思いつかないです...
前掲の Ruby スクリプトでは再現に対応しています。

タイプ D

送信元ポートのマッピングをランダム化する。
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE --random
スプラトゥーン2のナワバリバトルはプレイ困難です。

参考文献

調査環境

  • Nintendo Switch 10.0.1 (2020-04-22 released)
  • Fedora 31 (5.3.7-301.fc31.x86_64)

本記事の条件は実機の挙動から推測したものであり、まだ明らかではない条件があるかもしれません。

38
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?