NAS DiskStationの導入 #15 メディアサーバー(DLNAサーバー) – ライブラリーの修正

前回の投稿で、接続できなくなったDLNAクライアントは、メディアサーバー側で使用しているライブラリーの仕様変更であることがわかりました。そのライブラリーを修正します。

サポートとのやり取り

Synologyのサポートのやり取りの中で、「メディアサーバー」のバージョンアップに伴い、使用しているライブラリーの問題で、一部のDLNAクライアントが「メディアサーバー」に接続できなくなった問題に対して、以下の回答を得ました。

弊社では、今後も本事象をフォローアップ予定となっております。

libupnp (pupnp) 側で修正が行われた場合、弊社のDSMもしくはMedia Serverのアップデートにて当該修正を反映させていただきます。

libupnp (pupnp) の修正後、どの程度の期間を置いて弊社製品に修正が反映されるかにつきましては、恐れ入りますが現段階ではご案内ができませんことご了承願います。

「メディアサーバー」が使用しているライブラリーが修正されれば、Synologyの「メディアサーバー」の将来のバージョンで反映されることの確認が取れました。

いつ「メディアサーバー」に反映されるのかは未定ですが、早めにそのライブラリーを修正しておくと、「メディアサーバー」に反映されるタイミングが早くなると思われます。

一部のDLNAクライアントで接続できなくなった問題の原因となっているライブラリー

Synologyの「メディアサーバー」が使用している今回の問題の原因となったライブラリーは libupnp (pupnp) です。

The Portable SDK for UPnP* Devices (libupnp)

このライブラリーは、以前は Source Forge で管理されていましたが、現在は、GitHubで管理されています。

https://github.com/pupnp/pupnp/

このライブラリーは何を実現するものなのでしょうか?

GitHubのこのライブラリーのプロジェクトページに記載されている概要を引用します。

1. Overview

The Portable SDK for UPnP™ Devices is an SDK for development of UPnP device and control point applications. It consists of the core UPnP protocols along with a UPnP-specific eXtensible Markup Language (XML) parser supporting the Document Object Model (DOM) Level 2 API and an optional, integrated mini web server for serving UPnP related documents. It provides developers with an API and open source code for building control points, devices, and bridges that are compliant with Version 1.0 of the Universal Plug and Play Device Architecture Specification and supports several operating systems like Linux, *BSD, Solaris and others.

このOverviewの日本語訳です。

1. 概要

Portable SDK for UPnP™ Devicesは、UPnPデバイスおよびコントロール・ポイント・アプリケーションを開発するためのSDKでです。この SDK は、UPnP のコア・プロトコルと、Document Object Model (DOM) Level 2 API をサポートする UPnP 向けの eXtensible Markup Language (XML) パーサー、および、 UPnP 関連ドキュメントを配信するためのオプションの統合ミニ Web サーバーで構成されています。開発者には、Universal Plug and Play Device Architecture 仕様バージョン 1.0 に準拠したコントロールポイント、デバイス、およびブリッジを構築するための API とオープンソースコードが提供され、Linux、*BSD、Solaris などの複数のオペレーティングシステムがサポートされています。

このライブラリーは、ユニバーサル プラグ アンド プレイ(UPnP)の実装を容易にするためのライブラリーのようです。

DLNAでは、機器発見にUniversal Plug and Play(UPnP)で規定されたSimple Service
Discovery Protocol(SSDP)を用います。そのため、Synologyの「メディアサーバー」ではこのUPnPのライブラリーを利用しているようです。

libupnp (pupnp)の接続できない問題に対応するissue

Synologyのサポートから連絡があったように、接続できない問題に対応するissueがGitHubに登録されています。

[1.14.6] Compatibility issues #342
https://github.com/pupnp/pupnp/issues/342

このissueによると、

pupnp/upnp/src/genlib/miniserver/miniserver.c の host_header_is_numeric() 関数の実装の影響で、HttpリクエストヘッダーのHostの値として、ポート番号が省略されているとレスポンスを正しく返えせない問題がある。

RFC7230 によると、Hostの値としては、ホスト名は必須であるが、ポート番号は省略可能とされている。なので、この関数の実装に問題がある。

とのこと。コードを見てみると、たしかに、ポート番号が省略されたときの処理が適切ではないです。

バグの混入時期

さて、このコード修正はいつ頃されたものなのでしょうか?

libupnp (upnp)のコミット履歴を調べてみると、

2021/04/21 DNS rebind: Fix [Commit 21fd858]

でこの問題が埋め込まれています。そして、このコミットを含むlibupnp (pupnp)が、2021/04/21にバージョン1.14.6としてリリースされています。

また、SynologyのDSM 7.0の初版は2021/07/19にリリースされています。DSMに新メジャーバージョンをリリースするにあたり、使用しているライブラリーを最新版にしたことにより、libupnp (pupnp)のバグも一緒に「メディアサーバー」に取り込まれたようです。

このようにlibupnp (pupnp)とSynologyの「メディアサーバー」間の関係は、時系列的にも一致します。

修正とプルリクエスト

さて、「メディアサーバー」は、使用しているライブラリーであるlibupnp (pupnp)が修正されれば、将来のバージョンで取り込む予定であるとのことです。

「メディアサーバー」の次回のバージョンで修正を早期に取り込んでもらえるように libupnp (pupnp) を修正しておきます。

修正対象は、masterブランチとbranch-1-14.xブランチとなります。この二つのブランチは、2022年6月上旬時点で、先の問題のコードが含まれていました。なお、現在(2022月7月時点)では、masterブランチはbranch-1-16.x-deprecatedブランチに名前変更されています。

対象のコードの変更量が少なくなるような修正を試みます。

  static int host_header_is_numeric(char *host_port, size_t host_port_size)
  {
    int rc = 0;
    struct in6_addr addr;
    char *s;

    /* Remove the port part. */
    s = host_port + host_port_size - 1;
-   while (s != host_port && *s != ':') {
+   while (s != host_port && *s != ']' && *s != ':') {
      --s;
    }
+   if (*s == ':') {
      *s = 0;
+   } else {
+     s = host_port + host_port_size;
+   }

2022年6月3日に作成したプルリクエストは以下の二つです。

  • Fix #342: accept port number omission for master branch #396
  • Fix #342: accept port number omission for branch-1.14.x branch #397

プロジェクトのメンテナーのアクティビティは2022年4月30日で止まっていたので、マージされるまでには、しばらくかかると思っていました。

ところが、想定より早く、2週間後の2022年6月16日にマージされました。

しかし、コードはマージされましたが、ライブラリーを新しいバージョン(1.16.13)としてリリースがされていません。メディアサーバーに取り込んでもらうためには、新しいバージョンとしてリリースされる必要があります。

libupnp (pupnp)は、いつ頃に新しいバージョンとしてリリースされるのでしょうか。待ち遠しいです。

新しいバージョンとリリースされたら、Synologyのサポートにももう一度連絡を入れようと思っています。


今回の投稿は、「メディアサーバー」で使われているUPnPのライブラリーの修正とプルリクエストの紹介でした。

コメントを残す