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).
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.
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.
-
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鈥攖he stream head, all
processing modules, and the driver鈥攃ontains at least one pair of
queues: a write queue and a read
queue. We show this in Figure
31.4.
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.
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.
|