Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Web Development

Internet Multicasting


Dr. Dobb's Journal October 1997: Internet Multicasting

Killer network apps that aren't network killers

Bob is a consultant and principal author of Windows Sockets Network Programming (Addison-Wesley, 1996). He can be reached at [email protected].


Sidebar: The IP Multicast Initiative

Most providers of push media currently use unicast to deliver content to their customers. This means that each server sends content to each listener in a stream of individually addressed datagrams. This works, but does not scale well.

With unicast-based push media, the CPU capacity and size of a sender's network pipe determine the number of receivers that senders can accommodate. Unicast also uses considerable bandwidth on receiving networks that have multiple listeners. From a programming standpoint, it isn't easy to send data to many individual destinations simultaneously. A simple round-robin is insufficient, because of the latency in processing a long list of recipients. With real-time data like video and audio, many datagrams must be sent back-to-back to avoid jitter (interpacket delays) that can disrupt the media.

Since many receivers get the same datastreams, these limitations and adverse effects are unnecessary. You can avoid much of this overhead by using multicast, rather than unicast, for push media.

Multicast allows a content provider to send a single datastream to a single address, a datastream that network routers subsequently distribute to as many receivers as desired. Multicast requires no additional effort on the part of the sender to add new receivers, since the network handles the distribution from the single datastream. The network also prunes, so as not to send content where it is not wanted.

What is Multicast?

Multicast is a method for delivering content from a single sender to multiple receivers. It is similar to broadcast, but does not incur broadcast's overhead or router limitations. Routers interpret any datagram sent to an IP address in the range of 224.0.0.0 to 239.255.255.255 as multicast. Any IP application with a UDP socket can send to a multicast address, with some limitations. Applications that request data from a specific multicast address (known as "joining a multicast group") can receive multicast datagrams sent to that group address.

A multicast receiver application must:

1. Get a UDP socket.
2. Bind to the application's port number (name the socket).
3. Join the application's multicast address group.
4. Receive.
5. Close the socket when complete.

Alternately, a multicast sender must:

1. Get a UDP socket.
2. Set the IP Time-To-Live appropriately.
3. Send to the application's multicast address and port number.
4. Close the socket when complete.

The sender does not have to join a multicast group. While the methodology just described sends content in one direction, from one sender to (potentially) many receivers, the roles of sender and receiver are not mutually exclusive. A many-to-many application is also possible, where a receiver is also a sender, so data flow is full duplex.

Both the one-to-many and many-to-many models have numerous interesting application possibilities. Possible one-to-many application examples include real-time data distribution (weather, stocks, telemetry, and remote sensing), file distribution (software updates, database mirrors, and web caching), cryptographic key or seed value distribution, network management and system configuration, and the like.

Possible many-to-many applications include conferencing (video, audio, and whiteboard sharing), collaborative document sharing, interactive distance learning, and virtual reality.

Multicast Requirements

The most important multicast requirement is that your TCP/IP protocol stack be multicast enabled. Most are these days: Windows 95/NT, for instance, ship with multicast capability enabled.

Multicast requires that all routers between a sender and its receivers be multicast capable. Most (but not all) routers support multicast these days. Few dial-up remote access servers are multicast capable. Even when routers are multicast capable, not all Internet Service Providers (ISPs) or network system managers enable them. But this is improving as demand increases and more multicast applications appear.

Ethernet switches are another consideration. New switches support multicast but some older models change multicast into broadcasts, which can adversely affect your network hosts. Check with your network managers to find out about your LAN. Again, sometimes it is just a configuration issue.

Programming Multicast

As a student at Stanford University, Steve Deering invented multicast for a thesis project in 1988. His original motivation came from his thesis advisor's suggestion to enable service location and automatic configuration capabilities available on the SUN (Stanford University Network) across IP routers. Deering described his final design in the Internet Engineering Task Force (IETF) standards document RFC 1112 ("Host Extensions for IP Multicasting"). RFC 1112 does not define service location or automatic configuration, but does describe the infrastructure to enable such protocols and services.

At the core of the design is the Internet Group Management Protocol (IGMP), which basically lets a multicast host talk to a multicast router about multicast group membership. RFC 1112 describes IGMP in detail, and provides a high-level description of the relevant APIs. The Stanford release of BSD 4.3 provided the first multicast implementation, and the BSD sockets API, modified for multicast (see Table 1), has since become the de facto standard.

Applications using these Berkeley-based APIs use setsockopt() to initiate multicasting and adjust operational parameters. getsockopt() can be used to retrieve the current settings.

Most BSD-compatible sockets implementations support multicast, including SunOS 4.1.3+, Solaris 2.4, and Linux 1.1.80+ (see http://www.mbone.com/ mbone/kernel-patches.html). Many Windows Sockets (WinSock) implementations support them too, including those from Microsoft. They weren't included in the WinSock 1.1 specification, but are officially part of Version 2.

The TimeCast Application

TimeCast is a one-to-many application that multicasts the time to multiple clients. Everything it demonstrates separately in the client (receiver) and server (sender) could be combined to create a many-to-many application that sends and receives multicast datagrams. (The complete source code and related files for TimeCast are available electronically; see "Availability," page 3.)

TimeCast uses the multicast-enabled WinSock API. There are minor differences between the WinSock API and BSD sockets API. I'll identify these differences as I describe the code, and I note them in comments in the code. In spite of these special considerations, you could port these WinSock applications to a UNIX system with very few modifications; the biggest change would be to specify different header files.

Both the client and server initialize WinSock and use datagram sockets in the same way. Example 1 is a call to WSAStartup(), the first step in any WinSock application. The WinSock DLL allocates resources for each process that calls WSAStartup(). Without a successful call to WSAStartup(), any WinSock call fails with WSAENOTINITIALISED (10093).

The call to socket() in Example 2 shows how the client and server get a socket, an endpoint for datagram communications. You can only use SOCK_DGRAM (UDP) or SOCK_RAW socket types for IP multicast, not SOCK_STREAM (TCP), the connection-oriented socket type commonly used for reliable data delivery. Multicast is only available for message-oriented, connectionless sockets. The UDP transport protocol does not guarantee delivery, maintain sequence, or guard against duplication of datagrams. If you need reliable delivery using multicast, implement the reliability at the application level, since you cannot depend on reliability at the transport level.

Both applications finish by closing their datagram socket with a call to closesocket(), and deinitializing the WinSock DLL with WSACleanup(). These calls ensure that all resources are returned to the system, preventing resource leaks.

TimeCast Client

In this example, the TimeCast client is a receiver that listens for datagrams sent to the specific multicast address and port number that I arbitrarily decided to make the destination for TimeCast datagrams. When the client receives datagrams, it displays the Universal Coordinated Time (UTC) received and sets the local time (adjusted by the UTC bias, which is set by your time-zone configuration).

Unfortunately, there's currently no way to programmatically -- via a remote protocol, or local service -- request an address for use in an ad hoc multicast application. To make matters worse, there's no reliable way to verify that an address choice is not already in use. Possible alternatives are to listen for local multicast traffic, or snoop the "session directory" protocol traffic (if available).

This represents a significant consideration for multicast applications, since applications may occasionally receive unexpected data, which they must be prepared to ignore without failing. Updates to the session directory service and protocol, as well as the possible enhancement of the Dynamic Host Configuration Protocol (DHCP) to provide multicast address allocation, may soon help solve this problem.

A number of well-known standard applications have permanent multicast addresses assigned by the Internet Assigned Numbers Authority (IANA). There are also a growing number assigned to permanent multicast content services, like MSNBC and NetCast. Obviously, you want to avoid using any of these addresses as your application's multicast address.

The call to bind() (Example 3) assigns a specific local port number, TIMECAST_PORT, to the client socket. This allows the client to receive datagrams sent to this port by the server. Notice that I did not assign the multicast address in this bind() call, but instead assigned INADDR_ANY to select any/all interfaces. If I had assigned the multicast address, the call would fail with the error WSAEADDRNOTAVAIL (10056). I could have bound to a specific local interface address, but it is typically less troublesome to use INADDR_ANY. This way, I don't have to try to figure out my local IP address (which might be different than the one I'd end up using for multicast output).

After this call to bind() INADDR_ANY succeeds, the application is ready to receive datagrams sent to the TIMECAST_PORT number on any one of its interfaces (assuming that it has more than one). But it is not yet ready to receive datagrams sent to the TimeCast multicast address.

In Example 4, the call to setsockopt() IP_ADD_MEMBERSHIP joins a multicast group specified in the address field of the "multicast request" structure (mreq). At this point, the client socket can receive multicast datagrams sent from any sender to the TIMECAST_ADDR multicast address and TIMECAST_PORT.

A call to setsockopt() IP_ADD_MEMBERSHIP on a host with multiple network interfaces will join the group on only one interface. Here I specified INADDR_ANY in my mreq structure, which effectively selects the default multicast interface (just one). I could have entered a specific local interface address here instead, to join an interface other than the default. It is also possible to specify different local interface addresses in multiple calls to setsockopt() IP_ADD_MEMBERSHIP with the same socket to join a multicast group on more than one interface.

The IP_ADD_MEMBERSHIP socket option is the most significant API function for multicast receivers like the TimeCast client. It also has the closest tie to IGMP. When you call setsockopt() IP_ADD_MEMBERSHIP, the TCP/IP stack sends an IGMP group membership report to the group address. These membership report messages indicate to local routers that multicast traffic destined for the specified multicast address should be routed to this subnet.

In addition to receiving ad hoc membership reports, multicast routers periodically send IGMP "host membership queries" to the "all-hosts" group address (224.0.0.1) to solicit group membership reports. Upon receipt of a query, the TCP/IP stack for a group member sets a timer (up to ten seconds) for each of its current group addresses. After the timer expires, the TCP/IP stack will respond to the query by sending a group membership report if it has not seen another group member respond already. This delayed response helps to minimize unnecessary network traffic, and ensures that the router does not miss responses that might otherwise be sent all at once.

Notice that I call setsockopt() IP_ DROP_MEMBERSHIP before closing the socket. With IGMP Version 1, this function is effectively a no-op. A TCP/IP host does not actively notify a router when a socket leaves a group. However, with IGMP v2 (currently an Internet draft specification), a host does send an IGMP v2 "leave group" message.

TimeCast Server

The TimeCast server calls bind() and setsockopt() IP_ADD_MEMBERSHIP just like the client. Since the server does not receive multicast datagrams, these should not be necessary. However, to use setsockopt() IP_MULTICAST_TTL, which the server needs as a sender, the Microsoft multicast implementation requires a call to setsockopt() IP_ADD_MEMBERSHIP, and that requires a call to bind(). These extra function calls may or may not be necessary in other implementations, but should not cause problems in either case.

The server is a multicast sender. As RFC 1112 says, any (datagram) socket can send to a multicast address. However, RFC 1112 also stipulates that the default Time-To-Live (TTL) setting in the IP header of an outgoing multicast datagram must be only 1. This is a significant limitation that most senders need to consider, since the TTL value determines the scope of an IP multicast transmission.

The TTL field in an IP header is a fail-safe mechanism designed to kill IP datagrams that might be caught in router loops. It also limits the scope of a datagram, by limiting the number of IP routers it can traverse. Each router decrements the TTL by one, and does not forward a datagram when TTL reaches zero. Typically, when a datagram's TTL expires, a router will return an Internet Control Message Protocol (ICMP) "TTL Exceeded" error message back to the sender. The traceroute application commonly found on systems using TCP/IP uses this TTL exceeded error message to find routers. However, RFC 1112 stipulates that when the TTL is exceeded on a datagram sent to a multicast address, a router must never issue an ICMP error message. Multicast datagrams expire silently.

As a result, with a default TTL of only 1, multicast datagrams do not leave the local subnet. However, multicast senders can expand this scope explicitly by using the setsockopt() IP_MULTICAST_TTL command, which is exactly what our server application does in Example 5. Eventually, the use of IP TTL as a scoping mechanism will be replaced with Administrative Scoping, (which uses specific multicast address ranges to indicate scope). When Administrative Scoping becomes a prevalent standard, sending applications will need to set TTL to the maximum value of 255.

TimeCast's Accuracy

The service that this TimeCast application provides is an interesting exercise, but not an accurate time service. It does not compensate for the latency involved with the function calls and network transmission, which can be significant. It does not consider differing byte order in multibyte values, but assumes that both sender and receiver are running on Intel platforms. The TimeCast server simply uses the Win32 GetSystemTime() function to retrieve the "universal" Greenwich time (UTC), and multicasts the resulting structure to the client as is. The client uses that structure in a call to SetLocalTime() to set the system time with an adjustment for the local time-zone bias.

Maintaining accurate synchronization between widely distributed, multiplatform Internet hosts, where the latency varies unpredictably and system differences abound, is a significant challenge. The Network Time Protocol (NTP) described in RFC 1305 achieves 1-50 ms accuracy, but is huge and complex. The Simple Network Time Protocol (SNTP) that RFC 1769 describes provides microsecond accuracy -- sufficient for many applications. SNTP is significantly less complex than NTP, but still more complex than what I implemented in my TimeCast application. Both NTP and SNTP are designed to work with either unicast or multicast. They both share the permanently assigned multicast address 224.0.1.1 and port number 37, which were assigned by the IANA (see RFC 1700).

Details, Details

There are subtleties involved with joining multicast groups and using port numbers. Among them are the following:

  • With a single socket, you can join multiple groups on the same port number. In other words, you may call setsockopt() IP_ADD_MEMBERSHIP more than once with the same socket and interface, specifying a different multicast group address each time.
  • A single socket can join a group on multiple interfaces. To do so, simply specify a different interface address with each call to setsockopt() IP_ADD_MEMBERSHIP.
  • Multiple sockets may join the same group after having bound to the same port number. It is the job of the TCP/IP stack to duplicate incoming datagrams so all of the listening sockets can receive a copy.
  • Multiple sockets may join the same group after having bound to different port numbers. Support of this feature is where multicast implementations differ most. Be sure to test your application if you intend to use this feature.

These subtle features are somewhat specialized, but can be extremely useful. Beware, however, because not all vendors are consistent, and the behavior of different versions from the same vendor can vary, too.

What is Missing?

There are a number of significant multicast application considerations I have not covered here. Multicast is a mature technology, having been used extensively since its invention in 1988. But some areas of research and development are still incomplete. Open considerations include the following:

  • There are no established standards for reliable data delivery via multicast. There are a number of implementations available, and the Internet Research Task Force (IRTF) is researching further. In all likelihood, we will eventually have more than one standard reliable multicast transport protocol to choose from, since different applications have different reliable multicast requirements.
  • There is no standard way to check whether your local router is multicast enabled. You can infer multicast support when a router responds to an ICMP Router Discovery Message (RFC 1256), but that is no guarantee the router is configured to support multicast.
  • There is no standard way to find neighbors in a group. A host can send an IGMP host membership query to receive membership reports from other group members on the local subnet, but there is no way to find out about addresses on other subnets. As a result, there is potential for two applications to conflict as they use the same multicast address.
  • The standard for centrally managing the multicast address space needs formal standardization. The Session Directory (SD) application is the de facto standard. SD allocates multicast addresses and ports, and the SD protocol can be monitored to keep track of address/port usage. This protocol is described in an Internet Draft RFC. There is also a new proposal to use DHCP to request allocation of a multicast address; this would be an excellent enterprise front-end for SDP.
  • Adequate debugging and diagnostics tools are not yet available. We have useful applications like multicast traceroute (mtrace), but other tools are needed.
  • There is no way to guarantee bandwidth. This is not just a multicast issue, but relates to unicast also (for both UDP and TCP). The Resource ReSerVation Protocol (RSVP) nearing completion in the IETF is designed to address this need, and will include support for multicast.
  • Multicast has some unique security issues. In particular, we need standards for routers to authenticate senders. Multicast security still only exists in research labs. Development in the area of reliable multicast protocols may carry over to security, since both deal with some of the same issues.

Conclusion

Multicast is inevitable. The Internet cannot scale without the network savings it provides, and it creates the possibility for exciting new applications that people want. However, there are still some hurdles.

The most obvious and significant obstacle is the need to have multicast-capable routers from end-to-end between senders and receivers. This is easier to address on an enterprise network, with centralized network management. Thus, this is where multicast is proliferating now. But deploying multicast routers Internet-wide is a bigger challenge. In the interim, it is possible to have a virtual multicast-capable network using unicast tunnels. The world-wide "multicast backbone" (MBone) does exactly this now.

The other challenge is in multicast application development. Creating a multicast application is relatively simple, but this apparent simplicity belies some significant complexities. Standards are not yet established for managing the multicast address space, and providing reliable multicast transmission. Some of the larger issues of quality of service and security are also being addressed, but have a way to go.

References

Adoba, B. "Multicast Diagnostic Tools," draft-ietf-mboned-mdh-00.txt.

Deering, Steve. RFC 1112: "Host Extensions for IP Multicasting."

-- -- -- . "IP Multicast Extensions," http://portal.research.bell-labs.com/ipmulticast.README.new.

Fenner, W. "Internet Group Management Protocol," draft-ietf-idmr-igmp-v2-06.txt.

Handley, M. and V. Jacobson. "SDP: Session Description Protocol," draft-ietf-mmusic-sdp-03.txt.

IP Multicast Initiative: http://www.ipmulticast.com/.

Mankin, Allison (et al). "IETF Criteria For Evaluating Reliable Multicast Transport and Application Protocols," draft-mankin-reliable-multicast-00.txt.

MBone Information: http://www.mbone .com/.

Meyer, Dave. "Administratively Scoped IP Multicast," draft-ietf-mboned-admin-ip-space-01.txt.

Mills, D. RFC 1305: "Network Time Protocol (v3)."

-- -- -- . RFC 1769: "Simple Network Time Protocol (SNTP)."

Patel, B. and M. Shah. "Multicast address allocation extensions to the Dynamic Host Protocol," draft-ietf-dhc-mdhcp-00.txt.

-- -- -- . "Multicast address allocation extensions options," draft-ietf-dhc-multopt-00.txt.

Pusateri, T. RFC 1469: "IP Multicast over Token-Ring Local Area Networks."

Quinn and Shute. Windows Sockets Network Programming, Addison-Wesley, 1996.

Reynolds, J and J. Postel. RFC 1700: "ASSIGNED NUMBERS."

Stevens, W.R. TCP/IP Illustrated, Volume 1, Addison-Wesley, 1995.

Stevens, W.R. Unix Network Programming, Prentice-Hall, 1990.

WinSock 2 Overview and Pointers: http://www.sockets.com/winsock2.htm.

DDJ


Copyright © 1997, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.