Add multicast group membership (join/leave) to the IP and stack interfaces - #540
Add multicast group membership (join/leave) to the IP and stack interfaces#540tmcgilchrist wants to merge 2 commits into
Conversation
|
Thanks for your work. I'm no expert in multicast. From the API side, I have some questions:
The comment you inserted "IGMP membership reports are only needed for non link-local groups and are left as future work" -- is it worth to document this in the API? How does this solve #498? How can a listen call now specify to only accept multicast packets? (I don't remember what use case I had in mind when I opened #498 to be honest) |
Yes the For now I'm leaving the IGMP implementation as future work, I don't strictly need it for mDNS.
Yes, something like
No, sending multicast packets already works. This PR is receive-only.
This PR adds group membership, which is how I interpreted #498 when I read "I'm only interested in multicast packets". I assumed you wanted more control over which packets you needed to process, which is partially there with the filtering being done in this change but only on the receive side for multicast. |
A responder for a link-local multicast protocol such as mDNS/DNS-SD
needs to receive UDP datagrams sent to a multicast
group (e.g. 224.0.0.251), but the stack offers no way to join one:
- the direct IPv4 stack discards any datagram whose destination is not its
own address or a broadcast (static_ipv4.ml `of_interest`)
- the socket stack never issues IP_ADD_MEMBERSHIP.
Add join_multicast_group / leave_multicast_group to Tcpip.Ip.S and
Tcpip.Stack.V4V6:
- Static_ipv4 records joined groups and accepts datagrams addressed to them
at input. On a directly attached link the ethernet layer already delivers
multicast frames, so link-local groups (224.0.0.0/24) need no IGMP,
membership reports for other groups are left as future work.
- The IPV4V6 dual stack routes join/leave to the v4 or v6 layer, IPv6 (MLD)
is a no-op for now.
- The socket UDP stack performs IP_ADD_MEMBERSHIP on each bound fd (and fds
bound later), remembering the groups; a v4 group on the default dual-stack
socket is best-effort (logged on failure).
- The socket IP shim and v6 socket hold no state (no-op).
Requested in mirage-tcpip mirage#362 and mirage#498.
786b9a3 to
477c7c5
Compare
Adds join_multicast_group / leave_multicast_group to Tcpip.Ip.S and Tcpip.Stack.V4V6 so a stack can receive datagrams sent to a multicast group (the capability requested in #362 and #498) and what mDNS/DNS-SD (RFC 6762/6763) needs to answer queries on 224.0.0.251.
Problem: No way to join a group: the direct IPv4 stack drops any non-own-address/non-broadcast destination (static_ipv4.ml of_interest), the socket stack never issues IP_ADD_MEMBERSHIP. So a responder can announce but never receive.
Change
We add these functions to join and leave a multicast group:
224.0.0.0/24range, which includes mDNS's224.0.0.251) because switches flood that range and routers never forward it, so frames arrive without any on-wire membership announcement (ethernet already admits the multicast MAC). Routable (non-link-local) groups additionally require IGMP membership reports so the network forwards their traffic. Sending those, together with an IGMP implementation, which mirage-tcpip currently lacks, is left as future work.Testing: Wired into a MirageOS mDNS responder (dns-mdns-mirage) that I'm working on, it joins 224.0.0.251 at startup and is then discovered and resolved by stock Avahi, on both the unix target (direct stack over a tap) and Solo5/spt. Without this change the direct stack drops the queries and the responder is invisible.
Closes #362, #498.