3    X/Open Transport Interface

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:

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

3.1    Overview of XTI

XTI involves the interaction of the following entities:

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

3.2    XTI Features

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:

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:

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 XTIapp XTIappmain.o XTIapputil.o -lxti
 
% cc -o TLIapp TLIappmain.o TLIapputil.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 XTIapp XTIappmain.o XTIapputil.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 the tiuser.h file is /usr/include/tiuser.h.

3.2.2.2    XTI Library Calls

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:

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

3.2.4.2    Incoming Events

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:

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:

The uninitialized state (T_UNINIT) serves two purposes:

3.3.3    Writing a Connection-Oriented Application

Follow these steps to write a connection-mode application:

  1. Initialize an endpoint

  2. Establish a connection

  3. Transfer data

  4. Release a connection

  5. Deinitialize an endpoint

3.3.3.1    Initializing an Endpoint

To initialize an endpoint, complete the following steps:

  1. Open the endpoint

  2. Bind an address to the endpoint

  3. 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, or write 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:

3.3.3.2    Using XTI Options

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:

  1. A passive user, or server, listens for a connection request.

  2. An active user, or client, initiates a connection.

  3. 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:

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:

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:

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:

  1. The active user issues the t_sndrel function to request an orderly release of the connection.

  2. 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.

  3. When ready to disconnect, the passive user issues the t_sndrel function.

  4. 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:

  1. Initializing an endpoint

  2. Transferring data

  3. 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:

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:

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:

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:

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:

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:

  1. Make sure the TLI header file is included in your source code:

    #include <tli/tiuser.h>
    

  2. 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.

To make a TLI application a true XTI application, do the following:

  1. Include the XTI header file instead of the TLI header file in your source code:

    #include <xti.h>
     
    

  2. Make any changes or extensions to your program resulting from the differences between TLI and XTI.

  3. 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 the select 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:

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:

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

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:

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:

If an illegal option is passed to XTI, the following will happen:

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:

If the proposed option value is not an absolute requirement, the following outcomes are possible:

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:

To this end, the following functions take an output argument opt of the struct netbuf:

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:

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:

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:

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:

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:

To use the doconfig command without any options, do the following:

  1. Enter the /usr/sbin/doconfig command at the superuser prompt (#).

  2. 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]
    

  3. 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 ***
    

  4. 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]: 7
     
    Enter 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.
    

  5. 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.

  6. 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:

  1. 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
    

  2. 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 ***
    

  3. 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.

  4. 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.