The X/Open Transport Interface (XTI) is a transport layer application interface that consists of a series of functions designed to be independent of the specific transport provider used. In this operating system, XTI is implemented according to the XPG3 and XNS4.0 specifications. XNS4.0 is the default. (XPG3 is provided for backward compatibility and is available by using a compiler switch.) For more information about XPG3 and XNS4.0, see the X/Open Portability Guide Volume 7: Networking Services and X/Open CAE Specification: Networking Services, Issue 4, respectively. This operating system's implementation of XTI is also thread safe.
Although similar in concept to the Berkeley socket interface, XTI is based on the AT&T Transport Layer Interface (TLI). TLI, in turn, is based on the transport service definition for the Open Systems Interconnection (OSI) model.
Note
This operating system includes the Transport Control Protocol (TCP) and User Datagram Protocol (UDP) transport providers. Although the information provided in this chapter applies to all transport providers that this operating system's XTI supports, such as DECnet/OSI, the examples are specific to TCP or UDP. For more specific information using XTI over TCP and UDP, see
xti_internet
(7). For examples and information specific to other transport providers, see the documentation that accompanies their software.
This chapter contains the following information:
Overview of XTI
Description of XTI features
Instructions on how to use XTI
Instructions on how to port applications to XTI
Information on the differences between XPG3 and XNS4.0.
Explanation of XTI errors and error messages
Information on configuring transport providers.
Figure 3-1
highlights XTI and its relationship to the operating system's implementation
of the Internet Protocol suite.
It also shows how XTI and the Internet Protocol
suite fit into the rest of the network programming environment.
Figure 3-1: X/Open Transport Interface
XTI involves the interaction of the following entities:
Transport providers
A transport provider is a transport protocol, such as TCP or UDP, that offers transport layer services.
Transport users
A transport user is an application program that requires the services of a transport provider to send data to or receive data from another program. A transport user communicates with a transport provider over a communications path identified by a transport endpoint.
Transport endpoints
A
transport endpoint
is created when an application
issues a
t_open
library call.
All of the transport user's
requests to the transport provider pass through the endpoint associated with
that provider.
The transport user activates a transport endpoint by binding a transport address to it. Once an endpoint is active, a transport user can send data over it. The transport provider routes the data to the appropriate peer user or other destination.
When using a connection-oriented transport service, such as TCP, the
transport user must establish a connection between itself and a peer transport
user with a
t_connect
function, specifying an active endpoint,
before sending data.
In a transport connection, the transport
user
initiating the connection is the
active user, or client,
and the peer transport user responding to the connection request is the
passive user, or server.
Figure 3-2
summarizes the relationship between transport providers, transport users,
and transport endpoints.
Figure 3-2: A Transport Endpoint
XTI
consists of library calls, header files, and the rules and restrictions elaborating
how XTI processes work and interact.
This section describes the library calls
and header files, as well as the regulations that govern the interaction between
communicating processes.
3.2.1 Modes of Service and Execution
Transport users use different
service modes and execution modes to determine how data is exchanged with
transport providers.
The following sections introduce the service modes and
execution modes available in XTI.
3.2.1.1 Connection-Oriented and Connectionless Service
In XTI, an endpoint can support one of the following modes of service:
Connection-oriented transport service
A circuit-oriented service that transfers data over an established connection in a reliable, sequenced manner.
Connection-oriented transport is useful for applications that require long, order dependent and reliable, stream-oriented interactions. With connection-oriented transport, transport users and providers can negotiate the parameters and options that govern data transfer. In addition, because a connection provides identification of both parties, the transport user avoids the overhead of transmitting and resolving addresses during data transfer. A connection also provides a context that logically relates successive units of data.
Connectionless transport service
A message-oriented service that transfers data in self-contained units or datagrams, which have no logical sequence with respect to one another.
Connectionless transport is best suited for applications that have the following qualities:
Short-term request and response interactions
Dynamic reconfiguration of connections to multiple endpoints
No need for the guaranteed, sequential delivery of data
Each data unit is self-contained and has no relationship to previous or successive data units, so the transport provider can route it independently.
3.2.1.2 Asynchronous and Synchronous Execution
Execution modes provide a means for transport users to handle completion of functions and receipt of events. An event is an occurrence or happening that is significant to a transport user. XTI supports two execution modes:
Waits for transport primitives to complete before returning control to the transport user. Also known as blocking mode.
Synchronous mode is suited for applications that want to wait for functions
to complete or maintain only a single transport connection.
In synchronous
mode, the transport user cannot perform other tasks while waiting for a function
to complete.
For example, if the transport user issues a
t_rcv
function in synchronous mode,
t_rcv
waits until data is
received before returning control to the transport user.
Even while using synchronous mode, it is possible to get some event notification, which the transport user does not ordinarily expect. Such asynchronous events are returned to the user through a special error, TLOOK.
If an asynchronous event occurs while a function is executing, the function
returns the TLOOK error; the transport user can then issue the
t_look
function to retrieve the event.
Returns control to the transport user before transport primitives complete. Also known as nonblocking mode.
Asynchronous mode is useful for applications that have long delays between
completion of functions and other tasks to perform in the meantime.
This
mode is also useful for applications that handle multiple connections simultaneously.
Many applications handle networking functions in asynchronous mode because
they can perform useful work while waiting for particular networking functions
to complete.
For example, if a transport user issues a
t_rcv
function call in asynchronous mode, the function returns control to the user
immediately if no data is available.
The user periodically polls for data
until the data arrives.
By default, all functions that process incoming events operate in synchronous
mode, blocking until the task completes.
To select asynchronous mode, the
transport user specifies the O_NONBLOCK flag with the
t_open
function when the endpoint is created or before executing a function or group
of functions with the
fcntl
operating system call.
For a full discussion of the specific events supported by XTI, see
Section 3.2.3.
3.2.2 The XTI Library, TLI Library, and Header Files
XTI functions are implemented
as part of the XTI library,
libxti.a
.
TLI functions are
implemented in a separate TLI library,
libtli.a
.
There
are also shared versions of these libraries,
libxti.so
and
libtli.so
.
Shared library support is provided by default when you link an XTI or TLI application with the XTI or TLI library.
The first of the following examples illustrates how to relink an XTI application's object files with the XTI shared library; the second illustrates how to relink a TLI application's object files with the TLI shared library:
%
cc -o XTI
appXTI
appmain.o XTI
apputil.o -lxti
%
cc -o TLI
appTLI
appmain.o TLI
apputil.o -ltli
To link programs statically with the XTI or TLI libraries, use the
non_shared
option to the
cc
command.
The following
example illustrates how to link an XTI application's object files to the XTI
library statically:
%
cc -non_shared -o XTI
appXTI
appmain.o XTI
apputil.o -lxti
See
cc
(1)
for more information.
To make a program thread safe, build the program with DECthreads
pthreads
routines.
For more information, see
Guide to DECthreads.
The few differences between XTI and TLI are described in
Section 3.5.2,
which also describes how to link your programs with the correct library at
compile time.
3.2.2.1 XTI and TLI Header Files
XTI and TLI header files contain data definitions, structures, constants,
macros, and options used by the XTI and TLI library calls.
An application
program must include the appropriate header file to make use of structures
or other information a particular XTI or TLI library call requires.
Table 3-1
lists the XTI and TLI header files.
Table 3-1: Header Files for XTI and TLI
File Name | Description |
<tiuser.h> |
Contains data definitions and structures for TLI applications. You must include this file for all TLI applications. |
<xti.h> |
Contains data definitions and structures for XTI applications. You must include this file for all XTI applications. |
<fcntl.h> |
Defines flags for modes of execution for
the
t_open
function.
You must include this file for all
XTI and TLI applications. |
Note
Typically, header file names are enclosed in angle brackets (< >). To obtain the absolute path to the header file, prepend
/usr/include/
to the information enclosed in the angle brackets. For example, the absolute path for thetiuser.h
file is/usr/include/tiuser.h
.
Some of the calls apply to connection-oriented transport (COTS), some to connectionless transport (CLTS), some to connection-oriented transport when used with the orderly release feature (COTS_ORD), and some to all service modes. A small group of the calls are utility functions and do not apply to a particular service mode. Table 3-2 lists the name, purpose, and service mode of each XTI library call. Each call has an associated reference page by the same name.
The operating system provides XTI reference pages only; it does
not provide TLI reference pages.
For information about TLI and for the TLI
reference pages see the
UNIX System V Programmer's Guide: Networking Interfaces, which is issued by UNIX System Laboratories, Inc.
The
operating system provides reference pages for each of the functions.
For
more information, see the
X/Open CAE Specification: Networking Services.
Table 3-2: XTI Library Calls
Name of Call | Purpose | Service Mode |
t_accept |
Accepts a connection request | COTS, COTS_ORD |
t_alloc |
Allocates memory for a library structure | All |
t_bind |
Binds an address to a transport endpoint | All |
t_close |
Closes a transport endpoint | All |
t_connect |
Establishes a connection with another transport user | COTS, COTS_ORD |
t_error |
Produces an error message | All |
t_free |
Frees memory previously allocated for a library structure | All |
t_getinfo |
Returns protocol-specific information | All |
t_getprotaddr
[Footnote 1]
|
Returns the protocol address | All |
t_getstate |
Returns the current state for the transport endpoint | All |
t_listen |
Listens for a connection request | COTS, COTS_ORD |
t_look |
Returns the current event on the transport endpoint | All |
t_open |
Establishes a transport endpoint | All |
t_optmgmt |
Retrieves, verifies, or negotiates protocol options | All |
t_rcv |
Receives data or expedited data over a connection | COTS, COTS_ORD |
t_rcvconnect |
Receives the confirmation from a connection request | COTS, COTS_ORD |
t_rcvdis |
Identifies the cause of a disconnect, and retrieves information sent with a disconnect | COTS, COTS_ORD |
t_rcvrel
[Footnote 2]
|
Acknowledges receipt of an orderly release indication | COTS_ORD |
t_rcvudata |
Receives a data unit | CLTS |
t_rcvuderr |
Receives information about an error associated with a data unit | CLTS |
t_snd |
Sends data or expedited data over a connection | COTS, COTS_ORD |
t_snddis |
Initiates a release on an established connection, or rejects a connection request | COTS, COTS_ORD |
t_sndrel
[Footnote 2] |
Initiates an orderly release | COTS_ORD |
t_sndudata |
Sends a data unit | CLTS |
t_strerror
[Footnote 1] |
Produces an error message string | All |
t_sync |
Synchronizes the data structures in the transport library | All |
t_unbind |
Disables a transport endpoint | All |
XTI supports an orderly release
mechanism,
t_sndrel
and
t_rcvrel
functions.
(See
Table 3-2
for more information.) However, if your applications need to be portable to
the ISO transport layer, we recommend that you do not use this mechanism.
Finally, the XTI header file defines the following constants to identify service modes:
T_COTS - Connection-oriented transport service (for example, OSI transport)
T_CLTS - Connectionless transport service (for example, UDP)
T_COTS_ORD - Connection-oriented transport service with the orderly release mechanism implemented (for example, TCP)
These service modes are returned by the transport provider in the
servtype
field of the
info
structure when
you create an endpoint with the
t_open
function.
3.2.3 Events and States
Each transport provider has a particular state associated with it, as
viewed by the transport user.
The state of a transport provider and its transition
to the next allowable state is governed by outgoing and incoming events, which
correspond to the successful return of specified user-level transport functions.
Outgoing events correspond to functions that send a request or response to
the transport provider, whereas incoming events correspond to functions that
retrieve data or event information from the transport provider.
This section
describes the possible states of the transport provider, the outgoing and
incoming events that can occur, and the allowable sequence of function calls.
3.2.3.1 XTI Events
XTI applications
must manage asynchronous events.
An asynchronous event is identified by a
mnemonic which is defined as a constant in the XTI header file.
Table 3-3
lists the name, purpose, and service mode for each type of asynchronous event
in XTI.
Table 3-3: Asynchronous XTI Events
Event Name | Purpose | Service Mode |
T_CONNECT | The transport provider received a connection
response.
This event usually occurs after the transport user issues the
t_connect
function. |
COTS, COTS_ORD |
T_DATA | The transport provider received normal data, which is all or part of a Transport Service Data Unit (TSDU). | COTS, CLTS, COTS_ORD |
T_DISCONNECT | The transport provider received a disconnect
request.
This event usually occurs after the transport user issues data transfer
functions, the
t_accept
function, or the
t_snddis
function. |
COTS, COTS_ORD |
T_EXDATA | The transport provider received expedited data. | COTS, COTS_ORD |
T_GODATA | The flow control restrictions on the flow of normal data are lifted. The transport user can send normal data again. | COTS, CLTS, COTS_ORD |
T_GOEXDATA | The flow control restrictions on the flow of expedited data are lifted. The transport user can send expedited data again. | COTS, COTS_ORD |
T_LISTEN | The transport provider received a connection request from a remote user. This event occurs only when the file descriptor is bound to a valid address and no transport connection is established. | COTS, COTS_ORD |
T_ORDREL | The transport provider received a request for an orderly release. | COTS_ORD |
T_UDERR | An error was found on a datagram that was
previously sent.
This event usually occurs after the transport user issues
the
t_rcvudata
or
t_unbind
functions. |
CLTS |
XTI stores all events that occur at a transport endpoint.
If using a synchronous mode of execution, the transport user returns
from the function it was executing with a value of -1 and then checks for
a value of TLOOK in
t_errno
and retrieves the event with
the
t_look
function.
In asynchronous mode, the transport
user continues doing productive work and periodically checks for new events.
Every event at a transport endpoint is consumed by a specific XTI function,
or it remains outstanding.
Exceptions are the T_GODATA and T_GOEXDATA events,
which are cleared by retrieving them with
t_look
.
Thus,
once the transport user receives a TLOOK error from a function, subsequent
calls to that function or a different function continue to return the TLOOK
error until the transport user consumes the event.
Table 3-4
summarizes the consuming functions for each asynchronous event.
Table 3-4: Asynchronous Events and Consuming Functions
Event | Cleared by t_look | Consuming Function(s) |
T_CONNECT | No | t_connect ,
t_rcvconnect |
T_DATA | No | t_rcv, t_rcvudata |
T_DISCONNECT | No | t_rcvdis |
T_EXDATA | No | t_rcv |
T_GODATA | Yes | t_snd, t_sndudata |
T_GOEXDATA | Yes | t_snd |
T_LISTEN | No | t_listen |
T_ORDREL | No | t_rcvrel |
T_UDERR | No | t_rcvuderr |
Table 3-5
lists the events that cause a specific XTI function to return the TLOOK error.
This information may be useful when you structure the event checking mechanisms
in your XTI applications.
Table 3-5: XTI Functions that Return TLOOK
Function | Events Causing TLOOK |
t_accept |
T_DISCONNECT, T_LISTEN |
t_connect |
T_DISCONNECT, T_LISTEN [Footnote 3] |
t_listen |
T_DISCONNECT [Footnote 4] |
t_rcv |
T_DISCONNECT, T_ORDREL [Footnote 5] |
t_rcvconnect |
T_DISCONNECT |
t_rcvrel |
T_DISCONNECT |
t_rcvudata |
T_UDERR |
t_snd |
T_DISCONNECT, T_ORDREL |
t_snddis |
T_DISCONNECT |
t_sndrel |
T_DISCONNECT |
t_sndudata |
T_UDERR |
t_unbind |
T_LISTEN, T_DATA [Footnote 6] |
Each XTI function manages one transport endpoint at a time.
It is not
possible to wait for several events from different sources, particularly from
several transport connections at a time.
This implementation of XTI allows
the transport user to monitor input and output on a set of
file descriptors with the
poll
function.
See
poll
(2)
for more information.
3.2.3.2 XTI States
XTI controls the legality of the calls issued by a program at a given point in time. XTI uses eight states to manage communication over a transport endpoint. Both the active and passive user have a unique state that reflects the function in process.
Table 3-6
describes the purpose of each XTI
state.
A service mode of COTS indicates the state occurs regardless of whether
or not orderly service is implemented.
A service mode of COTS_ORD indicates
the state occurs only when orderly service is implemented.
Table 3-6: XTI States
State | Description | Service Mode |
T_UNINIT | Uninitialized.
Initial and final state of
the interface.
To establish a transport endpoint, the user must issue a
t_open . |
COTS, CLTS, COTS_ORD |
T_UNBIND | Unbound. The user can bind an address to a transport endpoint or close a transport endpoint. | COTS, CLTS, COTS_ORD |
T_IDLE | Idle. The active user can establish a connection with a passive user (COTS), disable a transport endpoint (COTS, CLTS), or send and receive data units (CLTS). The passive user can listen for a connection request (COTS). | COTS, CLTS, COTS_ORD |
T_OUTCON | Outgoing connection pending. The active user can receive confirmations for connection requests. | COTS, COTS_ORD |
T_INCON | Incoming connection pending. The passive user can accept connection requests. | COTS, COTS_ORD |
T_DATAXFER | Data transfer. The active user can send data to and receive data from the passive user. The passive user can send data to and receive data from the active user. | COTS, COTS_ORD |
T_OUTREL | Outgoing orderly release. The user can respond to an orderly release indication. | COTS_ORD |
T_INREL | Incoming orderly release. The user can send an orderly release indication. | COTS_ORD |
If you are writing a connection-oriented application,
note that your program can release a connection at any time during the connection-establishment
state or data-transfer state.
3.2.4 Tracking XTI Events
The XTI library keeps track of outgoing
and incoming events to manage the legal states of transport endpoints.
The
following sections describe these outgoing and incoming events.
3.2.4.1 Outgoing Events
Outgoing events are caused by XTI functions that send a request or response to the transport provider. An outgoing event occurs when a function returns successfully. Some functions produce different events, depending on the following values:
ocnt | A count of outstanding connection indications (those passed to the transport user but not yet accepted or rejected). This count is only meaningful for the current transport endpoint (fd). A count of outstanding connection indications (those passed to the transport user but not yet accepted or rejected). This count is only meaningful for the current transport endpoint (fd). |
fd | The file descriptor of the current transport endpoint. |
resfd | The file descriptor of the endpoint where a connection will be accepted. |
Table 3-7
describes the outgoing
events available in XTI.
A service mode of COTS indicates the event occurs
for a connection-oriented service regardless of whether or not orderly service
is implemented.
A service mode of COTS_ORD indicates the event occurs only
when orderly service is implemented.
Table 3-7: Outgoing XTI Events
Event | Description | Service Mode |
opened | Successful return of
t_open
function. |
COTS, CLTS, COTS_ORD |
bind | Successful return of
t_bind
function. |
COTS, CLTS, COTS_ORD |
optmgmt | Successful return of
t_optmgmt
function. |
COTS, CLTS, COTS_ORD |
unbind | Successful return of
t_unbind
function. |
COTS, CLTS, COTS_ORD |
closed | Successful return of
t_close
function. |
COTS, CLTS, COTS_ORD |
connect1 | Successful return of
t_connect
function in synchronous execution mode. |
COTS, COTS_ORD |
connect2 | The
t_connect
function
returned the TNODATA error in asynchronous mode, or returned the TLOOK error
because a disconnect indication arrived on the transport endpoint. |
COTS, COTS_ORD |
accept1 | Successful return of
t_accept
function, where
ocnt
== 1 and
fd
==
resfd. |
COTS, COTS_ORD |
accept2 | Successful return of
t_accept
function, where
ocnt
== 1 and
fd
!=
resfd. |
COTS, COTS_ORD |
accept3 | Successful return of
t_accept
function, where
ocnt
>
1. |
COTS |
snd | Successful return of
t_snd
function. |
COTS |
snddis1 | Successful return of
t_snddis
function, where
ocnt
<= 1. |
COTS, COTS_ORD |
snddis2 | Successful return of
t_snddis
function, where
ocnt
>
1. |
COTS, COTS_ORD |
sndrel | Successful return of
t_sndrel
function. |
COTS_ORD |
sndudata | Successful return of
t_sndudata
function. |
CLTS |
Incoming events are caused by XTI functions that retrieve data or events from the transport provider. An incoming event occurs when a function returns successfully. Some functions produce different events, depending on the value of the ocnt variable. This variable is a count of outstanding connection indications (those passed to the transport user but not yet accepted or rejected). This count is only meaningful for the current transport endpoint (fd).
The pass_conn incoming event is not associated directly with the successful return of a function on a given endpoint. The pass_conn event occurs on the endpoint that is being passed a connection from the current endpoint. No function occurs on the endpoint where the pass_conn event occurs.
Table 3-8
describes the incoming events
available in XTI.
A service mode of COTS indicates the event occurs regardless
of whether or not orderly service is implemented.
A service mode of COTS_ORD
indicates the event occurs only when orderly service is implemented.
Table 3-8: Incoming XTI Events
Event | Description | Service Mode |
listen | Successful return of the
t_listen
function |
COTS, COTS_ORD |
rcvconnect | Successful return of the
t_rcvconnect
function |
COTS, COTS_ORD |
rcv | Successful return of the
t_rcv
function |
COTS, COTS_ORD |
rcvdis1 | Successful return of the
t_rcvdis
function, where
ocnt
== 0 |
COTS, COTS_ORD |
rcvdis2 | Successful return of the
t_rcvdis
function, where
ocnt
== 1 |
COTS, COTS_ORD |
rcvdis3 | Successful return of the
t_rcvdis
function, where
ocnt
>
1 |
COTS, COTS_ORD |
rcvrel | Successful return of the
t_rcvrel
function |
COTS_ORD |
rcvudata | Successful return of the
t_rcvudata
function |
CLTS |
rcvuderr | Successful return of the
t_rcvuderr
function |
CLTS |
pass_conn | Successfully received a connection that was passed from another transport endpoint | COTS, COTS_ORD |
3.2.5 Map of XTI Functions, Events, and States
This section describes the relationship among XTI functions, outgoing and incoming events, and states. Since XTI has well-defined rules about state transitions, it is possible to know the next allowable state given the current state and most recently received event. This section provides detailed tables that map the current event and state to the next allowable state.
This section excludes the
t_getstate
,
t_getinfo
,
t_alloc
,
t_free
,
t_look
,
t_sync
, and
t_error
functions from discussions of state transitions.
These utility functions
do not affect the state of the transport interface, so they can be issued
from any state except the uninitialized (T_UNINIT) state.
To use Table 3-9, Table 3-10, and Table 3-11, find the row that matches the current incoming or outgoing event and the column that matches the current state. Go to the intersection of the row and column to find the next allowable state. A dash (--) at the intersection indicates an invalid combination of event and state. Some state transitions are marked by a letter that indicates an action that the transport user must take. The letters and their meanings are listed at the end of the appropriate table.
Table 3-9
shows the state transitions
for initialization and deinitialization functions, functions that are common
to both the connection-oriented and connectionless modes of service.
For
example, if the current event and state are bind and T_UNBND, the next allowable
state is T_IDLE.
In addition, the transport user must set the count of outstanding
connection indications to zero, as indicated by the letter a.
Table 3-9: State Transitions for Initialization of Connection-Oriented or Connectionless Transport Services
Event | T_UNINIT State | T_UNBND State | T_IDLE State |
opened | T_UNBND | -- | -- |
bind | -- | T_IDLE [Footnote 7] | -- |
unbind | -- | -- | T_UNBND |
closed | -- | T_UNINIT | T_UNINIT |
Table 3-10
shows the state transitions
for data transfer functions in connectionless transport services.
Table 3-10: State Transitions for Connectionless Transport Services
Event | State T_IDLE |
sndudata | T_IDLE |
rcvudata | T_IDLE |
rcvuderr | T_IDLE |
Table 3-11
and
Table 3-12
show the transitions for connection, release, and data transfer functions
in connection-oriented transport services for incoming and outgoing events.
For example, if the current event and state are
accept2
and T_INCON, the next allowable state is T_IDLE, providing the transport user
decrements the count of outstanding connection indications and passes a connection
to another transport endpoint.
Table 3-11: State Transitions for Connection-Oriented Transport Services: Part 1
Event | T_IDLE State | T_OUTCON State | T_INCON State | T_DATAXFER State |
connect1 | T_DATAXFER | -- | -- | -- |
connect2 | T_OUTCON | -- | -- | -- |
rcvconnect | -- | T_DATAXFER | -- | -- |
listen | T_INCON [Footnote 8] | -- | T_INCON [Footnote 8] | -- |
accept1 | -- | -- | T_DATAXFER [Footnote 9] | -- |
accept2 | -- | -- | T_IDLE [Footnote 9] [Footnote 10] | -- |
accept3 | -- | -- | T_INCON [Footnote 9] [Footnote 10] | -- |
snd | -- | -- | -- | T_DATAXFER |
rcv | -- | -- | -- | T_DATAXFER |
snddis1 | -- | T_IDLE | T_IDLE [Footnote 9] | T_IDLE |
snddis2 | -- | -- | T_INCON [Footnote 9] | -- |
rcvdis1 | -- | T_IDLE | -- | T_IDLE |
rcvdis2 | -- | -- | T_IDLE [Footnote 9] | -- |
rcvdis3 | -- | -- | T_INCON [Footnote 9] | -- |
sndrel | -- | -- | -- | T_OUTREL |
rcvrel | -- | -- | -- | T_INREL |
pass_conn | T_DATAXFER | -- | -- | -- |
optmgmt | T_IDLE | T_OUTCON | T_INCON | T_DATAXFER |
closed | T_UNINIT | T_UNINIT | T_UNINIT | T_UNINIT |
Table 3-12: State Transitions for Connection-Oriented Transport Services: Part 2
Event | T_OUTREL State | T_INREL State | T_UNBND State |
connect1 | -- | -- | -- |
connect2 | -- | -- | -- |
rcvconnect | -- | -- | -- |
listen | -- | -- | -- |
accept1 | -- | -- | -- |
accept2 | -- | -- | -- |
accept3 | -- | -- | -- |
snd | -- | T_INREL | -- |
rcv | T_OUTREL | -- | -- |
snddis1 | T_IDLE | T_IDLE | -- |
snddis2 | -- | -- | -- |
rcvdis1 | T_IDLE | T_IDLE | -- |
rcvdis2 | -- | -- | -- |
rcvdis3 | -- | -- | -- |
sndrel | -- | T_IDLE | -- |
rcvrel | T_IDLE | -- | -- |
pass_conn | -- | -- | T_DATAXFER |
optmgmt | T_OUTREL | T_INREL | T_UNBND |
closed | T_UNINIT | T_UNINIT | -- |
3.2.6 Synchronization of Multiple Processes and Endpoints
In general, if you use multiple processes, you need to synchronize them carefully to avoid violating the state of the interface.
Although transport providers treat all transport users of a transport endpoint as a single user, the following situations are possible:
One process can create several transport endpoints simultaneously.
Multiple processes can share a single endpoint simultaneously.
For a single process to manage several endpoints in synchronous execution mode, the process must manage the actions on each endpoint serially instead of in parallel. Optionally, you can write a server to manage several endpoints at once. For example, the process can listen for an incoming connection indication on one endpoint and accept the connection on a different endpoint, so as not to block incoming connections. Then, the application can fork a child process to service the requests from the new connection.
Multiple processes that share a single endpoint must coordinate actions
to avoid violating the state of the interface.
To do this, each process calls
the
t_sync
function, which retrieves the current state
of the transport provider, before issuing other functions.
If all processes
do not cooperate in this manner, another process or an incoming event can
change the state of the interface.
Similarly, while several endpoints can share the same protocol address,
only one can listen for incoming connections.
Other endpoints sharing the
protocol address can be in data transfer state or in the process of establishing
a connection without causing a conflict.
This means that an address can have
only one server, but multiple endpoints can call the address at the same time.
3.3 Using XTI
This section presents guidelines to help you sequence functions, manage
states, and use XTI options.
It then describes the steps required to write
both connection-oriented and connectionless programs to XTI.
3.3.1 Guidelines for Sequencing Functions
Figure 3-3
shows the typical sequence of functions and state transitions for an active
user and passive user communicating with a connection-oriented transport service
in nonblocking mode.
The solid lines in the figure show the state transitions
for the active user, while the dashed lines show the transitions for the passive
user.
Each line represents the call of a function, while each ellipse represents
the resulting state.
This example does not include the orderly release feature.
Figure 3-3: State Transitions for Connection-Oriented Transport Services
Figure 3-4
shows the typical sequence of functions and transitions in state for two users
communicating with the connectionless transport service.
Each line in the
figure represents the call of a function, while each ellipse represents the
resulting state.
Both users are represented by solid lines.
Figure 3-4: State Transitions for the Connectionless Transport Service
3.3.2 State Management by the Transport Provider
All transport providers take the following actions with respect to states:
Keep a record of the state of the interface as seen by the transport user.
Reject any requests or responses that would place the interface out of state and return an error. In this case, the state does not change. For example, if the user passes data with a function and the interface is not in T_DATAXFER state, the transport provider does not accept or forward the data.
The uninitialized state (T_UNINIT) serves two purposes:
The initial state of a transport endpoint. The transport user must initialize and bind the transport endpoint before the transport provider views it as active.
The final state of a transport endpoint.
The transport provider
must view the endpoint as unused.
When the transport user issues the
t_close
function, the transport provider is closed, and the resources
associated with the transport library are freed for use by another endpoint.
3.3.3 Writing a Connection-Oriented Application
Follow these steps to write a connection-mode application:
Initialize an endpoint
Establish a connection
Transfer data
Release a connection
Deinitialize an endpoint
3.3.3.1 Initializing an Endpoint
To initialize an endpoint, complete the following steps:
Open the endpoint
Bind an address to the endpoint
Negotiate protocol options
Note that the steps described here for initializing an endpoint for
connection-oriented service are identical for connectionless service.
Opening a Transport Endpoint
Both
connection-oriented and connectionless applications must open a transport
endpoint using the
t_open
function.
See
t_open
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
This XTI implementation uses pathnames to device special files to identify
transport providers, which is the same method as in the AT&T TLI.
The
device special files corresponding to TCP or UDP transport providers reside
in the
/dev/streams/xtiso
directory.
If you use a different
transport provider, see its documentation for the correct device name.
Note
Using the special device with any mechanism other than XTI/TLI, for example, direct
open
,read
, orwrite
calls, is illegal and will generate undefined results.
The XTI specification forbids the use of O_RDONLY or O_WRONLY to make the endpoint either read-only or write-only as expected.
If you are designing a protocol-independent program, you can determine
data buffer sizes by accessing the information that the
t_open
function returns about the
t_info
structure.
If
the transport user exceeds the allowed data size, you receive an error.
Alternatively,
you can use the
t_alloc
function to allocate data buffers.
The following is an example of the
t_open
function
for the TCP transport provider:
if ( (newfd = t_open( "/dev/streams/xtiso/tcp+" , O_RDWR , NULL) ) == -1 ) { (void) t_error("could not open tcp transport"); exit (1); }
Binding an Address to the Endpoint
Once
you open an endpoint, you need to bind a protocol address to the endpoint
by using the
t_bind
function.
By binding the address,
you activate the endpoint.
In connection mode, you also direct the transport
provider to begin accepting connection indications or servicing connection
requests on the transport endpoint.
To determine if the transport provider
has accepted a connection indication, you can issue the
t_listen
function.
In connectionless mode, once you bind the address, you
can send or receive data units through the transport endpoint.
See
t_bind
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
To determine if the transport provider generates addresses, do not specify
one in the
t_bind
function (set
req
to a null pointer).
If the transport provider supplies addresses, the function
returns an assigned address in the
ret
field.
If the transport
provider does not supply addresses, the function returns an error of TNOADDR.
If you accept a connection on an endpoint that is used for listening for connection indications, the bound address is busy for the duration of the connection. You cannot bind any other endpoint for listening on that same address while the initial listening endpoint is actively transferring data or in T_IDLE state.
You can use the
gethostbyname
routine, described
in
Section 4.2.3.2, to obtain host information when
either TCP or UDP is the underlying transport provider.
If you use a method to retrieve host information other than the
gethostbyname
routine, consider the following:
Your applications must pass XTI functions a socket address
in the format that the transport provider expects.
For XTI over TCP/IP, the
expected address format is a
sockaddr_in
structure.
Your applications also need to pass a transport provider identifier to XTI functions. The operating system expects this identifier to be in the format of a pathname to the device special file for the transport provider.
XPG3 and XNS4.0 implement option management differently.
In XPG3, option management is handled exclusively by the
t_optmgmt
function.
In XNS4.0, several functions contain an
opt
argument which is used to convey options between a transport
user and the transport provider.
For more information, see
Section 3.6.6.
3.3.3.3 Establishing a Connection
The connection establishment phase typically consists of the following actions:
A passive user, or server, listens for a connection request.
An active user, or client, initiates a connection.
A passive user, or server, accepts a connection request and a connection indication is received.
These steps are described in the following sections.
Listening for Connection Indications
The
passive user issues the
t_listen
function to look for enqueued
connection indications.
If the
t_listen
function finds
a connection indication at the head of the queue, it returns detailed information
about the connection indication and a local sequence number that identifies
the indication.
The number of outstanding connection indications that can
be queued is limited by the value of the
qlen
parameter
that was accepted by the transport provider when the
t_bind
function was issued.
By default, the
t_listen
function executes synchronously
by waiting for a connection indication to arrive before returning control
to the user.
If you set the O_NONBLOCK flag of the
t_open
function or the
fcntl
function for asynchronous execution,
the
t_listen
function checks for an existing connection
indication and returns an error of TNODATA if none is available.
See
t_listen
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Initiating Connections
A connection is initiated
in either synchronous or asynchronous mode.
In synchronous mode, the active
user issues the
t_connect
function, which waits for the
passive user's response before returning control to the active user.
In asynchronous
mode,
t_connect
initiates a connection but returns control
to the active user before a response to the connection arrives.
Then, the
active user can determine the status of the connection request by issuing
the
t_rcvconnect
function.
If the passive user accepted
the request, the
t_rcvconnect
function returns successfully
and the connection establishment phase is complete.
If a response has not
been received yet, the
t_rcvconnect
function returns an
error of TNODATA.
The active user should issue the
t_rcvconnect
function again later.
See
t_connect
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Accepting Connections
When the passive user accepts
a connection indication, it can issue the
t_accept
function
on the same endpoint (the endpoint where it has been listening with
t_listen
) or a different endpoint.
If the passive user accepts on the same endpoint, the endpoint can no
longer receive and enqueue incoming connection indications.
The protocol
address that is bound to the endpoint remains busy for the duration it is
active.
No other transport endpoints can be bound to the same protocol address
as the listening endpoint.
That is, no other endpoints can be bound until
the passive user issues the
t_unbind
function.
Further,
before the connection can be accepted on the same endpoint, the passive user
must respond (with either the
t_accept
or
t_snddis
functions) to all previous connection indications that it has received.
Otherwise,
t_accept
returns an error of TBADF.
If the passive user accepts the connection on a different endpoint, the listening endpoint can still receive and enqueue incoming connection requests. The different endpoint must already be bound to a protocol address and be in the T_IDLE state. If the protocol address is the same as for the endpoint where the indication was received, the qlen parameter must be set to zero (0).
For both types of endpoints,
t_accept
will fail and
return an error of TLOOK if there are connect or disconnect indications waiting
to be received.
See
t_accept
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.3.3.4 Transferring Data
Once
a connection is established between two endpoints, the active and passive
users can transfer data in full-duplex fashion over the connection.
This
phase of connection-oriented service is known as the data transfer phase.
The following sections describe how to send and receive data during the data
transfer phase.
Sending Data
Transport users can send either
normal or expedited data over a connection with the
t_snd
function.
Normally,
t_snd
sends successfully and returns
the number of bytes accepted if the transport provider can immediately accept
all the data.
If the data cannot be accepted immediately, the result of
t_snd
depends on whether it is executing synchronously or asynchronously.
By default, the
t_snd
function executes synchronously
and waits if flow control conditions prevent the transport provider from accepting
the data.
The function blocks until one of the following conditions becomes
true:
The flow control conditions clear, and the transport provider
can accept a new data unit.
The
t_snd
function returns
successfully.
A disconnect indication is received.
The
t_snd
function returns with an error of TLOOK.
If you call the
t_look
function, it returns the T_DISCONNECT event.
Any data in transit
is lost.
An internal problem occurs.
The
t_snd
function returns with an error of TSYSERR.
Any data in transit is lost.
If the O_NONBLOCK flag was set when the endpoint was created,
t_snd
executes asynchronously and fails immediately if flow control
restrictions exist.
In some cases, only part of the data was accepted by
the transport provider, so
t_snd
returns a value that is
less than the number of bytes that you requested to be sent.
At this point,
you can do one of the following:
Issue
t_snd
again with the remaining data.
Check with the
t_look
function to see if
the flow control restrictions are lifted, then resend the data.
The
t_look
function is described at the end of this chapter.
See
t_snd
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Receiving Data
Transport users can receive either
normal or expedited data over a connection with the
t_rcv
function.
Typically, if data is available,
t_rcv
returns
the data.
If the connection has been disconnected,
t_rcv
returns immediately with an error.
If data is not available, but the connection
still exists,
t_rcv
behaves differently depending on the
mode of execution:
By default,
t_rcv
executes synchronously
and waits for one of the following to arrive:
Data
A disconnect indication
A signal
Instead of issuing
t_rcv
and waiting,
you can issue the
t_look
function and check for the T_DATA
or T_EXDATA events.
If you set the O_NONBLOCK flag,
t_rcv
executes
asynchronously and fails with an error of TNODATA if no data is available.
You should continue to poll for data by issuing the
t_rcv
or
t_look
functions.
See
t_rcv
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.3.3.5 Releasing Connections
XTI
supports two ways to release connections: abortive release and orderly release.
All transport providers support abortive release.
Orderly release is not
provided by all transport providers.
For example, the OSI transport supports
only abortive release, while TCP supports abortive release and optionally,
orderly release.
Abortive Release
An abortive release, which can be requested by the transport user or the transport provider, aborts a connection immediately. Abortive releases cannot be negotiated, and once the abortive release is requested, there is no guarantee that user data will be delivered.
Transport users can request an abortive release in either the connection establishment or data transfer phases. During connection establishment, a transport user can use the abortive release to reject a connection request. In data transfer phase, either user can release the connection at any time. If a transport provider requests an abortive release, both users are informed that the connection no longer exists.
See
t_snddis
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Transport
users are notified about abortive releases through the T_DISCONNECT event.
If your program receives a T_DISCONNECT event, it must issue the
t_rcvdis
function to retrieve information about the disconnect and
to consume the T_DISCONNECT event.
See
t_rcvdis
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Orderly Release
An orderly release allows for release of a connection
without loss of data.
Orderly release is not provided by all transport providers.
If the transport provider returned a service type of T_COTS_ORD with the
t_open
or
t_getinfo
functions, orderly release
is supported.
Transport users can request an orderly release during the data
transfer phase.
The typical sequence of orderly release is as follows:
The
active user issues the
t_sndrel
function to request an
orderly release of the connection.
The passive user receives the T_ORDREL event indicating the
active user's request for the orderly release and issues the
t_rcvrel
function to indicate the request was received and consume the T_ORDREL
event.
When ready to disconnect, the passive user issues the
t_sndrel
function.
The active user responds by issuing the
t_rcvrel
function.
The transport user cannot send more data over the connection after it
issues the
t_sndrel
function.
The transport user can,
however, continue to receive data until it receives an orderly release indication
(the T_ORDREL event).
See
t_sndrel
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
To acknowledge
the receipt of an orderly release indication, issue the
t_rcvrel
function with the following syntax:
After a transport user receives an orderly release indication (T_ORDREL),
it cannot receive more data.
(If the user attempts to do so, the function
blocks indefinitely.) The transport user can, however, continue to send data
until it issues the
t_sndrel
function.
See
t_rcvrel
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.3.3.6 Deinitializing Endpoints
When you are finished using
an endpoint, you deinitialize it by unbinding and closing the endpoint with
the
t_unbind
and
t_close
functions.
Note that the steps described here for deinitializing an endpoint with connection-oriented
service are identical to those for connectionless service.
When you unbind the endpoint, you disable the endpoint so that the transport provider no longer accepts requests for it.
See
t_unbind
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
By closing the endpoint, you inform the transport provider that you are finished with it and you free any library resources associated with the endpoint.
You should call
t_close
when the endpoint is in the
T_UNBND state.
However, this function does not check state information, so
it may be called to close a transport endpoint from any state.
If you close an endpoint that is not in the T_UNBND state, the library resources associated with the endpoint are freed automatically, and the file associated with the endpoint is closed. If there are no other descriptors in this or any other process that references the endpoint, the transport connection is broken.
See
t_close
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.3.4 Writing a Connectionless Application
This section describes the steps required to write a connectionless mode application:
Initializing an endpoint
Transferring data
Deinitializing an endpoint
3.3.4.1 Initializing an Endpoint
Initializing
an endpoint for connection-oriented and connectionless applications is the
same.
See
Section 3.3.3.1
for information on how to
initialize an endpoint for a CLTS application.
3.3.4.2 Transferring Data
The data transfer phase of connectionless service consists of the following:
Sending data to other users
Receiving data from other users
Retrieving error information about previously sent data
Note that connectionless service:
Sending Data
The
t_sndudata
function can execute synchronously or asynchronously.
When executing synchronously,
t_sndudata
returns control
to the user when the transport provider can accept another datagram.
In some
cases, the function blocks for some time until this occurs.
In asynchronous
mode, the transport provider refuses to send a new datagram if flow control
restrictions exist.
The
t_sndudata
function returns an
error of TFLOW, and you must either try again later or issue the
t_look
function to see when the flow control restriction is lifted,
which is indicated by the T_GODATA or T_GOEXDATA events.
If you attempt to send a data unit before you activate the endpoint
with the
t_bind
function, the transport provider discards
the data.
See
t_sndudata
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Receiving Data
When
you call the
t_rcvudata
function and data is available,
t_rcvudata
returns immediately indicating the number of octets received.
If data is not available,
t_rcvudata
behaves differently
depending on the mode of execution, as follows:
Synchronous mode
The
t_rcvudata
function blocks until either a datagram,
error, or signal is received.
As an alternative to waiting for
t_rcvudata
to return, you can issue the
t_look
function periodically for the T_GODATA event, and then issue
t_rcvudata
to receive the data.
Asynchronous mode
The
t_rcvudata
function returns immediately with
an error.
You then must either retry the function periodically or poll for
incoming data with the
t_look
function.
See
t_rcvudata
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
Retrieving Error Information
If you issue the
t_look
function and receive the T_UDERR event, previously sent data has
generated an error.
To clear the error and consume the T_UDERR event, you
should issue the
t_rcvuderr
function.
This function also
returns information about the data that caused the error and the nature of
the error, if you want.
To receive an error indication with information about data, issue the
t_rcvuderr
function with the following syntax:
t_rcvuderr(fd,uderr);
See
t_rcvuderr
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.3.4.3 Deinitializing Endpoints
Deinitializing
an endpoint for connection-oriented and connectionless applications is the
same.
See
Section 3.3.3.6
for information on how to
deinitialize an endpoint for a connectionless application.
3.4 Phase-Independent Functions
XTI provides a number of functions that can be issued during any phase
of connection-oriented or connectionless service (except the uninitialized
state) and do not affect the state of the interface.
Table 3-13
lists and briefly describes these functions.
Table 3-13: Phase-Independent Functions
Function | Description |
t_getinfo |
Returns information about the characteristics of the transport provider associated with the endpoint. |
t_getprotaddr
[Footnote 11]
|
Returns the protocol address. |
t_getstate |
Returns the current state of the endpoint. |
t_strerror
[Footnote 11] |
Produces an error message string. |
t_sync |
Synchronizes the data structures managed by the transport library with information from the transport provider. |
t_alloc |
Allocates storage for a specified data structure. |
t_free |
Frees storage for a data structure that was
previously allocated by
t_alloc . |
t_error |
Prints a message describing the last error returned by an XTI function. (Optional) |
t_look |
Returns the current event associated with the endpoint. |
The
t_getinfo
and
t_getstate
functions can be useful for retrieving important
information.
The
t_getinfo
function returns the same information
about the transport provider as
t_open
.
It offers the
advantage that you can call it during any phase of communication, whereas
you can call
t_open
only during the initialization phase.
If a function returns the TOUTSTATE error to indicate that the endpoint is
not in the proper state, you can issue
t_getstate
to retrieve
the current state and take action appropriate for the state.
The
t_sync
function can do the following:
Synchronize data structures managed by the transport library with information from the underlying transport provider.
Permit two cooperating processes to synchronize their interaction with a transport provider.
The
t_alloc
and
t_free
functions are convenient for allocating and
freeing memory because you specify the names of the XTI structures rather
than information about their size.
If you use
t_alloc
and
t_free
to manage the memory for XTI structures, and
the structures change in future releases, you will not need to change your
program.
With
t_error
you can print a user-supplied message (explanation) plus
the contents of
t_errno
to standard output.
Finally,
t_look
is an important function for retrieving the current outstanding
event associated with the endpoint.
Typically, if an XTI function returns
TLOOK as an error to indicate a significant asynchronous event has occurred,
the transport user follows by issuing the
t_look
function
to retrieve the event.
For more information about events, see
Section 3.2.3.
3.5 Porting to XTI
This section provides the following:
Guidelines for writing programs to XTI
Information about XTI and TLI compatibility
Information about rewriting sockets applications to use XTI
3.5.1 Protocol Independence and Portability
XTI was designed to provide an interface that is independent of the specific transport protocol used. You can write applications that can modify their behavior according to any subset of the XTI functions and facilities supported by each of the underlying transport providers.
Providers do not have to provide all the features of all the XTI functions. Therefore, application programmers should follow these guidelines when writing XTI applications:
Use only the functions that are commonly supported features of XTI.
If your application uses features that are not provided by all transport providers, it may not be able to use them with some transport providers or some XTI implementations.
For example, the orderly release facility (the
t_sndrel
and
t_rcvrel
functions) is not supported by all connection-based
transport protocols; in particular it is not supported by ISO protocols.
If your application runs in an environment with multiple protocols, make sure
it does not use the orderly release facility.
As an alternative to using only the commonly supported features, write your application so that it modifies its behavior according to the subset of XTI functions supported by each transport provider.
Do not assume that logical data boundaries are preserved across a connection.
Some transport providers, such as TCP, do not support the concept of
a TSDU, so they ignore the T_MORE flag when used with the
t_snd
,
t_sndudata
,
t_rcv
, and
t_rcvudata
functions.
Do not exceed the protocol-specific service limits returned
on the
t_open
and
t_getinfo
functions.
Make sure your application retrieves these limits before transferring data and adheres to the limits throughout the communication process.
Do not rely on options that are protocol-specific.
Although the
t_optmgmt
function allows an application
to access the default protocol options from the transport provider and pass
them as an argument to the connection-establishment function, make sure your
application avoids examining the options or relying on the existence of certain
ones.
Do not interpret the reason codes associated with the
t_rcvdis
function or the error code associated with the
t_rcvuderr
function.
These codes depend on the underlying protocol so, to achieve protocol independence, make sure your application does not attempt to interpret the codes.
Perform only XTI operations on the file descriptor returned
by the
t_open
function.
If you perform other operations, the results can vary from system to system.
The following sections explain how to port applications from different transport-level programming interfaces to XTI. Specifically, they discuss how to port from the two most common transport-level programming interfaces: Transport Layer Interface (TLI), which many UNIX System V applications use, and the 4.3BSD socket interface, which many Berkeley UNIX applications use.
The information presented in the following sections presumes that you
are experienced at programming with TLI or sockets and that you understand
fundamental XTI concepts and syntax.
3.5.2 XTI and TLI Compatibility
This section discusses issues to consider before you recompile your TLI programs and explains how to recompile them. As a long-term solution, you should use the XTI interface instead of the TLI interface. As more applications and transport providers use XTI, you might find it advantageous to do so as well.
XTI and TLI support the same functions, states, and modes of service. Shared library support is the default when you link an XTI or TLI application with the XTI or TLI library. For more information on shared library support, see Section 3.2.2.
Before you recompile your TLI program, you should consider your program's
current implementation of the following event management:
The
System V UNIX operating system provides the
poll
function
as a tool for managing events.
The Tru64 UNIX implementation of XTI supports
the
poll
function, so if your application uses it, you
can recompile.
If your program uses a unique mechanism for managing events,
you should port that mechanism to Tru64 UNIX or change to the polling mechanism
provided with Tru64 UNIX.
Because the Tru64 UNIX implementation of TLI is compatible at the source level with AT&T TLI, you can recompile your TLI program with the Tru64 UNIX TLI library using the following steps:
Make sure the TLI header file is included in your source code:
#include <tli/tiuser.h>
Recompile your application using the following command syntax:
cc -o
name
name.c
-ltli
If you decide to change your TLI application to an XTI application, be aware of the following minor differences between TLI and XTI.
In XTI,
t_error
is a function of type
int
that returns an integer value (0 for success and -1 for failure),
while in TLI, it is a procedure of type
void
.
In XTI,
t_look
does not support the T_ERROR
event (as in TLI); it returns -1 and the
t_errno
instead.
For the
oflag
parameter of the
t_open
function, the O_NDELAY value in TLI is known as the O_NONBLOCK
value in XTI.
XTI opens an endpoint with read-write access because most
of its functions require read-write access to transport providers.
TLI opens
with read-only, write-only, or read-write access.
Specifically, in the
t_open
function, XTI uses the bitwise inclusive OR of O_RDWR and
O_NONBLOCK as the value of the
oflag
parameter;
TLI uses the bitwise inclusive OR of O_NDELAY and either O_RDONLY, O_WRONLY,
or O_RDWR.
The O_RDONLY and O_WRONLY values are not available in XTI; O_RDWR
is the only valid value for access to an endpoint.
TLI assumes the transport provider has an automatic address generator; XTI does not. If the transport provider does not have an automatic address generator, XTI can return the proper error message if conflicting requests are issued.
XTI defines protocol-specific information for the TCP/IP and OSI protocols. The Tru64 UNIX XTI implementation adds support for protocol-specific options for STREAMS-based protocols; TLI does not provide such information.
XTI provides additional events to manage flow control, such as T_GODATA and T_GOEXDATA; in TLI, you keep sending until successful.
XTI provides additional error messages to convey more precise
error information to applications.
All functions that change the state of
an endpoint use the TOUTSTATE error to indicate the function was called when
the endpoint was in the wrong state.
Some XTI functions return the TLOOK
error to indicate that an urgent asynchronous event occurred.
With TLI, you
must call the
t_look
function explicitly before the function
or set a signal for the TLOOK event, which are less convenient.
The TBADQLEN
error, returned when there are no queued connection requests, prevents an
application from waiting forever after issuing the
t_listen
function.
See the XTI reference pages for more information on error messages.
To make a TLI application a true XTI application, do the following:
Include the XTI header file instead of the TLI header file in your source code:
#include <xti.h>
Make any changes or extensions to your program resulting from the differences between TLI and XTI.
Recompile your application using the following command syntax:
cc -o
name
name.c
-lxti
3.5.3 Rewriting a Socket Application to Use XTI
This section explains the differences between the socket interface and XTI. It assumes that your applications use the standard 4.3BSD socket interface and does not account for any extensions or changes you have made to the socket interface. See Appendix B for examples of both sockets and XTI servers and clients.
Because it was designed eventually to replace the socket interface, XTI shares many common functions with the socket interface. However, you should be aware of any differences between it and your current socket interface when rewriting an application for use with XTI.
XTI provides 25 functions.
Of the 13 socket functions that map onto
corresponding XTI functions, 5 have subtle differences.
Table 3-14
lists each XTI function, its corresponding socket function (if one exists),
and whether the two functions share common semantics.
Generally, socket calls
pass parameters by value, while most XTI functions pass pointers to structures
containing a combination of input and output parameters.
Table 3-14: Comparison of XTI and Socket Functions
XTI Function | Socket Function | Shared Semantics |
t_accept |
accept |
No |
t_alloc
|
-- | -- |
t_bind |
bind |
No |
t_close |
close |
Yes |
t_connect |
connect |
Yes |
t_error
|
-- | -- |
t_free
|
-- | -- |
t_getinfo
|
-- | -- |
t_getstate
|
-- | -- |
t_listen |
listen ,
accept |
Yes [Footnote 12] |
t_look |
select |
No |
t_open |
socket |
Yes |
t_optmgmt |
setsockopt ,
getsockopt |
No |
t_rcv |
recv |
Yes |
t_rcvconnect |
-- | -- |
t_rcvdis |
-- | -- |
t_rcvrel
|
-- | -- |
t_rcvudata |
recvfrom |
Yes |
t_rcvuderr |
-- | -- |
t_snd |
send |
Yes |
t_snddis |
shutdown |
No |
t_sndrel
|
-- | -- |
t_sndudata |
sendto |
Yes |
t_sync |
-- | -- |
t_unbind |
-- | -- |
The XTI functions that do not share all semantics with their socket counterparts have the following differences:
t_accept
The
t_accept
function takes the user-specified
resfd
argument
and establishes a connection with the remote endpoint.
In contrast, the
accept
call from sockets asks the system to select the file descriptor
to which the connection will be established.
Additionally, the
t_accept
function is issued after a connection indication is received;
therefore, it does not block.
Conversely, the
accept
call
is issued in anticipation of a connect request and therefore may block until
the connect request occurs.
t_bind
XTI can bind one protocol address to many endpoints, while the socket interface permits one address to be bound with only one socket.
t_look
The
t_look
function returns the current event, which can be one of nine possible events:
T_LISTEN, T_CONNECT, T_DATA, T_EXDATA, T_DISCONNECT, T_UDERR, T_OREREL, T_GODATA,
T_GOEXDATA.
The
poll
function can be used to monitor incoming
events on a transport endpoint.
The
select
call can be
used to see if a single descriptor is ready for read or write, or if an exceptional
condition is pending.
t_snddis
The
t_snddis
function initiates an abortive release on an established connection or rejects
a connection request.
After an XTI program issues the
t_snddis
functions it can continue to listen for requests with the
t_listen
function or reestablish a connection with the
t_connect
function.
In sockets, once you shut down a connection with the
shutdown
and
close
calls, the system automatically
frees all local resources that are allocated for this connection.
Therefore,
in order to continue to listen for connections or establish a connection,
the program needs to reissue the
socket
and
bind
calls.
XTI and sockets both use a series of states to control the appropriate sequence of calls, but each uses a different set of states. XTI states and socket states do not share similar semantics. For example, XTI states are mutually exclusive; socket states are not.
Few error messages are common among sockets and XTI.
Table 3-15
lists the socket error messages that have comparable XTI error messages.
Table 3-15: Comparison of Socket and XTI Messages
Socket Error | XTI Error | Description |
EBADF | TBADF | You specified an invalid file descriptor. |
EOPNOTSUPP | TNOTSUPPORT | You issued a function the underlying transport provider does not support. |
EADDRINUSE | TADDRBUSY | You specified an address that is already in use. |
EACCES | TACCES | You do not have permission to use the specified address. |
Note
XTI and TLI are implemented using STREAMS. You should use the
poll
function instead of theselect
call on any STREAMS file descriptors.
3.6 Differences Between XPG3 and XNS4.0
This section provides information on the differences between the XPG3 and XNS4.0 implementation of XTI.
In earlier versions of Tru64 UNIX, the XTI implementation conformed to X/Open's XPG3 specification. The current implementation conforms to X/Open's XNS4.0 specification for XTI.
There are some changes in the specification of which you, as a programmer, should be aware. This section outlines these differences and the related programming issues.
Note that the implementation of Tru64 UNIX converges both XPG3 and XNS4.0 versions of XTI in a single subset. This section also provides details about the usage of the appropriate level of functionality.
In this manual, the terms XNS4.0 or XNS4.0 XTI are used to refer to
the implementation of XTI available in this version of Tru64 UNIX.
The
terms XPG3 XTI refer to the implementation of XTI that conforms to X/Open's
XPG3 specification.
Note that the latter can be available in the current
versions of Tru64 UNIX due to binary compatibility or source migration features.
3.6.1 Major Differences
Most of the changes between the two specifications are upwardly compatible,
with the exception of the
t_optmgmt
function.
The following is a quick summary of the basic changes in the XTI from XPG3 to XNS4.0:
Optional functions were made mandatory. This does not affect the Tru64 UNIX implementation of XTI, because Tru64 UNIX implemented all the optional functions in its XPG3 version of XTI.
Many aspects of the XPG3 specification were clarified, which makes XTI applications more portable.
Some new error codes were added, ensuring better programmatic behavior.
Options and management structures were revised to provide more control over various aspects of communications.
The changes to the
t_optmgmt
function are extensive
and incompatible with the XPG3 specification.
In general, an application
that uses the XPG3 implementation of the
t_optmgmt
function
cannot use the
t_optmgmt
function on a system running the
XNS4.0 specification, without making some modifications to the source.
3.6.2 Source Code Migration
If you have an application that was developed for XPG3 XTI, you have the following choices to support it under the current version of the operating system:
Use the older binaries of the application; see Section 3.6.3.
Recompile the unaltered sources.
Make changes to the sources to comply with XNS4.0 XTI.
Which option you choose will depend on your situation.
The following
sections describe these conditions in detail.
3.6.2.1 Use the Older Binaries of your Application
This choice is appropriate if the sources and features of your
application are not going to change.
It is useful to provide continued coverage
by ensuring that older releases of your products are still functional.
3.6.2.2 Unaltered Sources
This situation arises from minor changes due to correcting minor problems.
Therefore, there are no changes to the structure or features or the application.
In this case, you might want to compile the sources in the same manner as
XPG3 development environment.
In that case, compile your source code with
the
-DXPG3
compiler switch.
This ensures that the
headers automatically define the older features for you.
3.6.2.3 XNS4.0 Compliant Application
If you need to use the new features supported by XNS4.0 XTI, you will have to make changes in your source code. You cannot combine the features from the XPG3 and XNS4.0 XTI. Therefore, if you have large applications consisting of multiple files, you will need to recompile all files with the new features, rather than just the few you might have changed.
You need to compile your source code with the
-DXOPEN_SOURCE
compiler switch.
Additionally, you must ensure that the names
of the transport protocols (as provided through the streams device special
files as in
/dev/streams/xtiso/tcp
) are updated to reflect
the naming convention used in XNS4.0 XTI.
For example, the names for TCP
and UDP are
/dev/streams/xtiso/tcp+
and
/dev/streams/xtiso/udp+
.
Check the reference manual for the names for the other protocols.
3.6.3 Binary Compatibility
There are certain conditions of which you should be aware when running application binaries developed with XPG3 XTI.
Under unusual circumstances, the errors in XPG3 programs may have been masked due to the way in which the programs or libraries were compiled and linked. It is feasible that the new implementation is able to flag such conditions as errors. Since the error manifested is a programming error in the application, you will have to correct it. The common programming errors that may cause these errors are pointer overruns and uninitialized variables.
Another issue to consider is the availability of XNS4.0 features through STREAMS special files. This is significant if your application accepts command line input for the specifying transport protocol or imports the protocol names from some configuration files. Since the system configured with XTI will have the file names for XNS4.0-compliant protocols as well, it is important to warn users and administrators that those special names should not be used with applications running with binary-compatibility mode. The results of such an action are undefined.
If you are planning to run an old applications without recompiling them,
check them for binary compatibility to avoid these problems.
3.6.4 Packaging
Systems running the current version of the operating system and configured
to run XTI support both XPG3 and XNS4.0-compliant functionality.
You cannot
run the XPG3 and XNS4.0 functionality separately.
Therefore, you only need
to ensure that XTI subsystem is configured.
3.6.5 Interoperability
You can use the XPG3 and XNS4.0 versions of XTI on the same network. If you are using compatible versions of your application, then the operation should be transparent to users.
It is possible to of convert your application in simple steps, so that
you have some pieces that are XPG3 XTI compatible and some pieces that are
XNS4.0 compatible.
The only thing you have to ensure is that application-level
protocol remains the same.
Apart from that there will be no issue for interoperability
of these components.
Therefore, if you have client and server components
of an application, you can choose to upgrade the server component for XNS4.0
compliance, while the client component is still operational in binary compatibility
mode.
Later, once the server functionality is updated satisfactorily, you
can choose to update the client software.
3.6.6 Using XTI Options
This section provides information on using XTI
options in XNS4.0 and XPG3.
3.6.6.1 Using XTI Options in XNS4.0
This section provides the following information on using XTI options:
General information on using options
Format of options
Elements of negotiation
Option management of transport endpoint
General Information
The following functions contain an
opt
argument
of the type
struct netbuf
as an input or output parameter.
This argument is used to convey options between the transport user and the
transport provider:
t_accept
t_connect
t_listen
t_optmgmt
t_rcvconnect
t_rcvudata
t_rcvuderr
t_sndudata
There is no general definition about the possible contents of options. There are general XTI options and those that are specific for each transport provider. Some options allow you to tailor your communication needs; for instance, by asking for high throughput or low delay. Others allow the fine-tuning of the protocol behavior so that communication with unusual characteristics can be handled more effectively. Other options are for debugging purposes.
All options have default values. Their values have meaning to and are defined by the protocol level in which they apply. However, their values can be negotiated by a transport user. This includes the simple case where the transport user can enforce its use. Often, the transport provider or even the remote transport user can have the right to negotiate a value of lesser quality than the proposed one, that is, a delay can become longer, or a throughput can become lower.
It is useful to differentiate between options that are association-related and those that are not. (Association-related means a pair of communication transport users.) Association-related options are intimately related to the particular transport connection or datagram transmission. If the calling user specifies such an option, some ancillary information is transferred across the network in most cases. The interpretation and further processing of this information is protocol-dependent. For instance, in an ISO connection-oriented communication, the calling user can specify quality-of-service parameters on connection establishment. These are first processed and possibly lowered by the local transport provider, then sent to the remote transport provider that may degrade them again, and finally conveyed to the called user who makes the final selection and transmits the selected values back to the caller.
Options that are not association-related do not contain information
destined for the remote transport user.
Some have purely local relevance;
for example, an option that enables debugging.
Others influence the transmission;
for instance, the option that sets the IP
time-to-live
field or TCP_NODELAY.
(See
xti_internet
(7).) Local options are negotiated
solely between the transport user and the local transport provider.
The distinction
between these two categories of options is visible in XTI through the following
relationship: on output, the
t_listen
and
t_rcvudata
functions return association-related options only.
The
t_rcvconnect
and
t_rcvuderr
functions may return
options of both categories.
On input, options of both categories may be specified
with the
t_accept
and
t_sndudata
functions.
The
t_connect
and
t_optmgmt
functions
can process and return both categories of options.
The transport provider has a default value for each option it supports. These defaults are sufficient for the majority of communication relations. Therefore, a transport user should only request options actually needed to perform the task and leave all others at their default value.
This section describes the general framework for the use of options.
This framework is obligatory for transport providers.
The
t_optmgmt
reference page provides information on general XTI options.
The
xti_internet
reference page provides information on the specific
options that are legal with the TCP and UDP transport providers.
Format of Options
Options are conveyed through an
opt
argument of
struct netbuf
.
Each option in the buffer specified
is of the form
struct t_opthdr
possibly followed by an
option value.
A transport provider embodies a stack of protocols.
The
level
field of
struct t_opthdr
identifies
the XTI level or a protocol of the transport provider as TCP or ISO 8073:1986.
The
name
field identifies the option within the
level and the
len
field contains the total length;
that is, the length of the option header
t_ophdr
plus the
length of the option value.
The
status
field is
used by the XTI level or the transport provider to indicate success or failure
of a negotiation.
Several options can be concatenated; however, The transport user has
to ensure that each option starts at a long-word boundary.
The macro
OPT_NEXTHDR(pbuf,buflen,poptons)
can
be used for that purpose.
The parameter
pbuf
denotes
a pointer to an option buffer
opt.buf
and
buflen
is its length.
The parameter
poption
points to the current options in the option buffer.
OPT_NEXTHDR
returns a pointer to the position of the next option or returns
a null pointer if the option buffer is exhausted.
The macro is helpful for
writing and reading the option list.
Elements of Negotiation
This section describes the general rules governing the passing
and retrieving of options and the error conditions that can occur.
Unless
explicitly restricted, these rules apply to all functions that allow the exchange
of options.
Multiple Options and Options Levels
When multiple options are specified in an option buffer on input, different
rules apply to the levels that may be specified, depending on the function
call.
Multiple options specified on input to
t_optmgmt
must address the same option level.
Options specified on input to
t_connect
,
t_accept
, and
t_sndudata
can address different levels.
Illegal Options
Only legal options can be negotiated; illegal options can cause failure. An option is illegal if one of the following applies:
The length specified in the t_opthdr.len parameter exceeds the remaining size of the option buffer (counted from the beginning of the option).
The option value is illegal.
The legal values are defined
for each option.
See
t_optmgmt
(3)
and
xti_internet
(7).
If an illegal option is passed to XTI, the following will happen:
A call to the
t_optmgmt
function fails
with a TBADOPT error.
The
t_accept
or
t_connect
functions fail with a TBADOPT error or the connection establishment aborts,
depending on the implementation and the time the illegal option is detected.
If the connection aborts, a T_DISCONNECT event occurs and a synchronous call
to
t_connect
fails with a TLOOK error.
It depends on timing
and implementation conditions whether a
t_accept
function
will succeed or fail with a TLOOK error in that case.
A call to the
t_sndudata
function either
fails with a TBADOPT error or it successfully returns; but a T_UDERR event
occurs to indicate that the datagram was not sent.
If the transport user passes multiple options in one call and one of
them is illegal, the call fails as described previously.
It is, however,
possible that some or even all of the submitted legal options were successfully
negotiated.
The transport user can check the current status by a call to
the
t_optmgmt
function with the T_CURRENT flag set.
See
t_optmgmt
(3)
and
xti_internet
(7).
Specifying an option level unknown to or not supported by the protocol
selected by the option level does not cause failure.
The option is discarded
in calls to the
t_connect
,
t_accept
,
or
t_sndudata
functions.
The
t_opmgmt
function returns T_NOTSULPORT in the
level
field
of the option.
Initiating an Option Negotiation
A transport user initiates an option negotiation when calling the
t_connect
,
t_sndudata
, or
t_optmgmt
functions with the T_NEGOTIATE flag set.
The negotiation rules for these functions depend on whether an option
request is an absolute requirement.
This is explicitly defined for each option.
See
t_optmgmt
(3)
and
xti_internet
(7).
In the case of an ISO transport
provider, for example, the option that requests use of expedited data is not
an absolute requirement.
On the other hand, the option that requests protection
could be an absolute requirement.
Note
The term absolute requirement originates from the quality-of-service parameters in the ISO 8072:1986 specification. Its use is extended here to all options.
If the proposed option value is an absolute requirement, there are three possible outcomes:
The negotiated value is the same as the proposed one.
When
the result of the negotiation is retrieved, the
status
field in
t_opthdr
is set to T_SUCCESS.
The negotiation is rejected if the option is supported but the proposed value cannot be negotiated. This leads to the following:
The
t_optmgmt
function successfully returns;
but the returned option has its
status
field set
to T_FAILURE.
Any attempt to establish a connection aborts; a T_DISCONNECT
event occurs and a synchronous call to the
t_connect
function
fails with a TLOOK error.
The
t_sndudata
function fails with a TLOOK
error or successfully returns; but a T_UDERR event occurs to indicate that
the datagram was not sent.
If multiple options are submitted in one call and one of them is rejected, XTI behaves as just described. Although the connection establishment or the datagram transmission fails, options successfully negotiated before some option was rejected retain their negotiated values. There is no roll-back mechanism. See the Option Management of a Transport Endpoint section for more information.
The
t_optmgmt
function attempts to negotiate each
option.
The
status
fields of the returned options
indicate success (T_SUCCESS) or failure (T_FAILURE).
If the local transport provider does not support the option
at all, the
t_optmgmt
function reports T_NOTSULPORT in
the
status
field.
The
t_connect
and
t_sndudata
functions ignore this option.
If the proposed option value is not an absolute requirement, the following outcomes are possible:
The negotiated value is of equal or lesser quality than the proposed one; for example, a delay may become longer.
When the result of the negotiation is retrieved, the
status
field in
t_opthdr
is set to T_SUCCESS if
the negotiated value equals the proposed one; otherwise, it is set to T_PARTSUCCESS.
If the local transport provider does not support the option
at all,
t_optmgmt
reports T_NOTSULPORT in the
status
field.
The
t_connect
and
t_sndudata
functions ignore this option.
Unsupported options do not cause functions to fail or a connection to abort, since different vendors possibly implement different subsets of options. Furthermore, future enhancements of XTI might encompass additional options that are unknown to earlier implementations of transport providers. The decision whether or not the missing support of an option is acceptable for the communication is left to the transport user.
The transport provider does not check for multiple occurrences of the same options, possibly with different option values. It simply processes the options in the option buffer sequentially. However, the user should not make any assumption about the order of processing.
Not all options are independent of one another. A requested option value might conflict with the value of another option that was specified in the same call or is currently effective. See the Option Management of a Transport Endpoint section for more information. These conflicts may not be detected at once, but they might later lead to unpredictable results. If detected at negotiation time, these conflicts are resolved within the rules stated above. The outcomes may thus be quite different and depend on whether absolute or nonabsolute requests are involved in the conflict.
Conflicts are usually detected at the time a connection is established
or a datagram is sent.
If options are negotiated with the
t_optmgmt
function, conflicts are usually not detected at this time, since
independent processing of the requested options must allow for temporal inconsistencies.
When called, the
t_connect
, and
t_sndudata
functions initiate a negotiation of all association-related options
according to the rules of this section.
Options not explicitly specified
in the function calls themselves are taken from an internal option buffer
that contains the values of a previous negotiation.
See the
Option Management of a Transport Endpoint section
for more information.
Responding to a Negotiation Proposal
In connection-oriented communication, some protocols give the peer transport
users the opportunity to negotiate characteristics of the transport connection
to be established.
These characteristics are association-related options.
With the connect indication, the called user receives (through the
t_listen
function) a proposal about the option values that should
be effective for this connection.
The called user can accept this proposal
or weaken it by choosing values of lower quality; for example, longer delays
than proposed.
The called user can, of course, refuse the connection establishment
altogether.
The called user responds to a negotiation proposal using the
t_accept
function.
If the called transport user tries to negotiate
an option of higher quality than proposed, the outcome depends on the protocol
to which that option applies.
Some protocols may reject the option, some
protocols take other appropriate action described in protocol-specific reference
pages.
If an option is rejected, the connection fails; a T_DISCONNECT event
occurs.
In that case, whether a
t_accept
function can
still succeed or fail with a TLOOK error depends on timing and implementation
conditions.
If multiple options are submitted with the
t_accept
function and one of them is rejected, the connection fails as described previously.
Options that could be successfully negotiated before the erroneous option
was processed retain their negotiated value.
There is no rollback mechanism.
See the
Option Management of a Transport
Endpoint section
for more information.
The response options can either be specified with the
t_accept
call or can be preset for the responding endpoint (not the listening
endpoint)
resfd
in a
t_optmgmt
call (action T_NEGOTIATE) prior to the
t_accept
call.
(See the
Option Management of a Transport
Endpoint section
for more information.) Note that the response to
a negotiation proposal is activated when the
t_accept
function
is called.
A
t_optmgmt
function call with erroneous option
values as described previously will succeed; the connection aborts at the
time the
t_accept
function is called.
The connection also fails if the selected option values lead to contradictions.
The
t_accept
function does not check for multiple
specification of an option.
(See
the Initiating
an Option Negotiation section.) Unsupported options are ignored.
Retrieving Information About Options
This section describes how a transport user can retrieve information about options.
A transport user must be able to:
Know the result of a negotiation; for example, at the end of a connection establishment.
Know the proposed option values under negotiation during connection establishment.
Retrieve option values sent by the remote transport user for notification only; for example, IP options.
Check option values currently in effect for the transport endpoint.
To this end, the following functions take an output argument
opt
of the
struct netbuf
:
t_connect
t_listen
t_optmgmt
t_rcvconnect
t_rcvudata
t_rcvuderr
The transport user has to supply a buffer to which the options will be written; the opt.buf parameter must point to this buffer and the opt.maxlen parameter must contain the buffer's size. The transport user can set the opt.maxlen parameter to zero to indicate that no options are to be retrieved.
Which options are returned depend on the function call involved:
t_connect
in synchronous mode and
t_rcvconnect
The functions return the values of all association-related options that
were received with the connection response and the negotiated values of those
nonassociation-related options that had been specified on input.
However,
options specified on input in the
t_connect
call that are
not supported or refer to an unknown option level are discarded and not returned
on output.
The
status
field of each option returned
with the
t_connect
or
t_rcvconnect
function
indicates if the proposed value (T_SUCCESS) or a degraded value (T_PARTSUCCESS)
has been negotiated.
The
status
field of received
ancillary information (for example, IP options) that is not subject to negotiation
is always set to T_SUCCESS.
t_listen
The received association-related options are related to the incoming
connection (identified by the sequence number), not to the listening endpoint.
(However, the option values currently in effect for the listening endpoint
can affect the values retrieved by the
t_listen
function,
since the transport provider might also be involved in the negotiation process.)
Therefore, if the same options are specified in a call to the
t_optmgmt
function with action T_CURRENT, they will usually not return the
same values.
The number of received options may vary for subsequent connect indications, since many association-related options are only transmitted on explicit demand by the calling user; for example, IP options or ISO 8072:1986 throughput. It is even possible that no options at all are returned.
The status field is irrelevant.
t_rcvudata
The received association-related options are related to the incoming
datagram, not to the transport endpoint
fd.
Therefore,
if the same options are specified in a call to the
t_optmgmt
function with action T_CURRENT, the
t_optmgmt
function
will usually not return the same values.
The number of options received may vary from call to call.
The status field is irrelevant.
t_rcvuderr
The returned options are related to the options input of the previous
t_sndudata
call that produced the error.
Which options are returned
and which values they have depend on the specific error condition.
The
status
field is irrelevant.
t_optmgmt
This call can process and return both categories of options.
It acts
on options related to the specified transport endpoint, not on options related
to a connect indication or an incoming datagram.
For more information, see
t_optmgmt
(3).
Privileged and Read-Only
Options
Only privileged users can request privileged options, or option values. The meaning of privilege is hereby implementation-defined.
Read-only options serve for information purposes only. The transport user may be allowed to read the option value but not to change it. For instance, to select the value of a protocol timer or the maximum length of a protocol data unit may be too subtle to leave to the transport user, though the knowledge about this value might be of some interest. An option might be read-only for all users or solely for nonprivileged users. A privileged option might be inaccessible or read-only for nonprivileged users.
An option might be negotiable in some XTI states and read-only in other XTI states. For instance, the ISO quality-of-service options are negotiable in the T_IDLE and T_INCON states, and read-only in all other states (except T_UNINIT).
If a transport user requests negotiation of a read-only option, or a nonprivileged user requests illegal access to a privileged option, the following outcomes are possible:
The
t_optmgmt
function successfully returns,
but the returned option has its
status
field set
to T_NOTSULPORT if a privileged option was requested illegally, and to T_READONLY
if modification of a read-only option was requested.
If negotiation of a read-only option is requested, the
t_accept
or
t_connect
functions fail with TACCES
or the connection establishment aborts and a T_DISCONNECT event occurs.
If
the connection aborts, a synchronous call to
t_connect
fails with TLOOK.
If a privileged option is illegally requested, the option
is quietly ignored.
A nonprivileged user is not able to select an option that
is privileged or unsupported.
Timing and implementation conditions determine
whether a
t_accept
call succeeds or fails with TLOOK.
If negotiation of a read-only option is requested, the
t_sndudata
function may return TLOOK or successfully return, but
a T_UDERR event occurs to indicate that the datagram was not sent.
If a privileged
option is illegally requested, the option is quietly ignored.
A nonprivileged
user cannot select an option that is privileged or unsupported.
If multiple options are submitted to the
t_connect
,
t_accept
, or
t_sndudata
functions and a read-only
option is rejected, the connection or the datagram transmission fails as described.
Options that could be successfully negotiated before the erroneous option
was processed retain their negotiated values.
There is no rollback mechanism.
See the
Option Management of a Transport
Endpoint section
for more information.
Option Management of
a Transport Endpoint
This section describes how option management works during the lifetime of a transport endpoint.
Each transport endpoint is (logically) associated with an internal option buffer. When a transport endpoint is created, this buffer is filled with a system default value for each supported option. Depending on the option, the default may be OPTION ENABLED, OPTION DISABLED, or denote a time span, and so on. These default settings are appropriate for most uses. Whenever an option value is modified in the course of an option negotiation, the modified value is written to this buffer and overwrites the previous one. At any time, the buffer contains all option values that are currently effective for this transport endpoint.
The current value of an option can be retrieved at any time by calling
the
t_optmgmt
function with the T_CURRENT flag set.
Calling
the
t_optmgmt
function with the T_DEFAULT flag set yields
the system default for the specified option.
A transport user can negotiate new option values by calling the
t_optmgmt
function with the T_NEGOTIATE flag set.
The negotiation
follows the rules described in the
Elements of
Negotiation section.
Some options may be modified only in specific XTI states and are read-only in other XTI states. Many association-related options, for instance, may not be changed in the T_DATAXFER state, and an attempt to do so fails; see the Privileged and Read-Only Options section. The legal states for each option are specified with its definition.
As usual, association-related options take effect at the time a connection
is established or a datagram is transmitted.
This is the case if they contain
information that is transmitted across the network or determine specific transmission
characteristics.
If such an option is modified by a call to the
t_optmgmt
function, the transport provider checks whether the option
is supported and negotiates a value according to its current knowledge.
This
value is written to the internal option buffer.
The final negotiation takes place if the connection is established or the datagram is transmitted. This can result in a degradation of the option value or even in a negotiation failure. The negotiated values are written to the internal option buffer.
Some options can be changed in the T_DATAXFER state; for example, those specifying buffer sizes. Such changes might affect the transmission characteristics and lead to unexpected side effects; for example, data loss if a buffer size was shortened.
The transport user can explicitly specify both categories of options
on input when calling the
t_connect
,
t_accept
, or
t_sndudata
functions.
The options are at
first locally negotiated option by option and the resulting values written
to the internal option buffer.
The modified option buffer is then used if
a further negotiation step across the network is required; for example, in
connection-oriented ISO communication.
The newly negotiated values are then
written to the internal option buffer.
At any stage, a negotiation failure can cause the transmission to abort. If a transmission aborts, the option buffer preserves the content it had at the time the failure occurred. Options that could be negotiated before the error occurred are written back to the option buffer, whether the XTI call fails or succeeds.
It is up to the transport user to decide which option it explicitly
specifies on input when calling the
t_connect
,
t_accept
, or
t_sndudata
functions.
The transport
user need not pass options at all by setting the
len
field of the function's input
opt
argument to zero
(0).
The current content of the internal option buffer is then used for negotiation
without prior modification.
The negotiation procedure for options at the time of a
t_connect
,
t_accept
, or
t_sndudata
call always obeys the rules in
the Initiating
an Option Negotiation section
whether the options were explicitly specified
during the call or implicitly taken from the internal option buffer.
The transport user should not make assumptions about the order in which options are processed during negotiation.
A value in the option buffer is only modified as a result of a successful
negotiation of this option.
It is, in particular, not changed by a connection
release.
There is no history mechanism that would restore the buffer state
existing prior to the connection establishment of the datagram transmission.
The transport user must be aware that a connection establishment or a datagram
transmission may change the internal option buffer, even if each option was
originally initialized to its default value.
The Option Value T_UNSPEC
Some options may not always have a fully specified value. An ISO transport provider, for instance, that supports several protocol classes might not have a preselected preferred class before a connection establishment is initiated. At the time of the connection request, the transport provider may conclude from the destination address, quality-of-service parameters, and other locally available information which preferred class it should use. A transport user asking for the default value of the preferred class option in the T_IDLE state would get the value T_UNSPEC. This value indicates that the transport provider did not yet select a value. The transport user could negotiate another value as the preferred class; for example, T_CLASS2. The transport provider would then be forced to initiate a connect request with class 2 as the preferred class.
An XTI implementation may also return the T_UNSPEC value if it currently cannot access the option value. This can happen in the T_UNBND state in systems where the protocol stacks reside on separate controller cards and not in the host. The implementation may never return T_UNSPEC if the option is not supported at all.
If T_UNSPEC is a legal value for a specific option, it can be used on input, as well. It is used to indicate that it is left to the provider to choose an appropriate value. This is especially useful in complex options as ISO throughput, where the option value has an internal structure. The transport user can leave some fields unspecified by selecting this value. If the user proposes T_UNSPEC, the transport provider is free to select an appropriate value. This might be the default value, some other explicit value, or T_UNSPEC.
For each option, it is specified whether T_UNSPEC is a legal value for
negotiation purposes.
The info Argument
The
t_open
and
t_getinfo
functions return values representing characteristics of the transport provider
in the
info
argument.
The value of
info->options
is used by the
t_alloc
function
to allocate storage for an option buffer to be used in an XTI call.
The value
is sufficient for all uses.
In general, info->options also includes the size of privileged options; even if these are not read-only for nonprivileged users. Alternatively, an implementation can choose to return different values in info->options for privileged and nonprivileged users.
The values in
info->etsdu,
info->connect, and
info->discon
possibly
diminish as soon as the T_DATAXFER state is entered.
Calling the
t_optmgmt
function does not influence these values.
For more information,
see
t_optmgmt
(3).
Portability Issues
An application programmer who writes XTI programs has the following portability issues across the following:
Protocol profiles
Different system platforms
Options are intrinsically coupled with a definite protocol or protocol profile. Therefore, explicit use of options degrades portability across protocol profiles.
Different vendors might offer transport providers different option support.
This is due to different implementation and product policies.
The list of
options on the
t_optmgmt
(3)
reference page and in the protocol-specific reference pages
are maximal sets, but do not necessarily reflect common implementation practice.
Vendors implement subsets that suit their needs.
Therefore, making careless
use of options endangers portability across different system platforms.
Every implementation of a protocol profile accessible by XTI can be used with the default values of options. Applications can thus be written that do not care about options at all.
An application program that processes options retrieved from an XTI
function should discard options it does not know to lessen its dependence
from different system platforms and future XTI releases with possibly increased
option support.
3.6.6.2 Negotiating Protocol Options in XPG3
The Tru64 UNIX
XPG3 implementation of XTI provides an optional function,
t_optmgmt
, for retrieving, verifying, and negotiating protocol options with
transport providers.
After you create an endpoint with
t_open
and bind an address to it, you can verify or negotiate options with the transport
provider.
Note
Although other transport providers may support the
t_optmgmt
function, the TCP transport provider provided with this operating system does not. See the transport provider documentation for information about option management.
See
t_optmgmt
(3)
for function syntax, parameters, and errors.
See
Section 3.7
for a general description of XTI errors.
3.7 XTI Errors
XTI returns library errors and system errors. When an XTI function encounters an error, it returns a value of -1, and can do one of the following:
Check the external variable t_errno to get the specific error. (For multithreaded applications, t_errno is thread specific.)
Call the
t_error
function to print the
text of the message associated with the error stored in
t_errno.
Check the state of the transport endpoint with the
t_getstate
function.
Some errors change the state of the endpoint.
Note
Since a successful call to an XTI function does not clear the contents of t_errno, check t_errno only after an error occurs.
The
<xti.h>
header file defines the
t_errno
variable as a macro as follows:
#define t_errno(*_t_errno())
For more information on errors, see the individual XTI reference pages.
3.8 Configuring XTI Transport Providers
Use the
xtiso
kernel configuration option to configure XTI transport providers.
You can
configure the
xtiso
option into your system at installation
time or you can add it to your system using the
doconfig
command.
See the
Installation Guide.
You can use the
doconfig
command in one of the following
ways:
Use the
doconfig
command without options
if you have not customized your kernel.
Without options the
doconfig
command creates a new kernel configuration file for your system.
Use the
doconfig -c
command if you
have customized your kernel and you do not want to recustomize it.
The
doconfig -c
command allows you to add information to the existing
kernel configuration file.
To use the
doconfig
command without any options,
do the following:
Enter the
/usr/sbin/doconfig
command at
the superuser prompt (#).
Enter a name for the kernel configuration file. It should be the name of your system in uppercase letters, and will probably be the default provided in square brackets ([]). For example:
Enter a name for the kernel configuration file. [HOST1]:
[RETURN]
Enter
y
when the system asks whether you
want to replace the system configuration file.
For example:
A configuration file with the name 'HOST1' already exists.
Do you want to replace it? (y/n) [n]:
y
Saving /sys/conf/HOST1 as /sys/conf/HOST1.bck
*** KERNEL CONFIGURATION AND BUILD PROCEDURE ***
Select the
X/Open Transport Interface (XTISO, TIMOD,
TIRDWR)
option from the Kernel Option Selection menu.
Confirm your
choice at the prompt.
For example:
*** KERNEL OPTION SELECTION *** Selection Kernel Option -------------------------------------------------------------- 1 System V Devices 2 NTP V3 Kernel Phase Lock Loop (NTP_TIME) 3 Kernel Breakpoint Debugger (KDEBUG) 4 Packetfilter driver (PACKETFILTER) 5 Point-to-Point Protocol (PPP) 6 STREAMS pckt module (PCKT) 7 X/Open Transport Interface (XTISO, TIMOD, TIRDWR) 8 File on File File System (FFM) 9 ISO 9660 Compact Disc File System (CDFS) 10 Audit Subsystem 11 ACL Subsystem 12 Logical Storage Manager (LSM) 13 Advanced File System (ADVFS) 14 All of the above 15 None of the above 16 Help -------------------------------------------------------------- Enter the selection number for each kernel option you want. For example, 1 3 [15]: 7Enter the selection number for each kernel option you want.
For example, 1 3 :
7
You selected the following kernel options:
X/Open Transport Interface (XTISO, TIMOD, TIRDWR)
Is that correct? (y/n) [y]:
y
Configuration file complete.
Enter
n
when the
doconfig
command asks whether you want to edit the configuration file.
The
doconfig
command then creates device special
files, indicates where a log of the files it created is located, and builds
the new kernel.
After the new kernel is built, you must move it from the
directory where
doconfig
places it to the root directory
(
/
) and reboot your system.
When you reboot, the
strsetup -i
command runs
automatically, creating the device special files for any new STREAMS modules.
Enter the
strsetup -c
command to
verify that the device is configured properly.
The following example shows the output from the
strsetup -c
command:
#
/usr/sbin/strsetup -c
STREAMS Configuration Information...Fri Nov 3 14:23:36 1995 Name Type Major Module ID ---- ---- ----- --------- clone 32 0 dlb device 52 5010 kinfo device 53 5020 log device 54 44 nuls device 55 5001 echo device 56 5000 sad device 57 45 pipe device 58 5304 xtisoUDP device 59 5010 xtisoTCP device 60 5010 xtisoUDP+ device 61 5010 xtisoTCP+ device 62 5010 ptm device 63 7609 pts device 6 7608 bba device 64 24880 lat device 5 5 pppif module 6002 pppasync module 6000 pppcomp module 6001 bufcall module 0 null module 5002 pass module 5003 errm module 5003 ptem module 5003 spass module 5007 rspass module 5008 pipemod module 5303 timod module 5006 tirdwr module 0 ldtty module 7701 Configured devices = 15, modules = 14
To use the
doconfig -c
command to add the XTISO
option to the kernel configuration file, do the following:
Enter the
doconfig -c
HOSTNAME
command from the superuser prompt (#).
HOSTNAME
is the name of your system in uppercase letters.
For
example, for a system called
host1
you would enter:
#
doconfig -c HOST1
Add XTISO to the options section of the kernel configuration file.
Enter
y
at the prompt to edit the kernel configuration
file.
The
doconfig
command allows you to edit the configuration
file with the
ed
editor.
For information about using the
ed
editor, see
ed
(1).
The following
ed
editing session shows how to add
the XTISO option to the kernel configuration file for
host1
.
The number of the line after which you append the new line can differ between
kernel configuration files:
*** KERNEL CONFIGURATION AND BUILD PROCEDURE ***
Saving /sys/conf/HOST1 as /sys/conf/HOST1.bck
Do you want to edit the configuration file? (y/n) [n]:
y
Using ed to edit the configuration file. Press return when ready,
or type 'quit' to skip the editing session:
2153
48a
options XTISO
.
1,$w
2185
q
*** PERFORMING KERNEL BUILD ***
After the new kernel is built you must move it from the directory
where
doconfig
places it to the root directory (/
) and reboot your system.
When you reboot, the
strsetup -i
command is
run automatically, creating the device special files for any new STREAMS modules.
Run the
strsetup -c
command to verify
that the device is configured properly.
The following example shows the output from the
strsetup -c
command:
#
/usr/sbin/strsetup -c
STREAMS Configuration Information...Fri Nov 3 14:23:36 1995 Name Type Major Module ID ---- ---- ----- --------- clone 32 0 dlb device 52 5010 kinfo device 53 5020 log device 54 44 nuls device 55 5001 echo device 56 5000 sad device 57 45 pipe device 58 5304 xtisoUDP device 59 5010 xtisoTCP device 60 5010 xtisoUDP+ device 61 5010 xtisoTCP+ device 62 5010 ptm device 63 7609 pts device 6 7608 bba device 64 24880 lat device 5 5 pppif module 6002 pppasync module 6000 pppcomp module 6001 bufcall module 0 null module 5002 pass module 5003 errm module 5003 ptem module 5003 spass module 5007 rspass module 5008 pipemod module 5303 timod module 5006 tirdwr module 0 ldtty module 7701 Configured devices = 15, modules = 14
For detailed information on reconfiguring your kernel or the
doconfig
command see the
System Administration
manual.