2015/11/06(金)UPnP/SSDPマルチキャスト中継プログラム(DLNA用)
UPnPのマルチキャストパケットを中継するためのプログラムです。通常、同一ネットワーク内でしか使用できないUPnPを、ルーターを超えて使用できるようになります。
想定
- DLNAサーバとクライアント(またはコントローラーとレンダー)がルーターを超えて存在する。
- それぞれネットワークAとBとすれば、A内のPCとB内のPCは互いに通信可能である(NATされていない)。
- どちらのネットワークにも属するPCが存在する。
「WiFiと有線LAN環境を同一ネットワークにしたくない」ただそれだけなのですが、そのせいでUPnP/DLNAが超えられず大変苦労しました……。
プログラム本体
Perlで動作します。"IO::Socket::Multicast"を使用するのでインストールしてください。
# apt-get install libio-socket-multicast-perl
- PCにインターフェイスが複数あるとき、それぞれのネックワーク内のUPnPパケットを中継します。
- 具体的には M-SEARCH マルチキャストを中継し、その応答結果のユニキャストを、M-SEARCH を送信してきた機器に転送します。
- SSDPによりルーター越しに機器が発見できても、その後のアクセスが同一ネットワーク内に制限されている機器では使用できない。
仕組みの解説
UPnP/SSDPという仕組みについて説明します。
ネットワーク内にSSDPを投げて応答を出力するテストプログラム(Perl用)を置いておきますので、試しながら読むとよく分かると思います。
WindowsやLinux等で統一ネットワーク内のルーターやメディアサーバ、プリンタ等をOSが自動的に見つけてくるのを見たこともある人が多いと思います。そこで使われてる仕組みがUPnPです。
これを発見するためにブロードキャストに似たUDPマルチキャストパケットを投げます。UPnPでは "239.255.255.250:1900" にパケットを投げる決まりになっています。*1
例えばすべての機器を探す場合は次のメッセージを投げます。*2
M-SEARCH * HTTP/1.1 HOST: 239.255.255.250:1900 MAN: "ssdp:discover" MX: 3 ST: ssdp:all
すると次のような応答がユニキャストで帰ってきます。
HTTP/1.1 200 OK CACHE-CONTROL: max-age=1800 EXT: LOCATION: http://192.168.0.10:20081/description.xml SERVER: Linux/2.6.10-TSB20090810test UPnP/1.0 Intel_SDK_for_UPnP_devices/1.2 ST: urn:schemas-upnp-org:service:ContentDirectory:1 USN: uuid:ddc9f300-45e4-11d9-b397-001c7e09a370::urn:schemas-upnp-org:service:ContentDirectory:1
これはとあるHDDレコーダーの例です。この応答を受け取ったクライアントは、LOCATIONヘッダに書かれた「http://192.168.0.10:20081/description.xml」にアクセスし、より詳細な情報を得ます。
これより後はTCPアクセスですので、UDPマルチキャスト(SSDP)を使うのは最初だけになります。
まとめ
UPnP/SSDPを中継してあげても、その後のhttpアクセス等が同一ネットワーク内に制限されているものも多く、例えば Windows Media Player 12 や東芝のHDDレコーダーは操作できませんでした。
KodiというUPnP/DLNA対応ソフトは大丈夫でしたので、そちらを使っています。
メモ
- UPnPメッセージは必ず「CR/LF」で改行する。
- UPnPメッセージは最後に必ず空行を入れる。
- UPnP/SSDPパケットを中継しても、その後のhttpアクセス(LOCATION)がローカルネットワークのIP以外からは禁止されてることが多い。
- UDP 1900番ポートからマルチキャストを投げると無視する機器がある。