-
Notifications
You must be signed in to change notification settings - Fork 231
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
Support for sending multicast packets on multiple interfaces with a single socket #86
Comments
Thanks for the explanation and the thorough issue report! I suspect that the bindings here are pretty simple so I think they'd work well in this crate. In general this crate is "mostly single-line wrappers around system functionality", so as long as it fits that bill it should be good to add. |
Hi @alexcrichton, thanks for the comment. I've started exploring the design space and doing something usable across platforms required many lines of unsafe code. I've started to do that on a fork of socket2, but as it kept growing I felt like it would be a bit too big for the project. So I've moved those out to a new crate using some of the OS-specific traits to get access to the socket handle, which was great! I've put the functionality on multicast-socket, and maybe there are a few things that could be added back here, such as The actual Thanks a lot for providing the Feel free to either close the issue or suggest any of the code to be contributed back that fits project. Thanks for the attention! |
@bltavares what concretely has to be done to solve this issue? In other words what is socket2 missing (on the master branch)? |
I think we could close the issue, as it is already possible to use the
This is not required to work, more of a list of ideas when using socket2 on this specific use-case. Given the crate can be used through the |
Is Lines 65 to 78 in 9c4a404
A pr for this would definitely be accepted.
These would be a bit harder but we can work on it. At the very least we could expose the OS specific functions.
We expose Lines 318 to 328 in 9c4a404
And Lines 363 to 381 in 9c4a404
Or do you need access to |
|
Hi there @alexcrichton,
Thanks a lot for the project. It has helped me to get started with a multicast-based project, and it was amazing. I was able to send messages and find peers, until I couldn't anymore. I've dig deep into the depths of the network stack, to find, with amusement, that network is chaos.
One of my computers could find the other announcements, but the other computer would not find the first one. After some analyses, I realized this is related to having multiple interfaces, which is very common on laptops (wifi and cable) and Windows machines with HyperV (and WSL2). To my surprise, I could listen to multicast packets on any of the interfaces, and it would only send on a specific one instead of a broadcast to all.
socket2-rs
already supports most of the calls to have a "Single socket, multi interface listeners". If we bind to0.0.0.0
, we can use Socket::join_multicast_v4 for each interface ip (enumerating it is outside the package scope).As we bind to
0.0.0.0
, selecting the interface to use for sending the packets is delegated to the OS, and it might end-up selecting the interface that does not talk to the other computers, leading to partial discovery and something that I find very often with my dual network computer.I found this StackOverflow answer that shows that it would be possible to use the already available Socket::set_multicast_if_v4 call to determine which interface to use before sending the packet, so we can hop around to respond on the same interface that we received the packet.
As you may already know, the default socket API does not return the origin interface on the packet, which made me despaired to find alternatives and question my own sanity of why I'm shaving this yak. I was surprised to find some incantations using
IP_PKTINFO
and/or/I'm not sure anymoreIP_RECVIF
to load the information from a "magic" place of the network stack, usingCMSG_FIRSTHDR
,CMSG_NXTHDR
,CMSG_DATA
, and WSARecvMsg on Windows.It looks like this is what Avahi does the interface hopping already, in order to use a single socket to broadcast messages on all interfaces and locate peers happily
until the next network topology breaks it again.My question here; TL; DR; Would it make sense for the
socket2-rs
project to expose this extra information fromCMSG_DATA
andWSARecvMsg
?I do think I could make something as a separate crate, but it would also benefit a lot from the already available Windows/Unix infrastructure to build this project on the
sys.rs
file. If you do think it fits this project, I could try to get something running, but I would also be super ok to ask to have this on another crate.The alternative seems to be create a socket per interface and put a MultiSocket struct grouping them, which would avoid all this side-quest, but it is not resource efficient, and I'm afraid I would displease Ferris by opening too many sockets.
If you have any other suggestions from your experience, I would love to hear them as well! This is way out of my depth hehehe
Thank you a lot for your attention and time to read this up :)
(PS: I've tried to make this issue funny to read, and I'm sorry ahead of time if it ended up too verbose, or came up weird. This hobby project is leading to so many rabbit holes but I'm learning a lot!)
The text was updated successfully, but these errors were encountered: