This MR follows discussions about implementation that can be found here: https://mailman.videolan.org/pipermail/vlc-devel/2021-March/142703.html
These changes implements a fully functional UPNP server exposing the medialibrary content on the network.
MR Description
Extracted from the main commit message:
This is the first implementation of a vlc upnp server module.
The module behave as an interface, it works in pair with the
medialibrary API to expose most of its content.
Here is a list of the server main features:
- Very straightforward to deploy, you start vlc with `-I upnp` and it
simply exposes the medialibrary on the local network.
- The server automatically exposes downscaled versions of your videos
- While the DLNA spec is far from being fully supported, a lot of DLNA
clients are supported.
- DLNA's "time based seeking" during transcoding is supported.
- Special transcoding profiles depending on client's user-agent are
suported, for the moment only the PLAYSTATION3 has differents
profiles hardcoded in the source code but it should be extensible to
other specific clients eventually using config files.
The module is split into different parts, here's a quick overview:
- upnp_server.cpp: The core of the module, all the interactions with
libupnp are done here, this file brings all the module parts
together.
- cds/*: The "ContentDirectory Service", represents and implements the
server file hierarchy, in our case, it mostly reflect the
medialibrary content.
- sout.cpp: The access out upnp server submodule internals. Used in
media transcoding to make the connection between the vlc transcode
pipeline output and the upnp HTTP callbacks.
- xml_wrapper: Wrap the xmli library with modern c++ code to fit the
codebase better.
- test/*: Unit tests
The upnp_server module is based on Hamza Parnica's great proof of
concept.
What changed since the first discussion/review
The first discussion posted on the mailing list mainly focused on data privacy. Being a rather old protocol based on HTTP 1.1 and mainly focused on private local network sharing, the concerns about security are justified. Having a module exposing your media quietly and without any authentification is hardly acceptable given the amount of mobile devices VLC is running on.
On that regard UPNP is pretty hard to deal with, there is no authentification built in the protocol. The only implementation I know that adds password protection (miniDLNA) does it via UPNP virtual directories. Basically the user have to type the password by clicking on directories labeled as letters to get access to the medias. This is tedious, not supported by all the UPNP clients and hard to justify to the users that just want a home media server. The approach we chose instead is to enhance the module verbosity and interactions with the user running the VLC instance:
- A GUI dialog appears at module startup asking confirmation for the user. It tries to explain the privacy problematics in a concise way so the user think twice before starting the module.
- The server won't start if GUI dialogs are unavailable unless
--upnp-server-accept-risks
is explicitly specified via command line options.
I strongly believe that, this, at least, remove the "typical user launching the module unwillingly" case. Which was to my understanding the main concerns raised during the first discussion.
Here's a screenshot of the GUI dialog:
Also I decided to bump libupnp to the latest 1.14.7 as a lot of security issues are fixed since 1.8.