[Trimming recipients and re-adding dev] To be clear, after the discussion we've just had and thinking some more a little, I think we only need two sockets at all: 1) one that only receives multicast (never sends anything) 2) one that sends unicast and multicast and receives unicast
This rests on the assumption that socket #1 can be joined to multiple multicast groups, one per interface, using IP(V6)_ADD_MEMBERSHIP. That socket must have SO_REUSEADDR enabled. For a dual-stack IPv4-IPv6 solution[1], we may need three sockets instead of two: socket #2 should be IPv6 with IPV6_V6ONLY = 0, so it can send and receive IPv4 packets. === Sending multicast (socket #2) === Using IP(V6)_MULTICAST_IF ancillary data in sendmsg is enough to indicate which interface the packet should be sent on. The sendmsg call needs to loop over all the enabled interfaces and send. === Receiving (sockets #1 and #2) === We'll need to setsockopt to enable IP_PKTINFO[2] and IPV6_RECVPKTINFO, since we need to know which interface the packet was received on. The reason we need that is that our sockets are bound to all interfaces, but the user may not want us to act on them all. Therefore, we need to implement a simple firewalling mechanism and drop packets from the wrong interfaces. Once that is done, we shouldn't need the interface information any more. This means all reception needs to use recvmsg(). === Sending unicast (socket #2) === To send a reply, we need the interface info only if the destination address is link-local. For IPv6 link-local, the interface index is already encoded in sockaddr_in6, so we won't need to keep an extra field anywhere else. I recommend ignoring IPv4 link-local (169.254.x.x) and assume no one does that. All IPv4 networks shall be stateful and your DHCP server is a single point of failure. If you don't like that, use IPv6. For global IPv4 and IPv6 addresses, we would let the operating system decide how to best route the packet. In most cases, there will be only one route anyway so there's no point in us trying to second-guess the OS. Multihoming is a feature: if there is more than one route to a given destination, the peer will identify us as the same resource from the unique ID that is present in the packet, not by source address. This means sendto() is enough to send unicast. [1] note: we may need to treat IPv4 and IPv6 completely separate, no dual stack, depending on how OIC determines it will do the migration [2] FreeBSD doesn't have IP_PKTINFO, so this needs to be protected under #ifdefs. FreeBSD has IP_RECVIF and the ancillary data is a struct sockaddr_dl. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4447 bytes Desc: not available URL: <http://lists.iotivity.org/pipermail/iotivity-dev/attachments/20150424/b365609d/attachment.p7s>
