I submitted JIRA IOT-497 to summarize this.

The secure multicast receiver can't be combined with the normal one because 
they should use different ports as well as being in different multicast groups, 
so I believe three descriptors are needed.

Descriptors fd1 and fd4 in IOT-497 could be combined as Thiago suggests, but 
why?  Sockets aren't expensive.  I aimed to reduce file descriptor usage to 
reduce complexity and size.  Overloading fd1 does neither.  Quite the opposite, 
in my mind.

I have chosen not to set IPV6_V6ONLY = 0 since not all stacks support it.  
Since sockets aren't expensive, having only one way of doing IPv6 rather than 
two simplifies the code.  The one way will add another socket and keep the code 
simple.

Firewalling is not in any IoTivity spec that I know.  Let's keep it simple 
until we understand the need.  We can always add RECVPKTINFO in if we need it 
since the effect is localized.

John

Thiago, I thought you were on vacation.


-----Original Message-----
From: Macieira, Thiago 
Sent: Friday, April 24, 2015 12:28 PM
To: ashok.channa at samsung.com; iotivity-dev at lists.iotivity.org
Cc: MyeongGi Jeong; Light, John J
Subject: Re: Change in iotivity[master]: Integrated WIFI/ETHERNET adapters to 
single IPAdapter.

[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

Reply via email to