Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
6.  Socket Interfaces Using Multicast Sending IPv4 Multicast Datagrams  Previous   Contents   Next 
   
 

Receiving IPv4 Multicast Datagrams

Before a host can receive IP multicast datagrams, it must become a member of one or more IP multicast groups. A process can ask the host to join a multicast group by using the following socket option:

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) 

where mreq is the structure:

    struct ip_mreq {
        struct in_addr imr_multiaddr;   /* multicast group to join */
        struct in_addr imr_interface;   /* interface to join on */
    }  

Each membership is associated with a single interface and you can join the same group on more than one interface. Specify the imr_interface address as in6addr_any to choose the default multicast interface, or specify one of the host's local addresses to choose a particular (multicast-capable) interface.

To drop a membership, use:

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))  

where mreq contains the same values used to add the membership. Closing a socket or killing the process that holds the socket drops the memberships associated with that socket. More than one socket can claim a membership in a particular group and the host remains a member of that group until the last claim is dropped.

If any socket claims membership in the destination group of the datagram, the kernel IP layer accepts incoming multicast packets. A given socket's receipt of a multicast datagram depends on the socket's associated destination port and memberships, or the protocol type for raw sockets, just as with unicast datagrams. To receive multicast datagrams sent to a particular port, bind to the local port, leaving the local address unspecified (such as INADDR_ANY).

More than one process can bind to the same SOCK_DGRAM UDP port if the bind(3SOCKET) is preceded by:
    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  
In this case, every incoming multicast or broadcast UDP datagram destined for the shared port is delivered to all sockets bound to the port. For backwards compatibility reasons, this does not apply to incoming unicast datagrams. Unicast datagrams are never delivered to more than one socket, regardless of how many sockets are bound to the datagram's destination port. SOCK_RAW sockets do not require the SO_REUSEADDR option to share a single IP protocol type.

The definitions required for the new, multicast-related socket options are found in <netinet/in.h>. All IP addresses are passed in network byte-order.

Sending IPv6 Multicast Datagrams

To send an IPv6 multicast datagram, specify an IP multicast address in the range ff00::0/8 as the destination address in a sendto(3SOCKET) call.

By default, IP multicast datagrams are sent with a hop limit of one, which prevents them from being forwarded beyond a single subnetwork. The socket option IPV6_MULTICAST_HOPS allows the hop limit for subsequent multicast datagrams to be set to any value from 0 to 255, to control the scope of the multicasts:
    uint_l;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,sizeof(hops))

You cannot transmit multicast datagrams with a hop limit of zero on any subnet, but you can deliver them locally if:

  • The sending host belongs to the destination group

  • Multicast loopback on the sending socket is enabled (see below)

You can deliver multicast datagrams with a hop limit greater than one to more than one subnet if the first-hop subnet attaches to one or more multicast routers. The IPv6 multicast addresses, unlike their IPv4 counterparts, contain explicit scope information encoded in the first part of the address. The defined scopes are (where X is unspecified):

ffX1::0/16

Node-local scope -- restricted to the same node

ffX2::0/16

Link-local scope

ffX5::0/16

Site-local scope

ffX8::0/16

Organization-local scope

ffXe::0/16

Global scope

An application can, separately from the scope of the multicast address, use different hop limit values. For example, an application might perform an expanding-ring search for a network resource by sending a multicast query, first with a hop limit of 0, and then with larger and larger hop limits, until a reply is received, using, for example, the hop limit sequence 0, 1, 2, 4, 8, 16, 32.

Each multicast transmission is sent from a single network interface, even if the host has more than one multicast-capable interface. If the host is also a multicast router and the hop limit is greater than 1, a multicast can be forwarded to interfaces other than the originating interface. A socket option is available to override the default for subsequent transmissions from a given socket:

    uint_t ifindex;

    ifindex = if_nametoindex )"hme3");
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,
          sizeof(ifindex))

where ifindex is the interface index for the desired outgoing interface. Revert to the default interface by specifying the value 0.

If a multicast datagram is sent to a group to which the sending host itself belongs, a copy of the datagram is, by default, looped back by the IP layer for local delivery. Another socket option gives the sender explicit control over or not subsequent datagrams are looped back:

    uint_t loop;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, 
            sizeof(loop))  

where loop is zero to disable loopback and one to enable loopback. This option provides a performance benefit for applications that have only one instance on a single host (such as a router or a mail demon), by eliminating the overhead of receiving their own transmissions. Applications that can have more than one instance on a single host (such as a conferencing program) or for which the sender does not belong to the destination group (such as a time querying program) should not use this option.

If the sending host belongs to the destination group on another interface, a multicast datagram sent with an initial hop limit greater than 1 can be delivered to the sending host on the other interface. The loopback control option has no effect on such delivery.

Receiving IPv6 Multicast Datagrams

Before a host can receive IP multicast datagrams, it must become a member of one, or more IP multicast groups. A process can ask the host to join a multicast group by using the following socket option:

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) 

where mreq is the structure:

    struct ipv6_mreq {
        struct in6_addr ipv6mr_multiaddr;   /* IPv6 multicast addr */
        unsigned int    ipv6mr_interface;   /* interface index */
    }  

Each membership is associated with a single interface and you can join the same group on more than one interface. Specify ipv6_interface to be 0 to choose the default multicast interface, or an interface index for one of the host's interfaces to choose that multicast-capable interface.

To leave a group, use:

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IP_LEAVE_GROUP, &mreq, sizeof(mreq))  

where mreq contains the same values used to add the membership. The socket drops associated memberships when the socket is closed or the process holding the socket is killed. More than one socket can claim a membership in a particular group and the host remains a member of that group until the last claim is dropped.

The kernel IP layer accepts incoming multicast packets if any socket has claimed a membership in the destination group of the datagram. Delivery of a multicast datagram to a particular socket is determined by the destination port and the memberships associated with the socket, or the protocol type for raw sockets, just as with unicast datagrams. To receive multicast datagrams sent to a particular port, bind to the local port, leaving the local address unspecified, such as INADDR_ANY.

More than one process can bind to the same SOCK_DGRAM UDP port if the bind(3SOCKET) is preceded by:

    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  

In this case, all sockets bound to the port receive every incoming multicast UDP datagram destined to the shared port. For backward compatibility reasons, this does not apply to incoming unicast datagrams. Unicast datagrams are never delivered to more than one socket, regardless of how many sockets are bound to the datagram's destination port. SOCK_RAW sockets do not require the SO_REUSEADDR option to share a single IP protocol type.

The definitions required for the new, multicast-related socket options are found in <netinet/in.h>. All IP addresses are passed in network byte-order.

 
 
 
  Previous   Contents   Next