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 the Digital UNIX operating system XTI is implemented according to the XPG3 and XPG4 specifications. XPG4 is the default. (XPG3 is provided for backward compatibility and is available by using a compiler switch.) For more information about XPG3 and XPG4, see the X/Open Portability Guide Volume 7: Networking Services. The Digital UNIX 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

Digital UNIX 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 Digital UNIX 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 the xti_internet(7) reference page. 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 Digital UNIX 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.

Digital UNIX provides shared library support by default when you link an XTI or TLI application with the XTI or TLI library.

For XTI or TLI applications built in the Digital UNIX Version 1.2 environment to use shared library support, you must relink the required object files with the appropriate library. You do not need to recompile source files.

The first of the following examples illustrates how to relink an XTI application's object files with the XTI shared library; the second illustrates how to relink a TLI application's object files with the TLI shared library:

cc -o XTI app XTI appmain .o  XTI apputil .o -lxti
 
cc -o TLI app TLI appmain .o  TLI apputil .o -ltli

To link programs statically with the XTI or TLI libraries (as was the default in Digital UNIX Version 1.2), use the non_shared option to the cc command.

The following example illustrates how to link an XTI application's object files to the XTI library statically:

cc -non_shared -o XTI app XTI appmain .o  \
      XTI apputil .o -lxti

See the cc(1) reference page 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.

Digital UNIX 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. Digital UNIX 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[Table Note 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[Table Note 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[Table Note 2] Initiates an orderly release COTS_ORD
t_sndudata Sends a data unit CLTS
t_strerror[Table Note 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

Table notes:

  1. This function is supported in XPG4 only.

  2. Digital UNIX as supplied by Digital does not provide a transport provider that supports the use of COTS_ORD; therefore, this function returns an error.

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 [Table Note 1]
t_listen T_DISCONNECT [Table Note 2]
t_rcv T_DISCONNECT, T_ORDREL [Table Note 3]
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 [Table Note 4]

Table notes:

  1. This event occurs only when t_connect is issued for an endpoint that was bound with a qlen > 0, and has a pending connection indication.

  2. This event indicates a disconnect on an outstanding connection indication.

  3. This occurs only when all pending data has been read.

  4. T_DATA may only occur for the connetionless mode.

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. The Digital UNIX 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 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 ).
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    A 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 number in parentheses that indicates an action that the transport user must take. The numbers 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 numeral 1.

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 [Table Note 1] --
unbind -- -- T_UNBND
closed -- T_UNINIT T_UNINIT

Table notes:

  1. Set the count of outstanding connection indications, ocnt, to 0.

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 [Table Note 1] -- T_INCON [Table Note 1] --
accept1 -- -- T_DATAXFER [Table Note 1] --
accept2 -- -- T_IDLE [Table Note 2] [Table Note 3] --
accept3 -- -- T_INCON [Table Note 2] [Table Note 3] --
snd -- -- -- T_DATAXFER
rcv -- -- -- T_DATAXFER
snddis1 -- T_IDLE T_IDLE [Table Note 2] T_IDLE
snddis2 -- -- T_INCON [Table Note 2] --
rcvdis1 -- T_IDLE -- T_IDLE
rcvdis2 -- -- T_IDLE [Table Note 2] --
rcvdis3 -- -- T_INCON [Table Note 2] --
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 notes:

  1. Increment the count of outstanding connection indications.

  2. Decrement the count of outstanding connection indications.

  3. Pass a connection to another transport endpoint, as indicated in the t_accept function.

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. The syntax of the t_open function is as follows:

fd = t_open (name,oflag,&info) ;

In the preceding statement:

fd
Identifies the file descriptor for the endpoint. You use the file descriptor in subsequent calls to identify this transport endpoint.

The t_open function returns a file descriptor upon successful completion. Otherwise, t_open returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)

name
Identifies the transport provider to be accessed. Currently, the XTI implemented in Digital UNIX 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 on a Digital UNIX system 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.

oflag
Specifies whether the endpoint will block on functions to wait for completion. Specify O_RDWR to indicate that the endpoint supports reading and writing by functions and blocks on them, or specify the bitwise inclusive OR of O_RDWR and O_NONBLOCK to indicate the endpoint supports reading and writing by functions but does not block on them. You must use O_RDWR optionally with OR with O_NONBLOCK for the mode flag passed to t_open. In other words, the XTI specification forbids the use of O_RDONLY or O_WRONLY to make the endpoint either read-only or write-only as expected.

info
Returns the pointer to a structure containing the default characteristics of the transport provider. You use these characteristics to determine subsequent calls. The info parameter points to the t_info structure. See t_open(3) for more information.

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.

See t_open(3) for more information.

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

To bind an address to an endpoint, issue the t_bind function with the following syntax:

t_bind (fd,req,ret) ;

In the preceding statement:

fd
Identifies the file descriptor for the endpoint, which is returned by the t_open function.

req
Specifies a pointer to the structure containing the address you wish to bind to the endpoint.

ret
Returns a pointer to the structure containing the address that XTI bound to the endpoint.

See t_bind(3) for more information.

If the transport provider supports the automatic generation of addresses, you have the following choices in binding addresses:

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:

The t_bind function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


3.3.3.2    Using XTI Options

XPG3 and XPG4 implement option management differently.

In XPG3, option management is handled exclusively by the t_optmgmt function. In XPG4, 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.

To listen for connection requests, issue the t_listen function with the following syntax:

t_listen (fd,call) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint where connection indications arrive.

call
Returns a pointer to information describing the connection indication.

See t_listen(3) for more information.

The t_listen function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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.

To initiate a connection, issue the t_connect function with the following syntax:

t_connect (fd,sndcall,rcvcall) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint where the connection will be established.

sndcall
Points to a structure containing information that the transport provider needs to establish the connection.

rcvcall
Points to a structure containing information that the transport provider associates with the connection that was just established.

See t_connect(3) for more information.

The t_connect function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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.

To accept a connection, issue the t_accept function with the following syntax:

t_accept (fd,resfd,call) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint where the connection indication arrived.

resfd
Specifies the file descriptor of the endpoint where the connection will be established.

call
Points to information needed by the transport provider to establish the connection.

See t_accept(3) for more information.

The t_accept function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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:

To send data or expedited data over a connection, issue the t_snd function with the following syntax:

t_snd (fd,buf,nbytes,flags) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint over which data should be sent.

buf
Points to the data.

nbytes
Specifies the number of bytes of data to be sent.

flags
Specifies any optional flags, such as the following:

See t_snd(3) for more information.

The t_snd function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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:

To receive data, issue the t_rcv function with the following syntax:

t_rcv (fd,buf,nbytes,flags) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint through which data arrives.

buf
Points to a buffer where the data that is received will be placed.

nbytes
Specifies the size of the buffer.

flags
Returns the following optional flags that apply to the received data:

See t_rcv(3) for more information.

The t_rcv function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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.

To request an abortive release or to reject a connection indication, issue the t_snddis function with the following syntax:

t_snddis (fd,call) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint.

call
Points to the information associated with the abortive release. This field is only meaningful if the transport user wants to send user data with the disconnect request, or if the transport user is rejecting a connection indication.

See t_snddis(3) for more information.

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. The following is the syntax of the t_rcvdis function:

t_rcvdis (fd,discon) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint where the connection existed.

discon
Points to information about the disconnect.

See t_rcvdis(3) for more information.

Both t_snddis and t_rcvdis return a value of 0 upon successful completion. Otherwise, they return a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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.

To initiate an orderly release, use the t_sndrel function which has the following syntax:

t_sndrel (fd) ;

In the preceding statement:

fd
Specifies the field descriptor of the endpoint.

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 more information.

To acknowledge the receipt of an orderly release indication, issue the t_rcvrel function with the following syntax:

t_rcvrel (fd) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint.

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 more information.

Both t_sndrel and t_rcvrel return a value of 0 upon successful completion. Otherwise, they return a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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. The syntax for t_unbind is as follows:

t_unbind (fd) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint.

See t_unbind(3) for more information.

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.

To close the endpoint, issue the t_close function. The syntax for t_close is as follows:

t_close (fd) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint.

See t_close(3) for more information.

Both t_unbind and t_close return a value of 0 upon successful completion. Otherwise, they return a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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.

To send a data unit, issue the t_sndudata function with the following syntax:

t_sndudata (fd,unitdata) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint through which data is sent.

unitdata
Points to the t_unitdata structure.

See t_sndudata(3) for more information.

The t_sndudata function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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:

To receive data, issue the t_rcvudata function with the following syntax:

t_rcvudata (fd,unitdata,flags) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint through which data is received.

unitdata
Points to the data to be sent, which consists of the following fields:

flags
Indicates whether a complete data unit was received (no flag) or a portion of a data unit was received (T_MORE flag).

See t_rcvudata(3) for more information.

The t_rcvudata function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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) ;

In the preceding statement:

fd
Specifies the file descriptor of the endpoint through which the error report is received.

uderr
Points to the t_uderr structure, which identifies the error.

See t_rcvuderr(3) for more information.

The t_rcvuderr function returns a value of 0 upon successful completion. Otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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[Table Note 1] Returns the protocol address.
t_getstate Returns the current state of the endpoint.
t_strerror[Table Note 1] 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.

Table notes:

  1. This function is supported in XPG4 only.

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, Digital recommends that you 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. Note that Digital UNIX provides shared library support by 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 Digital 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 Digital UNIX or change to the polling mechanism provided with Digital UNIX.

Because the Digital UNIX implementation of TLI is compatible at the source level with AT&T TLI, you can recompile your TLI program with the Digital 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 [Table Note 1]
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 -- --

Table notes:

  1. In XTI, the t_listen function specifies the queue length parameter as well as waiting for the incoming connection. In sockets, the listen function only specifies the queue length parameter.

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 re-establish 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 XPG4

This section provides information on the differences between the XPG3 and XPG4 implementation of XTI.

In earlier versions of Digital UNIX, the XTI implementation conformed to X/Open's XPG3 specification. The current implementation conforms to SPEC1170's XTI (part of Networking Services' specification) as well as X/Open's XPG4 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 Digital UNIX converges both XPG3 and XPG4 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 SPEC1170 or SPEC1170 XTI are used to refer to the implementation of XTI available in this version of Digital 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 Digital 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 SPEC1170:

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 XPG4 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 Digital UNIX:

Which option you choose will depend on your situation. The following sections describe these conditions in details.


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    SPEC1170 Compliant Application

If you need to use the new features supported by SPEC1170 XTI, you will have to make changes in your source code. You cannot combine the features from the XPG3 and SPEC1170 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 SPEC1170 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

Application binaries developed with XPG3 XTI will run on systems running the current version of Digital UNIX. However, there are certain conditions of which you should be aware.

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 SPEC1170 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 SPEC1170-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 Digital UNIX and configured to run XTI support both XPG3 and SPEC1170-compliant functionality. You cannot run the XPG3 and SPEC1170 functionality separately. Therefore, you only need to ensure that XTI subsystem is configured.


3.6.5    Interoperability

You can use the XPG3 and SPEC1170 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 SPEC1170 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 SPEC1170 compliance, while the client component is still operational in binary compatibility mode. Later on, 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 XPG4 and XPG3.


3.6.6.1    Using XTI Options in XPG4

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 may 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 that 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 the xti_internet(7) reference page.) 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 the following applies:

If and 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 the t_optmgmt(3) and xti_internet(7) reference pages.

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 the t_optmgmt(3) and xti_internet(7) reference pages. 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 following error occurs:

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 function 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 change 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 the t_optmgmt(3) reference page.


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 lists 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 Digital 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. To do so, issue the t_optmgmt function, with the following syntax:

t_optmgmt (fd,req,ret) ;

In the preceding statement:

fd
Identifies the file descriptor for the endpoint, which is returned by the t_open function.


req
Points to a t_optmgmt structure that sends protocol options to the transport provider and requests actions of the transport provider.

ret
Points to a t_optmgmt structure that returns the valid protocol options and the actions taken by the transport provider.

Both the req and ret arguments point to a t_optmgmt structure.

Note

Although other transport providers may support the t_optmgmt function, the Digital UNIX TCP transport provider does not. See the transport provider documentation for information about option management.

See t_optmgmt(3) for more information.

The t_optmgmt function returns a value of 0 upon successful completion; otherwise, it returns a value of -1, and t_errno is set to one of the values described in Section 3.7. (For multithreaded applications, t_errno is thread specific.)


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