[ Team LiB ] Previous Section Next Section

31.2 Overview

STREAMS provide a full-duplex connection between a process and a driver, as shown in Figure 31.1. Although we describe the bottom box as a driver, this does not need to be associated with a hardware device; it can also be a pseudo-device driver (e.g., a software driver).

Figure 31.1. A stream shown between a process and a driver.

graphics/31fig01.gif

The stream head consists of the kernel routines that are invoked when the application makes a system call for a STREAMS descriptor (e.g., read, putmsg, ioctl, and the like).

A process can dynamically add and remove intermediate processing modules between the stream head and the driver. A module performs some type of filtering on the messages going up and down a stream. We show this in Figure 31.2.

Figure 31.2. A stream with a processing module.

graphics/31fig02.gif

Any number of modules can be pushed onto a stream. When we say "push," we mean that each new module gets inserted just below the stream head.

A special type of pseudo-device driver is a multiplexor, which accepts data from multiple sources. A STREAMS-based implementation of the TCP/IP protocol suite, as found on SVR4, for example, could be set up as shown in Figure 31.3.

Figure 31.3. A potential implementation of TCP/IP using STREAMS.

graphics/31fig03.gif

  • When a socket is created, the module sockmod is pushed onto the stream by the sockets library. It is the combination of the sockets library and the sockmod STREAMS module that provides the sockets API to the process.

  • When an XTI endpoint is created, the module timod is pushed onto the stream by the XTI library. It is the combination of the XTI library and the timod STREAMS module that provides the X/Open Transport Interface (XTI) API to the process.

    This is one of the few places where we mention XTI. An earlier edition of this book described the XTI API in great detail, but it fell out of common use and even the POSIX specification no longer covers it, so we dropped the coverage from this book. Figure 31.3 shows where the XTI implemention typically lives and we touch on it briefly in this chapter, but we stop short of providing any detail since there's rarely a reason to use XTI anymore.

  • The STREAMS module tirdwr must normally be pushed onto a stream to use read and write with an XTI endpoint. The middle process using TCP in Figure 31.3 has done this. This process has probably abandoned the use of XTI by doing this, so we have not shown the XTI library there.

  • Various service interfaces define the format of the networking messages exchanged up and down a stream. We describe the three most common. TPI [Unix International 1992b] defines the interface provided by a transport-layer provider (e.g., TCP and UDP) to the modules above it. The Network Provider Interface (NPI) [Unix International 1992a] defines the interface provided by a network-layer provider (e.g., IP). DLPI is the Data Link Provider Interface [Unix International 1991]. An alternate reference for TPI and DLPI, which contains sample C code, is [Rago 1993].

Each component in a stream—the stream head, all processing modules, and the driver—contains at least one pair of queues: a write queue and a read queue. We show this in Figure 31.4.

Figure 31.4. Each component in a stream has at least one pair of queues.

graphics/31fig04.gif

Message Types

STREAMS messages can be categorized as high priority, priority band, or normal. There are 256 different priority bands, between 0 and 255, with normal messages in band 0. The priority of a STREAMS message is used for both queueing and flow control. By convention, high-priority messages are unaffected by flow control.

Figure 31.5 shows the ordering of the messages on a given queue.

Figure 31.5. Ordering of STREAMS messages on a queue, based on priority.

graphics/31fig05.gif

Although the STREAMS system supports 256 different priority bands, networking protocols often use band 1 for expedited data and band 0 for normal data.

TCP's out-of-band data is not considered true expedited data by TPI. Indeed, TCP uses band 0 for both normal data and its out-of-band data. The use of band 1 for expedited data is for protocols in which the expedited data (not just the urgent pointer, as in TCP) is sent ahead of normal data.

Beware of the term "normal". In releases before SVR4, there were no priority bands; there were just normal messages and priority messages. SVR4 implemented priority bands, requiring the getpmsg and putpmsg functions, which we will describe shortly. The older priority messages were renamed high-priority. The question is what to call the new messages, with priority bands between 1 and 255. Common terminology [Rago 1993] refers to everything other than high-priority messages as normal-priority messages and then subdivides these normal-priority messages into priority bands. The term "normal message" should always refer to a message with a band of 0.

Although we talk about normal-priority messages and high-priority messages, there are about a dozen normal-priority message types and around 18 high-priority message types. From an application's perspective, and the getmsg and putmsg functions we are about to describe, we are interested in only three different types of messages: M_DATA, M_PROTO, and M_PCPROTO (PC stands for "priority control" and implies a high-priority message). Figure 31.6 shows how these three different message types are generated by the write and putmsg functions.

Figure 31.6. STREAMS message types generated by write and putmsg.

graphics/31fig06.gif

    [ Team LiB ] Previous Section Next Section