huin/goupnp

httpu multicast fails on multiple interfaces

viric opened this issue · 7 comments

viric commented

Using a single PacketConn to send multicast UDP requests for SSDP search fails, if there are multiple interfaces in the system.
The WriteTo() will pick any interface and use that alone, not sending the SSDP search to any other network interface.

I think that for SSDP search to work we need a PacketConn per network interface.

viric commented

Using the interface of the default 0.0.0.0 route would be good too. In my case (Windows) it is not using the interface of the default route, but another.

huin commented

Sorry for the (very) delayed reply, and thanks for diagnosing this.
I've created the multi-interface branch to provide a possible solution along the lines of your first suggestion. Could you try that out and see if that resolves your issue?

I faced same issue, that with 1 interface all is fine.
Having 2 interfaces to different networks does not work, goupnp.DiscoverDevices("ssdp:all") does not return any results.

I've tested the multi-interface branch. When using it even with only 1 interface I do not get any results. Same for multiple interfaces.

huin commented

I faced same issue, that with 1 interface all is fine.
Having 2 interfaces to different networks does not work, goupnp.DiscoverDevices("ssdp:all") does not return any results.

I've tested the multi-interface branch. When using it even with only 1 interface I do not get any results. Same for multiple interfaces.

Did the library work for you on the master or devel branch? It's not clear to me if you're describing a regression on the multi-interface branch or if it's a potential problem with the library as a whole.

Also, do you expect network devices to respond on your network? Note that this library only supports IPv4. You might want to try performing packet captures or other UPnP clients to see if they work. A big problem with this library is that I only have my own home network to test on, and everyone's network and computer configurations are different. Reproducing problems is key to fixing any bugs.

I've also written a command on the devel branch called discoverall which should print out anything that it finds. I've merged that into the multi-interface branch as well, which should be useful for comparison.

Obviously don't share any private information on this bug.

Did the library work for you on the master or devel branch? It's not clear to me if you're describing a regression on the multi-interface branch or if it's a potential problem with the library as a whole.

Sorry for not being precise enough.

The working application used require github.com/huin/goupnp v1.0.0 which AFAI see is the master. The library in whole did work very well, as long as only connected via 1 interface. Thanks for sharing your code BTW !!!

When testing the multi-interface branch, go mod tidy resolved on 2020-05-14

require github.com/huin/goupnp multi-interface

to

require github.com/huin/goupnp v1.0.1-0.20200510113636-70bc05ba64ba

Also, do you expect network devices to respond on your network? Note that this library only supports IPv4. You might want to try performing packet captures or other UPnP clients to see if they work.

Yes: I have IPv4 and IPv6 running in network, but I am aware that only IPv4 is supported. I am using >10 UPnP devices inside network (for business needs), different types of routers, TVs, NASs, and many more.
I am using other UPnP clients as well (all on macOS, gupnp, UPnPAnalyzer, Java UPnP tools), so I can compare behavior, and can obseve network traffic as well (UPnPAnalyzer, wireshark).

A big problem with this library is that I only have my own home network to test on, and everyone's network and computer configurations are different. Reproducing problems is key to fixing any bugs.

I understand this problem very good, as I maintain a Java UPnP tool from time to time (https://github.com/jupnp/jupnp/tree/master/tools/org.jupnp.tool) and you have to fiddle around with a lot of non-compliant behavior due to "broken" UPnP devices. So you need other peoples help to check problems with THEIR devices in case of troubleshooting.

I've also written a command on the devel branch called discoverall which should print out anything that it finds. I've merged that into the multi-interface branch as well, which should be useful for comparison.

Thanks a lot, I will give it a testing next days. I'll keep you updated here.

I gave the branch multi-interface a test in my network environment.

On first test discoverall reported

2020/05/25 14:10:27 write udp 127.0.0.1:58394->239.255.255.250:1900: sendto: can't assign requested address

Why will be the loopback IP be used? I assumed thats wrong.
After applying a small fix discoverall did work well from a first testing, finding UPnP devices on all connected networks:

File network.go, func localIPv4MCastAddrs

if addr.IP.To4() == nil {
	// Not IPv4.
	continue
}
// Fix: do NOT consider loopback IPs
if addr.IP.IsLoopback() {
	// do not use local addrs
	continue
}
addrs = append(addrs, addr.IP.String())

I will provide a PR for that.

huin commented

I've merged these commits into master. Hopefully that resolves the issue. I'll close this issue, but please reopen it if the problem remains.