Subject: Re: Revised a little, was Re: Multicast oddity
To: Bill Studenmund <wrstuden@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: tech-net
Date: 04/29/2005 20:09:49
Turns out my printfs were somehow messed up. Now the code's reporting it
recvfrom()s the loopback address, and then does a sendto to it.
So we have a valid destdir, and we're a socket bound to unspec in a
multicast group.
I wonder what happens if the same socket should get the packet as sent
it. But since the packet is queued on the IP input queue, this
special case should not matter.
The one thing that may be going on is that when we join the multicast
group, we don't specify which interface to use, we use the "default"
interface. I bet that's not being remembered right...
It should be looked up at join time, and remembered as an ifnet *.
This code has been around forever (well, probably late 80s), and I
doubt it is broken. In ip_setmoptions:
/*
* If no interface address was provided, use the interface of
* the route to the given multicast address.
*/
if (in_nullhost(mreq->imr_interface)) {
bzero((caddr_t)&ro, sizeof(ro));
ro.ro_rt = NULL;
dst = satosin(&ro.ro_dst);
dst->sin_len = sizeof(*dst);
dst->sin_family = AF_INET;
dst->sin_addr = mreq->imr_multiaddr;
rtalloc(&ro);
if (ro.ro_rt == NULL) {
error = EADDRNOTAVAIL;
break;
}
ifp = ro.ro_rt->rt_ifp;
rtfree(ro.ro_rt);
} else {
ifp = ip_multicast_if(&mreq->imr_interface, NULL);
}
/*
* See if we found an interface, and confirm that it
* supports multicast.
*/
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
error = EADDRNOTAVAIL;
break;
}
Typically the interface with the default route will be found. On a
machine with one Ethernet, the right thing happens - the group is
joined on "the" interface.
Being joined should have absolutely nothing to do with sending.
There is no requirement that a socket be joined to a group to send to
it (and if it snuck in it's a bug - that violates the RFC1112
multicast service model).
Note that a socket has a default interface for where to send multicast
packets (see netinet/ip_output.c:ip_setmoptions and IP_MULTICAST_IF).
But this should not matter when sending to 127.0.0.1, since that's not
a multicast address.
--
Greg Troxel <gdt@ir.bbn.com>