[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>

Reply via email to