Previous section.
Transport Provider Interface (TPI), Version 2 Draft 2
Copyright © 1999 The Open Group
Introduction
STREAMS-based Transport Provider Interface
The Transport Provider Interface (TPI) is an interface for drivers that
provide transport services.
The TPI
defines the set of messages and their formats
that the driver must generate/process.
This chapter introduces the STREAMS-based Transport Provider
Interface (TPI). TPI is a service interface that maps
to strategic levels of the Open
Systems Interconnection (OSI) Reference Model.
TPI supports
the services of the Transport Layer for connection-mode and
connectionless-mode services.
One advantage to using TPI is its ability to hide implementation details of a
particular service from the consumer of the service.
This enables system programmers to
develop software independent of the particular protocol that
provides a specific service.
This chapter focuses on TPI as it is defined
within the STREAMS environment.
Although there are no formal standards for a STREAMS environment,
extensive descriptions of STREAMS and STREAMS programming can be
found in the referenced document
TPI_SMD.
How TPI Works
TPI defines a message interface
to a transport provider implemented under STREAMS.
A user communicates to a transport provider via a full duplex
path known as a
stream
(see
Example of a Stream from a User to a Transport Provider).
This
stream
provides a mechanism in which messages may be passed to the
transport provider from the transport user and vice versa.
Figure: Example of a Stream from a User to a Transport Provider
The STREAMS messages that are used to communicate between the
transport user and the transport provider may have one of the following
formats:
-
A
M_PROTO
message block followed by zero or more
M_DATA
message blocks.
The
M_PROTO
message block contains the type of transport service primitive
and all the relevant arguments associated with the primitive.
The
M_DATA
blocks contain transport user data associated with the
transport service primitive.
-
One
M_PCPROTO
message block containing the type of transport service primitive
and all the relevant arguments associated with the primitive.
-
One or more
M_DATA
message blocks containing transport user data.
-
One
M_ERROR
message block indicating that an unrecoverable error has occurred.
-
One
M_FLUSH
message block indicating that queued requests should be discarded.
TPI Message Formats
contains descriptions of the transport primitives which define both
a connection-mode and connectionless-mode transport service.
There are also primitives that pertain to both transport modes.
For each type of transport service, two types of primitives exist:
-
Primitives which originate from the transport user.
These make requests to the transport provider or respond to
an event of the transport provider.
-
Primitives which originate from the transport provider.
These are either
confirmations of a request or are indications to the transport user that
an event has occurred.
For the connection-mode transport service, a connection is
associated with a single stream and,
except while processing inbound connections,
a stream will have at most one connection associated with it.
Transport Primitives
lists the primitive types along with the mapping of those
primitives to the STREAMS message types and the transport primitives
of the ISO IS 8072 and IS 8072/DAD transport service definitions (see
referenced documents).
The format of these primitives and the rules governing the use of them
are described in
Allowable Sequence of TPI Primitives.
Overview of Error Handling Capabilities
There are two error handling facilities available to the transport
user:
-
one to handle non-fatal errors
-
one to handle fatal errors.
Non-fatal Errors
The non-fatal errors are those that a transport user can correct, and
are reported in the form of an error acknowledgment to the appropriate
primitive in error.
Only those primitives which require acknowledgments may generate a
non-fatal error acknowledgment.
These acknowledgments always report a syntactical error in the
specified primitive when
the transport provider receives the primitive.
The primitive descriptions above define those primitives and rules
regarding the acknowledgment of them.
These errors are reported to the transport user via the
T_ERROR_ACK
primitive, and give the transport user the option of reissuing the
transport service primitive that caused the error.
The
T_ERROR_ACK
primitive also indicates to the transport user that no
action was taken by the transport provider on receipt of
the primitive which caused the error.
These errors do not change the state of the transport service
interface as seen by the transport user.
The state of the interface
after the issuance of a
T_ERROR_ACK
primitive
should be the same as it was before the
transport provider received the interface primitive that was in
error.
The allowable errors that can be reported on the receipt of a
transport initiated primitive are presented in the description of the
appropriate primitives.
Fatal Errors
Fatal errors are those which can not be corrected by the transport
user, or those errors which result in an uncorrectable error in the
interface or in the transport provider.
The most common of these errors are listed under the appropriate primitives.
The transport provider should issue fatal errors only if the transport user
can not correct the condition which caused the error or if the transport
provider has no means of reporting a transport user correctable error.
If the transport provider detects an
uncorrectable non-protocol error internal to the transport provider,
the provider should issue a fatal error to the user.
Fatal errors are indicated to the transport user via the STREAMS
message type
M_ERROR
with an appropriate UNIX system error.
EPROTO
should be used if the user has broken the TPI protocol.
The message
M_ERROR
will result in the failure of all the
operating system service routines on the
stream.
The user must then close the stream and, if required, attempt
to open a new stream to the provider. Note that some
providers may reject the "open" if, for example, the reason for the
fatal error is that the provider has been shut down.
Rules for Transport Service Interface Sequence of Primitives
The allowable sequence of primitives are described in the state
diagrams and tables in
Allowable Sequence of TPI Primitives,
for both the connection-mode and
connectionless-mode transport services.
The following are rules regarding the maintenance of the
state of the interface:
-
It is the responsibility of the transport provider to keep record of
the state of the interface as viewed by the transport user.
-
The state of the endpoint known by the transport user may
differ from that kept by the provider (and returned in
T_INFO_ACK messages) if there are messages queued on the
read or write side of the stream.
-
The transport provider must not generate a primitive that is illegal
in the current state of the endpoint.
-
The uninitialized state of a
stream
is the initial and final state,
and it must be bound (see the
T_BIND_REQ
primitive,
T_BIND_REQ)
before the transport provider may view it as
an active
stream.
-
If the transport provider sends a
M_ERROR
upstream,
it should also drop any further messages received
on its write side of the
stream.
The following rules apply only to the connection-mode transport services:
-
A transport connection release procedure can be initiated at any time
during the transport connection establishment or data transfer phase.
-
The state tables for the connection-mode transport service
providers include the
management of the sequence numbering when a transport provider sends
multiple
T_CONN_IND
requests without waiting for the response of the
previously sent indication.
It is the responsibility of the transport providers not to change state
until all the indications have been responded to. Therefore the provider
should remain in the
TS_WRES_CIND
state while there are any outstanding
connect indications pending response.
The provider should change state appropriately when all the connect
indications have been responded to.
-
The state of a transport service interface of a
stream
may only be transferred to another
stream
when it is indicated in a
T_CONN_RES
primitive.
The following rules then apply to the cooperating
streams:
-
The
stream
which is to accept the current state may be unbound, or
bound but not connected to a peer.
-
The user transferring the current state of a
stream
must have
correct permissions for the use of the
protocol address
bound to the accepting
stream.
-
The
stream
which transfers the state
of the transport interface must be placed into an appropriate state after
the completion of the transfer.
Rules for Precedence of TPI Primitives on a Stream
The following rules apply to the precedence of transport interface
primitives with respect to their position on a
stream:
-
The transport provider has responsibility for determining precedence on its
stream write
queue, as described in the rules in
.
This section specifies the rules for precedence for both the
connection-mode
and connectionless-mode transport services.
-
The transport user has responsibility for determining precedence on its
stream read
queue, as described in the rules in
.
-
All primitives on the
stream
are assumed to
be placed on the queue in the correct sequence as defined above.
- Note:
- The
stream
queue which contains the transport user initiated
primitives is referred to as the
stream write
queue.
The
stream
queue which contains the transport provider initiated
primitives is referred to as the
stream read
queue.
The following rule applies only to the connection-mode transport services:
-
There is no guarantee of delivery of user data once a
T_DISCON_REQ
primitive has been issued.
Rules for Flushing Queues
The following rules pertain to flushing the stream queues.
No other flushes should be needed to keep the queues in the proper condition.
-
The transport providers must be aware that they will receive
M_FLUSH
messages from upstream.
These flush requests are issued to ensure that the providers receive certain
messages and primitives.
It is the responsibility of the providers to act appropriately as deemed
necessary by the providers.
-
The transport provider must send up a
M_FLUSH
message to
flush both the read and write
queues after receiving a successful
T_UNBIND_REQ
message and
before issuing the
T_OK_ACK
primitive.
The following rules pertain only to the connection-mode transport providers.
-
If the interface is in the
TS_DATA_XFER,
TS_WIND_ORDREL
or
TS_WACK_ORDREL
state, the transport provider must send up a
M_FLUSH
message to
flush both the read and write
queues before sending up a
T_DISCON_IND.
-
If the interface is in the
TS_DATA_XFER,
TS_WIND_ORDREL
or
TS_WACK_ORDREL
state, the
transport provider must send up a
M_FLUSH
message to flush both the read and write
queues after receiving a successful
T_DISCON_REQ
message and before
issuing the
T_OK_ACK
primitive.
Receipt of Unknown Primitives
For compatability with older implementations, this specification
does not mandate a particular response by a transport provider
on receipt of an unknown TPI primitive.
Implementations have been known to:
-
M_ERROR the stream
-
silently ignore the message
-
send a T_ERROR_ACK response
It is recommended that implementations should send a T_ERROR_ACK
with a TLI_error field set to TNOTSUPPORT.