20.9 Multicast

Team-FLY

The connectionless protocols that we have been discussing thus far are unicast or point-to-point, meaning that each message is sent to a single communication endpoint. In multicast , by contrast, a single send call can cause the delivery of a message to multiple communication endpoints.

Multicasting, which is usually implemented over an existing network structure, supports the abstraction of a group of processes that receive the same messages. Reliable multicast delivers messages exactly once to the members of the group. Ordered multicast delivers messages to each group member in the same order.

This section focuses on low-level IP multicasting available to applications through UDP sockets. Unlike unicast operations, several processes on the same host can receive messages on communication endpoints bound to the same multicast port.

IP multicast groups are identified by a particular IP address. A process joins a multicast group by binding a UDP socket ( SOCK_DGRAM ) to its multicast address and by setting appropriate socket options. The socket options inform the network interface that incoming messages for the indicated multicast address should be forwarded to the socket. If several processes on the same machine have joined a multicast group, the network interface duplicates each incoming message for all group members. The socket options also cause the host to inform LAN routers that processes on this host have joined the group. If a multicast message arrives at a LAN router, the router forwards the message on all LANs that have at least one host with a member process.

20.9.1 Multicast Addressing

This book discusses only IPv4 multicast. IPv4 multicast addresses are in the range 224.0.0.0 through 239.255.255.255 . IPv4 hosts and routers are not required to support multicasting. Hosts that support multicasting must join the all-hosts group 224.0.0.1 . Routers that support multicasting must join the all-routers group 224.0.0.2 . The addresses used to specify multicast groups are divided into four groups according to the scope of the group. The multicast scope refers to how far from the source multicast messages should be distributed.

Link-local multicast addresses are in the range 224.0.0.0 through 224.0.0.255 . Link-local addresses are only for machines connected at the lowest level of topology of the network. Multicast messages with these addresses are not forwarded by a multicast router.

Global multicast addresses are in the range 224.0.1.0 to 238.255.255.255 . Global addresses should be forwarded by all multicast routers. Currently, multicast is not truly global because some routers do not support multicast and many router administrators have disabled global multicast for security reasons. Also, there is no political mechanism for reserving a global multicast address and port.

Addresses in the rest of the range, 239.0.0.0 to 239.255.255.255 , are called administratively scoped multicast addresses . These addresses are meant to be used inside an organization. They should not be forwarded outside the administrative control of the organization, since they are not guaranteed to be unique.

Table 20.2 gives the prototypes of the two UICI UDP functions needed to support multicast communication. The u_join function creates a UDP socket and calls the socket options needed for the socket to join a particular multicast group. The u_leave function calls a socket option to leave the multicast group. After u_leave returns, the socket is still open and bound to the same port, but it can no longer receive multicast messages.

Table 20.2. Summary of UICI UDP multicast calls.

UICI UDP

description

 int u_join(char *IP_address,        u_port_t port,        u_buf_t *mcast_info) 

creates UDP socket for multicast and binds socket to port returns the socket file descriptor

 int u_leave(int fd, u_buf_t *mcast_info) 

leaves multicast group

The IP_address parameter of u_join holds a string representing the multicast address in dotted form. The port parameter is the multicast port number. The mcast_info parameter points to a user -supplied u_buf_t structure. If successful, u_join returns the file descriptor of the newly created socket and fills in the user-supplied u_buf_t structure with the multicast address for later use with u_sendto or u_leave . If successful, u_leave returns 0. If unsuccessful , u_join and u_leave return “1 and set errno .

The u_join function sets up a socket that can both send to and receive from the multicast group, but a socket does not have to belong to a multicast group to send to it . The simple UDP client in Program 20.2 can be used for sending. All that is necessary is for sendto to use a valid multicast destination address.

Program 20.16 shows a program that receives multicast messages. It takes two command-line arguments: the multicast IP address in dotted form and the multicast port number. The program first joins the multicast group with u_join and then echoes what it receives to standard output along with the name of the sending host.

Program 20.16 multicast_receiver.c

A multicast receiver that echoes what it receives to standard output .

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "restart.h" #include "uiciudp.h" #define BUFSIZE 1024 int main(int argc, char *argv[]) {    char buf[BUFSIZE];    ssize_t bytesread;    char hostinfo[BUFSIZE];    int mcastfd;    u_buf_t mcastinfo;    u_port_t mcastport;    u_buf_t senderinfo;    if (argc != 3) {       fprintf(stderr, "Usage: %s multicast-address multicast-port\n", argv[0]);       return 1;    }    mcastport = (u_port_t)atoi(argv[2]);          /* join the multicast group */    if ((mcastfd = u_join(argv[1], mcastport, &mcastinfo)) == -1) {       perror("Failed to join multicast group");       return 1;    }    u_gethostinfo(&mcastinfo, buf, BUFSIZE);    fprintf(stderr, "Info: %s\n", buf);    fprintf(stderr, "mcastfd is %d\n", mcastfd);                  /* read information from multicast, send to standard output */    while ((bytesread = u_recvfrom(mcastfd, buf, BUFSIZE, &senderinfo)) > 0) {       u_gethostinfo(&senderinfo, hostinfo, BUFSIZE);       if ((r_write(STDOUT_FILENO, hostinfo, strlen(hostinfo)) == -1)            (r_write(STDOUT_FILENO, buf, bytesread) == -1)) {          perror("Failed to echo message received to standard output");          break;       }    }    return 0; } 

20.9.2 Implementation of u_join

Program 20.17 implements the u_join function. The application first creates a UDP socket . Next, the application joins the multicast group by using setsockopt with level IPPROTO_IP , option name IP_ADD_MEMBERSHIP , and an option value specifying the multicast address. These options instruct the link layer of the host's network subsystem to forward multicast packets from that address to the application. The application can then use u_sendto and u_recvfrom (and the underlying sendto and recvfrom ) as before.

Program 20.17 u_join.c

An implementation of u_join .

 #include <arpa/inet.h> #include <sys/socket.h> #include "uiciudp.h" int u_join(char *IP_address, u_port_t port, u_buf_t *ubufp) {    int mcastfd;    struct ip_mreq tempaddress;    if ((mcastfd = u_openudp(port)) == -1)       return mcastfd;    tempaddress.imr_multiaddr.s_addr = inet_addr(IP_address);    tempaddress.imr_interface.s_addr = htonl(INADDR_ANY);         /* join the multicast group; let kernel choose the interface */    if (setsockopt(mcastfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,                    &tempaddress, sizeof(tempaddress)) == -1)       return -1;    ubufp->sin_family = AF_INET;    ubufp->sin_addr.s_addr = inet_addr(IP_address);    ubufp->sin_port = htons((short)port);    return mcastfd; } 

20.9.3 Implementation of u_leave

Program 20.18 implements the u_leave function. The u_leave function informs the network subsystem that the application is no longer participating in the multicast group by calling by setsockopt with the IP_DROP_MEMBERSHIP option. Since u_leave does not close it, the mcast socket can still send multicast messages and receive non-multicast messages.

Program 20.18 u_leave.c

An implementation of u_leave .

 #include <string.h> #include <sys/socket.h> #include "uiciudp.h" int u_leave(int mcastfd, u_buf_t *ubufp) {    struct ip_mreq tempaddress;    memcpy(&(tempaddress.imr_multiaddr),          &(ubufp->sin_addr), sizeof(struct in_addr));    tempaddress.imr_interface.s_addr = htonl(INADDR_ANY);    return setsockopt(mcastfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,                    &tempaddress, sizeof(tempaddress)); } 
Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net