Some extended and commonly used tag names may store metadata useful to minidlna, so read these where allowance is already made for their storage and use.
Use newer API for IP_MULTICAST_IF which allows one to specify
interface by index, not by address. Introduced in Linux 3.5, it IMHO should
be available on all systems that declare struct ip_mreqn.
This fixes operation failure when a system has multiple interfaces
with same address, but only on of them is desired. Example:
> grep interface /usr/local/etc/minidlna.conf
network_interface=igb0
> ifconfig igb0
igb0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 0c:c4:7a:xx:xx:xx
inet 10.1.10.3 netmask 0xffffff00 broadcast 10.1.10.255
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
> ifconfig ng0
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
inet 10.1.10.3 --> 10.1.10.2 netmask 0xffffffff
In such configuration, ng0 would be chosen before this fix.
Using $USER in the friendly name will display which user minidlna is
running as on the clients, which can be helpful for detecting problems.
Using $LOGNAME on the other hand will display "root" as the username if
minidlna was started using the init script, regardless of which user
minidlna is currently running as.
Originally added by Benoît Knecht <benoit.knecht@fsfe.org>
Define setjmp_buffer as static to avoid the following build failure with
gcc 10 (which defaults to -fno-common):
/home/buildroot/autobuild/instance-1/output-1/host/lib/gcc/arm-buildroot-linux-gnueabihf/10.2.0/../../../../arm-buildroot-linux-gnueabihf/bin/ld: image_utils.o:(.bss+0x0): multiple definition of `setjmp_buffer'; metadata.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Fixes:
- http://autobuild.buildroot.org/results/8754bb4f7d749f999d5f8ddfec587470ceec4476
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
The UPnP protocol specification mandates that subscribers can request a
callback to an arbitrary URL. This recently resulted in CVE-2020-12695
(CallStranger) outlining the risk of information disclosure and DoS
attacks.
This commit ensures that the callback URL sent in a SUBSCRIBE request
points to the same IP address that made the request.
If our response buffer fills up to the max buffer size on a UPnP Browse
request, we should return short results rather than erroring out.
Fixes: #314 (Cannot browse MiniDLNA 1.2.1 with VLC 2.2.6 (UPnPError 709: Unsupported or invalid sort criteria))
Add flag for milliseconds conversion for bookmarks and model for Samsung Q
series, which needs this. This allows for bookmark synchronization when 2
or more TVs are using the same DLNA server.
getsyshwaddr assumed that the first ifaddr it came across was the MAC
address, and as such assumes that it has the right length. After
upgrading to OS X 10.13.4, this causes minidlnad to crash on startup due
to tripping stack smash protection -- I'm not sure if the order of
addresses returned previously happened to accidentally hit this
invariant, or if this was always an issue and the stack smash protection
got smarter.
In any event, we just need to look for the AF_LINK address and use that.
As an extra check, we make sure the length is the length we expect to
copy into the target buffer.
There's a report about a nightly "crash" when users download, compile
from source, and replace their distro's mindlnad binary. This is because
the Debian package includes a patch that uses SIGUSR2 to reopen the log
file and sends SIGUSR2 from logrotate instead of just using the
"copytruncate" logrotate option. Then logrotate sends SIGUSR2 at 6:25AM,
which causes us to abort due to the unhandled signal.
I don't want to sacrifice SIGUSR2 just for log rotation, especially when
we already do some reload operations on SIGHUP. So to avoid this
Debian/Ubuntu issue, we'll explicitly ignore SIGUSR2, and add log file
reopening to the SIGHUP handler. Then hopefully a future Debian package
version will remove the SIGUSR2 patch and use SIGHUP instead (or
copytruncate).
Fixes: SF Bug #313 (log rotation kills minidlna service)
The Control4 app apparently sends us badly-formatted SearchCriteria,
where they don't quote the upnp:class value. So we'll add it in for them
if we detect that situation.
Fixes: SF Patches #173 (DLNA search query not as minidlna expects)
There's no point in returning bookmark info without a bookmark. It also
has been reported that certain Samsung models may have issues with
subtitles if we send dcmInfo data. So we'll only return it if we have a
bookmark set.
[minidlna:support-requests] #52 External srt subtitles for Samsung UA48JU7800
Add back SSDP filtering. Relying on the kernel to filter out multicast
traffic from non-member interfaces simply doesn't work the way many
people think it does, so we need to re-introduce manual filtering. But
this time we will use in_pktinfo's ifindex for comparison rather than a
netmask comparison, so SSDP packets from other subnets should still work.
This has theoretical bug if our collection spans different
filesystems and some filesystems support holes, and some not.
If this ever encountered we should use pathconf(2) and cache
its result for directories.
My guess the goal was to skip files with holes in them. Original commit
590f0761f4aba64c4a3b4c8f11543a929178da38, doesn't explain that. If that
is still necessary, better to add lseek(SEEK_DATA) check later.
Some effort was made to unify monitoring via kqueue and via inotify
APIs. Now both provide their implementation of add_watch() function.
I guess there are some logical bugs in vnode_process(). With this commit
it would be better provide code as is, and resolve bugs separately.
The idea is taken from the nginx web server, but much simplified and
almost no copypaste left. This will allow minidlna to use different
event dispatcher APIs, which would be defined at compile time.
My personal goal is to convert minidlna to kqueue(2) on FreeBSD. This
would later allow for kqueue based directory change notification, which
won't conflict with select(2) like the current patch does.
Other platforms will also benefit from the pluggability of the event
system, Linux can switch to epoll(2) or at least to poll(2).
Detailed list of changes:
* event.h [New]
Our internal API to unify different event dispatch systems.
* select.c [New]
Much simplified version of nginx's ngx_select_module.c.
* minidlna.c
- Split out listen socket event processing into separate function
ProcessListen(), which matches event_process_t type.
- Create and initialize struct event for the monitor socket, SSDP
socket, HTTP socket and beacon socket.
- Simplify and make more precise timeout calculation using
helper timeval functions from utils.c. Treat gettimeofday() error
as a fatal event.
- Rip out all stuff related to select(2). Just call event_module.process().
* upnpevents.c
- Embed struct event into upnp_event_notify.
- Merge upnp_event_create_notify() with upnp_event_notify_connect().
Start connecting immediately after socket creation. Garbage collect
now useless ECreated state.
- Make upnp_event_process_notify() of event_process_t type, and use it
as process callback for upnp_event_notify event.
- Looks like we always create upnp_event_notify with existing subscriber,
and never clear it later. Remove checks for obj->sub and assert that it
is never NULL. Simplifies things.
- When switching obj state, add/del it to event dispatcher accrodingly.
- Garbage collect upnpevents_selectfds().
- Garbage collect select(2) related stuff from upnpevents_processfds().
Rename function to upnpevents_gc(), since the remaining functionality
is garbage collecting, not file descriptor processing.
Actually, this can be simplified even more. We can safely close sockets
and free objects immediately, eliminating need for upnpevents_gc(). But
this change would be beyond scope of this commit.
* upnphttp.c, upnphttp.h
Embed struct event into struct upnphttp. Adjust Process_upnphttp() to match
event_process_t type. Add/del to event dispatcher once creating/closing a
socket.
* minissdp.c, minissdp.h
Make ProcessSSDPRequest() of event_process_t type.
* getifaddr.c, getifaddr.h
Make ProcessMonitorEvent() of event_process_t type.