I have a Linux host with two Ethernet interfaces. I have a program
that joins and listens to a multicast group. On the command line, I
tell the program the multicast address and port number, and the name
of the network interface (eth0 or eth1) that I want it to use.
If I run one instance of the program, everything is fine. However, if
I start up a second instance of the program and have it listen to the
same multicast group as the first instance, but on the other ethernet
interface, both instances of the program start receiving two copies of
every packet. The obvious explanation is that a copy of each packet is
being received from each ethernet interface. This is not what I want.
I only want each program to receive packets from the interface that it
specified when it joined the multicast group.
Is the duplication a result of a bug in my program, or is this the
expected behavior?
Here is a stripped-down version of my code that creates the socket.
The function arguments specify the multicast address, the multicast
port, and the index of the network interface to use. The command-line
argument that defines the network interface as a string has been
converted to an unsigned int for this function by calling
if_nametoindex. This code is mostly extracted from "Unix Network
Programming" by Richard Stevens:
#include <sys/socket.h>
#include <assert.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <netdb.h>
int create_mc_socket(const char *addr, const char *port, unsigned int
interface)
{
int s, r, option;
struct addrinfo hints, *res;
struct group_req req;
s = socket(AF_INET, SOCK_DGRAM, 0);
assert(s >= 0);
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
r = getaddrinfo(addr, port, &hints, &res);
assert(r == 0 && res->ai_next == NULL);
option = 1;
r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &option, sizeof
(option));
assert(r == 0);
r = bind(s, res->ai_addr, res->ai_addrlen);
assert(r == 0);
req.gr_interface = interface;
memcpy(&req.gr_group, res->ai_addr, res->ai_addrlen);
r = setsockopt(s, IPPROTO_IP, MCAST_JOIN_GROUP, &req, sizeof
(req));
assert(r == 0);
freeaddrinfo(res);
return s;
}
OS details:
SLES VERSION=10 PATCHLEVEL=1
kernel: 2.6.16.46-0.12-bigsmp
Thanks for any info.
Jon
|