Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broadcast discovery of servers on a local network #12

Closed
guruofquality opened this issue Oct 18, 2015 · 11 comments
Closed

Broadcast discovery of servers on a local network #12

guruofquality opened this issue Oct 18, 2015 · 11 comments

Comments

@guruofquality
Copy link
Contributor

Multicast discovery means that the device enumeration routine can discover devices without an explicit addresses specified.

https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol

@guruofquality
Copy link
Contributor Author

@cjcliffe If you feel like giving this a shot, try this branch: https://github.com/pothosware/SoapyRemote/commits/ssdp_work It works, but its not well tested. We will have to see how portable the multicast code ends up being across platforms.

@guruofquality
Copy link
Contributor Author

Here is an interesting quirk of SSDP (at least in my mind). So we have this system where anyone should be able to open a UDP socket, join the multi-cast group and discover and share information. But the service provider replies to the MSEARCH queries through unicast UDP. So when you have multiple processes on the same host, only one of them is going to actually receive the unicast response, and its not always going to be the one that sent the multicast MSEARCH request.

That's not a problem when a host only runs one instance of the SSDP service, and there are some platform specific means to query from the deamon/service what network services have been discovered. But for this use case, I want the SoapyRemote implementation to be portable, so it must talk to a socket and not a platform-specific interface. Also, I want localhost clients to be able to discover localhost servers. Or even multiple of such clients.

For reference, here is another with the same problem: https://stackoverflow.com/questions/12794761/upnp-multicast-missing-answers-from-m-search-discovery The work-a-round of using a different port would not fix the multiple processes issue. It basically makes its own domain-specific multi-cast group separate from the other SSDP traffic, which would also be technically OK for SoapyRemote.

Anyway, my workaround for this issue was to simply respond to MSEARCH with multicast. The usual unicast MSEARCH response is still sent. In addition, the server responds with a multicast NOTIFY packet. NOTIFY packets are part of the specification, and this way the client always gets notified ASAP, one way or the other. Triggering a NOTIFY from an MSEARCH may or may not be typical, but judging from my local network (with wireshark), NOTIFY packets are like a forest full of birds in spring all trying to get their mating calls heard.

@guruofquality
Copy link
Contributor Author

OSX Update

  • IPv4 protocol works
  • IPv6 IPV6_JOIN_GROUP for ff02::c fails (Can't assign requested address)
  • MCAST_JOIN_GROUP should handle multicast joining for both IPv4 and IPv6, and it would simplify the code. That too fails on OSX, for both IPv4 and IPv6. I might think it was me doing something wrong but: https://bugs.php.net/bug.php?id=63000
  • Set SO_REUSEPORT when using multicast, but only on BSD style machine (portability grrr):
    #ifdef __APPLE__
    ret = ::setsockopt(_sock, SOL_SOCKET, SO_REUSEPORT, (const char *)&one, sizeof(one));
    if (ret != 0)
    {
        SoapySDR::logf(SOAPY_SDR_ERROR, "setsockopt(SO_REUSEPORT) -- %d", ret);
    }
    #endif //__APPLE__

@cjcliffe
Copy link
Contributor

Will try this out here on OSX this weekend -- should be able to get a couple systems on the network and see how it goes.

@guruofquality
Copy link
Contributor Author

@cjcliffe Let me know if you get the IPV6_JOIN_GROUP error as well. Its harmless, it just means the ipv6 part of the service doesn't run. You are welcome to mess around with sockets. But more to the point, if every every apple is going to dump an error here, I will just ifdef out the ipv6 multicast for osx. To test it, just run SoapySDRServer --bind, it happens right away.

@guruofquality
Copy link
Contributor Author

merged. We will just have to see what errors come up.

@cjcliffe
Copy link
Contributor

@guruofquality aye; haven't had a chance to spin it up here yet been battling some CubicSDR crashes and gain updates :)

@guruofquality
Copy link
Contributor Author

No problem. I tested enough so that things should be safe to use -- worst case, the feature doesn't work. And I did some tweaks to the error reporting so that any failures wouldn’t look obnoxious.

@guruofquality
Copy link
Contributor Author

Relevant comments about the OSX IPv6 issue, it may not support the automatic interface (ipv6mr_interface = 0): syncthing/syncthing#1563

@guruofquality
Copy link
Contributor Author

This was the work-around, basically logic to automatically select an interface thats up, not loopback, and supports multicast: 43a5bef

So everything seems to be working as far as I can test. Closing off.

@cjcliffe
Copy link
Contributor

awesome work, actually building on Raspberry Pi for testing some remote stuff at the moment; will be trying discovery soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants