2015/11/06(金)UPnP/SSDPマルチキャスト中継プログラム(DLNA用)

UPnPのマルチキャストパケットを中継するためのプログラムです。通常、同一ネットワーク内でしか使用できないUPnPを、ルーターを超えて使用できるようになります。

想定

  • DLNAサーバとクライアント(またはコントローラーとレンダー)がルーターを超えて存在する。
  • それぞれネットワークAとBとすれば、A内のPCとB内のPCは互いに通信可能である(NATされていない)。
  • どちらのネットワークにも属するPCが存在する。

「WiFiと有線LAN環境を同一ネットワークにしたくない」ただそれだけなのですが、そのせいでUPnP/DLNAが超えられず大変苦労しました……。

プログラム本体

ssdp-relay.pl

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)を使うのは最初だけになります。

*1 : 「224.0.0.0 ~ 239.255.255.255」がマルチキャスト用ネットワークアドレスになります。

*2 : 最後の空行は必要なものです。こう書かないと応答しないソフトがあります。

まとめ

UPnP/SSDPを中継してあげても、その後のhttpアクセス等が同一ネットワーク内に制限されているものも多く、例えば Windows Media Player 12 や東芝のHDDレコーダーは操作できませんでした。

KodiというUPnP/DLNA対応ソフトは大丈夫でしたので、そちらを使っています。

メモ

  • UPnPメッセージは必ず「CR/LF」で改行する。
  • UPnPメッセージは最後に必ず空行を入れる。
  • UPnP/SSDPパケットを中継しても、その後のhttpアクセス(LOCATION)がローカルネットワークのIP以外からは禁止されてることが多い。
  • UDP 1900番ポートからマルチキャストを投げると無視する機器がある。

ソース