Technical Standard: Networking Services (XNS), Issue 5.2 Draft 2.0
Copyright © 1999 The Open Group
Explanatory Notes for XTI
A transport endpoint
specifies a communication path between a
transport user and a specific transport provider, which is identified by
a local file descriptor (.iX "file descriptor" ""
When a user opens a
identifier, a local file descriptor
is returned which identifies the
A transport provider
is defined to be the transport protocol that provides
the services of the transport layer.
All requests to the
must pass through a
The file descriptor
is returned by the function
and is used as an argument to the subsequent functions to
identify the transport endpoint.
A transport endpoint (fd
and local address) can support only one established
transport connection at a time.
To be active, a
must have a transport
address associated with it by the
A transport connection is characterised by the association of two active
endpoints, made by using the
functions of establishment of transport connection.
is a communication path to a
There is no direct assignation of the processes to the
so multiple processes, which obtain the
operations, may access a given communication path.
Note that the
function will work only if the opened character string is a pathname.
Note that in order to guarantee portability, the only operations which
the applications may perform on any
are those defined by XTI and
Other operations are permitted but these will have system-dependent
The transport layer may comprise one or more transport providers
at the same time. The identifier parameter of the transport provider passed
function determines the required transport provider. To keep the applications
identifier parameter of the transport provider
should not be hard-coded into the application source code.
An application which wants to manage
multiple transport providers must call
for each provider.
For example, a server application which is waiting for incoming connection
indications from several transport providers must open a transport endpoint
for each provider and listen for connection
indications on each of the associated file descriptors.
Association of a UNIX Process to an Endpoint
One process can simultaneously open several
However, in synchronous mode, the process must manage the different
actions of the associated transport connections sequentially.
Conversely, several processes can share the same
they have to synchronise themselves so as
not to issue a function that is unsuitable to the current state of the
It is important to remember that the
treats all users of a
as a single user.
If multiple processes are using the same endpoint, they should coordinate
their activities so as not to violate the state of the provider.
function returns the current state of the
provider to the user, thereby enabling the user to verify
the state before taking further action.
This coordination is only valid among cooperating processes;
it is possible that a process or an incoming event could change the
A process can listen for an incoming connection indication on one
and accept the connection on a different
which has been bound with the
set to zero.
This facilitates the writing of a listener application whereby the
listener waits for all incoming connection indications on a given
Transport Service Access Point
(TSAP). The listener will accept the connection on a new
a child process to service the request without blocking other
incoming connection indications.
Use of the Same Protocol Address
If several endpoints are bound to the same protocol address, only one
at the time may be listening for incoming connections.
However, others may be in data transfer state
or establishing a transport
connection as initiators.
Modes of Service
The transport service interface supports two modes of
service: connection-mode and connectionless-mode.
A single transport endpoint may not support both modes of service
The connection-mode transport service is circuit-oriented and
enables data to be
transferred over an established connection in a reliable,
This service enables the negotiation of the
parameters and options that govern the transfer of data.
It provides an identification mechanism that avoids the overhead
of address transmission and resolution during the data transfer
It also provides a context in which successive units of data,
transferred between peer users, are logically related.
This service is attractive to applications that
require relatively long-lived, datastream-oriented interactions.
In contrast, the connectionless-mode transport service
is message-oriented and supports data transfer
in self-contained units with no logical relationship required among
These units are also known as datagrams.
requires a pre-existing association between the
peer users involved, which determines the characteristics of
the data to be transmitted.
No dynamic negotiation of parameters and options is supported by
All the information required to deliver a unit of data
(for example, destination address) is presented to the transport provider,
together with the data to be transmitted, in a single service
access which need not relate to any other service access.
Also, each unit of data transmitted is entirely self-contained,
and can be independently routed by the transport provider.
This service is attractive to
applications that involve short-term request/response
interactions, exhibit a high level of redundancy, are dynamically
reconfigurable or do not require
guaranteed, in-sequence delivery of data.
Two levels of error are defined for the transport interface.
The first is the library error level.
Each library function has one or more error returns.
Failures are indicated by a return value of -1.
When header file
is included, symbol
is defined as a modifiable
can be used to access the specific error number when such
a failure occurs. Applications should not include
in the left operand of assignment statements.
This value is set when errors occur but is not cleared on
successful library calls, so it should be
tested only after an error has been indicated.
A diagnostic function,
prints out information on the current transport error.
The state of the transport provider may change if a transport error occurs.
The second level of error is the operating system service routine level.
A special library level error number has been defined called [TSYSERR]
which is generated by each library function when an operating system
service routine fails
or some general error occurs.
When a function sets
to [TSYSERR], the specific system error may
be accessed through the external variable
For example, a system error can be generated by the
when a protocol error has occurred. If the error is severe, it may
cause the file descriptor and
to be unusable.
To continue in this case, all users of the
must close it.
may be re-opened and initialised.
Synchronous and Asynchronous Execution Modes
The transport service interface is inherently asynchronous;
various events may occur which are independent of the actions of a
For example, a user may be sending data over a transport connection
when an asynchronous disconnection indication arrives.
The user must somehow be informed that the connection has been broken.
The transport service interface supports two execution modes for handling
asynchronous events: synchronous mode and asynchronous mode.
In the synchronous mode of operation, the transport primitives wait for specific
events before returning control to the user.
While waiting, the user cannot perform other tasks.
For example, a function that attempts to receive data in
will wait until data arrives before returning control to the user.
Synchronous mode is the default mode of execution.
It is useful for user processes that want to wait for events to occur,
or for user processes that maintain only a single transport connection.
The asynchronous mode of operation, on the other hand, provides a mechanism
for notifying a user of some event without forcing the user to wait for
The handling of networking events in an asynchronous manner is seen as
a desirable capability of the transport interface.
This would enable users to perform useful work while expecting a
For example, a function that attempts to receive data in asynchronous
mode will return control to the user immediately if no data is available.
The user may then periodically poll for incoming data until it arrives.
The asynchronous mode is intended for those applications that expect long
delays between events and have other tasks that they can perform in the
meantime or handle multiple connections concurrently.
The two execution modes are not provided through separate interfaces
or different functions.
Instead, functions that process incoming events have two
modes of operation: synchronous and asynchronous.
The desired mode is specified through the
flag, which may be set when the transport provider is initially opened,
or before any specific function or group of functions is
executed using the
operating system service routine.
The effect of this flag is local to this process and is completely
specified in the description of each function.
Nine (only eight if the orderly release is not supported)
asynchronous events are defined in the transport
service interface to cover both connection-mode and
They are represented as separate bits in a bit-mask using the following
defined symbolic names:
These are described in
A process that issues functions in synchronous mode must still be
able to recognise certain asynchronous events and act on them if necessary.
This is handled through a special transport error [TLOOK]
which is returned by a function when an asynchronous event occurs.
function is then invoked to identify
the specific event that has occurred when this error is returned.
Another means to notify a process that an asynchronous event has occurred
The polling capability enables processes to do useful work and periodically
poll for one of the above asynchronous events.
This facility is provided by setting O_NONBLOCK
for the appropriate primitive(s).
Events and t_look()
All events that occur at a transport endpoint are stored by XTI. These
events are retrievable one at a time via the
function. If multiple events occur, it is implementation-dependent in
will return the events. An event is outstanding on a transport endpoint
until it is consumed.
Every event has a corresponding consuming function which handles the
event and consumes it.
In addition, the abortive T_DISCONNECT consumes other
Both T_DATA and T_EXDATA events are consumed when the corresponding
consuming function has read all the corresponding data associated with that
event. The intention of this is that T_DATA should always indicate that there is
data to receive.
are also cleared as they are returned by
||Cleared on t_look() ?
||Consuming XTI functions
Table: Events and t_look()
Effect of Signals
In both the synchronous and the asynchronous execution modes, XTI
calls may be affected by signals. Unless specified otherwise in
the description of each function, the functions behave as
If a synchronous XTI call is blocking under circumstances where
an asynchronous call would have returned because no event was
available, then the call returns -1 with
set to [EINTR]. The state of the endpoint is unchanged.
In addition an [EINTR] error may be returned by all XTI calls
under implementation defined
conditions. In these cases the state of the endpoint will not
have been changed, and no data will have been sent or received.
Any buffers provided by the user for return values may have been
A "well written" application will itself mask out signals except
during specific code sequences (typically only its idle point)
to avoid having to handle an [EINTR] return from all system
Application writers should be aware that XTI calls may be
implemented in a library as multiple system calls. In order to
maintain the endpoint and associated library data areas in a
consistent state, some of these system calls may be repeated when
interrupted by a signal.
Applications should not call XTI functions from within a signal
or using the
interfaces (see reference
to exit a signal handler, as either
may leave XTI data areas in an inconsistent state.
Applications may be able to cause the XTI library itself to
generate signals that interrupt its internal actions (for example, by
issuing ioctl( fd, I_SETSIG, S_INPUT ) on a UNIX system); this
may cause the user's signal handler to be scheduled, but will not
stop the XTI call from completing.
Each XTI call deals with one transport endpoint at a time.
It is not possible to wait for several events from
different sources, particularly from several transport connections at
We recognise the need for this functionality which may be available
today in a system-dependent fashion.
Throughout the document we refer to an event management service called Event Management (EM) which provides those functions useful to XTI.
This Event Management
will allow a process to be notified of the following events:
- A connection request from a remote user was
received by a transport provider (connection-mode service only);
this event may occur under the following conditions:
The file descriptor is bound to a valid address.
No transport connection is established at this time.
- In connection mode only; a connection response was received by the
transport provider; occurs after a
has been issued.
- Normal data (whole or part of Transport Service Data Unit (TSDU))
was received by the transport provider.
- Expedited data was received by the transport provider.
- In connection mode only; a disconnection request was received by the
It may be reported on both data transfer functions and connection
establishment functions and on the
- An orderly release request was received by a transport provider
(connection mode with orderly release only).
- In connectionless-mode only; an error was found in a previously sent
It may be notified on the
- Flow control restrictions on normal data flow that led to a [TFLOW]
error have been lifted.
Normal data may be sent again.
- Flow control restrictions on expedited data flow that led to a [TFLOW]
error have been lifted. Expedited data may be sent again.
- This may be implemented as a macro. In addition the name
is an XTI library-reserved-name for use within such a macro. A
typical definition of
for a multithreaded implementation is:
extern int *_t_errno(void);
#define t_errno (*(_t_errno()))
- In the case of the
function the T_CONNECT event is both generated and consumed by the
execution of the function and is therefore not visible to the application.