Fwd: 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 23:27, vous avez écrit :
> Don,
>       I don't have a current copy of UNP, so I'm operating blind here. But,
> if I understand correctly, if I have a process with a socket  bound to
> INADDR_ANY:9462 and some other process joins, say, 239.0.0.1, then without
> your patch, packets sent to 239.0.0.1:9462 will be delivered, and with your
> patch they will not be delivered. Is that correct?

No, that's not exactly what I mean.  If both processes joined 239.0.0.1 on
their respective sockets, then they will both receive the multicast traffic
for 239.0.0.1:9462 with or without the patch.

The only difference would be if the processes joined different groups.  Then
the socket that bound INADDR_ANY:9462 would get all traffic sent to all the
groups, and the socket that bound 239.0.0.1:9462 would get only traffic sent
to 239.0.0.1:9462.

Let me give a better example that includes all the steps which might help me
explain what I mean.  This example will use three processes, P1, P2, and P3,
with a single UDP socket each, S1, S2, and S3 respectively (note that they
don't have to be different processes--it works exactly the same even if the
sockets belonged to the same process).  Also, let's assume any interface for
simplicity:

-- P1
- opens S1 and binds it to INADDR_ANY:9462 (this tells the os that if wants
all UDP traffic destined for port 9462)
- joins multicast group 239.0.0.1 on S1

-- P2
- opens S2 and binds it to 239.0.0.1:9462 (this tells the os that it only
wants UDP traffic destined for 239.0.0.1:9462.)
- joins multicast group 239.0.0.1 on S2

-- P3
- opens S2 and binds it to INADDR_ANY:9462 (just as P1)
- joins multicast group 239.0.0.2 on S3 (note a different group)

Current behavior:
S1 and S3 will receive multicast traffic for both groups, 239.0.0.1:9462 and
239.0.0.2:9462, even though they only joined one group each.  S2 will only
receive multicast traffic for 239.0.0.1:9462, since it bound the multicast
address as well as the port (this is the current workaround we use).

With patch:
S1 will receive only multicast traffic for 239.0.0.1:9462.  S2 will receive
only multicast traffic for 239.0.0.1:9462.  And S3 will receive only
multicast traffic for 239.0.0.2:9462.

This also works the same with multiple joins, but if you bind an address you
will silently only receive traffic sent to the address you bound (this is a
common mistake).  In the case of multiple, but different, joins on S1 and S2,
the sockets will only receive the traffic for the groups they joined with the
patch, but will receive all the traffic sent to all groups without the patch.

>       If so, a literal reading of RFC 1112 suggests that multicast packets
> should be treated like any other local addresses. And INADDR_ANY should
> match any local addresses, so that would imply that any unicast, broadcast
> or multicast packet delivered to a host that has that address configured
> should be delivered.

The patch is for function udp_v4_mcast_next() in linux/net/ipv4/udp.c and
only applies to filtering multicast dgrams.

>       I don't see any huge problem with limiting delivery to sockets that
> have actually joined the group, as long as that doesn't require the socket
> be bound to the particular multicast address (if I bind to INADDR_ANY:9462
> and join a group, I should definitely still receive multicasts on my
> INADDR_ANY socket).

Yes, this is what the patch does.  But it also filters out all the other
multicast groups that you didn't join.

>       But I also don't see any advantage.

It's a big advantage to us, since we can join multiple goups on the same
socket and know that they were addressed to the groups we joined.  Otherwise
we either get *all* the multicast traffic that any application on the box has
subscribed to, or use a socket for each group (which is the current
workaround).

It limits admittedly trivial and

> not-very-useful things, like sending a UDP "time" request to the NTP
> multicast address, or anything else where you're requesting service on a
> host identified by membership in a group not associated with that service.
> (for example, any UDP service to the "all routers" group) I do this sort of
> thing all the time "ping" to identify routers, NTP servers, etc. ; maybe
> other applications using UDP might also find that useful.

I don't follow what you mean here.  Since NTP only listens on 224.0.1.1, it
probably binds the address.  If so, then my patch would have no effect, since
it would find the joined group on the first loop and return a pointer to the
sock stucture--which is what it does right now.

>       Is the goal of your patch BSD compatibility, or is there some problem
> this causes? I think it's better that multicasts identify a set of
> machines, and filtering for services be left to the port (only). I think
> that's the intent of RFC 1112, whether or not BSD took it further.

If that's the case, i.e., filter on port only, then all applications will
have to burn a socket for each group or try to filter out all the crosstalk
themselves--which is slow and error prone.  Also, it has nothing to do with
BSD.  In fact, the current implementation is how the older BSD
implementations did it (according to Stevens, that is).

Finally, the current application of IPv6 that ships with Linux, does this
filtering (from linux/net/ipv6/mcast.c).  If you really want port-only
filtering, then you'd need cut this function out of the IPv6 implementation.
Notice that it does essentially what I'm advocating for IPv4:

int inet6_mc_check(struct sock *sk, struct in6_addr *addr)
{
	struct ipv6_mc_socklist *mc;

	read_lock(&ipv6_sk_mc_lock);
	for (mc = sk->net_pinfo.af_inet6.ipv6_mc_list; mc; mc=mc->next) {
		if (ipv6_addr_cmp(&mc->addr, addr) == 0) {
			read_unlock(&ipv6_sk_mc_lock);
			return 1;
		}
	}
	read_unlock(&ipv6_sk_mc_lock);

	return 0;
}

So, I'm just trying to get the IPv4 implementation to behave the same as IPv6
and IPv4 on Solaris and Windows, etc...  It shouldn't break anything, except
perhaps applications that are trying to snoop on all the other applications
on the box, since it's equivelent to promiscuous mode.

Btw, my previous patch didn't include the required locks, so I've included an
updated version below.

take care...
don

--- udp.c.old   Wed Nov  6 19:16:03 2002
+++ udp.c       Fri Nov  8 20:13:16 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,16 @@
                    (s->rcv_saddr  && s->rcv_saddr != loc_addr)         ||
                    (s->bound_dev_if && s->bound_dev_if != dif))
                        continue;
+               else {
+                       rtnl_shlock();
+                       for (mc=s->protinfo.af_inet.mc_list; mc; mc=mc->next)
{
+                               if (mc->multi.imr_multiaddr.s_addr ==
loc_addr)
+                                       break;
+                       }
+                       rtnl_shunlock();
+                       if (!mc)
+                               continue;
+               }
                break;
        }
        return s;

--
Don Hinton  <dhinton @ ieee.org>
Software Engineer
P.O. Box 23524, Alexandria, Virginia  22304

-------------------------------------------------------

-- 
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