DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Developing applications over IPX/SPX using TLI

Accessing SPX

The following TLI routines are used to access SPX:


t_accept
accept a connect request

t_bind
bind an address to a transport endpoint

t_close
close a transport endpoint

t_connect
establish a connection with another transport user

t_listen
listen for a connect request

t_open
establish a transport endpoint

t_optmgmt
manage options for a transport endpoint

t_rcv
receive data or expedited data sent over a connection

t_rcvdis
retrieve information from disconnect

t_snd
send data or expedited data over a connection

t_snddis
send user-initiated disconnect request

t_unbind
disable a transport endpoint

The following header files must be included in the order listed in any program that uses the TLI interface to SPX:

t_bind

The t_bind call works as specified in t_bind(NET), with the following additions:

The qlen field of the t_bind structure is used to indicate the total number of outstanding connection requests allowed on this endpoint. Applications that do not service connection requests should set this field to 0. Applications that service connection requests should set this field to 1. See ``Connection requests'' for more information .

The t_bind call allows an endpoint to bind to a socket number. The socket number can be either dynamic or static. SPX keeps track of which socket number is bound to which transport endpoint. The net and node fields do not need to be filled in the ipxAddr_t structure, but the sock field must be initialized to either a static or dynamic socket value. ``Socket numbers'' presents procedures for obtaining both static and dynamic socket numbers.

t_connect

The t_connect call works as specified in t_connect(NET), with the following additions:

SPX supports both synchronous and asynchronous modes.

On input, sndcall passes a pointer to a t_call structure that contains the IPX address of the server with which the SPX client wants to connect; rcvcall passes a pointer to a t_call structure that contains the server's connection information upon successful completion of the call.

On output, rcvcall receives the server's connection information: network number, node number, socket number, connection ID, and allocation number.

The SPX driver tries a certain number of times (as specified in the spx_tune.h file) to connect with the remote transport endpoint. After trying the specified number of times without receiving an acknowledgment, the SPX driver generates a disconnect indication of TLI_SPX_CONNECTION_FAILED -- see ``t_rcvdis''. If this error occurs, the state of the stream is set to T_IDLE.

See t_connect(NET) for other possible errors.

The SPX driver does not use the udata structure in the t_call structure; its fields should be initialized. You must set the udata.len and udata.maxlen fields to 0 and the udata.buf field to NULL.

The SPX driver does not use the sequence field in the t_call structure.

All information passed in the ipxAddr_t structure must be in high-to-low byte order. See ``Network byte ordering'' for more information.

The sndcall.opt.len and sndcall.opt.maxlen fields must be initialized to the size of an SPX_OPTS or equivalent structure. The sndcall.opt.buf field must point to an SPX_OPTS structure, which is returned by the service provider.

The t_connect call uses two t_call structures: sndcall and rcvcall.

The t_connect call sends an SPX connection request to the SPX address specified in sndcall.addr. The sndcall.addr.len and sndcall.addr.maxlen fields must be initialized to the size of an ipxAddr_t or equivalent structure. The sndcall.addr.buf field must point to an ipxAddr_t structure. The ipxAddr_t structure must be initialized to the server's IPX address.

If the rcvcall structure is passed in t_connect, the server's address and connection information is returned. If a rcvcall structure is passed, maxlen, len, and buf must be set appropriately to receive the ipxAddr_t and SPX_OPTS structures. The server's IPX address is returned in the rcvcall.addr.buf field. The server's connection ID and allocation number is passed back in the rcvcall.opt.buf field.

The state after a successful connection establishment is T_DATAXFER for both the client and server. The state after an unsuccessful connection establishment is T_BND.

t_listen

The t_listen call works as specified in t_listen(NET), with the following additions:

The udata fields in the t_call structure are not used but must be initialized. Set the udata.len and udata.maxlen fields to 0, and set the udata.buf to NULL. A value is placed in the sequence field when the t_listen receives a connection request. The application uses the sequence value to reject the connection request with a t_snddis call or to accept the connection request with a t_accept.

The addr.len and addr.maxlen fields must be initialized to the size of an ipxAddr_t structure. The addr.buf field must point to an ipxAddr_t structure.

The opt.len and opt.maxlen fields must be initialized to the size of an SPX_OPTS structure. The opt.buf field must point to an SPX_OPTS structure.

If t_listen returns successfully, call.addr points to an ipxAddr_t structure that contains the net, node, and sock of the remote transport endpoint requesting the connection. The net, node, and sock are in high-to-low byte order. The call.opt points to an SPX_OPTS structure that contains the remote transport endpoint's connection ID and allocation number. The call.udata contains nothing.

The t_listen call retrieves any connection requests residing on the stream head. The t_listen call can function synchronously or asynchronously.

SPX ensures that each connection indication is unique by dropping any duplicate connection requests. A duplicate request is a request that comes from the same network, node, socket, and source connection ID as a previous request.

When a t_connect call has been received from a client, the SPX server can either accept or reject the connection request.

The client issuing the connection request learns that the connection request has been rejected by retrying the connection request and eventually timing out. This differs from the DOS/SPX/TLI library in that DOS sends terminate connection indication if the application issues a t_snddis after a t_listen return.

This call can be issued only from the T_BND state.

t_open

The t_open call works as specified in t_open(NET), with the following additions:

On input, path passes a pointer to the path of the SPX driver. The path is /dev/nspx.

On output, spxInfo receives the SPX protocol information as a t_info structure. The t_open call returns a value greater than or equal to 0 if successful, or -1 if not. If the t_open call is successful, the value returned is a file descriptor that identifies the local transport endpoint. This document uses the variable fd to refer to this value. If t_open returns an error, errno may be set to:


ENONET
The STREAMS facility requires that a daemon be run in the background to build the protocol stack before SPX can be used. This daemon links IPX to the Ethernet driver, then links SPX to IPX. If NPSD has not been run, all attempts to open SPX fail with this error.

ESRCH
SPX has not been initialized.

ENOSPC
The SPX_MAX_CONNECTIONS parameter in the tunable file spx_tune.h sets the maximum number of simultaneous endpoints. If that number is reached, all attempts to open SPX fail with this error.

ENOSR
If no STREAMS resources are available, all attempts to open SPX fail with this error.

SPX may be used either synchronously or asynchronously.

The path and name of the clonable SPX device is /dev/nspx.

The t_open call returns a file descriptor and a TLI information structure (of type t_info) upon the successful return of an open call. ``t_info structure fields'' describes the fields in the t_info structure.

t_info structure fields

Field Value Description
addr 12 The address is 12 bytes and consists of: network number (4 bytes), node number (6 bytes), and socket number (2 bytes).
options 4 SPX supports 4 bytes of options data.
tsdu -1 There is no limit on the amount of data that can be sent during a connection.
etsdu -2 Not supported.
connect -2 Not supported.
discon -2 Not supported.
servtype T_COTS The service type is always T_COTS. SPX is a connection-oriented service with a disorderly release.

t_open changes the state of the service connection to T_UNBND (unbound).

t_optmgmt

The t_optmgmt call works as specified in t_optmgmt(NET), with the following additions:

The t_optmgmt call enables the SPX user to set the maximum number of retries for a connection request or for a data unit delivery.

On input, req passes the address of the t_optmgmt structure that contains the requested retry count value for a connection request or for a data unit delivery; ret passes the address of a t_optmgmt structure that contains the granted retry count value.

On output, ret receives the granted retry count value in the t_optmgmt structure.

On completion, the t_optmgmt call returns 0 if successful or -1 if unsuccessful. If t_optmgmt returns an error, t_errno may be set to one of the following:


TBADOPT
The size of the structure was less than the size of an SPX_OPTMGMT structure or there has been an internal SPX/TLI error.

TBADFLAG
The specified flag is invalid.

This call has one negotiable option. It enables the SPX user to set the maximum number of retries when the SPX driver tries to deliver data reliably to the opposite transport endpoint.

The req.opt.buf field and ret.opt.buf field must point to an SPX_OPTMGMT structure.

The SPX driver does not support spxo_watchdog_flag or spxo_min_retry_delay.

The value in spxo_retry_count becomes the new maximum number of retries unless its value exceeds the maximum retry value in spx_tune.h (the SPX_MAX_TRETRIES parameter).

The flags field in the t_optmgmt structure must be initialized to the appropriate value. The flags supported are: T_NEGOTIATE, T_CHECK, and T_DEFAULT.

t_rcv

The t_rcv call works as specified in t_rcv(NET), with the following additions:

The T_EXPEDITED flag is never set. On input, flags passes the address of an integer that indicates whether there is more data to receive. SPX does not support the T_EXPEDITED flag.

The SPX watchdog in the SPX driver prevents transport endpoints from blocking forever waiting for a packet. For example, suppose a local transport endpoint blocks waiting for an incoming packet. While the local transport blocks, the remote transport endpoint goes down before sending the packet. In this situation, the local transport endpoint could block forever. The SPX watchdog solves this problem by periodically checking all active connections. If the SPX watchdog determines that the remote transport endpoint is no longer participating in the connection, the SPX watchdog generates a disconnect indication, causing t_rcv to return with an error. (See ``t_rcvdis'' for more information.)

SPX does flow control. If SPX determines that the remote endpoint is sending data faster than the application can receive the data, SPX sends a packet notifying the remote endpoint to stop sending data. When the application receives all of the data queued for it, SPX notifies the remote endpoint to begin sending data again.

t_rcv can be called only if SPX is in the T_DATAXFER state. This state does not change on successful completion of the call.

t_rcvdis

The t_rcvdis call works as specified in t_rcvdis(NET), with the following additions:

On completion, the t_rcvdis call returns 0 if successful or -1 if unsuccessful. If any of the following conditions occur, a disconnect indication is generated and passed to the stream head. The reason integer of the t_discon structure (described below) is set accordingly in the following situations:


TLI_SPX_CONNECTION_FAILED
The remote transport endpoint fails to acknowledge any transmission. This is generated by the SPX watchdog after failing to connect to the remote transport endpoint.

Alternatively, the SPX driver could not reliably deliver the data or connection request. The remote transport endpoint does not acknowledge transmissions.


ENOSTR
The SPX driver has tried the maximum number of times to send data to the stream head. Each try has been unsuccessful. This is usually caused by a very slow or deadlocked receiving local endpoint. (The number of retries is a tunable parameter in the spx_tune.h file.)

Alternatively, SPX has tried a number of times to allocate memory and has failed.


TLI_SPX_CONNECTION_TERMINATED
No error occurred. An SPX terminate connection packet was received from the remote transport endpoint.

The SPX driver does not use the udata field in the t_discon structure. SPX does not support the transmission of user data with a disconnect request.

Upon receiving a disconnect request, SPX sets the stream to the T_IDLE state.


NOTE: A transmission error or a disconnect indication can arrive at any moment from the remote transport endpoint.

t_snd

The t_snd call works as specified in t_snd(NET), with the following additions:

A known problem with TLI is its inability to notify the user within a reasonable amount of time that a call to t_snd has failed. The t_snd call does not check for disconnect indications before and after doing the t_snd. If the remote transport endpoint has gone down or fails to acknowledge the transmitted data, the SPX driver generates a disconnect indication and changes the state of the local transport endpoint to T_IDLE. Following the TLI specification, any t_snd issued in the T_IDLE state is dropped by the SPX driver. This indication is not detected by the application until a routine other than t_snd is called. The application should check the return code in the disconnect indication to make sure it is TLI_SPX_CONNECTION_TERMINATED.

The following errors can occur during the send request:


EPROTO
The data request was issued from a state other than T_DATAXFER. This transport endpoint is no longer valid and must be closed.

Alternatively, the size of the data request header or data portion of the message received by SPX was invalid (too small or too large). This transport endpoint is no longer valid and must be closed.

These errors lock the stream and disable the local transport endpoint. Only errno is set; t_errno is not affected.

All data is sent on a first-come, first-served basis. The application must take care not to close the connection before all the data is sent. The t_snd call returns before the data has actually been transmitted.

When writing an application that communicates with an unknown machine type, consider the byte order of data sent. See ``Network byte ordering'' for more information.

During the connection, SPX uses the most recent round trip delay multiplied by 1.5 as the timeout for the next transmission.

The T_MORE flag is supported by SPX as follows:


If the application sets the T_MORE flag when calling t_snd, the EOF bit is not set in the SPX packet header.

TLI breaks any large send request into a sequence of maximum packets for the given connection.

The SPX driver does not send empty SPX packets. If nbytes is 0, no data or packet is sent.

t_snd can be called only if SPX is in the T_DATAXFER state. If errors occur, the state changes to T_IDLE.

t_snddis

The t_snddis call works as specified in t_snddis(NET), with the following additions:

SPX does not support the TLI concept of an orderly release. The correct procedure for aborting or terminating a connection is to use the combination of t_snddis and t_rcvdis.

A t_snddis call sends a connection termination request to the remote transport endpoint. This call is used to abort or break a connection. t_snddis generates an SPX terminate connection request, and releases all outstanding data messages on both the local and remote transport endpoints. The terminate request is not delivered reliably and only one terminate request is sent. After an application calls t_snddis, the application can call t_unbind and t_close without waiting.

SPX does not allow sending address options or user data along with a disconnect request.

The correct procedure for terminating an SPX connection is for both transport endpoints to correlate the moment that the connection is no longer needed, then call t_snddis and t_rcvdis to terminate the connection.

Regardless of the outcome of the call to t_snddis, the transport endpoint remains in the T_UNBND state.

t_unbind

The t_unbind call works as specified in t_unbind(NET), with the following additions:

This call releases the socket number used by the transport endpoint for future use. This allows the callng process to bind to a new socket number.

This call places the transport endpoint in the T_UNBND state.


Next topic: Using the SAP protocol
Previous topic: Initializing SPX

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003