alexballas / go2tv

Cast media files to UPnP/DLNA Media Renderers and Smart TVs.
MIT License
468 stars 45 forks source link

Unable to find upnp device #72

Closed kero990 closed 1 month ago

kero990 commented 11 months ago

I tried running go2tv on an arm64 Linux device

Compilation was successful, but no upnp devices could be found during program execution

Run go2tv - l using cli

The error is as follows:

Encountered error(s): checkflags error: checkTflag service loading error: loadSSDPservices: No available Media Renderers

alexballas commented 11 months ago

Hello @kero990, thanks for raising this. Where you expecting a different output? Do you have any media renderers to your local network? The error is self-explanatory.

mpeter50 commented 11 months ago

I have the same problem, this is the only line printed when running go2tv -l before it exists.

In my case I expected an LG webOS TV to appear as media renderer.

I had some success with the GUI mode, however. I was able to start it twice, first time I couldn't seek, but on the second try it was very stable! After that, I mostly cant see the TV in the "Select Device" list. Sometimes it appears for a few seconds, but then it disappears.

I'm running go2tv on Linux, specifically openSUSE Leap 15.4.

While I was writing this I kept the GUI open, and the TV has reappeared in the list, and now it stayed there for 10-20 seconds. After that it disappeared multi times but reappeared soon, but after a few such cycles its not visible again. The TV was still on, not in standby.

alexballas commented 10 months ago

Hello, So this seems to be more of network / device related issue. I also have a device on my network that behaves exactly the same way and I haven't yet identified why it happens.

I could try to workaround it and and extra checks during the device list refreshing in the GUI mode and give the perception that the device is always detected, but that would not work in the CLI mode where the device discovery is run adhoc and it's up to the device to properly broadcast its presence on a timely manner to the rest of the network.

alexballas commented 9 months ago

Pushed this commit https://github.com/alexballas/go2tv/commit/122e2b480ec4a9c712c0e66a3294f86f6532e100 in the develop branch that should improve things in the GUI mode

kczulko commented 8 months ago

@kero990 In my case it was a device issue. I am running nixos on my device where firewall is enabled by default. Disabling it fixed this issue for me.

uninsane commented 6 months ago

UPNP/SSDP is notorious for causing problems with stateful firewalls (such as the default one in NixOS) because the IP address which responds to your query doesn't match the IP address to which you send a query. the discovery process has your device sending to the broadcast address, like 239.255.255.250, and then you might get responses from 192.168.0.111, 192.168.0.54, etc: to your firewall that looks like unsolicited traffic.

but notably, despite the IP addresses not matching, the ports do match. if you issue the query from port 1901, the responses will always arrive back at port 1901. currently go2tv issues its SSDP queries from an unspecified (ephemeral) port. but if go2tv were instead to issue its queries from a known, fixed port, then you could whitelist that port in your firewall. for example:

diff --git a/devices/devices.go b/devices/devices.go
index cf97633..4072639 100644
--- a/devices/devices.go
+++ b/devices/devices.go
@@ -21,7 +21,7 @@ var (
 func LoadSSDPservices(delay int) (map[string]string, error) {
        // Reset device list every time we call this.
        urlList := make(map[string]string)
-       list, err := ssdp.Search(ssdp.All, delay, "")
+       list, err := ssdp.Search(ssdp.All, delay, "0.0.0.0:1901")
        if err != nil {
                return nil, fmt.Errorf("LoadSSDPservices search error: %w", err)
        }

then, for Nix users, go2tv will work with the firewall configured as such:

  # to discover local UPNP endpoints:
  networking.firewall.allowedUDPPorts = [ 1901 ];
  # to serve local files:
  networking.firewall.allowedTCPPorts = [ 3500 ];

this type of firewall issue seems pretty common: @alexballas how would you feel about exposing some option (CLI arg, environment variable, ...) to control the SSDP port bind so that we can work around the firewall issues w/o patching? a different solution which avoids exposing new options is to let the OS choose the port as it does now, but narrow the range from which it's allocated (e.g. 47000 - 47100). this seems to be what similar projects (e.g. catt) do, and the user just opens the full range of ports.

if either of these options sound OK i'd be happy to make a PR for it.

alexballas commented 6 months ago

@uninsane Apologies for the delay; this month has been a bit slow for me in terms of development. Thanks for the great feedback. In general and as you might have seen from the app itself, I try to keep things as easy as possible for the users. Adding an extra option there in the CLI and the GUI settings tab would probably confuse the less techie people. I like the idea of having a fixed range better. We can then document it in the README file as a workaround for the stateful firewalls.

uninsane commented 6 months ago

@alexballas i looked deeper into the solution i proposed. it's doable, but IMO not pretty. Linux offers no way to say "give me a socket bound to any port between 47000 and 47100". instead, go2tv would have to randomly pick a number between 47000-47100, try binding to it, and if we fail (because something else was using the random port we chose), try again -- in a loop until we succeed.

instead, i'm using this solution, which fixes the issue by configuring the firewall to understand SSDP, no code changes necessary.

alexballas commented 6 months ago

@uninsane I think it's fine. I do something similar here for the webserver port https://github.com/alexballas/go2tv/blob/devel/soapcalls/utils/iptools.go#L50-L65

In general I'm not against the change but if there is an indeed a solid workaround on the network / firewall side, I would leave it as is.

alexballas commented 1 month ago

Pushed this commit 122e2b4 in the develop branch that should improve things in the GUI mode

These improvements are now part of the 1.16.0 release. Closing