Previous section.
Technical Standard: Networking Services (XNS), Issue 5.2 Draft 2.0
Copyright © 1999 The Open Group
XTI Overview
Overview of Connection-oriented Mode
The connection-mode transport service consists of four phases
of communication:
-
Initialisation/De-initialisation
-
Connection Establishment
-
Data Transfer
-
Connection Release.
A state machine is described in
Transport Service Interface Sequence of Functions,
and the figure in
Example in Connection-oriented Mode,
which defines the
legal sequence in which functions from each phase may be issued.
In order to establish a transport connection, a user (application) must:
-
supply a transport provider identifier
for the appropriate type of transport provider (using
t_open());
this establishes a transport endpoint through which the user
may communicate with the provider
-
associate (bind) an address with this endpoint (using
t_bind())
-
use the appropriate connection functions (using
t_connect(),
or
t_listen()
and
t_accept())
to establish a transport connection; the set of functions depends on
whether the user is an initiator or responder
-
once the connection is established, normal, and if authorised,
expedited data can be exchanged; of course, expedited data may be
exchanged only if:
-
the provider supports it
-
its use is not precluded by the selection of
protocol characteristics; for example, the use of ISO Transport Class 0
-
both the peer tranport providers support the feature, have
negotiated it if necessary, and the peer applications have
agreed to its use.
The semantics of expedited data may be quite different
for different transport providers. XTI's notion of
expedited data has been defined as the lowest
reasonable common denominator.
The transport connection can be released at any time by using the
disconnection functions.
Then the user can either de-initialise the transport endpoint by closing the
file descriptor returned by
t_open()
(thereby freeing the resource for future use),
or specify a new local address (after the old one has been unbound) or
reuse the same address and
establish a new transport connection.
When reusing an endpoint, the user should be aware that the local
address may be different from that originally bound (for example,
one of the
systems' local addresses may be explicitly associated with the
endpoint, or the address may have been changed during
t_accept()).
The value of certain options will also reflect the previous connect and
may need to be reset (see the definition for
t_optmgmt())
to the providers' default values.
Initialisation/De-initialisation Phase
The functions that support initialisation/de-initialisation
tasks are described below.
All such functions provide local management functions.
- t_open()
- This function creates a transport endpoint and returns
protocol-specific information associated with that endpoint.
It also returns a file descriptor that
serves as the local identifier of the endpoint.
- t_bind()
- This function associates a protocol address with a given transport
endpoint, thereby activating the endpoint.
It also directs the transport provider to begin accepting connection
indications if so desired.
- t_unbind()
- This function disables a transport endpoint such that
no further request
destined for the given endpoint will be accepted by the
transport provider.
- t_close()
- This function informs the transport provider that the user is
finished with the transport endpoint, and frees any local
resources associated with that endpoint.
The following functions are also local management functions, but
can be issued during any phase of communication:
- t_getprotaddr()
- This function returns the addresses (local and remote) associated
with the specified transport endpoint.
- t_getinfo()
- This function returns protocol-specific information associated
with the specified transport endpoint.
- t_getstate()
- This function returns the current state of the transport
endpoint.
- t_sync()
- This function synchronises the data structures managed by the
transport library with the transport provider.
- t_alloc()
- This function allocates storage for the specified library data
structure.
- t_free()
- This function frees storage for a library data
structure that was allocated by
t_alloc().
- t_error()
- This function prints out a message describing the last error
encountered during a call to a transport library
function.
- t_look()
- This function returns the current event associated with the given
transport endpoint.
- t_optmgmt()
- This function enables the user to get or negotiate protocol
options with the transport provider.
- t_strerror()
- This function maps an XTI error into a language-dependent error
message string.
- t_sysconf()
- This function is used to obtain the values of
configurable and implementation-dependent XTI variables.
Overview of Connection Establishment
This phase enables two transport users to establish a transport connection
between them.
In the connection establishment scenario, one user is considered active
and initiates the conversation, while the second user is passive and
waits for a transport user to request a connection.
In connection mode:
-
The user has first to establish an endpoint; that is, to open
a communications
path between the application and the transport provider.
-
Once established, an endpoint must be bound to an address and more
than one
endpoint may be bound to the same address.
A transport user can determine the addresses associated with a connection
using the
t_getprotaddr()
function.
-
An endpoint can be associated with one, and only one, established transport
connection.
-
It is possible to use an endpoint to receive and enqueue incoming connection
indications (only if the provider is able to accept more than one
outstanding connection indication; this mode of operation is declared
at the time of calling
t_bind()
by setting
qlen
greater than 0).
However, if more than one endpoint is bound
to the same address, only one of them may be used in
this way.
-
The
t_listen()
function is used to look for an enqueued connection indication;
if it finds one (at the head of the queue), it returns details of the connection
indication, and a local sequence number which uniquely
identifies this indication,
or it may return a negative value with
t_errno
set to [TNODATA].
The number of outstanding connection requests to dequeue is limited by the
value of the
qlen
parameter accepted by the transport provider on the
t_bind()
call.
-
If the endpoint has more than one connection indication enqueued,
the user should dequeue all connection indications (and
disconnection indications)
before accepting or rejecting any or all of them.
The number of outstanding connection indications is limited by
the value of the
qlen
parameter accepted by the transport provider on the call to
t_bind().
-
When accepting a connection indication, the transport service user may
issue the
accept on the same (listening) endpoint or on a different endpoint.
If the same endpoint is used, the
listening endpoint cannot receive or enqueue incoming connect
indications for the duration of the connection.
If a different endpoint is used, the listening endpoint can continue
to receive and enqueue incoming connect indications.
-
If the user issues a
t_connect()
on a listening endpoint, again, that endpoint
cannot receive or enqueue incoming connect
indications for the duration of the connection.
-
A connection attempt failure will result in a value -1 returned from either
the
t_connect()
or
t_rcvconnect()
call, with
t_errno
set to [TLOOK] indicating that a [T_DISCONNECT] event has arrived.
In this case, the reason for the failure may be identified by issuing a
t_rcvdis()
call.
The functions that support these operations of connection establishment are:
- t_connect()
- This function requests a connection to the transport user at a
specified destination and waits for the remote user's response.
This function may be executed in either synchronous or asynchronous mode.
In synchronous mode, the function waits for the remote user's
response before returning control to the local user.
In asynchronous mode, the function initiates connection
establishment but returns control to the local user before a
response arrives.
- t_rcvconnect()
- This function enables an active transport user to determine the
status of a previously sent connection request.
If the request was accepted, the connection establishment phase will be
complete on return from this function.
This function is used in conjunction with
t_connect()
to establish a connection in an asynchronous manner,
or to continue an interrupted synchronous-mode
t_connect()
call.
- t_listen()
- This function enables the passive transport user to receive connection
indications from other transport users.
- t_accept()
- This function is issued by the passive user to accept a particular
connection request after an indication has been received.
Overview of Data Transfer
Once a transport connection has been established between two users,
data may be transferred back and forth over the connection in a full duplex way.
The functions that support data transfer in
connection mode are as follows:
- t_snd()
- This function enables transport users to send either normal or
expedited data over a transport connection.
- t_rcv()
- This function enables transport users to receive either normal
or expedited data on a transport connection.
- t_sndv()
- This function enables transport users to send either normal or
expedited data from non-contiguous buffers over a transport connection.
- t_rcvv()
- This function enables transport users to receive either normal
or expedited data into non-contiguous buffers on a transport connection.
Throughout the rest of this section, all references of calls to
t_rcv()
include calls to
t_rcvv(),
and calls to
t_snd()
include calls to
t_sndv().
In data transfer phase, the occurrence of the [T_DISCONNECT] event
implies an unsuccessful return from the called function (.Fn t_snd
or
t_rcv())
with
t_errno
set to [TLOOK].
The user must then issue a
t_look()
call to get more details.
Receiving Data
If data (normal or expedited) is immediately available, then a call to
t_rcv()
returns data.
If the transport connection no longer exists, then the call returns immediately,
indicating failure.
If data is not immediately available and the transport connection still
exists, then the result of a call to
t_rcv()
depends on the mode:
-
Asynchronous Mode
The call returns immediately, indicating failure.
The user must continue to "poll" for incoming data, either by issuing
repeated call to
t_rcv(),
or by using the
t_look()
or the EM interface.
-
Synchronous Mode
The call is blocked until one of the following conditions becomes true:
-
Data (normal or expedited) is received.
-
A disconnection indication is received.
-
A signal has arrived.
The user may issue a
t_look()
or use EM calls, to determine if data is available.
If a normal TSDU is to be received in multiple
t_rcv()
calls, then its delivery may be interrupted at any time by the arrival
of expedited data.
The application can detect this by checking the
flags
field
on return from a call to
t_rcv();
this will be indicated by
t_rcv()
returning:
-
data with T_EXPEDITED flag not set and
T_MORE set (this is a fragment of
normal data)
-
data with T_EXPEDITED set (and T_MORE set or unset); this is an
expedited message (whole or part of, depending on the setting
of T_MORE).
The provider will continue to return the expedited data (on this and
subsequent calls to
t_rcv())
until the end of the Extended Transport Service Data Unit
(ETSDU) is reached,
at which time it will continue to return normal data.
It is the user's responsibility to remember that the receipt of normal
data has been interrupted in this way.
Sending Data
If the data can be accepted immediately by the provider, then it is
accepted, and the call returns the number of octets accepted.
If the data cannot be accepted because of a permanent failure condition
(for example, transport connection lost),
then the call returns immediately, indicating failure.
If the data cannot be accepted immediately because of a transient
condition (for example, lack of buffers,
flow control in effect), then the result of a call to
t_snd()
depends on the execution mode:
-
Asynchronous Mode
The call returns immediately indicating failure.
If the failure was due to flow control restrictions, then it is possible
that only part of the data will actually be accepted by the transport provider.
In this case
t_snd()
will return a value that is less than the number of octets requested to be sent.
The user may either
retry the call to
t_snd()
or
first receive notification of the clearance of the flow control restriction
via either
t_look()
or the EM interface, then retry the call.
The user may retry the call with the data remaining from the original call
or with more (or less) data, and with the T_MORE flag set appropriately to
indicate whether this is now the end of the TSDU.
-
Synchronous Mode
The call is blocked until one of the following conditions becomes true:
-
The flow control restrictions are cleared and the transport provider
is able to accept a new data unit.
The
t_snd()
function then returns successfully.
-
A disconnection indication is received.
In this case the
t_snd()
function returns unsuccessfully with
t_errno
set to [TLOOK].
The user can issue a
t_look()
function to determine the cause of the error.
For this particular case
t_look()
will return a T_DISCONNECT event.
All or part of the data that was being sent might be lost.
-
An internal problem occurs.
In this case the
t_snd()
function returns unsuccessfully with
t_errno
set to [TSYSERR].
Data that was being sent will be lost.
For some transport providers,
normal data and expedited data constitute two distinct flows of data.
If either flow is blocked, the user may
nevertheless continue using the other one,
but in synchronous mode a second process is needed.
The user may send expedited data between the fragments of a normal
TSDU, that is, a
t_snd()
call with the T_EXPEDITED flag set may follow a
t_snd()
with the T_MORE flag set and the T_EXPEDITED flag not set.
Note that XTI supports two modes of sending data,
record-oriented and stream-oriented.
In the record-oriented mode,
the concept of TSDU is supported, that is, message boundaries
are preserved.
In stream-oriented mode, message boundaries are not preserved and the
concept of a TSDU is not supported.
A transport user can determine the mode by using the
t_getinfo()
function, and examining the
tsdu
field.
If
tsdu
is greater than zero, this indicates that record-oriented
mode is supported and the return value indicates the maximum TSDU size.
If
tsdu
is zero, this indicates that stream-oriented transfer is
supported.
For more details see
t_getinfo.
Overview of Connection Release
Some communication providers (for example, the ISO
connection-mode transport) support only the abortive release.
However, some communication providers (for example, mOSI,
NetBIOS, SNA, TCP) also support an orderly release.
XTI includes functions to provide access to transports that
support or require the orderly release features.
An abortive release may be invoked from either the connection establishment
phase or the data transfer phase.
When in the connection establishment phase, a transport user may
use the abortive release to reject a connection request.
In the data transfer phase, either user may abort a connection at
any time.
The abortive release is not
negotiated by the transport users and it takes effect immediately on
request.
The user on the other side of the connection is notified when a
connection is aborted.
The transport provider may also initiate an abortive release, in which case
both users are informed that the connection no longer exists.
There is no guarantee of delivery of user data once an abortive
release has been initiated.
Whatever the state of a transport connection, its user(s) will be informed as soon
as possible of the failure of the connection through a disconnection event
or an unsuccessful return from a blocking
t_snd()
or
t_rcv()
call.
If the user wants to prevent loss of data by notifying the remote user of an
imminent connection release, it is the user's
responsibility to use an upper level mechanism.
For example, the user may send specific (expedited) data and wait for the
response of the remote user before issuing a disconnection request.
Some transport providers support an orderly release capability
(for example, mOSI, NetBIOS, SNA, TCP).
If supported by
the communications provider,
orderly release may be invoked from the data transfer
phase to enable two users to gracefully release a connection.
The procedure for orderly release prevents the loss of data that
may occur during an abortive release.
When supported by the underlying protocol, some
communications providers optionally allow applications
to send or retrieve user data with an orderly release,
through the use of the
t_sndreldata()
or
t_rcvreldata()
functions instead of the
t_sndrel()
or
t_rcvrel()
functions.
The functions that support connection release are:
- t_snddis()
- This function can be issued by either transport user to initiate
the abortive release of a transport connection.
It may also be used to reject a connection request during the
connection establishment phase.
- t_rcvdis()
- This function identifies the reason for the abortive release of a connection,
where the connection is released by the transport provider or another
transport user.
- t_sndrel()
- This function can be called by either transport user to initiate an orderly
release. The connection remains intact until both users call this function
and
t_rcvrel().
- t_rcvrel()
- This function is called when a user is notified of an orderly
release request, as a means of informing the transport provider
that the user is aware of the remote user's actions.
- t_sndreldata()
- This function can be used instead of
t_sndrel()
to send user data with an orderly release.
- t_rcvreldata()
- This function can be used instead of
t_rcvrel()
to retrieve orderly release user data.
Overview of Connectionless Mode
The connectionless-mode transport service consists of two phases
of communication: initialisation/de-initialisation
and data transfer.
A brief description of each phase and its associated functions is
presented below.
A state machine is described in
Transport Service Interface Sequence of Functions,
and the figure in
Example in Connectionless Mode,
that defines the
legal sequence in which functions from each phase may be issued.
In order to permit the transfer of
connectionless-mode data, a user (application) must:
-
supply a transport endpoint for the appropriate type of provider (using
t_open());
this establishes a transport endpoint through which
the user may communicate with the provider
-
associate (bind) an address with this
transport endpoint (using
t_bind())
The user may then send and/or receive connectionless-mode data,
as required, using the functions
t_sndudata()
and
t_rcvudata().
Once the data transfer phase is finished, the application may either directly
close the file descriptor returned by
t_open()
(using
t_close()),
thereby freeing the resource for future use, or start a new exchange of
data after disassociating the old address and binding a new one.
Initialisation/De-initialisation Phase
The functions that support the initialisation/de-initialisation
tasks are the
same functions used in the connection-mode service.
Overview of Data Transfer
Once a transport endpoint has been activated, a user is free to
send and receive data units through that endpoint in
connectionless mode as follows:
- t_sndudata()
- This function enables transport users to send a self-contained
data unit to the user at the specified protocol address.
- t_sndvudata()
- This function enables transport users to send a self-contained
data unit to the user from one or more non-contiguous buffers
at the specified protocol address.
- t_rcvudata()
- This function enables transport users to receive data units from
- t_rcvvudata()
- This function enables transport users to receive data units from
other users into one or more non-contiguous buffers.
- t_rcvuderr()
- This function enables transport users to
retrieve error information associated with a previously sent data
unit.
The only possible events
reported to the user are [T_UDERR],
[T_DATA] and [T_GODATA].
Expedited data cannot be used with a connectionless-mode transport provider.
Throughout the rest of this section,
all references of calls to
rcvudata()
include calls to
rcvvudata(),
and calls to
t_sndudata()
include calls to
t_sndvudata().
Receiving Data
If data is available (a datagram or a part), the
t_rcvudata()
call returns immediately indicating the number of octets received.
If data is not immediately available, then the result of the
t_rcvudata()
call depends on the chosen mode:
-
Asynchronous Mode
The call returns immediately indicating failure.
The user must either retry the call repeatedly, or "poll" for incoming
data by using the EM interface or the
t_look()
function so as not to be blocked.
-
Synchronous Mode
The call is blocked until one of the following conditions becomes true:
-
A datagram is received.
-
An error is detected by the transport provider.
-
A signal has arrived.
The application may use the
t_look()
function or the EM mechanism to know if data is available instead of issuing a
t_rcvudata()
call which may be blocking.
Sending Data
-
Synchronous Mode
In order to maintain some flow control, the
t_sndudata()
function will block until the datagram has
been accepted by the provider.
The call returns immediately after the datagram has been sent.
A process which sends data in synchronous mode
may be blocked for some time.
-
Asynchronous Mode
The transport provider may refuse to send a new datagram for flow control
restrictions.
In this case, the
t_sndudata()
call fails returning a negative value and setting
t_errno
to [TFLOW].
The user may retry later or use the
t_look()
function or EM interface to be informed of the flow control restriction
removal.
If
t_sndudata()
is called before the destination user has activated
its transport endpoint, the data unit may be discarded.
XTI Features
The following functions, which correspond to the subset common to
connection-mode
and connectionless-mode services, are always implemented:
-
-
t_bind()
t_close()
t_look()
t_open()
t_sync()
t_unbind()
If a connection-mode Transport Service is provided, then the
following functions are always implemented:
-
-
t_accept()
t_connect()
t_listen()
t_rcv()
t_rcvv()
t_rcvconnect()
t_rcvdis()
t_snd()
t_sndv()
t_snddis()
If XTI supports the access to the connectionless-mode Transport Service,
the following three functions are always implemented:
-
-
t_rcvudata()
t_rcvvudata()
t_rcvuderr()
t_sndudata()
t_sndvudata()
Mandatory mechanisms:
-
synchronous mode
-
asynchronous mode.
Utility functions:
-
-
t_alloc()
t_free()
t_error()
t_getprotaddr()
t_getinfo()
t_getstate()
t_optmgmt()
t_strerror()
t_sysconf()
The orderly release mechanism (using
t_sndrel(),
t_sndreldata(),
t_rcvrel()
and
t_rcvreldata())
is supported only for T_COTS_ORD type providers. Use with other providers
will cause the [TNOTSUPPORT] error to be returned.
Optional mechanisms:
-
the ability to manage (enqueue) more than one incoming connection
indication at any one time
-
the address of the caller passed with
t_accept()
may optionally be checked by an XTI implementation
XTI Functions versus Protocols
Classification of the XTI Functions
presents all the functions defined in XTI.
The character "x" indicates that the mapping of that function is
possible onto
a connection-mode or connectionless-mode Transport Service.
The table indicates the type of utility functions as well.
Functions
| Necessary for Protocol
| Utility Functions
|
---|
| _
| _
|
---|
| Connection
| Connectionless
| General
| Memory
|
---|
| Mode
| Mode
|
|
|
---|
t_accept()
| x
|
|
|
|
t_alloc()
|
|
|
| x
|
t_bind()
| x
| x
|
|
|
t_close()
| x
| x
|
|
|
t_connect()
| x
|
|
|
|
t_error()
|
|
| x
|
|
t_free()
|
|
|
| x
|
t_getprotaddr()
|
|
| x
|
|
t_getinfo()
|
|
| x
|
|
t_getstate()
|
|
| x
|
|
t_listen()
| x
|
|
|
|
t_look()
| x
| x
|
|
|
t_open()
| x
| x
|
|
|
t_optmgmt()
|
|
| x
|
|
t_rcv()
| x
|
|
|
|
t_rcvv()
| x
|
|
|
|
t_rcvconnect()
| x
|
|
|
|
t_rcvdis()
| x
|
|
|
|
t_rcvrel()
| x
|
|
|
|
t_rcvreldata()
| x
|
|
|
|
t_rcvudata()
|
| x
|
|
|
t_rcvvudata()
|
| x
|
|
|
t_rcvuderr()
|
| x
|
|
|
t_snd()
| x
|
|
|
|
t_sndv()
| x
|
|
|
|
t_snddis()
| x
|
|
|
|
t_sndrel()
| x
|
|
|
|
t_sndreldata()
| x
|
|
|
|
t_sndudata()
|
| x
|
|
|
t_sndvudata()
|
| x
|
|
|
t_strerror()
|
|
| x
|
|
t_sync()
|
|
| x
|
|
t_sysconf()
|
|
| x
|
|
t_unbind()
| x
| x
|
|
|
Table: Classification of the XTI Functions