ConnectSDK / Connect-SDK-Android-Core

Core source code for the Android Connect SDK project
Apache License 2.0
114 stars 79 forks source link

TTL of SSDP search does not conform to the UPnP specification, causing some devices not being listed as renderers #70

Open gabrielmagno opened 8 years ago

gabrielmagno commented 8 years ago

DLNA renderers in a multi-router environment are not found

Steps to Reproduce

  1. Connect your android device (where Connect-SDK will run) in a router. This is the "main router".
  2. Connect a DLNA renderer (TV, Kodi/XBMC box, etc) in another router. This is the "secondary router".
  3. Connect the secondary router into the main router. Make sure both routers are in the same network, and that the computer and the renderer can "see" (ping) each other.
  4. Open the Connect-SDK application in the android device. The renderer will not be listed.

I have an LG TV (with builtin DLNA) and a Raspberry Pi running Raspbmc (with UPnP controller/renderer enabled). Both are connected in a wireless bridge router, which is connected into my main router. My android device, from where I run Connect-SDK, is connected into the main router. With this setup, Connect-SDK does not list them as renderers. If I connect them directly into the main router, Connect-SDK will show them.

I looked into the code, and it seems that the library does not set the proper value of TTL when searching for devices. According to the UPnP Specification:

To limit network congestion, the time-to-live (TTL) of each IP packet for each multicast message should default to 4 and should be configurable. When the TTL is greater than 1, it is possible for multicast messages to traverse multiple routers; therefore control points and devices using non-AutoIP addresses must send an IGMP Join message so that routers will forward multicast messages to them (this is not necessary when using an Auto-IP address, since packets with Auto-IP addresses will not be forwarded by routers).

Possible Fix

By inspecting the packet of SSDP M-SEARCH with Wireshark, it is indeed set as TTL=1, while it should be set as TTL=4.

In Java, it's possible to do that by calling setTimeToLive in the socket object. This method is available only to Multicast sockets.

I looked into Connect-SDK's code, and noticed that a Datagram socket is used to send the SSDP search. It should actually be of the Multicast type, so that we could call socket.setTimeToLive(4) before binding it.

I tried to fix it myself, and now both my TV and Kodi are listed as renderers. I could issue a pull request with my simple fix, but was not sure if the way I did was the best way, so I decided to report my findings with all the details, so that you could handle it properly.

sv244 commented 8 years ago

+1

ghenry22 commented 7 years ago

hi @gabrielmagno any chance you could submit a pull request or just drop some details into a reply here? I'd like to get this fixed as well and if I can do it without re-inventing the wheel that would be nice!

gabrielmagno commented 7 years ago

Hi @ghenry22 . I've just submitted a pull request that seems to fix this issue. I've tested it back them when I reported the issue, and it solve the problem for me.