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外なら直接繋げば良いし。