Add Book to My BookshelfPurchase This Book Online

Chapter 15 - Networking with TLI

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Transport Endpoint Management
In the socket interface, a socket was used to refer to one end of a communications channel. The socket was simply a file descriptor, and could be used with read and write, as well as the special-purpose networking functions.
In the TLI, the end of a communications channel is called a transport endpoint. A transport endpoint is a file descriptor with some associated state information. Without some special preparations, described later in this chapter, transport endpoints cannot be be used with read and write; they must instead be accessed through TLI functions.
Creating a Transport Endpoint
To create a transport endpoint, use the t_open function:
    #include <tiuser.h>
    #include <fcntl.h>
    int t_open(const char *path, int oflag, struct t_info *info);
The path parameter should be the path to the communications device; this will usually be the nc_device field of a struct netconfig structure. The oflag parameter specifies how the endpoint should be opened; it is specified using the same flags that are used with the open system call (see Chapter 3, Low-Level I/O Routines) and should include at least O_RDWR. The info parameter, if non-null, points to a structure of type struct t_info into which the characteristics of the underlying transport protocol will be stored. On success, t_open returns a valid file descriptor. On failure, it returns -1 and stores the reason for failure in t_errno (and perhaps errno).
Information about the characteristics of the underlying protocol may be obtained when the transport endpoint is created. It may also be obtained at any other time by using the t_getinfo function:
    #include <tiuser.h>
    int t_getinfo(int fd, struct t_info *info);
The fd parameter should refer to a transport endpoint, and info should point to a structure of type struct t_info:
    struct t_info {
        long    addr;
        long    options;
        long    tsdu;
        long    etsdu;
        long    connect;
        long    discon;
        long    servtype;
    };
The fields of this structure have the following meanings:
addr
The maximum size of a transport protocol address; a value of -1 indicates that there is no maximum, and a value of -2 indicates that the user does not have access to transport protocol addresses.
options
The maximum number of bytes of protocol-specific options supported by the provider; a value of -1 indcates that there is no maximum, and a value of -2 indicates that the transport provider does not support user-settable options.
tsdu
The maximum size of a Transport Service Data Unit (TSDU). This is the maximum amount of data whose message boundaries are preserved from one transport endpoint to another. A value of 0 indicates that the transport provider does not support the concept of a TSDU, although it does support transferring data across a stream with no logical boundaries. A value of -1 indicates that there is no limit on the size of a TSDU; a value of -2 indicates that the transport provider does not support the transfer of normal data.
etsdu
The maximum size of an Expedited Transport Service Data Unit (ETSDU), with the same meanings as for the TSDU. Expedited data is delivered immediately, without waiting for the delivery of previously-sent normal data. (The socket interface term for this is out-of-band data.)
connect
The maximum amount of data that can be sent along with a connection request; -1 indicates there is no limit, and -2 indicates that data may not be sent with connection establishment functions.
discon
The maximum amount of data that can be associated with the t_snddis and t_rcvdis functions. A value of -1 indicates no limit; a value of -2 indicates that data may not be sent with these functions.
srvtype
The type of service supported by the transport provider; may be one of the following:
T_COTS
Connection-oriented service, but without orderly release.
T_COTS_ORD
Connection-oriented service with orderly release.
T_CLTS
Connectionless service. For this type of service, etdsu, connect, and discon will contain -2.
On success, t_getinfo returns 0. On failure, it returns -1, and t_errno (and possibly errno) will be set to indicate the error.
Binding an Address to a Transport Endpoint
Before a transport endpoint can be used, it must be bound to an address. Unlike the socket interface, in which a client program only needs to bind its socket to an address if it wants to use a specific port number, TLI requires both the client and server processes to bind addresses to their transport endpoints.
An address is described by a structure of type struct t_bind:
    struct t_bind {
        struct netbuf    addr;
        unsigned int     qlen;
    };
The addr field contains the address to be bound, and the qlen field specifies the maximum number of outstanding connection requests a server will allow on the endpoint.
The t_bind function binds an address to a transport endpoint:
    #include <tiuser.h>
    int t_bind(int fd, struct t_bind *reqp, struct t_bind *retp);
The fd parameter is the transport endpoint. The reqp parameter specifies the requested address, and the retp parameter, if non-null, points to a location in which the actual address that is bound will be stored.
Notice that the actual address bound by t_bind may be different than the requested address; this occurs if an address is already in use. In the case of servers, which usually have to live at specific addresses, the benefit of this behavior is not clear. It would probably make more sense to just refuse to bind the address, and return an “address in use” error, like the socket interface does. At any rate, after performing the t_bind, a process that cares about the address to which it is bound should check to see that the address in retp is the same as that in reqp.
If reqp is NULL, the system will assume that the user doesn't care what address is used, and the system will choose an appropriate one. This is usually the case with client programs (except for those that use reserved ports).
On success, t_bind returns 0. On failure, it returns -1 and t_errno (and perhaps errno) will be set to indicate the error.
Closing a Transport Endpoint
The t_unbind function disables a transport endpoint:
    #include <tiuser.h>
    int t_unbind(int fd);
Upon return, the endpoint may no longer be used to transfer data. The endpoint may be bound to another address at this time. The t_unbind function returns 0 on success, or -1 on failure. If a failure occurs, the error indication will be stored in t_errno (and perhaps errno).
The t_close function closes a transport endpoint:
    #include <tiuser.h>
    int t_close(int fd);
This function should be called when the endpoint is in an unbound state (after a call to t_unbind), but can also be called when the endpoint is in any state. It frees any local library resources used by the endpoint, and closes the file descriptor. On success, t_close returns 0; on failure it returns -1 and stores the reason for failure in t_errno (and perhaps errno).
Transport Endpoint Options
Some transport providers let the user control certain protocol options. To examine and change these options, TLI provides the t_optmgmt function:
    #include <tiuser.h>
    int t_optmgmt(int fd, const struct t_optmgmt *req,
            struct t_optmgmt *ret);
The fd parameter is a bound transport endpoint. The req and ret parameters point to structures of type struct t_optmgmt:
    struct t_optmgmt {
        struct netbuf    opt;
        long             flags;
    };
The opt field contains the options (in req, len contains the number of bytes in the options string, and buf contains the options; in ret, maxlen contains the maximum size of buf). The flags field specifies the action to be taken with the following options:
T_NEGOTIATE
Negotiate the values of the options specified in req with the transport provider. The provider will examine the options and negotiate the values, and return the negotiated values through ret.
T_CHECK
Check whether the options specified in req are supported by the transport provider. On return, the flags field of ret will contain either T_SUCCESS or T_FAILURE.
T_DEFAULT
Retrieve the default options supported by the transport provider into ret. When making this call, the len field in req must be zero.
The actual structure and content of the options are imposed by the transport provider.
If t_optmgmt succeeds, it returns 0. If it fails, it returns -1, and places an error code in t_errno (and perhaps errno).

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback