|
|
1.1 ! root 1: % run this through LaTeX with the appropriate wrapper ! 2: ! 3: \chapter {Transport Services}\label{libtsap} ! 4: At the heart of this distribution is the \man libtsap(3n) library. ! 5: This library contains a set of routines which implement the ! 6: transport services access point (TSAP). ! 7: ! 8: As with most models of OSI services, ! 9: the underlying assumption is one of a symmetric, asynchronous environment. ! 10: That is, ! 11: although peers exist at a given layer, one does not necessarily view a peer as ! 12: either a client or a server. ! 13: Further, ! 14: the service provider may generate events for the service user without the ! 15: latter entity triggering the actions which led to the event. ! 16: For example, ! 17: in a synchronous environment, ! 18: an indication that data has arrived usually occurs only when the service user ! 19: asks the service provider to read data; ! 20: in an asynchronous environment, ! 21: the service provider may interrupt the service user at any time to announce ! 22: the arrival of data. ! 23: ! 24: The \verb"tsap" module in this release initially uses a client/server ! 25: paradigm to start communications. ! 26: Once the connection is established, ! 27: a symmetric view is taken. ! 28: In addition, ! 29: initially the interface is synchronous; ! 30: however once the connection is established, ! 31: an asynchronous interface may be selected. ! 32: ! 33: All of the routines in the \man libtsap(3n) library are integer-valued. ! 34: They return the manifest constant \verb"OK" on success, ! 35: or \verb"NOTOK" otherwise. ! 36: ! 37: \section {Addresses}\label{tsap:addresses} ! 38: Addresses at the transport service access point are represented by the ! 39: \verb"TSAPaddr" structure. ! 40: \begin{quote}\index{TSAPaddr}\small\begin{verbatim} ! 41: struct TSAPaddr { ! 42: #define NTADDR 4 ! 43: struct NSAPaddr ta_addrs[NTADDR]; ! 44: int ta_naddr; ! 45: ! 46: #define TSSIZE 64 ! 47: int ta_selectlen; ! 48: char ta_selector[TSSIZE]; ! 49: }; ! 50: #define NULLTA ((struct TSAPaddr *) 0) ! 51: \end{verbatim}\end{quote} ! 52: This structure contains two elements: ! 53: \begin{describe} ! 54: \item[\verb"ta\_addrs"/\verb"ta\_nadr":] a list of network addresses, ! 55: as described in the Section~\ref{nsap:addresses} on ! 56: page~\pageref{nsap:addresses}; ! 57: ! 58: \item[\verb"ta\_selector"/\verb"ta\_selectlen":] the transport selector, ! 59: as described in the \man isoservices(5) database in Chapter~\ref{isoservices}, ! 60: for the service provider \verb"tsap". ! 61: \end{describe} ! 62: ! 63: In Figure~\ref{getSSprovider}, ! 64: an example of how one constructs the TSAP address for the session provider on ! 65: host \verb"RemoteHost" is presented. ! 66: The routine \verb"is2taddr" takes a host and service, ! 67: and then consults the \man isoentities(5) file described in ! 68: Chapter~\ref{isoentities} of \volone/ to construct a transport ! 69: address. ! 70: \begin{quote}\index{is2taddr}\small\begin{verbatim} ! 71: struct TSAPaddr *is2taddr (host, service, is) ! 72: char *host, ! 73: *service; ! 74: struct isoservent *is; ! 75: \end{verbatim}\end{quote} ! 76: \tagrind[tp]{grind6-1}{Constructing the TSAP address for the Session provider}% ! 77: {getSSprovider} ! 78: ! 79: \subsection {Calling Address} ! 80: Certain users of the transport service ! 81: might need to know the name of the local host when they initiate a connection. ! 82: The routine \verb"TLocalHostName" has been provided for this reason. ! 83: \begin{quote}\index{TLocalHostName}\small\begin{verbatim} ! 84: char *TLocalHostName () ! 85: \end{verbatim}\end{quote} ! 86: ! 87: \subsection {Address Encodings} ! 88: It may be useful to encode a transport address for viewing. ! 89: Although a consensus for a standard way of doing this has not yet been ! 90: reached, ! 91: the routines \verb"taddr2str" and \verb"str2taddr" may be used in the interim. ! 92: \begin{quote}\index{taddr2str}\small\begin{verbatim} ! 93: char *taddr2str (ta) ! 94: struct TSAPaddr *ta; ! 95: \end{verbatim}\end{quote} ! 96: The parameter to this procedure is: ! 97: \begin{describe} ! 98: \item[\verb"ta":] the transport address. ! 99: \end{describe} ! 100: If \verb"taddr2str" fails, ! 101: it returns the manifest constant \verb"NULLCP". ! 102: ! 103: The routine \verb"str2taddr" takes an ascii string encoding and ! 104: returns a ! 105: transport address. ! 106: \begin{quote}\index{str2taddr}\small\begin{verbatim} ! 107: struct TSAPaddr *str2taddr (str) ! 108: char *str; ! 109: \end{verbatim}\end{quote} ! 110: The parameter to this procedure is: ! 111: \begin{describe} ! 112: \item[\verb"str":] the ascii string. ! 113: \end{describe} ! 114: If \verb"str2taddr" fails, ! 115: it returns the manifest constant \verb"NULLTA". ! 116: ! 117: Once a connection has been established, ! 118: the routine \verb"TGetAddresses" may be called to retrieve to the associated ! 119: addresses. ! 120: (Normally this information is presented to the application during connection ! 121: establishment.) ! 122: \begin{quote}\index{TGetAddresses}\small\begin{verbatim} ! 123: struct TSAPaddr *TGetAddresses (sd, initiating, ! 124: responding, td) ! 125: int sd; ! 126: struct TSAPaddr *initiating, ! 127: *responding; ! 128: struct TSAPdisconnect *td; ! 129: \end{verbatim}\end{quote} ! 130: The parameters to this procedure are: ! 131: \begin{describe} ! 132: \item[\verb"sd":] the transport-descriptor; ! 133: ! 134: \item[\verb"initiating":] the TSAP address of the initiator (to be filled-in); ! 135: ! 136: \item[\verb"responding":] the TSAP address of the responder (to be filled-in); ! 137: and, ! 138: ! 139: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 140: updated only if the call fails. ! 141: \end{describe} ! 142: If the call is successful, ! 143: the \verb"initiating" and \verb"responding" parameters will be updated ! 144: accordingly. ! 145: Otherwise, ! 146: the parameter \verb"td" contains the reason for the failure. ! 147: ! 148: \section {Connection Establishment} ! 149: Until the connection has been fully established, ! 150: the implementation distinguishes between clients and servers, ! 151: which are more properly referred to as {\em initiators\/} and ! 152: {\em responders}, to use the OSI terminology. ! 153: ! 154: \subsection {Connection Negotiation} ! 155: From the user's perspective, ! 156: there are two parameters which are negotiated by the transport providers ! 157: during connection establishment: ! 158: {\em expedited data transfer}, ! 159: and the {\em maximum size\/} of transport service data units. ! 160: ! 161: \subsubsection {Expedited Data} ! 162: If the transfer of expedited data is negotiated, ! 163: then small amounts of data may be sent out-of-band once the connection has ! 164: been established. ! 165: The size of the largest discrete unit to be sent is \verb"TX_SIZE" ! 166: (which is non-negotiable). ! 167: This parameter is negotiated downward; ! 168: that is, both the initiator and responder must agree to the use of expedited ! 169: data. ! 170: ! 171: \subsubsection {Maximum TSDU Size} ! 172: The transport provider will accept arbitrarily large transport service data ! 173: units (TSDUs) and transparently fragment and re-assemble them during transit. ! 174: Hence, the actual TSDU is of unlimited size. ! 175: However, for efficiency reasons, ! 176: it may be desirable for the user to send TSDUs which are no larger than a ! 177: certain threshold. ! 178: When a connection has been established, ! 179: the service providers inform the initiator and responder as to what this ! 180: threshold is. ! 181: ! 182: \[\fbox{\begin{tabular}{lp{0.8\textwidth}}\label{TSDU:atomic} ! 183: \bf NOTE:& In the current implementation, ! 184: TSDUs which are no larger than the maximum atomic TSDU size ! 185: are handled very efficiently. ! 186: For optimal performance, ! 187: users of the transport service should strive to avoid sending ! 188: TSDUs which are larger than this threshold. ! 189: \end{tabular}}\] ! 190: ! 191: \subsection {Server Initialization} ! 192: The \man tsapd(8c) daemon, ! 193: upon accepting a connection from an initiating host, ! 194: consults the ISO services database to determine which program ! 195: on the system implements the desired TSAP entity. ! 196: For efficiency reasons, ! 197: the \pgm{tsapd} program contains the bootstrap for several providers ! 198: (e.g., session). ! 199: ! 200: Once the program has been ascertained, ! 201: the daemon runs the program with any arguments listed in the database. ! 202: In addition, it appends some {\em magic arguments\/} to the argument vector. ! 203: Hence, the very first action performed by the responder is to re-capture the ! 204: TSAP state contained in these magic arguments. ! 205: This is done by calling the routine \verb"TInit", ! 206: which on a successful return, ! 207: is equivalent to a {\sf T-CONNECT.INDICATION\/} event from the transport ! 208: service provider. ! 209: \begin{quote}\index{TInit}\small\begin{verbatim} ! 210: int TInit (vecp, vec, ts, td) ! 211: int vecp; ! 212: char **vec; ! 213: struct TSAPstart *ts; ! 214: struct TSAPdisconnect *td; ! 215: \end{verbatim}\end{quote} ! 216: The parameters to this procedure are: ! 217: \begin{describe} ! 218: \item[\verb"vecp":] the length of the argument vector; ! 219: ! 220: \item[\verb"vec":] the argument vector; ! 221: ! 222: \item[\verb"ts":] a pointer to a \verb"TSAPstart" structure, which is updated ! 223: only if the call succeeds; ! 224: and, ! 225: ! 226: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 227: updated only if the call fails. ! 228: \end{describe} ! 229: If \verb"TInit" is successful, ! 230: it returns information in the \verb"ts" parameter, ! 231: which is a pointer to a \verb"TSAPstart" structure. ! 232: \begin{quote}\index{TSAPstart}\small\begin{verbatim} ! 233: struct TSAPstart { ! 234: int ts_sd; ! 235: ! 236: struct TSAPaddr ts_calling; ! 237: struct TSAPaddr ts_called; ! 238: ! 239: int ts_expedited; ! 240: ! 241: int ts_tsdusize; ! 242: ! 243: struct QOStype ts_qos; ! 244: ! 245: #define TS_SIZE 32 ! 246: int ts_cc; ! 247: char ts_data[TS_SIZE]; ! 248: }; ! 249: \end{verbatim}\end{quote} ! 250: The elements of this structure are: ! 251: \begin{describe}\label{TSAPstart} ! 252: \item[\verb"ts\_sd":] the transport-descriptor to be used to reference this ! 253: connection; ! 254: ! 255: \item[\verb"ts\_calling":] the address of peer initiating the connection; ! 256: ! 257: \item[\verb"ts\_called":] the address of the peer being asked to respond; ! 258: ! 259: \item[\verb"ts\_expedited":] whether initiator requests the use of expedited ! 260: data; ! 261: ! 262: \item[\verb"ts\_tsdusize":] the largest atomic TSDU size that can be used ! 263: on the connection (see the note on page~\pageref{TSDU:atomic}); ! 264: ! 265: \item[\verb"ts\_qos":] the quality of service on the connection ! 266: (see Section~\ref{tsap:qos}); ! 267: and, ! 268: ! 269: \item[\verb"ts\_data"/\verb"ts\_cc":] any initial data ! 270: (and the length of that data). ! 271: \end{describe} ! 272: ! 273: If the call to \verb"TInit" is not successful, ! 274: then the user is informed that a {\sf T-DISCONNECT.INDICATION\/} event has ! 275: occurred, ! 276: and the relevant information is returned in a \verb"TSAPdisconnect" structure. ! 277: \begin{quote}\index{TSAPdisconnect}\small\begin{verbatim} ! 278: struct TSAPdisconnect { ! 279: int td_reason; ! 280: ! 281: #define TD_SIZE 64 ! 282: int td_cc; ! 283: char td_data[TD_SIZE]; ! 284: }; ! 285: \end{verbatim}\end{quote} ! 286: The elements of this structure are:\label{TSAPdisconnect} ! 287: \begin{describe} ! 288: \item[\verb"td\_reason":] reason for disconnect ! 289: (codes are listed in Table~\ref{TSAPreasons}); ! 290: and, ! 291: ! 292: \item[\verb"td\_data"/\verb"td\_cc":] any disconnect data ! 293: (and the length of that data) from the peer. ! 294: \end{describe} ! 295: \tagtable[tp]{6-1}{TSAP Failure Codes}{TSAPreasons} ! 296: ! 297: After examining the information returned by \verb"TInit" on a successful call ! 298: (and possibly after examining the argument vector), ! 299: the responder should either accept or reject the connection. ! 300: If accepting, the \verb"TConnResponse" routine is called ! 301: (which corresponds to the {\sf T-CONNECT.RESPONSE\/} action). ! 302: \begin{quote}\index{TConnResponse}\small\begin{verbatim} ! 303: int TConnResponse (sd, responding, expedited, data, cc, ! 304: qos, td) ! 305: int sd; ! 306: struct TSAPaddr *responding; ! 307: int expedited, ! 308: cc; ! 309: char *data; ! 310: struct QOStype *qos; ! 311: struct TSAPdisconnect *td; ! 312: \end{verbatim}\end{quote} ! 313: The parameters to this procedure are: ! 314: \begin{describe} ! 315: \item[\verb"sd":] the transport-descriptor; ! 316: ! 317: \item[\verb"responding":] the TSAP address of the responder ! 318: (defaulting to the called address, if not present); ! 319: ! 320: \item[\verb"expedited":] whether expedited data is to be permitted ! 321: (this value must be \verb"0" unless the {\sf T-CONNECT.INDICATION\/} event ! 322: indicated a willingness on the part of the initiator to support expedited ! 323: data transfer); ! 324: ! 325: \item[\verb"data"/\verb"cc":] any initial data ! 326: (and the length of that data, ! 327: which may not exceed \verb"TC_SIZE" octets); ! 328: ! 329: \item[\verb"qos":] the quality of service on the connection ! 330: (see Section~\ref{tsap:qos}); ! 331: and, ! 332: ! 333: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 334: updated only if the call fails. ! 335: \end{describe} ! 336: If the call to \verb"TConnResponse" is successful, ! 337: then connection establishment has completed ! 338: and the users of the transport service now operate as symmetric peers. ! 339: Otherwise, if the call fails and the reason is not an interface error ! 340: (see Table~\ref{TSAPreasons} on page~\pageref{TSAPreasons}), ! 341: then the connection is closed. ! 342: ! 343: If instead, the responder wishes to reject the connection, ! 344: it should fire the {\sf T-DISCONNECT.REQUEST\/} action by calling the ! 345: \verb"TDiscRequest" routine. ! 346: \begin{quote}\index{TDiscRequest}\small\begin{verbatim} ! 347: int TDiscRequest (sd, data, cc, td) ! 348: int sd; ! 349: char *data; ! 350: int cc; ! 351: struct TSAPdisconnect *td; ! 352: \end{verbatim}\end{quote} ! 353: The parameters to this procedure are: ! 354: \begin{describe}\label{TDiscRequest} ! 355: \item[\verb"sd":] the transport-descriptor; ! 356: ! 357: \item[\verb"data"/\verb"cc":] any disconnect data ! 358: (and the length of that data, which may not exceed \verb"TD_SIZE" octets); ! 359: and, ! 360: ! 361: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 362: updated only if the call fails. ! 363: \end{describe} ! 364: After a return from this call, the responder may exit. ! 365: ! 366: \subsection {Client Initialization} ! 367: A program wishing to connect to another user of transport services calls the ! 368: \verb"TConnRequest" routine, ! 369: which corresponds to the {\sf T-CONNECT.REQUEST\/} action. ! 370: \begin{quote}\index{TConnRequest}\small\begin{verbatim} ! 371: int TConnRequest (calling, called, expedited, data, cc, ! 372: qos, tc, td) ! 373: struct TSAPaddr *calling, ! 374: *called; ! 375: int expedited, ! 376: cc; ! 377: char *data; ! 378: struct QOStype *qos; ! 379: struct TSAPconnect *tc; ! 380: struct TSAPdisconnect *td; ! 381: \end{verbatim}\end{quote} ! 382: The parameters to this procedure are: ! 383: \begin{describe} ! 384: \item[\verb"calling":] the TSAP address of the initiator; ! 385: (need not be present); ! 386: ! 387: \item[\verb"called":] the TSAP address of the responder; ! 388: ! 389: \item[\verb"expedited":] whether expedited data is to be permitted; ! 390: ! 391: \item[\verb"data"/\verb"cc":] any initial data ! 392: (and the length of that data, which may not exceed \verb"TS_SIZE" octets); ! 393: ! 394: \item[\verb"qos":] the quality of service on the connection ! 395: (see Section~\ref{tsap:qos}); ! 396: ! 397: \item[\verb"tc":] a pointer to a \verb"TSAPconnect" structure, which is ! 398: updated only if the call succeeds; ! 399: and, ! 400: ! 401: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 402: updated only if the call fails. ! 403: \end{describe} ! 404: If the call to \verb"TConnRequest" is successful ! 405: (a successful return corresponds to a {\sf T-CONNECT.CONFIRMATION} event), ! 406: then information is returned in the \verb"tc" parameter, ! 407: which is a pointer to a \verb"TSAPconnect" structure. ! 408: \begin{quote}\index{TSAPconnect}\small\begin{verbatim} ! 409: struct TSAPconnect { ! 410: int tc_sd; ! 411: ! 412: struct TSAPaddr tc_responding; ! 413: ! 414: int tc_expedited; ! 415: ! 416: int tc_tsdusize; ! 417: ! 418: struct QOStype tc_qos; ! 419: ! 420: #define TC_SIZE 32 ! 421: int tc_cc; ! 422: char tc_data[TC_SIZE]; ! 423: }; ! 424: \end{verbatim}\end{quote} ! 425: The elements of this structure are: ! 426: \begin{describe} ! 427: \item[\verb"tc\_sd":] the transport-descriptor to be used to reference this ! 428: connection; ! 429: ! 430: \item[\verb"tc\_responding":] the responding peer's address ! 431: (which is the same as the \verb"called" address given as a parameter to ! 432: \verb"TConnRequest"); ! 433: ! 434: \item[\verb"tc\_expedited":] whether expedited data will be supported; ! 435: ! 436: \item[\verb"tc\_tsdusize":] the largest atomic TSDU size that can be used ! 437: on the connection (see the note on page~\pageref{TSDU:atomic}); ! 438: ! 439: \item[\verb"tc\_qos":] the quality of service on the connection ! 440: (see Section~\ref{tsap:qos}); ! 441: and, ! 442: ! 443: \item[\verb"tc\_data"/\verb"tc\_cc":] any initial data ! 444: (and the length of that data). ! 445: \end{describe} ! 446: If the call to \verb"TConnRequest" is successful, ! 447: then connection establishment has completed ! 448: and the users of the transport service now operate as symmetric peers. ! 449: Otherwise, if the call fails then the connection is not established, ! 450: and the \verb"TSAPdisconnect" structure has been updated. ! 451: ! 452: \subsubsection {Asynchronous Connections}\label{tsap:async} ! 453: Normally \verb"TConnRequest" returns only after a connection has succeeded or ! 454: failed. ! 455: This is termed a {\em synchronous\/} connection initiation. ! 456: If the user desires, an {\em asynchronous\/} connection may be initiated. ! 457: The routine \verb"TConnRequest" is really a macro which calls the routine ! 458: \verb"TAsynConnRequest" with an argument indicating that a connection should ! 459: be attempted synchronously. ! 460: \begin{quote}\index{TAsynConnRequest}\small\begin{verbatim} ! 461: int TAsynConnRequest (calling, called, expedited, ! 462: data, cc, qos, tc, td, async) ! 463: struct TSAPaddr *calling, ! 464: *called; ! 465: int expedited, ! 466: cc, ! 467: async; ! 468: char *data; ! 469: struct QOStype *qos; ! 470: struct TSAPconnect *tc; ! 471: struct TSAPdisconnect *td; ! 472: \end{verbatim}\end{quote} ! 473: The additional parameter to this procedure is: ! 474: \begin{describe} ! 475: \item[\verb"async":] whether the connection should be initiated asynchronously. ! 476: \end{describe} ! 477: If the \verb"async" parameter is non-zero, ! 478: then \verb"TAsynConnRequest" returns one of four values: ! 479: \verb"NOTOK", which indicates that the connection request failed; ! 480: \verb"DONE", which indicates that the connection request succeeded; ! 481: or, either of \verb"CONNECTING_1" or \verb"CONNECTING_2", which indicates that ! 482: the connection request is still in ! 483: progress. ! 484: In the first two cases, ! 485: the usual procedures for handling return values from \verb"TConnRequest" are ! 486: employed ! 487: (i.e., a \verb"NOTOK" return from \verb"TAsynConnRequest" is equivalent to a ! 488: \verb"NOTOK" return from \verb"TConnRequest", and, ! 489: a \verb"DONE" return from \verb"TAsynConnRequest" is equivalent to a ! 490: \verb"OK" return from \verb"TConnRequest"). ! 491: In the final case, when either \verb"CONNECTING_1" or ! 492: \verb"CONNECTING_2" is returned, ! 493: only the \verb"tc_sd" element of the \verb"tc" parameter has been updated; ! 494: it reflects the transport-descriptor to be used to reference this connection. ! 495: Note that the \verb"data" parameter is still being referenced by ! 496: \man libtsap(3n) and should not be tampered with until the connection attempt ! 497: has been completed. ! 498: ! 499: To determine when the connection attempt has been completed, ! 500: the routine \verb"xselect" (consult Section~\ref{acs:select} of \volone/) ! 501: should be used after calling \verb"TSelectMask". ! 502: In order to determine if the connection attempt was successful, ! 503: the routine \verb"TAsynRetryRequest" is called: ! 504: \begin{quote}\index{TAsynRetryRequest}\small\begin{verbatim} ! 505: int TAsynRetryRequest (sd, tc, td) ! 506: int sd; ! 507: struct TSAPconnect *tc; ! 508: struct TSAPdisconnect *td; ! 509: \end{verbatim}\end{quote} ! 510: The parameters to this procedure are: ! 511: \begin{describe} ! 512: \item[\verb"sd":] the transport-descriptor; ! 513: ! 514: \item[\verb"tc":] a pointer to a \verb"TSAPconnect" structure, which is ! 515: updated only if the call succeeds; ! 516: and, ! 517: ! 518: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 519: updated only if the call fails. ! 520: \end{describe} ! 521: Again, one of four values are returned: ! 522: \verb"NOTOK", which indicates that the connection request failed; ! 523: \verb"DONE", which indicates that the connection request succeeded; ! 524: or, either of \verb"CONNECTING_1" or \verb"CONNECTING_2" which indicates that ! 525: the connection request is still in progress. ! 526: ! 527: In order to make efficient use of the asychronous connection facility, ! 528: it is necessary to understand a bit of its underlying mechanisms. ! 529: From a temporal perspective, ! 530: connection establishment consists of two parts: ! 531: \begin{enumerate} ! 532: \item establishing a reliable end-to-end connection; ! 533: and, ! 534: ! 535: \item exchanging connection establishment information. ! 536: \end{enumerate} ! 537: In some cases, ! 538: the underlying transport mechanisms accomplish both simultaneously ! 539: (when the end-to-end connection is built, ! 540: connection establishment information is also exchanged). ! 541: ! 542: Thus, in order to to perform asynchronous connections effectively, ! 543: use of \verb"TAsynConnRequest" and \verb"TAsynRetry" should reflect this ! 544: two-step process: ! 545: \begin{enumerate} ! 546: \item Call \verb"TAsynConnRequest" with the \verb"async" parameter taking the ! 547: value~1. ! 548: If the return value was either \verb"NOTOK" ! 549: (the connection was not established), ! 550: or \verb"DONE" (the connection was established), ! 551: then terminate this algorithm. ! 552: ! 553: Otherwise, a return value of \verb"CONNECTING_1" or ! 554: \verb"CONNECTING_2" indicates that connection ! 555: establishment process has begun. Remember this value. ! 556: ! 557: \item At some point in the future, ! 558: call \verb"TSelectMask" to get an argument for \verb"xselect". ! 559: Then call \verb"xselect" checking to see if writing is ! 560: permitted. Then call \verb"xselect" checking for writing if ! 561: the remembered value was \verb"CONNECTING_1" and for reading ! 562: if it was \verb"CONNECTING_2". If either call returns ! 563: \verb"NOTOK", then a catastrophic error has occurred. ! 564: ! 565: Repeat this step as often as necessary until \verb"xselect" says that ! 566: reading or writing as required is permitted. ! 567: ! 568: \item Call \verb"TAsynRetry". ! 569: If the return value was either \verb"NOTOK" (the connection ! 570: was not established), or \verb"DONE" (the connection was ! 571: established), then terminate this algorithm. ! 572: ! 573: Otherwise, a return value of \verb"CONNECTING_1" or ! 574: \verb"CONNECTING_2" indicates that connection establishment is ! 575: {\em still\/} in progress. Remember this value and go back to ! 576: the previous step. ! 577: ! 578: \end{enumerate} ! 579: Although this seems complicated, ! 580: implementation of these rules is actually straight-forward. ! 581: In most cases, ! 582: your code will do some work unrelated to the connection ! 583: ! 584: Note that this procedure is equally applicable to the higher-layers ! 585: (session, presentation, and association control) which also provide ! 586: asynchronous connection facilities. ! 587: For example, ! 588: at the application layer, ! 589: the routines \verb"AcAsynAssocRequest" and \verb"AcAsynRetryRequest" would be ! 590: used. ! 591: ! 592: \section {Data Transfer} ! 593: Once the connection has been established, ! 594: a transport-descriptor is used to reference the connection. ! 595: This is usually the first parameter given to any of the remaining routines in ! 596: the \man libtsap(3n) library. ! 597: Further, ! 598: the last parameter is usually a pointer to a \verb"TSAPdisconnect" structure ! 599: (as described on page~\pageref{TSAPdisconnect}). ! 600: If a call to one of these routines fails, ! 601: then the structure is updated. ! 602: Otherwise, if the value of the \verb"td_reason" element is associated with a ! 603: fatal error, then the connection is closed. ! 604: That is, a {\sf T-DISCONNECT.INDICATION\/} event has occurred. ! 605: The \verb"DR_FATAL" macro can be used to determine this. ! 606: \begin{quote}\index{DR\_FATAL}\small\begin{verbatim} ! 607: int DR_FATAL (r) ! 608: int r; ! 609: \end{verbatim}\end{quote} ! 610: For protocol purists, ! 611: the \verb"DR_OFFICIAL" macro can be used to determine if the error is an ! 612: ``official'' error as defined by the specification, ! 613: or an ``unofficial'' error used by the implementation. ! 614: \begin{quote}\index{DR\_OFFICIAL}\small\begin{verbatim} ! 615: int DR_OFFICIAL (r) ! 616: int r; ! 617: \end{verbatim}\end{quote} ! 618: ! 619: \subsection {Sending Data} ! 620: There are three routines that may be used to send data. ! 621: A call to the \verb"TDataRequest" routine is equivalent to a ! 622: {\sf T-DATA.REQUEST\/} action on the part of the user. ! 623: \begin{quote}\index{TDataRequest}\small\begin{verbatim} ! 624: int TDataRequest (sd, data, cc, td) ! 625: int sd; ! 626: char *data; ! 627: int cc; ! 628: struct TSAPdisconnect *td; ! 629: \end{verbatim}\end{quote} ! 630: The parameters to this procedure are: ! 631: \begin{describe} ! 632: \item[\verb"sd":] the transport-descriptor; ! 633: ! 634: \item[\verb"data"/\verb"cc":] the data to be written ! 635: (and the length of that data); ! 636: and, ! 637: ! 638: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 639: updated only if the call fails. ! 640: \end{describe} ! 641: If the call to \verb"TDataRequest" is successful, ! 642: then the data has been queued for sending. ! 643: Otherwise, ! 644: the \verb"td" parameter indicates the reason for failure. ! 645: ! 646: The \verb"TWriteRequest" routine is similar in nature to the ! 647: \verb"TDataRequest" routine, ! 648: but uses a different set of parameters. ! 649: The invocation is: ! 650: \begin{quote}\index{TWriteRequest}\small\begin{verbatim} ! 651: int TWriteRequest (sd, uv, td) ! 652: int sd; ! 653: struct udvec *uv; ! 654: struct TSAPdisconnect *td; ! 655: \end{verbatim}\end{quote} ! 656: While the parameters are: ! 657: \begin{describe} ! 658: \item[\verb"sd":] the transport-descriptor; ! 659: ! 660: \item[\verb"uv":] the data to be written, ! 661: described in a null-terminated array of scatter/gather elements: ! 662: \begin{quote}\index{udvec}\small\begin{verbatim} ! 663: struct udvec { ! 664: caddr_t uv_base; ! 665: int uv_len; ! 666: }; ! 667: \end{verbatim}\end{quote} ! 668: The elements of the structure are: ! 669: \begin{describe} ! 670: \item[\verb"uv\_base":] the base of an element; and, ! 671: \item[\verb"uv\_cc":] the length of an element. ! 672: \end{describe} ! 673: and, ! 674: ! 675: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 676: updated only if the call fails. ! 677: \end{describe} ! 678: If the call to \verb"TWriteRequest" is successful, ! 679: then the data has been queued for sending. ! 680: Otherwise, ! 681: the \verb"td" parameter indicates the reason for failure. ! 682: ! 683: A call to the \verb"TExpdRequest" routine is equivalent to a ! 684: {\sf T-EXPEDITED-DATA.REQUEST\/} action on the part of the user. ! 685: \begin{quote}\index{TExpdRequest}\small\begin{verbatim} ! 686: int TExpdRequest (sd, data, cc, td) ! 687: int sd; ! 688: char *data; ! 689: int cc; ! 690: struct TSAPdisconnect *td; ! 691: \end{verbatim}\end{quote} ! 692: The parameters to this procedure are: ! 693: \begin{describe} ! 694: \item[\verb"sd":] the transport-descriptor; ! 695: ! 696: \item[\verb"data"/\verb"cc":] the data to be written ! 697: (and the length of that data, which may not exceed \verb"TX_SIZE" octets); ! 698: and, ! 699: ! 700: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 701: updated only if the call fails. ! 702: \end{describe} ! 703: If the call to \verb"TExpdRequest" is successful, ! 704: then the data has been queued for expedited sending. ! 705: Otherwise, ! 706: the \verb"td" parameter indicates the reason for failure. ! 707: ! 708: \subsection {Receiving Data} ! 709: There is one routine that is used to read data, ! 710: \verb"TReadRequest", ! 711: a call to which is equivalent to waiting for a {\sf T-DATA.INDICATION\/} ! 712: or {\sf T-EXPEDITED-DA\-TA.IN\-DI\-CA\-TION} event. ! 713: \begin{quote}\index{TReadRequest}\small\begin{verbatim} ! 714: int TReadRequest (sd, tx, secs, td) ! 715: int sd; ! 716: struct TSAPdata *tx; ! 717: int secs; ! 718: struct TSAPdisconnect *td; ! 719: \end{verbatim}\end{quote} ! 720: The parameters to this procedure are: ! 721: \begin{describe} ! 722: \item[\verb"sd":] the transport-descriptor; ! 723: ! 724: \item[\verb"tx":] a pointer to the \verb"TSAPdata" structure to be given ! 725: the data; ! 726: ! 727: \item[\verb"secs":] the maximum number of seconds to wait for the data ! 728: (a value of \verb"NOTOK" indicates that the call should block indefinitely, ! 729: whereas a value of \verb"OK" indicates that the call should not block at all, ! 730: e.g., a polling action); ! 731: and, ! 732: ! 733: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 734: updated only if the call fails. ! 735: \end{describe} ! 736: If the call to \verb"TReadRequest" is successful, ! 737: then the data has been read into the \verb"tx" parameter. ! 738: \begin{quote}\index{TSAPdata}\small\begin{verbatim} ! 739: struct TSAPdata { ! 740: int tx_expedited; ! 741: ! 742: int tx_cc; ! 743: struct qbuf tx_qbuf; ! 744: }; ! 745: \end{verbatim}\end{quote} ! 746: The elements of a \verb"TSAPdata" structure are: ! 747: \begin{describe} ! 748: \item[\verb"tx\_expedited":] whether the data was received via expedited ! 749: transfer ! 750: (i.e., an {\sf T-EXPEDITED-DATA.INDICATION\/} event occurred); ! 751: ! 752: \item[\verb"tx\_cc":] the total number of octets that was read; ! 753: and, ! 754: ! 755: \item[\verb"tx\_qbuf":] the data that was read, in a buffer-queue form. ! 756: \begin{quote}\index{qbuf}\small\begin{verbatim} ! 757: struct qbuf { ! 758: struct qbuf *qb_forw; ! 759: struct qbuf *qb_back; ! 760: ! 761: int qb_len; ! 762: char *qb_data; ! 763: ! 764: char qb_base[1]; ! 765: }; ! 766: \end{verbatim}\end{quote} ! 767: The elements of a \verb"qbuf" structure are:\label{tsap:qbuf} ! 768: \begin{describe} ! 769: \item[\verb"qb\_forw"/\verb"qb\_back":] forward and back pointers; ! 770: ! 771: \item[\verb"qb\_data"/\verb"qb\_len":] the user data ! 772: (and the length of that data); ! 773: and, ! 774: ! 775: \item[\verb"qb\_base":] the extensible array containing the data. ! 776: \end{describe} ! 777: \end{describe} ! 778: Note that the data contained in the structure was allocated via \man malloc(3), ! 779: and should be released by using the \verb"TXFREE" macro when no longer ! 780: referenced. ! 781: The \verb"TXFREE" macro, ! 782: which is used for this purpose, ! 783: behaves as if it was defined as:\label{TXFREE} ! 784: \begin{quote}\index{TXFREE}\small\begin{verbatim} ! 785: void TXFREE (tx) ! 786: struct TSAPdata *tx; ! 787: \end{verbatim}\end{quote} ! 788: The macro frees only the data allocated by \verb"TDataRequest", ! 789: and not the \verb"TSAPdata" structure itself. ! 790: Further, ! 791: \verb"TXFREE" should be called only if the call to the \verb"TDataRequest" ! 792: routine returned \verb"OK". ! 793: ! 794: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 795: \bf NOTE:& Because the \verb"TSAPdata" structure contains a ! 796: \verb"qbuf" element, care must be taken in initializing ! 797: and copying variables of this type. ! 798: The routines in \man libtsap(3n) library will correctly ! 799: initialize these structures when given as parameters. ! 800: But, users who otherwise manipulate \verb"TSAPdata" ! 801: structures should take great care. ! 802: \end{tabular}}\] ! 803: ! 804: Otherwise if the call to \verb"TReadRequest" did not succeed, ! 805: the \verb"td" parameter indicates the reason for failure. ! 806: ! 807: \subsection {Asynchronous Event Handling} ! 808: The data transfer events discussed thus far have been synchronous in nature. ! 809: Some users of the transport service may wish an asynchronous interface. ! 810: The \verb"TSetIndications" routine is used to change the service associated ! 811: with a transport-descriptor to or from an asynchronous interface. ! 812: \begin{quote}\index{TSetIndications}\small\begin{verbatim} ! 813: int TSetIndications (sd, data, disc, td) ! 814: int sd; ! 815: int (*data) (), ! 816: (*disc) (); ! 817: struct TSAPdisconnect *td; ! 818: \end{verbatim}\end{quote} ! 819: The parameters to this procedure are: ! 820: \begin{describe} ! 821: \item[\verb"sd":] the transport-descriptor; ! 822: ! 823: \item[\verb"data":] the address of an event-handler routine to be invoked when ! 824: data has arrived ! 825: (either a {\sf T-DATA.INDICATION\/} or {\sf T-EXPEDITED-DATA.INDICATION} event ! 826: occurs); ! 827: ! 828: \item[\verb"disc":] the address of an event-handler routine to be invoked when ! 829: the connection has been closed ! 830: (a {\sf T-DISCONNECT.INDICATION\/} event occurs); ! 831: and, ! 832: ! 833: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 834: updated only if the call fails. ! 835: \end{describe} ! 836: If the service is to be made asynchronous, ! 837: then both \verb"data" and \verb"disc" are specified; ! 838: otherwise, ! 839: if the service is to be made synchronous, ! 840: neither should be specified (use the manifest constant \verb"NULLIFP"). ! 841: The most likely reason for the call failing is \verb"DR_WAITING", ! 842: which indicates that an event is waiting for the user. ! 843: ! 844: When an event-handler is invoked, ! 845: future invocations of the event-hander are blocked until it returns. ! 846: The return value of the event-handler is ignored. ! 847: Further, ! 848: during the execution of a synchronous call to the library, ! 849: the event-handler will be blocked from being invoked. ! 850: ! 851: When an event associated with data arriving occurs, ! 852: the event-handler routine is invoked with two parameters: ! 853: \begin{quote}\small\begin{verbatim} ! 854: (*data) (sd, tx); ! 855: int sd; ! 856: struct TSAPdata *tx; ! 857: \end{verbatim}\end{quote} ! 858: The parameters are: ! 859: \begin{describe} ! 860: \item[\verb"sd":] the transport-descriptor; ! 861: and, ! 862: ! 863: \item[\verb"tx":] a pointer to a \verb"TSAPdata" structure containing ! 864: the data. ! 865: \end{describe} ! 866: Note that the data contained in the structure was allocated via \man malloc(3), ! 867: and should be released with the \verb"TXFREE" macro ! 868: (described on page~\pageref{TXFREE}) when no longer needed. ! 869: ! 870: Similarly, ! 871: when an event associated with connection release occurs, ! 872: the event-handler is also invoked with two parameters: ! 873: \begin{quote}\small\begin{verbatim} ! 874: (*disc) (sd, td); ! 875: int sd; ! 876: struct TSAPdisconnect *td; ! 877: \end{verbatim}\end{quote} ! 878: The parameters are ! 879: \begin{describe} ! 880: \item[\verb"sd":] the transport-descriptor; ! 881: and, ! 882: ! 883: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure ! 884: indicating why the connection was released. ! 885: \end{describe} ! 886: Note that the transport-descriptor is no longer valid at the instant the ! 887: call is made. ! 888: ! 889: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 890: \bf NOTE:& The \man libtsap(3n) library uses the SIGEMT signal to provide ! 891: these services. ! 892: Programs using asynchronous transport-descriptors should NOT ! 893: use SIGEMT for other purposes. ! 894: \end{tabular}}\] ! 895: ! 896: \subsection {Synchronous Event Multiplexing} ! 897: A user of the transport service may wish to manage multiple ! 898: transport-descriptors simultaneously; ! 899: the routine \verb"TSelectMask" is provided for this purpose. ! 900: This routine updates a file-descriptor mask and associated counter for use ! 901: with \verb"xselect". ! 902: \begin{quote}\index{TSelectMask}\small\begin{verbatim} ! 903: int TSelectMask (sd, mask, nfds, td) ! 904: int sd; ! 905: fd_set *mask, ! 906: int *nfds; ! 907: struct TSAPdisconnect *td; ! 908: \end{verbatim}\end{quote} ! 909: The parameters to this procedure are: ! 910: \begin{describe} ! 911: \item[\verb"sd":] the transport-descriptor; ! 912: ! 913: \item[\verb"mask":] a pointer to a file-descriptor mask meaningful to ! 914: \verb"xselect"; ! 915: ! 916: \item[\verb"nfds":] a pointer to an integer-valued location meaningful to ! 917: \verb"xselect"; ! 918: and, ! 919: ! 920: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 921: updated only if the call fails. ! 922: \end{describe} ! 923: If the call is successful, then the \verb"mask" and \verb"nfds" parameters can ! 924: be used as arguments to \verb"xselect". ! 925: The most likely reason for the call failing is \verb"DR_WAITING", ! 926: which indicates that an event is waiting for the user. ! 927: ! 928: If \verb"xselect" indicates that the transport-descriptor is ready for reading, ! 929: \verb"TReadRequest" should be called with the \verb"secs" parameter equal to ! 930: \verb"OK". ! 931: If the network activity does not constitute an entire event for the user, ! 932: then \verb"TReadRequest" will return \verb"NOTOK" with error code ! 933: \verb"DR_TIMER". ! 934: ! 935: In addition, ! 936: the routine \verb"TSelectOctets" is provided to return an estimate of how many ! 937: octets might be returned by the next call to \verb"TReadRequest": ! 938: \begin{quote}\index{TSelectOctets}\small\begin{verbatim} ! 939: int TSelectOctets (sd, nbytes, td) ! 940: int sd; ! 941: long *nbytes; ! 942: struct TSAPdisconnect *td; ! 943: \end{verbatim}\end{quote} ! 944: The parameters to this procedure are: ! 945: \begin{describe} ! 946: \item[\verb"sd":] the transport-descriptor; ! 947: ! 948: \item[\verb"nbytes":] a pointer to a longword location that, on success, will ! 949: be updated to contain the number of octets that might be returned; ! 950: and, ! 951: ! 952: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 953: updated only if the call fails. ! 954: \end{describe} ! 955: ! 956: \section {Connection Release} ! 957: The \verb"TDiscRequest" routine is used to release a connection. ! 958: Note, that the TSAP makes no guarantee that any queued data will be received ! 959: before the connection closes. ! 960: \begin{quote}\index{TDiscRequest}\small\begin{verbatim} ! 961: int TDiscRequest (sd, data, cc, td) ! 962: int sd; ! 963: char *data; ! 964: int cc; ! 965: struct TSAPdisconnect *td; ! 966: \end{verbatim}\end{quote} ! 967: The parameters to the procedure are described on page~\pageref{TDiscRequest}. ! 968: ! 969: \section {State Saving and Restoration} ! 970: Some users of the transport service, ! 971: and in particular the session provider, ! 972: require the ability to \man execve(2) another process image and have that ! 973: process use the transport connection. ! 974: Since the \man libtsap(3n) library is not kernel-resident, ! 975: special provisions are necessary to support this behavior. ! 976: ! 977: \subsection {Saving the State} ! 978: The routine \verb"TSaveState" is used to record the state of the TSAP for a ! 979: given transport-descriptor. ! 980: \begin{quote}\index{TSaveState}\small\begin{verbatim} ! 981: int TSaveState (sd, vec, td) ! 982: int sd; ! 983: char **vec; ! 984: struct TSAPdisconnect *td; ! 985: \end{verbatim}\end{quote} ! 986: The parameters to this procedure are: ! 987: \begin{describe} ! 988: \item[\verb"sd":] the transport-descriptor; ! 989: ! 990: \item[\verb"vec":] a pointer to the first free slot in the argument vector for ! 991: \man execve(2); ! 992: and, ! 993: ! 994: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 995: updated only if the call fails. ! 996: \end{describe} ! 997: If the call succeeds, ! 998: then an extra {\em magic argument\/} has been placed in the argument vector. ! 999: The most likely reason for the call failing is \verb"DR_WAITING", ! 1000: which indicates that an event is waiting for the user. ! 1001: ! 1002: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 1003: \bf NOTE:& Once a successful call to \verb"TSaveState" is made on a ! 1004: transport descriptor, that descriptor may no longer be ! 1005: referenced until a corresponding call to \verb"TRestoreState" ! 1006: is successful. ! 1007: \end{tabular}}\] ! 1008: ! 1009: \subsection {Restoring the State} ! 1010: The routine \verb"TRestoreState" is used to re-initialize the state of the ! 1011: TSAP. ! 1012: \begin{quote}\index{TRestoreState}\small\begin{verbatim} ! 1013: int TRestoreState (buffer, ts, td) ! 1014: char *buffer; ! 1015: struct TSAPstart *ts; ! 1016: struct TSAPdisconnect *td; ! 1017: \end{verbatim}\end{quote} ! 1018: The parameters to this procedure are: ! 1019: \begin{describe} ! 1020: \item[\verb"buffer":] the {\em magic argument\/} constructed by ! 1021: \verb"TSaveState"; ! 1022: ! 1023: \item[\verb"ts":] a pointer to a \verb"TSAPstart" structure, which is updated ! 1024: only if the call succeeds; ! 1025: and, ! 1026: ! 1027: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, which is ! 1028: updated only if the call fails. ! 1029: \end{describe} ! 1030: If \verb"TRestoreState" is successful, ! 1031: it returns information in a \verb"TSAPstart" structure, ! 1032: as defined on page~\pageref{TSAPstart}. ! 1033: There is one exception however: ! 1034: in the current implementation the \verb"ts_cc" and ! 1035: \verb"ts_data" elements are undefined on a successful return from ! 1036: \verb"TRestoreState". ! 1037: ! 1038: \section {Cookie Parameters} ! 1039: There are two {\em cookie\/} parameters: ! 1040: network addresses and quality of service. ! 1041: ! 1042: \subsection {Network Addresses}\label{nsap:addresses} ! 1043: Network addresses can vary greatly. ! 1044: In this software distribution, ! 1045: a ``unified'' format has been adopted in the \verb"NSAPaddr" structure: ! 1046: \begin{quote}\index{NSAPaddr}\small\begin{verbatim} ! 1047: struct NSAPaddr { ! 1048: long na_stack; ! 1049: #define NA_NSAP 0 ! 1050: #define NA_TCP 1 ! 1051: #define NA_X25 2 ! 1052: #define NA_BRG 3 ! 1053: ! 1054: long na_community; ! 1055: ! 1056: union { ! 1057: struct na_nsap { ! 1058: #define NASIZE 64 ! 1059: char na_nsap_address[NASIZE]; ! 1060: char na_nsap_addrlen; ! 1061: } un_na_nsap; ! 1062: ! 1063: struct na_tcp { ! 1064: #define NSAP_DOMAINLEN 63 ! 1065: char na_tcp_domain[NSAP_DOMAINLEN + 1]; ! 1066: u_short na_tcp_port; ! 1067: u_short na_tcp_tset; ! 1068: #define NA_TSET_TCP 0x0001 ! 1069: #define NA_TSET_UDP 0x0002 ! 1070: } un_na_tcp; ! 1071: ! 1072: struct na_x25 { ! 1073: #define NSAP_DTELEN 15 ! 1074: char na_x25_dte[NSAP_DTELEN + 1]; ! 1075: char na_x25_dtelen; ! 1076: ! 1077: #define NPSIZE 4 ! 1078: char na_x25_pid[NPSIZE]; ! 1079: char na_x25_pidlen; ! 1080: ! 1081: #define CUDFSIZE 16 ! 1082: char na_x25_cudf[CUDFSIZE]; ! 1083: char na_x25_cudflen; ! 1084: ! 1085: #define FACSIZE 6 ! 1086: char na_x25_fac[FACSIZE]; ! 1087: char na_x25_faclen; ! 1088: } un_na_x25; ! 1089: } na_un; ! 1090: ! 1091: #define na_address na_un.un_na_nsap.na_nsap_address ! 1092: #define na_addrlen na_un.un_na_nsap.na_nsap_addrlen ! 1093: ! 1094: #define na_domain na_un.un_na_tcp.na_tcp_domain ! 1095: #define na_port na_un.un_na_tcp.na_tcp_port ! 1096: ! 1097: #define na_dte na_un.un_na_x25.na_x25_dte ! 1098: #define na_dtelen na_un.un_na_x25.na_x25_dtelen ! 1099: #define na_pid na_un.un_na_x25.na_x25_pid ! 1100: #define na_pidlen na_un.un_na_x25.na_x25_pidlen ! 1101: #define na_cudf na_un.un_na_x25.na_x25_cudf ! 1102: #define na_cudflen na_un.un_na_x25.na_x25_cudflen ! 1103: #define na_fac na_un.un_na_x25.na_x25_fac ! 1104: #define na_faclen na_un.un_na_x25.na_x25_faclen ! 1105: }; ! 1106: #define NULLNA ((struct NSAPaddr *) 0) ! 1107: \end{verbatim}\end{quote} ! 1108: As shown, this structure is really a discriminated union ! 1109: (a structure with a tag element followed by a union). ! 1110: Based on the value of the tag (\verb"na_stack"), ! 1111: a different structure is selected. ! 1112: ! 1113: For a native OSI CO-mode transport service, ! 1114: the value of the tag is \verb"NA_NSAP", ! 1115: and the following elements are meaningful: ! 1116: \begin{describe} ! 1117: \item[\verb"na\_address"/\verb"na\_addrlen":] the network address ! 1118: (and its length), binary-valued. ! 1119: \end{describe} ! 1120: ! 1121: For emulation of the OSI transport service on top of the TCP, ! 1122: the value of the tag is \verb"NA_TCP", ! 1123: and the following elements are meaningful: ! 1124: \begin{describe} ! 1125: \item[\verb"na\_domain":] the null-terminated domain name ! 1126: (e.g., ``gonzo.twg.com'') or dotted-quad (e.g., ``128.99.0.17''); ! 1127: ! 1128: \item[\verb"na\_port":] the TCP-port number offering the service ! 1129: (if zero, the service on port~102 is used); ! 1130: and, ! 1131: ! 1132: \item[\verb"na\_tset":] the set of IP-based transport services available at ! 1133: the address ! 1134: (if zero, the TCP service is used). ! 1135: \end{describe} ! 1136: ! 1137: For use of a single-subnet X.25, ! 1138: the value of the tag is \verb"NA_X25", ! 1139: and the following elements are meaningful: ! 1140: \begin{describe} ! 1141: \item[\verb"na\_dte"/\verb"na\_dtelen":] the X.121 address (and its length), ! 1142: ascii-valued, possibly null-terminated; ! 1143: ! 1144: \item[\verb"na\_pid"/\verb"na\_pidlen":] the protocol id (and its length), ! 1145: binary-valued; ! 1146: ! 1147: \item[\verb"na\_cudf"/\verb"na\_cudflen":] the call user data (and its length), ! 1148: binary-valued; ! 1149: and, ! 1150: ! 1151: \item[\verb"na\_fac"/\verb"na\_faclen":] the negotiated facilities proposed ! 1152: in the call request packet (and its length), ! 1153: binary-valued. ! 1154: \end{describe} ! 1155: For use of a TP0-bridge between the TCP and X.25, ! 1156: the value of the tag is \verb"NA_BRG", ! 1157: and the elements above are meaningful. ! 1158: ! 1159: If the value of the tag is not \verb"NA_NSAP", ! 1160: it may be useful to normalize the address into a ``real'' OSI address. ! 1161: The routine \verb"na2norm" is used: ! 1162: \begin{quote}\index{na2norm}\begin{verbatim} ! 1163: char *na2norm (na) ! 1164: struct NSAPaddr *na; ! 1165: \end{verbatim}\end{quote} ! 1166: The parameter to this procedure is: ! 1167: \begin{describe} ! 1168: \item[\verb"na"]: the network address to be normalized. ! 1169: \end{describe} ! 1170: A new network address is returned from a static area which contains the ! 1171: normalized form. ! 1172: ! 1173: The routine \verb"na2str" takes a network address and returns a ! 1174: null-ter\-mi\-na\-ted ascii string suitable for viewing: ! 1175: \begin{quote}\index{na2str}\begin{verbatim} ! 1176: char *na2str (na) ! 1177: struct NSAPaddr *na; ! 1178: \end{verbatim}\end{quote} ! 1179: The parameter to this procedure is: ! 1180: \begin{describe} ! 1181: \item[\verb"na"]: the network address to be printed. ! 1182: \end{describe} ! 1183: ! 1184: The \verb"na_community" field is an internal number used to distinguish ! 1185: between different OSI communities. ! 1186: Consult Chapter~\ref{tswitch} starting on page~\pageref{tswitch} for further ! 1187: details. ! 1188: ! 1189: \subsection {Quality of Service}\label{tsap:qos} ! 1190: Currently, quality of service is largely uninterpreted by the software. ! 1191: However, ! 1192: the quality of service structure contains those parameters which are supported: ! 1193: \begin{quote}\index{QOStype}\small\begin{verbatim} ! 1194: struct QOStype { ! 1195: /* transport QOS */ ! 1196: int qos_reliability; ! 1197: #define HIGH_QUALITY 0 ! 1198: #define LOW_QUALITY 1 ! 1199: ! 1200: /* session QOS */ ! 1201: int qos_sversion; ! 1202: int qos_extended; ! 1203: int qos_maxtime; ! 1204: }; ! 1205: #define NULLQOS ((struct QOStype *) 0) ! 1206: \end{verbatim}\end{quote} ! 1207: The elements of this structure are: ! 1208: \begin{describe} ! 1209: \item[\verb"qos\_reliability":] the ``reliability'' level of the connection, ! 1210: either high- or low-quality; ! 1211: ! 1212: \item[\verb"qos\_sversion":] the session version requested/negotiated on this ! 1213: connection (only applicable above the transport layer, obviously), ! 1214: if the manifest constant \verb"NOTOK" is used when initiating a connection, ! 1215: this indicates that the highest possible version should be negotiated; ! 1216: ! 1217: \item[\verb"qos\_extended":] the extended control parameter for the connection, ! 1218: (if non-zero, extended control is used by the session layer); ! 1219: and, ! 1220: ! 1221: \item[\verb"qos\_maxtime":] after a transport connection is established, ! 1222: the maximum number of seconds to wait for an acknowledgement from the ! 1223: responding SPM ! 1224: (any non-positive number indicates that no timelimit is desired). ! 1225: \end{describe} ! 1226: ! 1227: \section {Listen Facility}\label{tsap:listen} ! 1228: The \man libtsap(3n) library, ! 1229: supports a facility which permits a process to {\em listen\/} for certain ! 1230: connections. ! 1231: This can be useful for implementing an application which requires that a ! 1232: single server process handle multiple clients, ! 1233: or for connection recovery. ! 1234: These routines return the manifest constant \verb"NOTOK" on error, ! 1235: and \verb"OK" on success, ! 1236: they also update the \verb"td" parameter given to the routine. ! 1237: This parameter is a pointer to a \verb"TSAPdisconnect" structure. ! 1238: ! 1239: Although this facility is described in terms of the \man libtsap(3n) library, ! 1240: it will function at any other higher-layer in the system ! 1241: (e.g., the listen facility can be used for session or application-entities). ! 1242: ! 1243: A program starts listening for an particular connection by calling the routine ! 1244: \verb"TNetListen". ! 1245: \begin{quote}\index{TNetListen}\small\begin{verbatim} ! 1246: int TNetListen (ta, td) ! 1247: struct TSAPaddr *ta; ! 1248: struct TSAPdisconnect *td; ! 1249: \end{verbatim}\end{quote} ! 1250: The parameters to this procedure are: ! 1251: \begin{describe} ! 1252: \item[\verb"ta":] the transport address (0 or more network addresses) ! 1253: to listen on; and, ! 1254: ! 1255: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, ! 1256: which is updated only if the call fails. ! 1257: \end{describe} ! 1258: If the call is successful, ! 1259: then the program is now listening for incoming connections on that network ! 1260: address. ! 1261: Otherwise, ! 1262: the \verb"td" parameter indicates the reason for failure. ! 1263: ! 1264: A variant of \verb"TNetListen" is the \verb"TNetUnique" routine, ! 1265: which starts the process listening on a set of unique network (sub)addresses. ! 1266: \begin{quote}\index{TNetUnique}\small\begin{verbatim} ! 1267: int TNetUnique (ta, td) ! 1268: struct TSAPaddr *ta; ! 1269: struct TSAPdisconnect *td; ! 1270: \end{verbatim}\end{quote} ! 1271: The parameters to this procedure are: ! 1272: \begin{describe} ! 1273: \item[\verb"ta":] a transport address containing one or more partially ! 1274: filled-in network addresses; and, ! 1275: ! 1276: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, ! 1277: which is updated only if the call fails. ! 1278: \end{describe} ! 1279: If the call is successful, ! 1280: each network address in the \verb"ta" parameter is fully filled-in, ! 1281: the program is now listening for incoming connections on the resulting ! 1282: transport. ! 1283: Otherwise, ! 1284: the \verb"td" parameter indicates the reason for failure. ! 1285: ! 1286: To check when a new connection is waiting, ! 1287: or when existing connections have activity on them, ! 1288: the routine \verb"TNetAccept" is used.\label{tsap:accept} ! 1289: \begin{quote}\index{TNetAccept}\small\begin{verbatim} ! 1290: int TNetAccept (vecp, vec, nfds, rfds, wfds, efds, secs, ! 1291: td) ! 1292: int *vecp, ! 1293: char **vec; ! 1294: int nfds; ! 1295: fd_set *rfds, ! 1296: *wfds, ! 1297: *efds; ! 1298: int secs; ! 1299: struct TSAPdisconnect *td; ! 1300: \end{verbatim}\end{quote} ! 1301: The parameters to this procedure are: ! 1302: \begin{describe} ! 1303: \item[\verb"vecp"/\verb"vec":] the initialization vector for the new ! 1304: connection. ! 1305: ! 1306: \item[\verb"nfds"/\verb"rfds"/\verb"wfds"/\verb"efds":] connection-descriptors ! 1307: for use with \verb"xselect"; ! 1308: ! 1309: \item[\verb"secs":] the maximum number of seconds to wait for activity ! 1310: (a value of \verb"NOTOK" indicates that the call should block indefinitely, ! 1311: whereas a value of \verb"OK" indicates that the call should not block at all, ! 1312: e.g., a polling action); and, ! 1313: ! 1314: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, ! 1315: which is updated only if the call fails. ! 1316: \end{describe} ! 1317: If the call to \verb"TNetAccept" succeeds then the value of \verb"vecp" ! 1318: should be checked. ! 1319: If \verb"vecp" is greater than zero, ! 1320: a new connection has been accepted, ! 1321: and \verb"TInit" should be called, ! 1322: presumably followed by \verb"TConnResponse".% ! 1323: \footnote{Actually, any service addressable via a transport selector ! 1324: can use this service, ! 1325: e.g., if appropriate, a call to \verb"AcInit", ! 1326: followed by a call to \verb"AcAssocResponse", ! 1327: can be made.} ! 1328: Regardless of the value of \verb"vecp", ! 1329: the value of \verb"rfds" and \verb"wfds" should be checked to see which ! 1330: connections have activity pending. ! 1331: For these connections, ! 1332: any reads should probably be done with a \verb"secs" argument indicating a ! 1333: polling operation (i.e., a value of \verb"OK"). ! 1334: Otherwise, ! 1335: if the call to \verb"TNetAccept" fails, ! 1336: then the \verb"td" parameter indicates the reason for failure. ! 1337: ! 1338: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 1339: \bf NOTE:& The \verb|TNetAccept| procedure when first called arranges to ! 1340: clean up dead child processes. If the program will run any ! 1341: sub-processes and check their exit status, the automatic ! 1342: collection of zombie process should be disabled, by first ! 1343: calling \verb|TNetAccept| with a timeout of \verb|OK| and then ! 1344: setting the child signal handler to it's default state. ! 1345: \end{tabular}}\] ! 1346: ! 1347: The routine \verb"TNetAccept" is actually a macro which invokes a routine ! 1348: called \verb"TNetAcceptAux": ! 1349: \begin{quote}\index{TNetAcceptAux}\small\begin{verbatim} ! 1350: int TNetAcceptAux (vecp, vec, newfd, ta, nfds, rfds, wfds, ! 1351: efds, secs, td) ! 1352: int *vecp, ! 1353: char **vec; ! 1354: int newfd; ! 1355: struct TSAPaddr *ta; ! 1356: int nfds; ! 1357: fd_set *rfds, ! 1358: *wfds, ! 1359: *efds; ! 1360: int secs; ! 1361: struct TSAPdisconnect *td; ! 1362: \end{verbatim}\end{quote} ! 1363: The additional parameters to this procedure are: ! 1364: \begin{describe} ! 1365: \item[\verb"newfd":] a pointer to an integer which will be given the value of ! 1366: the connection-descriptor associated with the new connection; ! 1367: and, ! 1368: ! 1369: \item[\verb"ta":] a pointer to a \verb"TSAPaddr" structure which will be given ! 1370: the value of the transport address receiving the new connection ! 1371: (the called or listening address). ! 1372: \end{describe} ! 1373: ! 1374: Prior to exiting, ! 1375: the user should call \verb"TNetClose" to stop listening for connections. ! 1376: \begin{quote}\index{TNetClose}\small\begin{verbatim} ! 1377: int TNetClose (ta, td) ! 1378: struct TSAPaddr *ta; ! 1379: struct TSAPdisconnect *td; ! 1380: \end{verbatim}\end{quote} ! 1381: The parameters to this procedure are: ! 1382: \begin{describe} ! 1383: \item[\verb"ta":] the transport address to stop listening on ! 1384: (use the manifest constant \verb"NULLTA" to stop listening on all addresses); ! 1385: and, ! 1386: ! 1387: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, ! 1388: which is updated only if the call fails. ! 1389: \end{describe} ! 1390: If the call is successful, ! 1391: then the program has stopped listening for incoming connections on that network ! 1392: address. ! 1393: Otherwise, ! 1394: the \verb"td" parameter indicates the reason for failure. ! 1395: ! 1396: \section {Queued (non-blocking) Writes Facility} ! 1397: All ``read'' operations in the ISODE are inherently non-blocking. ! 1398: Historically, ``write'' operations have not required this capability. ! 1399: However, ! 1400: some applications (e.g., the QUIPU DSA) require non-blocking writes. ! 1401: The routine \verb"TSetQueuesOK" is used to enable or disable this facility: ! 1402: \begin{quote}\index{TSetQueuesOK}\small\begin{verbatim} ! 1403: int TSetQueuesOK (sd, onoff, td) ! 1404: int sd; ! 1405: int onoff; ! 1406: struct TSAPdisconnect *td; ! 1407: \end{verbatim}\end{quote} ! 1408: The parameters to this procedure are: ! 1409: \begin{describe} ! 1410: \item[\verb"sd":] the transport-descriptor; ! 1411: ! 1412: \item[\verb"onoff":] a flag indicating whether the facility is to be enabled ! 1413: (non-zero value) or disabled (zero value) for the transport-descriptor; ! 1414: and, ! 1415: ! 1416: \item[\verb"td":] a pointer to a \verb"TSAPdisconnect" structure, ! 1417: which is updated only if the call fails. ! 1418: \end{describe} ! 1419: If the call is not successful, ! 1420: the \verb"td" parameter indicates the reason for failure. ! 1421: Otherwise, ! 1422: if the \verb"onoff" parameter has a non-zero value, ! 1423: then any ``write'' operations which ultimately map to this ! 1424: transport-descriptor will not block the process. ! 1425: This is done by maintaining a queue of write operations and periodically ! 1426: retrying them. ! 1427: In order to schedule retries, ! 1428: the routine \verb"TNetAccept" described earlier should be called frequently. ! 1429: In addition, ! 1430: if some failure occurs during the retry ! 1431: (e.g., the transport connection is disconnected), ! 1432: then \verb"TNetAccept" will mark that descriptor as being ready for reading. ! 1433: When the program interrogates the descriptor, ! 1434: the appropriate error code will be returned. ! 1435: Note that in order for this action to occur, ! 1436: any descriptor which has queued writes enabled must be included in the ! 1437: \verb"rfs" parameter supplied when the \verb"TNetAccept" routine is called. ! 1438: ! 1439: \section {Error Conventions} ! 1440: All of the routines in this library return the manifest constant \verb"NOTOK" ! 1441: on error, ! 1442: and also update the \verb"td" parameter given to the routine. ! 1443: The \verb"td_reason" element of the \verb"TSAPdisconnect" structure can be ! 1444: given as an parameter to the routine \verb"TErrString" which returns a ! 1445: null-terminated diagnostic string. ! 1446: \begin{quote}\index{TErrString}\small\begin{verbatim} ! 1447: char *TErrString (c) ! 1448: int c; ! 1449: \end{verbatim}\end{quote} ! 1450: ! 1451: \section {Compiling and Loading} ! 1452: Programs using the \man libtsap(3n) library should include ! 1453: \verb"<isode/tsap.h>". ! 1454: These programs should also be loaded with \verb"-ltsap" and, ! 1455: for reasons explained momentarily, ! 1456: \verb"-licompat". ! 1457: ! 1458: \section {An Example} ! 1459: Let's consider how one might construct a loopback entity that resides on the ! 1460: TSAP. ! 1461: This entity will use a synchronous interface. ! 1462: ! 1463: First, we must decide at what address the entity will reside. ! 1464: For simplicity's sake, ! 1465: we'll say that the location is \verb"tsap/echo", ! 1466: as defined in the \man isoservices(5) database. ! 1467: ! 1468: Next, we actually code the loopback entity. ! 1469: There are two parts to the program: initialization and data transfer; ! 1470: release will occur whenever data transfer fails. ! 1471: In our example, ! 1472: we assume that the routine \verb"error" results in the process being ! 1473: terminated after printing a diagnostic. ! 1474: ! 1475: In Figure~\ref{initTSloopback}, ! 1476: the initialization steps for the loopback entity, ! 1477: including the outer {\em C\/} wrapper, is shown. ! 1478: The entity does not examine any of its arguments, ! 1479: but could do so after the call to \verb"TInit". ! 1480: After examining the arguments, ! 1481: it could decide to reject the connection attempt, ! 1482: by using \verb"TDiscRequest". ! 1483: Instead, ! 1484: it uses \verb"TConnResponse" with the exact negotiated parameters with which ! 1485: it was supplied. ! 1486: Hence, ! 1487: if the initiator wanted to use expedited data transfer, ! 1488: the loopback entity responding to the connection would honor that. ! 1489: ! 1490: In Figure~\ref{dataTSloopback} on page~\pageref{dataTSloopback}, ! 1491: the data transfer loop is realized. ! 1492: The loopback entity awaits an event from the service provider, ! 1493: which either indicates that data has arrived or that the connection has been ! 1494: closed. ! 1495: If a disconnection occurred ! 1496: (a {\sf T-DISCONNECT.INDICATION\/} event is reported), ! 1497: then the reason is checked. ! 1498: If the event did not occur because the initiator performed a ! 1499: {\sf T-DISCONNECT.REQUEST\/} indication, ! 1500: then an error is signaled. ! 1501: Otherwise, the inner-loop is terminated and the process will gracefully ! 1502: terminate. ! 1503: If instead data arrived, ! 1504: it is echoed back to the initiator. ! 1505: \clearpage ! 1506: \tagrind[tp]{grind6-2}{Initializing the loopback entity}{initTSloopback} ! 1507: \clearpage ! 1508: \tagrind[tp]{grind6-3}{Data Transfer for the loopback entity}{dataTSloopback} ! 1509: ! 1510: \section {Compatibility Issues} ! 1511: The \man libicompat(3) library is used as an aid for porting the software from ! 1512: one system to another. ! 1513: This library contains generic service routines, ! 1514: which are in turn composed of the native facilities available on the target ! 1515: host. ! 1516: All of the higher layer \verb"#include" files automatically reference parts ! 1517: of this library as appropriate. ! 1518: Hence, when loading the the portions of the software independently, ! 1519: the loader must be given the \verb"-licompat" flag. ! 1520: ! 1521: The problem of this approach, of course, is that not all facilities can be ! 1522: precisely emulated. ! 1523: To misquote M.A.~Padlipsky\cite{Gateways.Heffalumps}: ! 1524: \begin{quote}\em ! 1525: Sometimes when you try to make an apple look like an orange you get back ! 1526: something that smells like a lemon. ! 1527: \end{quote} ! 1528: ! 1529: \section {For Further Reading} ! 1530: The ISO specification for transport services is defined in ! 1531: \cite{ISO.TP.Service}. ! 1532: The corresponding CCITT recommendation is defined in \cite{CCITT.TP.Service}. ! 1533: The document describing how these services can be implemented on top of the ! 1534: TCP\cite{TCP} is \cite{TSAP.on.TCP}. ! 1535: ! 1536: \section {Changes Since the Last Release}\label{tsap:changes} ! 1537: A brief summary of the major changes between v~\tsaprevrsn/ and ! 1538: v~\tsapvrsn/ are now presented. ! 1539: These are the user-visible changes only; ! 1540: changes of a strictly internal nature are not discussed. ! 1541: ! 1542: The \verb"na_type" and \verb"na_subnet" fields of the \verb"NSAPaddr" ! 1543: structure are now called \verb"na_stack" and \verb"na_community" respectively. ! 1544: For compatibility, ! 1545: macros are provided. ! 1546: These macros will be removed after this release.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.