Open gchiu opened 7 years ago
Fundamentally this sounds like it needs either 1, 2, or 3 ways to get in a call to setsockopt
:
1 call: Bare bones; affects the listening side of a UDP connection only, listener asks to join a multicast group.
2 calls: If you care to have a way to leave the group also, there needs to be a way to ask for that.
3 calls: If it's important to get the sender to be able to request a more aggressive transmission of multicast beyond its subnet.
So not a lot of C, but it could be wily to figure out exactly where to put it. And I don't really know a whole lot about the intention of the polling and waiting model, so @zsx might chime in on that.
But here's a short summary of what I've figured out:
Multicast groups are identified by a reserved range of IP addresses, 224.0.0.0 to 239.255.255.255. These addresses don't identify machines, but groups that machines can join.
There's little mechanical difference in sending a unicast UDP message and a multicast UDP message from the sender's point of view. Sending a datagram to a multicast address is what makes it multicast.
The only difference from the sender's perspective is that since a UDP message isn't targeting a specific address but rather an "anyone who's listening", there's an issue of who "anyone" is allowed to be. It defaults to addresses on your subnet (TTL = 1), and can be set to just the local machine (TTL = 0) or requested to larger numbers. Honoring the request or not is the business of the routers above you.
Joining a multicast group is done with a setsockopt
call. It requires the [ip_mreq](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738695(v=vs.85).aspx)
structure, which is just a struct with two addresses in it: The multicast group to join, and the person joining it. There's a matching operation for leaving a group.
Just as it's typical for servers to listen to INADDR_ANY (0.0.0.0) and accept connections from any interface on the machine, it's typical when joining a multicast to use INADDR_ANY in the ip_mreq
to identify yourself to the group. If you try and identify yourself with something like 127.0.1.1 to the multicast group, but the sender puts the message on some other adapter. (Note that there's no convenient C API for asking to send on a specific interface, and certainly not one exposed from Rebol.)
I've adapted some sample code on the Internet for implementing multicast in C. It's a simple listener and a simple sender.
They successfully send to each other, but also sender.c
is able to get messages to a Rebol2 multicast listener on both Linux and Windows:
https://gist.github.com/hostilefork/f7cae3dc33e7416f2dd25a402857b6c6
So that is pretty much proof of concept. The only question is how to get those C calls grafted into the network code, triggered from Rebol.
This type of code https://gist.github.com/gchiu/9a6c16ce0bbc3ecc5be4455c3e096832 I think should show some SSDP activity but nothing happens. Similar code for Rebol2 sees SSDP network activity being broadcast.