Re: [PATCH] (IPv4) multicast group filtering doesn't work if socket only bound to a port

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David:

Le Vendredi 8 Novembre 2002 01:12, David Stevens a écrit :
> Don,
>       Multicast group membership is per-interface, not per-port. If an
> application binds to INADDR_ANY:9462 (UDP), it should receive any multicast
> UDP packets sent to port 9462, whether or not that application did the join
> for that multicast group. 

You are correct, but are talking about a lower level.  The problem with the 
current implementation, which differs from the IPv6 one btw, is that an 
application that binds INADDR_ANY:9462, as in your example, and subscribes to 
a multicast group, will still receive all the groups that were subscribed to 
by all the applications on the box.  

For example, if applicaiton binds a socket S1 to INADDR_ANY:9462 and 
subscribes to 239.255.0.1 and it is the only application on the box that has 
subscribed to a multicast group on port 9462, it will only receive traffic on 
addressed to 239.255.0.1:9462.  On the other hand, if any application 
(including this one) binds another socket S2 to INADDR_ANY:9462 and 
subscribes to 239.255.0.2, both sockets will receive the traffic destined for 
both groups.

Similarly, if an application joins a group, but
> never binds to a UDP port, the host should still answer, for example, ICMP
> echo requests sent to that multicast address.

But if it doesn't bind a port, it won't receive anything.  But that's not the 
issue.  The issue is that the IPv4 udp layer does not perform perfect 
filtering of multicast groups for sockets that have bound a port and 
subscribed to one or more groups.  The socket should only receive traffice 
for groups it has joined.  

Please see Stevens' discussion of filtering in UNPv1 page 492 for a much 
better explaination than I can provide.

I have a test program I added to the ACE distribution that tests this and has 
been run on several different platforms, e.g., Solaris, OpenBDS, Windows, 
etc, and only Linux has a problem with receiving traffic on a socket for a 
group that was not joined.  The current work around is to bind the multicast 
group and only subscribe to a single group per socket--but that wastes a lot 
of sockets... 

take care...
don

>
>                               +-DLS
>
>
> Don Hinton <dhinton@ieee.org>@vger.kernel.org on 11/07/2002 03:55:05 PM
>
> Please respond to dhinton@ieee.org
>
> Sent by:    linux-net-owner@vger.kernel.org
>
>
> To:    linux-net@vger.kernel.org
> cc:
> Subject:    [PATCH] (IPv4) multicast group filtering doesn't work if socket
>        only bound to a port
>
>
>
> Hi:
>
> The IPv4 stack, unlike IPv6, doesn't filter mcast groups for sockets only
> bound to a port, but not an address, based on subscriptions.  So even
> if you only subscribe to a single group, but don't bind an address to the
> socket, you'll receive all mcast dgrams delivered to the udp layer, i.e.,
> all subscribed to groups no matter which application actually made the
> subscription.
>
> The following patch fixes the problem in a manner similar to the way the
> IPv6 stack does it.  It's against 2.4.19:
>
> --- linux-2.4.19/net/ipv4/udp.c.old     Wed Nov  6 19:16:03 2002
> +++ linux-2.4.19/net/ipv4/udp.c Thu Nov  7 20:43:00 2002
> @@ -82,6 +82,7 @@
>  #include <linux/mm.h>
>  #include <linux/config.h>
>  #include <linux/inet.h>
> +#include <linux/igmp.h>
>  #include <linux/netdevice.h>
>  #include <net/snmp.h>
>  #include <net/ip.h>
> @@ -267,6 +268,7 @@
>                                              int dif)
>  {
>         struct sock *s = sk;
> +       struct ip_mc_socklist *mc;
>         unsigned short hnum = ntohs(loc_port);
>         for(; s; s = s->next) {
>                 if ((s->num != hnum)                                    ||
> @@ -275,6 +277,14 @@
>                     (s->rcv_saddr  && s->rcv_saddr != loc_addr)         ||
>                     (s->bound_dev_if && s->bound_dev_if != dif))
>                         continue;
> +               else {
> +                       for (mc=s->protinfo.af_inet.mc_list; mc;
> mc=mc->next) {
> +                               if (mc->multi.imr_multiaddr.s_addr ==
> loc_addr)
> +                                       break;
> +                       }
> +                       if (!mc)
> +                               continue;
> +               }
>                 break;
>         }
>         return s;
>
>
> take care...
> don

-- 
Don Hinton  <dhinton @ ieee.org> 
Software Engineer
P.O. Box 23524, Alexandria, Virginia  22304
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux