UDP Hole Punching の実験

以前から気になっていた、NAT ごしに UDP 通信を行う, UDP Hole Punching の実験を NetCat(ports: net/netcat) を使って行ってみました。
 
1. (A)ホスト側端末(Firewall なし), WAN IP アドレス: 10.0.1.2

nc -lup 1234 -v # UDP の 1234 番で LISTEN

 
2. (B)クライアント側端末(ルータあり), 端末の IP アドレス: 192.168.1.100, ルータの WAN IP アドレス: 10.0.5.6

nc -u -p 5678 10.0.1.2 1234 # 10.0.1.2 の UDP 1234 に接続

 
3. (B) で Hello を入力
 
4. (A) に以下のようなログが出る

connect to [10.0.1.2] from ********* [10.0.5.6] 50000
Hello

(この例では 10.0.5.6 の UDP50000ポートからの送信があった。クライアント側 NAT で送信元ポートが書きかわっている事に注意)
 
5. (A), (B) 両方で netcat を一度終了させる
 
6. (B) で, 先程送信元にしたポートに対して UDP 受信を開始する(src port, dst port の入れ換え)

nc -lup 5678 -v

 
7. (A) で, 先程 LISTEN していたポートから、(4) で送信元になっていた IP アドレス、ポートに対して接続を開始する

nc -u -p 1234 10.0.5.6 50000

 
8. (A) から Hello over NAT を送信
 
9. (B) で以下のようなログが表示される

connect to [192.168.1.100] from ********* [10.0.1.2] 1234
Hello over NAT

 
両方が NAT 内にいる場合、双方について source port が書きかわるため、(A),(B) が通信することが不可能になります。
この場合、双方の source port を記録するための非 NAT 内ホスト端末 (C) が必要です。
ただし、双方が Symmetric NAT 内にいる場合は、宛先のポート番号に対して送信元の IP アドレス、ポート番号が固定されるためこの方法を用いることができません。
 
参考:
P2Pとファイアウォール
ごろ猫ブログ
みかログ
IT media エンタープライズ:PART2 Skype, その通信の仕組み