Messages in this thread Patch in this message | | | From | Mathieu Seigneurin <> | Subject | Multicast packet delivery question/issue (2.4.10) | Date | Tue, 23 Oct 2001 12:58:18 +0200 |
| |
Hello all,
i'm having some issues with incoming multicast packets not being directed to the sockets I was expecting (ipv4, kernel 2.4.10 w/ext3, realtek RTL-8139 NIC).
Short description: ------------------- Here's what I do (from a Sun or IBM 1.3 Java VM): - Create mcast socket A and set it up to listen on 239.0.0.1:12345 - Create mcast socket B and set it up to listen on 239.0.1.1:12345 (same process or not, though that shouldn't matter, really) (The actual addresses have nothing to do with it, it's just the port that need to be the same) Once the two sockets are up, if I send some multicast traffic on 239.0.0.1, both A and B receive it. Same thing with the other address. Basically, A and B can receive traffic from addresses they've not joined.
Now I guess the application should be able to filter the bad traffic out, but this behavior seems a bit odd. Is it the expected behavior ? (it isn't on the Solaris boxes I have access to, as far as I can tell. I tried it after I was about sure that my code wasn't just complete crap.) Do I need to send more info (hw/sw) for this to be undestandable ?
Any info appreciated. (I have not subscribed to this list directly, but get the digest version from lists.us.dell.com) (I've tried searches on google and the lkml archives but coulnd't find anything.) ------------------
Now for my utter newbie wonderings inside the ipv4 kernel code, if you're interested.
Since I found this a bit strange, I looked in kernel-docs.txt for some pointers on networking, and found some real good doc, and started looking. I found the following:
- multicast addresses a group has joined are stored in the list socket->protinfo.af_inet.mc_list - that list is not checked (as far as I could determine, which is pretty weak) in the udp delivery code.
I then examined the udp_v4_mcast_next function which seemed to be where all the action was going on. That function does filter on the port, but only checks the socket->daddr and socket->rcv_saddr fields which in my limited testing were alway 0 (and thus ignored by the filter) for my multicast sockets. That was consistent with what I was experiencing on the application level. Then, since I had nothing better to do, I gave a shot at actually changing the code and ended up with the diff at the end of this message. Now obviously I have no idea of the implications of such a thing - but if someone wants to tell me if this a good thing or not (I'm guessing it might actually break things that were relying on the current behavior), I'd be happy to hear about it.
Thanks a lot for having read this far! Mathieu Seigneurin CS student in Paris, France, and great fan of Linux and the people behind it.
--- ./linux-2.4.10-ext3.orig/net/ipv4/udp.c Fri Sep 7 20:01:21 2001 +++ ./linux-2.4.10-ext3.new/net/ipv4/udp.c Tue Oct 23 12:04:25 2001 @@ -87,6 +87,7 @@ #include <net/ip.h> #include <net/protocol.h> #include <linux/skbuff.h> +#include <linux/igmp.h> #include <net/sock.h> #include <net/udp.h> #include <net/icmp.h> @@ -268,6 +269,7 @@ { struct sock *s = sk; unsigned short hnum = ntohs(loc_port); + struct ip_mc_socklist *i; for(; s; s = s->next) { if ((s->num != hnum) || (s->daddr && s->daddr!=rmt_addr) || @@ -275,7 +277,13 @@ (s->rcv_saddr && s->rcv_saddr != loc_addr) || (s->bound_dev_if && s->bound_dev_if != dif)) continue; - break; + // We know this packet is coming from a mcast port + // that the packet is from. We need to check + // if the user also joined this mcast address. + for (i=s->protinfo.af_inet.mc_list; i; i=i->next) + if (i->multi.imr_multiaddr.s_addr == loc_addr) + break; // out of the mc_list loop + if (i) break; // out of the sock list } return s; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |