Subject: Re: kern/23221: setsockopt IP_ADD_MEMBERSHIP arguments not honored
To: Robert Elz <kre@munnari.OZ.AU>
From: William A.Carrel <william.a@carrel.org>
List: tech-net
Date: 10/24/2003 10:24:20
On Friday, October 24, 2003, at 3:39AM, Robert Elz wrote:
> However, you're making an assumption that the process didn't ask to
> receive the packets. Unless you're talking about link scope multicast
> addresses (or similar) - which I don't think were what your PR used as
> an example, and certainly weren't in your proposed patch, shouldn't a
> packet transmitted to a particular multicast address go everywhere?
> What difference does it make which interface happens to have been used
> (other than to the source address when the application transmits
> packets,
> and hence the forwarding path).
>
> My assumption when I bind to a particular (non limited scope) multicast
> address, is that I am going to receive *every* packet sent to (the
> correct port) using that multicast address, not some subset of them.
>
> If the issue is just that the "same" packets get delivered on multiple
> interfaces, and hence the application gets multiple copies (which I
> don't
> think is really what you're concerned about, but just in case) then I
> believe that's simply a fact of multicast life - packets can be
> delivered more than once.
>
> What process or application is actually depending upon different
> applications running on the same address and port, but binding to
> different interfaces, actually receiving different sets of packets,
> on something that isn't a limited scope address?
I handle multicast DNS on a machine that sits on a network border.
Multicast DNS is link-local multicast at 224.0.0.251:5353. I open a
separate socket for each of the networks. Each socket has membership
on one interface and only one interface so I can intelligently direct
responses to queries. With this bug, incoming packets on either
interface wind up in the queue for both sockets. I don't know where to
respond to with out broadcasting across both networks, which is
wasteful in a crowded network environment. Worse yet, if I want to
echo certain queries across the network border I could wind up causing
duplicate traffic by resending a query back to the interface it
originally came from. With two hosts doing this, I wind up with a
multicast storm saturating my network.
Potentially, I could go ask for the complete network configuration for
the machine and try to use the source address on the packet to help me
determine where the packet came from so I can intelligently send the
response. This won't work as soon as I stop talking about link-local
multicast though, as the addresses may not provide me with an adequate
clue as to where the packets came from. Plus caring a whole lot about
the source address on the packet seems somewhat antithetical to how to
play and win a multicast environment. This mucking about would not be
required if the kernel was behaving as the documentation says it
should.
A socket with multicast memberships should only receive packets
intended for its memberships. Multicast memberships include both a
specific multicast address and a specific interface. Q.E.D.
In the existing implementation your multicast socket, despite having
only asked for membership on a specific interface, could wind up
receiving traffic from any possible subset of available interfaces that
include the one you requested. For applications whose behavior hinges
on which interface a multicast packet arrived on this is a disaster.
As I mentioned in the last email, the patch should not cause any change
in behavior in existing programs, and has the potential to reduce the
heavy lifting that the program needs to do in order to handle the
packets in an efficient manner. Apple's example multicast DNS
responder code contains a large block devoted to working around this
bug to try and determine what interface a packet came in on. This same
hack can be avoided in other such projects with this small patch to
bring about the correct behavior in multicast DNS handling.
Thanks for reading.