SSDP (Simple Service Discovery Protocol) は、LAN 内のデバイスが提供しているサービスを発見したり、サービスがネットワークに参加したことを通知したりするプロトコルです。SSDP 自体はシンプルなプロトコルですが、DLNA などで使われている、機器発見プロトコルである UPnP の一部として利用されています。
SSDP は、以下のようなヘッダで始まる HTTP を拡張したような UDP ベースのプロトコルです。M-SEARCH メソッドは、ネットワーク内のサービスを SSDP クライアントが能動的に発見しにいくときに使用します。
M-SEARCH * HTTP/1.1 \r\n
ヘッダ1: ... \r\n
ヘッダ2: ... \r\n
ヘッダ3: ... \r\n
\r\n
SSDP では、内部で GENA (General Event Notification Architecture) で定義されているメッセージフォーマットも使用しており、こちらは、
ssdp:alive
)ssdp:byebye
)などの Notify をマルチキャストするために使用されます。
NOTIFY * HTTP/1.1 \r\n
ヘッダ1: ... \r\n
ヘッダ2: ... \r\n
ヘッダ3: ... \r\n
\r\n
SSDP では、以下のようなアドレス、ポート番号にメッセージを UDP でマルチキャストしましょうね、と決めています(ポート番号については、正式には UPnP の世界で決まっているのかも)。
239.255.255.250:1900
SSDP で検出するサービスは、以下の情報で識別されます。
ssdp:discover
リクエストの場合は ST ヘッダで指定ssdp:alive
、ssdp:byebye
リクエストの場合は NT ヘッダで指定「ユニークサービスネーム」はサービスを一意に特定する ID になっている必要があるため、通常は UUID を組み合わせて設定されます。
「サービスタイプ」はサービスのカテゴリのようなものであり、どのような形式の URI を入れるかは、SSDP では規定していません(DLNA の世界では、サービスタイプにどのような値を指定するかが規定されています)。
サービスタイプは、ssdp:discover
リクエストの場合は ST ヘッダで指定しますが、ssdp:alive
リクエスト、ssdp:byebye
リクエストの場合は NT ヘッダで指定します。これは、ssdp:alive
、ssdp:byebye
リクエストが GENA のメッセージフォーマットを採用しており、その中の必須で NT ヘッダをサービスタイプを指定するためのフィールドとして使い回しているからです。
分かりにくいですね。。。本来ならば、SSDP は GENA と独立させて、スッキリと定義された方がよかったように思います。まぁ、いろいろ事情があったんでしょう。
ssdp:discover
リクエスト – サービスの発見ssdp:all
リクエスト – 全てのサービスの発見ssdp:alive
リクエスト – サービスの参加を通知ssdp:byebye
リクエスト – サービスの脱退を通知Presence Announcements に分類されている、ssdp:alive
リクエストと、ssdp:byebye
リクエストは、GENA の NOTIFY メソッドのフォーマットで送信されます。
ssdp:discover
リクエストは、「~のサービスを提供するデバイスはいますかぁ?」というサービス発見のための要求です。
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
ST: your:serviceType
*
を指定する。ssdp:discover
を指定する。ssdp:discover
にはレスポンスがあります。ssdp:discover
リクエストを受信したサービスは、指定されたサービスタイプが自分に一致する場合は、UDP ユニキャストで以下のようなレスポンスを返します。
HTTP/1.1 200 OK
USN: uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6
ST: your:serviceType
LOCATION: http://192.168.1.101:53456/
CACHE-CONTROL: max-age = 3600
SSDP クライアントは、受信したサービスの情報をキャッシュに保存して使い回します。 キャッシュには以下のような情報を保持します。
ssdp:all
リクエストは、ssdp:discover
リクエストの特殊版で、サービスタイプ(ST ヘッダ)として ssdp:all
を指定したものです。
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
ST: ssdp:all ★ここだけ特殊
ssdp:all
リクエストを受信したサービス提供機器は、必ずレスポンスを返します。
レスポンスの内容は、ssdp:discover
リクエストのレスポンスと同様なので省略します。
ssdp:all
リクエストは、主に Network analysis tool などが利用します。
ssdp:alive
リクエストは、以下のような場合にマルチキャストされます。
ssdp:alive
リクエストのメッセージ形式は、GENA のフォーマットを利用しています。
GENA でオプショナルなヘッダとして定義されている NTS (Notification Sub-Type) ヘッダの値を ssdp:alive
として設定したものが ssdp:alive
リクエストとして用いられます。
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
USN: uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6
NT: your:serviceType
NTS: ssdp:alive
CACHE-CONTROL: max-age = 7393
LOCATION: http://192.168.1.101:53456/
ssdp:alive
リクエストを受信した SSDP クライアントは、その情報でキャッシュの内容を更新します。更新するキャッシュは、USN が一致するものです。
ssdp:alive
リクエストには、レスポンスはありません。
ssdp:byebye
リクエストは、以下のような場合にマルチキャストされます。
ssdp:byebye
リクエストのメッセージ形式も ssdp:alive
と同様に、GENA のフォーマットを利用しています。GENA でオプショナルなヘッダとして定義されている NTS (Notification Sub-Type) ヘッダの値を ssdp:byebye
として設定したものが ssdp:byebye
リクエストとして用いられます。
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
USN: uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6
NT: your:serviceType
NTS: ssdp:byebye
ssdp:byebye
を指定します。ssdp:byebye
リクエストには、レスポンスはありません。
NT ヘッダは GENA で必須ヘッダなので、サービスタイプを指定していますが、実際の実装では、USN の一致によりキャッシュクリアなどの判断をするため、通常は ssdp:byebye
リクエストの NT ヘッダが参照されることはありません。