Code Monkey home page Code Monkey logo

Comments (13)

huin avatar huin commented on June 1, 2024

Wild guess - have you checked if firewalls are intercepting network traffic to/from your program?

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

The firewall on my macbook is currently off. Do I need to have port 1900 open on my macbook? Using OSX network utility to portscan localhost shows the following

Port Scanning host: 127.0.0.1

	 Open TCP Port: 	22     		ssh
	 Open TCP Port: 	80     		http
	 Open TCP Port: 	1023

but httpu binds an available ephemeral port to receive the response so that shouldn't matter, right? I'll see if I can figure out how to get port 1900 opened (firewall is turned off, so I'm not sure why it's not already open)

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

This is kind of interesting and maybe related, but again, I don't think I would have to have port 1900 open on the machine receiving the SSDP response

$ nmap localhost -p1900

Starting Nmap 7.60 ( https://nmap.org ) at 2017-08-29 17:54 PDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00021s latency).
Other addresses for localhost (not scanned): ::1

PORT     STATE  SERVICE
1900/tcp closed upnp

Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds

from goupnp.

huin avatar huin commented on June 1, 2024

A few points:

  • SSDP uses UDP, not TCP. I also don't know that nmap would actually discover UDP ports (there's no connection handshake like with TCP) - almost certainly not in this case as the HTTPU client here only sends packets out and listens for responses, but does not respond to any packets it receives.
  • Note that portscanning localhost might well hit different firewall rules than packets from other addresses. But again - I don't think that portscanning will give you any useful results.
  • Your code (at least as pasted) is ignoring errors. If this is the actual code you are using, please check those errors.

If you address the above, but aren't getting error messages, then a better source of information than portscanning is capturing network traffic (with wireshark/tcpdump or similar). You would want to be capturing/filtering to UDP packets to/from port 1900 on all network interfaces.

from goupnp.

huin avatar huin commented on June 1, 2024

Another thought that occurs to me: does your linux install have an IPv4 assignment, but OSX/Windows only have IPv6? I don't think I ever implemented IPv6 support on this library.

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

Good call on enabling errors, I've updated the discovery code to

package main

import (
  "fmt"
  "github.com/huin/goupnp/ssdp"
  "github.com/huin/goupnp/httpu"
)

func main() {
  fmt.Println("Detecting roku devices")

  httpuClient, err := httpu.NewHTTPUClient()
  if err != nil {
    fmt.Printf("Error: %s\n", err.Error())
    return
  }

  responses, err := ssdp.SSDPRawSearch(httpuClient, "roku:ecp", 3, 2)
  if err != nil {
    fmt.Printf("Error: %s\n", err.Error())
    return
  }

  for _, response := range responses {
    fmt.Println(response)
  }
}

All of my experience is pretty exclusively in TCP land.

This is the result of sudo tcpdump -A 'udp port 1900' on my macbook.

tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
18:38:03.388991 IP 192.168.1.2.55204 > 239.255.255.250.ssdp: UDP, length 94
..^.....Z.|...E..zp..................l.f..M-SEARCH * HTTP/1.1
Host: 239.255.255.250:1900
Man: "ssdp:discover"
ST: ssdp:all
MX: 5


18:38:03.879322 IP 192.168.1.12.50170 > 239.255.255.250.ssdp: UDP, length 94
..^........Q..E..z>......"...........l.f9UM-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: roku:ecp


18:38:03.885769 IP 192.168.1.12.50170 > 239.255.255.250.ssdp: UDP, length 94
..^........Q..E..z?..................l.f9UM-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: roku:ecp


18:38:05.605048 IP 192.168.1.10.ssdp > 192.168.1.12.50170: UDP, length 215
.....Q...%.Q..E....u@.@......
.....l....f`HTTP/1.1 200 OK
Cache-Control: max-age=3600
ST: roku:ecp
USN: uuid:roku:ecp:YY005F185283
Ext:
Server: Roku UPnP/1.0 Roku/7.7.0
LOCATION: http://192.168.1.10:8060/
WAKEUP: MAC=08:05:81:25:89:51;Timeout=10

192.168.1.2 is a windows machine and can pretty much be ignored. 192.168.1.12 is the macbook running the discovery golang code, and 192.168.1.10 is the Roku.

So if I'm reading this right, we're binding port 50170 on the macbook and sending a UDP broadcast to 239.255.255.250.ssdp (i.e. port 1900) which is expected since that what the SSDP code does,

and then we do get a response back from the Roku to the macbook on port 50170 192.168.1.10.ssdp > 192.168.1.12.50170 and I can see the ST is correct (roku:ecp), but then we're still not registering any responses from the go library (output is just the Detecting roku devices with nothing else)

If configuration was blocking it on the client device side, I would think we should't even see the packets come back right? It's mysterious. I'm going to tcpdump on the linux box as well to see if the packets look different.

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

Ok, here's the tcpdump on the linux box

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:54:16.179673 IP brix.39730 > 239.255.255.250.1900: UDP, length 94
E..z.u@...(C.........2.l.fb.M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: roku:ecp


18:54:16.184554 IP brix.39730 > 239.255.255.250.1900: UDP, length 94
E..z.v@...(B.........2.l.fb.M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: roku:ecp


18:54:16.551455 IP 192.168.1.10.1900 > brix.39730: UDP, length 215
E.....@[email protected]...
.....l.2....HTTP/1.1 200 OK
Cache-Control: max-age=3600
ST: roku:ecp
USN: uuid:roku:ecp:YY005F185283
Ext:
Server: Roku UPnP/1.0 Roku/7.7.0
LOCATION: http://192.168.1.10:8060/
WAKEUP: MAC=08:05:81:25:89:51;Timeout=10

and the response

Detecting roku devices
&{200 OK 200 HTTP/1.1 1 1 map[Wakeup:[MAC=08:05:81:25:89:51;Timeout=10] Cache-Control:[max-age=3600] St:[roku:ecp] Usn:[uuid:roku:ecp:YY005F185283] Ext:[] Server:[Roku UPnP/1.0 Roku/7.7.0] Location:[http://192.168.1.10:8060/]] 0xc42010a040 -1 [] true false map[] 0xc420104000 <nil>}

It looks ... similar, but not exactly the same. brix is the hostname of the linux box. the port is explicitly 1900 instead of ssdp on the macbook. But the macbook isn't obviously a bad response, unless I'm reading that dump wrong.

from goupnp.

huin avatar huin commented on June 1, 2024

Lots of useful information there, thanks. Unfortunately this doesn't move my understanding further forwards. I think we're down to printf debugging now.

In httpu.go: follow this line n, _, err := httpu.conn.ReadFrom(responseBytes) with fmt.Println("ReadFrom: ", string(responseBytes[:n]))

That should tell us if the program is even receiving the bytes from the UDP socket.

If it's receiving reasonable looking responses, then I guess I'm slightly baffled as to how any platform/machine-specific differences can be creeping in, but I guess that means putting some print debug statements into SSDPRawSearch in ssdp.go, in order to see where responses aren't being added into the responses variable that gets returned (while iterating over allResponses).

from goupnp.

gsparx avatar gsparx commented on June 1, 2024
	responseBytes := make([]byte, 2048)
	for {
		// 2048 bytes should be sufficient for most networks.
		n, _, err := httpu.conn.ReadFrom(responseBytes)
		fmt.Println("ReadFrom: ", string(responseBytes[:n]))
		if err != nil {
			if err, ok := err.(net.Error); ok {
				if err.Timeout() {
					break
				}

Added that in, here's the responses

OSX

Detecting roku devices
ReadFrom:

Ubuntu

Detecting roku devices
ReadFrom:  HTTP/1.1 200 OK
Cache-Control: max-age=3600
ST: roku:ecp
USN: uuid:roku:ecp:YY005F185283
Ext:
Server: Roku UPnP/1.0 Roku/7.7.0
LOCATION: http://192.168.1.10:8060/
WAKEUP: MAC=08:05:81:25:89:51;Timeout=10


ReadFrom:
&{200 OK 200 HTTP/1.1 1 1 map[Cache-Control:[max-age=3600] St:[roku:ecp] Usn:[uuid:roku:ecp:YY005F185283] Ext:[] Server:[Roku UPnP/1.0 Roku/7.7.0] Location:[http://192.168.1.10:8060/] Wakeup:[MAC=08:05:81:25:89:51;Timeout=10]] 0xc42005e200 -1 [] true false map[] 0xc420104000 <nil>}

So that kind of sucks, because it looks like the issue might be in the net package? I'm not sure why we'd see the response from tcpdump but not get any bytes written from net.PacketConn.

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

It also seems kind of odd that we see two ReadFrom: logs from the Ubuntu run but not from the OSX run

from goupnp.

huin avatar huin commented on June 1, 2024

Well, that narrows it down some, at least. Possibilities that occur to me:

  • I'm using the net library wrong, in some non-cross compatible way. I think I'm doing the right thing, looking at the docs. https://golang.org/pkg/net/#PacketConn
  • Something firewall-like is preventing the packet reaching the application code. tcpdump is likely seeing the packets prior to them being dropped by the firewall (https://serverfault.com/questions/233302/will-tcpdump-see-packets-that-are-being-dropped-by-iptables), so tcpdump is probably seeing the raw packets before the kernel decodes (and drops) them.
  • Somehow another application is consuming the packet. I don't think this is possible, as the httpu opens a listening socket on a random unallocated port, and should therefore have exclusive access to it.

So I've run out of ideas here, other than it being something in the firewall. I only know how to debug firewall issues on Linux, so can't advise how to diagnose such issues on Windows/OSX.

from goupnp.

gsparx avatar gsparx commented on June 1, 2024

I'm going to close this.

I did some troubleshooting on Windows, and the behavior was incredibly inconsistent. It worked after I disabled the HomeGroup listener service, and then I re-enabled it and it still worked. On my other Windows machine it started working after I disabled the firewall, but my firewall was on on the other machine. And then, it inexplicably stopped working again.

The macbook is a work machine, so I wouldn't be surprised if there's some configuration that's blocking certain types of processes from receiving UDP traffic, or something like that.

So obviously this has nothing to do with the library itself, and everything to do with undetermined configuration.

I think my writeup is just going to eventually have to be "If you want automatic device discovery to work, use a Linux machine. Otherwise, just write the config file with the known IP address."

Thanks for helping me troubleshoot! I learned something about debugging UDP traffic which I didn't know before, and I maybe gained a tiny bit of insight into how unreliable SSDP can be.

from goupnp.

huin avatar huin commented on June 1, 2024

That's a shame. SSDP should be pretty reliable on a LAN, especially with the repeated queries that it recommends (and this library implements). Just a factor that we're not understanding somewhere, but I've run out of ideas.

Thanks for going through all the debugging though! Good to have people hammering on seeing if there are problems in the library.

from goupnp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.