John: So I caught up with Dave Thaler here at the IETF...
He said that NO UDP socket that has NOT joined a multicast group should ever receive a packet sent to a multicast address. He also said this was part of the POSIX API and the way all Unix machines worked. So.. no it is a bug and the fix is correct. R On Mar 29, 2011, at 2:01 PM, John Baldwin wrote: > On Wednesday, January 19, 2011 2:07:16 pm Randall Stewart wrote: >> Author: rrs >> Date: Wed Jan 19 19:07:16 2011 >> New Revision: 217592 >> URL: http://svn.freebsd.org/changeset/base/217592 >> >> Log: >> Fix a bug where Multicast packets sent from a >> udp endpoint may end up echoing back to the sender >> even with OUT joining the multi-cast group. >> >> Reviewed by: gnn, bms, bz? >> Obtained from: deischen (with help from) >> >> Modified: >> head/sys/netinet/udp_usrreq.c >> >> Modified: head/sys/netinet/udp_usrreq.c >> > ============================================================================== >> --- head/sys/netinet/udp_usrreq.c Wed Jan 19 18:20:11 2011 >> (r217591) >> +++ head/sys/netinet/udp_usrreq.c Wed Jan 19 19:07:16 2011 >> (r217592) >> @@ -479,11 +479,13 @@ udp_input(struct mbuf *m, int off) >> * and source-specific multicast. [RFC3678] >> */ >> imo = inp->inp_moptions; >> - if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) && >> - imo != NULL) { >> + if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { >> struct sockaddr_in group; >> int blocked; >> - >> + if(imo == NULL) { >> + INP_RUNLOCK(inp); >> + continue; >> + } >> bzero(&group, sizeof(struct sockaddr_in)); >> group.sin_len = sizeof(struct sockaddr_in); >> group.sin_family = AF_INET; > > So it turns out that this is a feature, not a bug, and is how multicast has > always worked. Specifically, if you bind a UDP socket with a wildcard > address, it should receive all traffic for the bound port, unicast or > multicast. When you join a group, you have switched the socket into a mode > where it now has a whitelist of acceptable multicast groups, but if a socket > has no joined groups, it should receive all multicast traffic, not none. > This > change breaks that. > > I did not find this behavior intuitive at first, but it does seem to be > required. Note the description of IP_ADD_MEMBERSHIP from RFC 3678 for > example: > > 3. Overview of APIs > > There are a number of different APIs described in this document that > are appropriate for a number of different application types and IP > versions. Before providing detailed descriptions, this section > provides a "taxonomy" with a brief description of each. > > There are two categories of source-filter APIs, both of which are > designed to allow multicast receiver applications to designate the > unicast address(es) of sender(s) along with the multicast group > (destination address) to receive. > > o Basic (Delta-based): Some applications desire the simplicity of > a delta-based API in which each function call specifies a > single source address which should be added to or removed from > the existing filter for a given multicast group address on > which to listen. Such applications typically fall into either > of two categories: > > + Any-Source Multicast: By default, all sources are accepted. > Individual sources may be turned off and back on as needed > over time. This is also known as "exclude" mode, since the > source filter contains a list of excluded sources. > > + Source-Specific Multicast: Only sources in a given list are > allowed. The list may change over time. This is also known > as "include" mode, since the source filter contains a list > of included sources. > > This API would be used, for example, by "single-source" > applications such as audio/video broadcasting. It would > also be used for logical multi-source sessions where each > source independently allocates its own Source-Specific > Multicast group address. > > > ..... > > 4.1.1. IPv4 Any-Source Multicast API > > The following socket options are defined in <netinet/in.h> for > applications in the Any-Source Multicast category: > > Socket option Argument type > IP_ADD_MEMBERSHIP struct ip_mreq > IP_BLOCK_SOURCE struct ip_mreq_source > IP_UNBLOCK_SOURCE struct ip_mreq_source > IP_DROP_MEMBERSHIP struct ip_mreq > > IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP are already implemented on > most operating systems, and are used to join and leave an any-source > group. > > IP_BLOCK_SOURCE can be used to block data from a given source to a > given group (e.g., if the user "mutes" that source), and > IP_UNBLOCK_SOURCE can be used to undo this (e.g., if the user then > "unmutes" the source). > > As to why the packets loop back to the receiver, I believe that is a separate > issue on the output side, not the receive side. > > -- > John Baldwin > ------------------------------ Randall Stewart 803-317-4952 (cell) _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"