UDP hole punching*1
pythonで書いてみた。
普通のFW越しのクライアント(C)・サーバ(S)通信では、C-->|FW|-->Sというように、クライアントからサーバへ通信するところから始まる。その際、FWはCとSの該当ポート間での通信を通すよう設定される。
ここまでは当たり前。TCPとは違いUDPではコネクションを持たないため、UDPでC-->|FW|-->Sと繋いだ場合、FWはCの該当ポートへの全ての通信を通すよう設定される。つまり、C-->|FW|-->Sというように、クライアントがサーバへ通信している間ならば、C<--|FW|<--Xというように、S以外の外部ノードからの通信を受け付けることができる。
これをUDP hole punchingと呼ぶ。*1
サンプルコードは以下に。
import select import random import time import sys import re _src_host = sys.argv[1] _src_port = int(sys.argv[2]) _dest_host = sys.argv[3] _dest_port = int(sys.argv[4]) _socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) _socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) _socket.bind((_src_host, _src_port)) _socket.sendto('HELLO!', (_dest_host, _dest_port)) while True: try: _sockins, _sockouts, _sockerrs = select.select([_socket], [], [], 0) if _sockins: for _sockin in _sockins: _message, _address = _sockin.recvfrom(1024) print _message, _address pass pass else: time.sleep(1) pass pass except (KeyboardInterrupt, SystemExit): break except: pass pass
*1:ここでは片道しか説明していないが、普通はFW内のXに対しても同じことをする。元々XがFW外なら直接繋げば良いし。