|
|
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.