setsockopt IP_ADD_MEMBERSHIP not honored

Joshua Graessley jgraessley at apple.com
Tue Oct 21 17:12:40 PDT 2003


Sounds good to me :)

At the very least, this would improve the performance of the 
mDNSResponder. mDNSResponder has some additional code to get the 
interface the packet was received on so it can filter out the packet if 
it wasn't received on the interface that socket is bound to/associated 
with. This results in a packet being copied multiple times (once for 
every mDNSResponder socket) from the kernel to user space only to have 
all but one of those packets discarded.

-josh

On Oct 21, 2003, at 2:02 PM, William A.Carrel wrote:

>> Some applications may rely on this behavior, so it might be unwise to 
>> change it. If you're going to make this change, you should probably 
>> make it some sort of socket option that applications can opt in to on 
>> a per socket basis.
>
> Relying on this behavior doesn't seem to make sense.  It would be 
> relying on the kernel to let other programs to make you receive 
> unintended multicast packets.  It would also be relying on behavior 
> contrary to the documentation.
>
> The only change in behavior would be if the program presumes someone 
> else is holding memberships on all the interfaces (on its behalf) so 
> it only has to open one.  For example, in the case of multicast DNS, 
> if the program is really wanting to listen for mDNS traffic on all 
> interfaces, it needs to be adding membership on all interfaces.  It 
> would be broken behavior on the part of the application to add 
> membership to the multicast address on one interface and trust that 
> someone else has memberships to that multicast address on all the 
> other interfaces, so it can get the multicast traffic for all 
> interfaces.  The example code from Apple in 
> mDNSResponder-58/mDNSPosix/mDNSPosix.c (SetupSocket() at line 464) 
> also seems to acknowledge that the multicast socket is only handling 
> multicast for a specific interface.
>
> If a program really wants to get the multicast traffic on all 
> interfaces, then it needs to add membership for all the interfaces.  
> And if it holds membership on all the interfaces, my suggested fix 
> will not keep it from receiving the packets that it wants destined for 
> it.   As such, I don't see the potential for a POLA violation in the 
> suggested fix.
>
> From the manpage:
>      A host must become a member of a multicast group before it can 
> receive
>      datagrams sent to the group.  To join a multicast group, use the
>      IP_ADD_MEMBERSHIP option:
>
>      struct ip_mreq mreq;
>      setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
>
>      where mreq is the following structure:
>
>      struct ip_mreq {
>          struct in_addr imr_multiaddr; /* multicast group to join */
>          struct in_addr imr_interface; /* interface to join on */
>      }
>
>      imr_interface should be INADDR_ANY to choose the default 
> multicast inter-
>      face, or the IP address of a particular multicast-capable 
> interface if
>      the host is multihomed.  Membership is associated with a single 
> inter-
>      face; programs running on multihomed hosts may need to join the 
> same
>      group on more than one interface.  Up to IP_MAX_MEMBERSHIPS 
> (currently
>      20) memberships may be added on a single socket.
>
> The assertion that "membership is associated with a single interface" 
> is false under the current implementation.  Membership is, at the 
> moment, associated with the interface you specified to join on, and 
> any other interfaces that any other processes on the entire system 
> (possibly even processes in jails) have joined the same multicast 
> address on.
>
> W. Richard Stevens wrote similarly on page 496 of UNP Vol. 1 (2nd 
> ed.).  "Join a multicast group on a specified local interface. ... If 
> the local interface is specified as the wildcard address (INADDR_ANY 
> for IPv4)..., then the local interface is chosen by the kernel. ... 
> More than one join is allowed on a given socket...  This can be used 
> on a multihomed host where, for example, one socket is created and 
> then for each interface a join is performed for a given multicast 
> address."
>
> It seems odd that someone would join on a specified local interface 
> and then start receiving packets on from an interface other than the 
> one they had specified.  The descriptions given both by Stevens, by 
> Apple's mDNS example code and in the ip(4) man page run counter to the 
> current behavior, hence the code I presented a moment ago to bring the 
> behavior in line with the documentation.
>


More information about the freebsd-net mailing list