Fixed a few entities
[yaz-moved-to-github.git] / doc / comstack.xml
1 <!-- $Id: comstack.xml,v 1.7 2002-02-24 12:23:43 adam Exp $ -->
2  <chapter id="comstack"><title>The COMSTACK Module</title>
3
4   <sect1 id="comstack.synopsis"><title>Synopsis (blocking mode)</title>
5
6    <programlisting>
7
8 COMSTACK stack;
9 char *buf = 0;
10 int size = 0, length_incoming;
11 char *protocol_package; 
12 int protocol_package_length;
13 char server_address_str[] = "myserver.com:2100";
14 void *server_address_ip;
15 int status;
16
17 stack = cs_create(tcpip_type, 1, PROTO_Z3950);
18 if (!stack) {
19     perror("cs_create");  /* use perror() here since we have no stack yet */
20     exit(1);
21 }
22
23 server_address_ip = cs_addrstr (stack, server_address_str);
24
25 status = cs_connect(stack, server_address_ip);
26 if (status != 0) {
27     cs_perror(stack, "cs_connect");
28     exit(1);
29 }
30
31 status = cs_put(stack, protocol_package, protocol_package_length);
32 if (status) {
33     cs_perror(stack, "cs_put");
34     exit(1);
35 }
36
37 /* Now get a response */
38
39 length_incoming = cs_get(stack, &amp;buf, &amp;size);
40 if (!length_incoming) {
41     fprintf(stderr, "Connection closed\n");
42     exit(1);
43 } else if (length_incoming &lt; 0) {
44     cs_perror(stack, "cs_get");
45     exit(1);
46 }
47
48 /* Do stuff with buf here */
49
50 /* clean up */
51 cs_close(stack);
52 if (buf)
53     free(buf);
54     
55    </programlisting>
56
57   </sect1>
58   <sect1 id="comstack.introduction"><title>Introduction</title>
59
60    <para>
61     The &comstack;
62     subsystem provides a transparent interface to different types of transport
63     stacks for the exchange of BER-encoded data. At present, the
64     RFC1729 method (BER over TCP/IP), and an experimental SSL stack
65     are supported, but others may be added in time. The philosophy of the
66     module is to provide a simple interface by hiding unused options and
67     facilities of the underlying libraries. This is always done at the risk
68     of losing generality, and it may prove that the interface will need
69     extension later on.
70    </para>
71
72    <note>
73     <para>
74      There hasn't been interest in the XTImOSI stack for some years.
75      Therefore, it is no longer supported.
76      </para>
77    </note>
78
79    <para>
80     The interface is implemented in such a fashion that only the
81     sub-layers constructed to the transport methods that you wish to
82     use in your application are linked in.
83    </para>
84
85    <para>
86     You will note that even though simplicity was a goal in the design,
87     the interface is still orders of magnitudes more complex than the
88     transport systems found in many other packages. One reason is that
89     the interface needs to support the somewhat different requirements of
90     the different lower-layer communications stacks; another important
91     reason is that the interface seeks to provide a more or less
92     industrial-strength approach to asynchronous event-handling.
93     When no function is allowed to block, things get more complex -
94     particularly on the server side.
95     We urge you to have a look at the demonstration client and server
96     provided with the package. They are meant to be easily readable and
97     instructive, while still being at least moderately useful.
98    </para>
99
100   </sect1>
101   <sect1 id="comstack.common"><title>Common Functions</title>
102
103    <sect2><title>Managing Endpoints</title>
104
105     <synopsis>
106      COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
107     </synopsis>
108
109     <para>
110      Creates an instance of the protocol stack - a communications endpoint.
111      The <literal>type</literal> parameter determines the mode
112      of communication.
113      At present, the values
114      <literal>tcpip_type</literal>
115      and
116      <literal>ssl_type</literal>
117      are recognized. The function returns a null-pointer if a system error
118      occurs. The <literal>blocking</literal> parameter should be one if
119      you wish the association to operate in blocking mode, zero otherwise.
120      The <literal>protocol</literal> field should be
121      <literal>PROTO_Z3950</literal>.
122      Protocol <literal>PROTO_SR</literal> is no longer supported.
123     </para>
124
125     <synopsis>
126      int cs_close(COMSTACK handle);
127     </synopsis>
128
129     <para>
130      Closes the connection (as elegantly as the lower layers will permit),
131      and releases the resources pointed to by the
132      <literal>handle</literal>
133      parameter. The
134      <literal>handle</literal>
135      should not be referenced again after this call.
136     </para>
137
138     <note>
139      <para>
140       We really need a soft disconnect, don't we?
141      </para>
142     </note>
143    </sect2>
144
145    <sect2><title>Data Exchange</title>
146
147     <synopsis>
148      int cs_put(COMSTACK handle, char *buf, int len);
149     </synopsis>
150
151     <para>
152      Sends
153      <literal>buf</literal>
154      down the wire. In blocking mode, this function will return only when a
155      full buffer has been written, or an error has occurred. In nonblocking
156      mode, it's possible that the function will be unable to send the full
157      buffer at once, which will be indicated by a return value of 1. The
158      function will keep track of the number of octets already written; you
159      should call it repeatedly with the same values of <literal>buf</literal>
160      and <literal>len</literal>, until the buffer has been transmitted.
161      When a full buffer has been sent, the function will return 0 for
162      success. -1 indicates an error condition (see below).
163     </para>
164
165     <synopsis>
166      int cs_get(COMSTACK handle, char **buf, int *size);
167     </synopsis>
168
169     <para>
170      Receives a PDU from the peer. Returns the number of bytes
171      read. In nonblocking mode, it is possible that not all of the packet can be
172      read at once. In this case, the function returns 1. To simplify the
173      interface, the function is
174      responsible for managing the size of the buffer. It will be reallocated
175      if necessary to contain large packages, and will sometimes be moved
176      around internally by the subsystem when partial packages are read. Before
177      calling
178      <function>cs_get</function>
179      for the fist time, the buffer can be initialized to the null pointer,
180      and the length should also be set to 0 - cs_get will perform a
181      <function>malloc(2)</function>
182      on the buffer for you. When a full buffer has been read, the size of
183      the package is returned (which will always be greater than 1). -1
184      indicates an error condition.
185     </para>
186
187     <para>
188      See also the <function>cs_more()</function> function below.
189     </para>
190
191     <synopsis>
192      int cs_more(COMSTACK handle);
193     </synopsis>
194
195     <para>
196      The <function>cs_more()</function> function should be used in conjunction
197      with <function>cs_get</function> and
198      <function>select(2)</function>.
199      The <function>cs_get()</function> function will sometimes
200      (notably in the TCP/IP mode) read more than a single protocol package
201      off the network. When this happens, the extra package is stored
202      by the subsystem. After calling <function>cs_get()</function>, and before
203      waiting for more input, You should always call
204      <function>cs_more()</function>
205      to check if there's a full protocol package already read. If
206      <function>cs_more()</function>
207      returns 1,
208      <function>cs_get()</function>
209      can be used to immediately fetch the new package. For the
210      mOSI
211      subsystem, the function should always return 0, but if you want your
212      stuff to be protocol independent, you should use it.
213     </para>
214
215     <note>
216      <para>
217       The <function>cs_more()</function>
218       function is required because the RFC1729-method
219       does not provide a way of separating individual PDUs, short of
220       partially decoding the BER. Some other implementations will carefully
221       nibble at the packet by calling
222       <function>read(2)</function>
223       several times. This was felt to be too inefficient (or at least
224       clumsy) - hence the call for this extra function.
225      </para>
226     </note>
227
228     <synopsis>
229      int cs_look(COMSTACK handle);
230     </synopsis>
231
232     <para>
233      This function is useful when you're operating in nonblocking
234      mode. Call it when
235      <function>select(2)</function>
236      tells you there's something happening on the line. It returns one of
237      the following values:
238     </para>
239
240     <variablelist>
241      <varlistentry><term>CS_NONE</term><listitem><para>
242         No event is pending. The data found on the line was not a
243         complete package.
244        </para></listitem></varlistentry>
245
246      <varlistentry><term>CS_CONNECT</term><listitem><para>
247         A response to your connect request has been received. Call
248         <function>cs_rcvconnect</function>
249         to process the event and to finalize the connection establishment.
250        </para></listitem></varlistentry>
251
252      <varlistentry><term>CS_DISCON</term><listitem><para>
253         The other side has closed the connection (or maybe sent a disconnect
254         request - but do we care? Maybe later). Call
255         <function>cs_close</function> to close your end of the association
256         as well.
257        </para></listitem></varlistentry>
258
259      <varlistentry><term>CS_LISTEN</term><listitem><para>
260         A connect request has been received.
261         Call <function>cs_listen</function> to process the event.
262        </para></listitem></varlistentry>
263
264      <varlistentry><term>CS_DATA</term><listitem><para>
265         There's data to be found on the line.
266         Call <function>cs_get</function> to get it.
267        </para></listitem></varlistentry>
268     </variablelist>
269
270     <note>
271      <para>
272       You should be aware that even if
273       <function>cs_look()</function>
274       tells you that there's an event event pending, the corresponding
275       function may still return and tell you there was nothing to be found.
276       This means that only part of a package was available for reading. The
277       same event will show up again, when more data has arrived.
278      </para>
279     </note>
280
281     <synopsis>
282      int cs_fileno(COMSTACK h);
283     </synopsis>
284
285     <para>
286      Returns the file descriptor of the association. Use this when
287      file-level operations on the endpoint are required
288      (<function>select(2)</function> operations, specifically).
289     </para>
290    </sect2>
291
292   </sect1>
293
294   <sect1 id="comstack.client"><title>Client Side</title>
295
296    <synopsis>
297     int cs_connect(COMSTACK handle, void *address);
298    </synopsis>
299
300    <para>
301     Initiate a connection with the target at <literal>address</literal>
302     (more onaddresses below). The function will return 0 on success, and 1 if
303     the operation does not complete immediately (this will only
304     happen on a nonblocking endpoint). In this case, use
305     <function>cs_rcvconnect</function> to complete the operation,
306     when <function>select(2)</function> reports input pending on the
307     association.
308    </para>
309
310    <synopsis>
311     int cs_rcvconnect(COMSTACK handle);
312    </synopsis>
313
314    <para>
315     Complete a connect operation initiated by <function>cs_connect()</function>.
316     It will return 0 on success; 1 if the operation has not yet completed (in
317     this case, call the function again later); -1 if an error has occurred.
318    </para>
319
320   </sect1>
321
322   <sect1 id="comstack.server"><title>Server Side</title>
323
324    <para>
325     To establish a server under the <application>inetd</application>
326     server, you can use
327    </para>
328
329    <synopsis>
330     COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
331                                int protocol);
332    </synopsis>
333
334    <para>
335     The <literal>socket</literal> parameter is an established socket (when
336     your application is invoked from <application>inetd</application>, the
337     socket will typically be 0.
338     The following parameters are identical to the ones for
339     <function>cs_create</function>.
340    </para>
341
342    <synopsis>
343     int cs_bind(COMSTACK handle, void *address, int mode)
344    </synopsis>
345
346    <para>
347     Binds a local address to the endpoint. Read about addresses below. The
348     <literal>mode</literal> parameter should be either
349     <literal>CS_CLIENT</literal> or <literal>CS_SERVER</literal>.
350    </para>
351
352    <synopsis>
353     int cs_listen(COMSTACK handle, char *addr, int *addrlen);
354    </synopsis>
355
356    <para>
357     Call this to process incoming events on an endpoint that has been
358     bound in listening mode. It will return 0 to indicate that the connect
359     request has been received, 1 to signal a partial reception, and -1 to
360     indicate an error condition.
361    </para>
362
363    <synopsis>
364     COMSTACK cs_accept(COMSTACK handle);
365    </synopsis>
366
367    <para>
368     This finalizes the server-side association establishment, after
369     cs_listen has completed successfully. It returns a new connection
370     endpoint, which represents the new association. The application will
371     typically wish to fork off a process to handle the association at this
372     point, and continue listen for new connections on the old
373     <literal>handle</literal>.
374    </para>
375
376    <para>
377     You can use the call
378    </para>
379
380    <synopsis>
381     char *cs_addrstr(COMSTACK);
382    </synopsis>
383
384    <para>
385     on an established connection to retrieve the host-name of the remote host.
386    </para>
387
388    <note>
389     <para>You may need to use this function with some care if your
390      name server service is slow or unreliable
391     </para>
392    </note>
393
394   </sect1>
395   <sect1 id="comstack.addresses"><title>Addresses</title>
396
397    <para>
398     The low-level format of the addresses are different depending on the
399     mode of communication you have chosen. A function is provided by each
400     of the lower layers to map a user-friendly string-form address to the
401     binary form required by the lower layers.
402    </para>
403
404    <synopsis>
405     void *cs_straddr(COMSTACK handle, const char *str);
406    </synopsis>
407
408    <para>
409     The format for TCP/IP addresses is straightforward:
410    </para>
411
412    <synopsis>
413     &lt;host> &lsqb; ':' &lt;portnum> &rsqb;
414    </synopsis>
415
416    <para>
417     The <literal>hostname</literal> can be either a domain name or an
418     IP address. The port number, if omitted, defaults to 210.
419    </para>
420
421    <para>
422     In all transport modes, the special hostname &quot;@&quot; is mapped
423     to any local address (the manifest constant <literal>INADDR_ANY</literal>).
424     It is used to establish local listening endpoints in the server role.
425    </para>
426
427    <para>
428     When a connection has been established, you can use
429    </para>
430
431    <synopsis>
432     char *cs_addrstr(COMSTACK h);
433    </synopsis>
434
435    <para>
436     to retrieve the host name of the peer system. The function returns
437     a pointer to a static area, which is overwritten on the next call
438     to the function.
439    </para>
440
441    <para>
442     A fairly recent addition to the &comstack; module is the utility
443     function
444    </para>
445    <synopsis>
446     COMSTACK cs_create_host (const char *str, int blocking, void **vp);
447    </synopsis>
448    <para>
449     which is just a wrapper around <function>cs_create</function> and
450     <function>cs_straddr</function>. The <parameter>str</parameter>
451     is similar to that described for <function>cs_straddr</function>
452     but with a prefix denoting the &comstack; type. Prefixes supported
453     are <literal>tcp:</literal> and <literal>ssl:</literal> for
454     TCP/IP and SSL respectively. If no prefix is given, then TCP/IP
455     is used. The <parameter>blocking</parameter> is passed to
456     function <function>cs_create</function>. The third parameter
457     <parameter>vp</parameter> is a pointer to &comstack; stack type
458     specific values.
459     For SSL (ssl_type) <parameter>vp</parameter> is an already create
460     OpenSSL CTX. For TCP/IP <parameter>vp</parameter> is unused (can be
461     set to <literal>NULL</literal>.
462    </para>
463
464   </sect1>
465
466   <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
467
468    <para>
469     All functions return -1 if an error occurs. Typically, the functions
470     will return 0 on success, but the data exchange functions
471     (<function>cs_get</function>, <function>cs_put</function>,
472     <function>cs_more</function>) follow special rules. Consult their
473     descriptions.
474    </para>
475
476    <para>
477     When a function (including the data exchange functions) reports an
478     error condition, use the function
479     <function>cs_errno()</function> to determine the cause of the
480     problem. The function
481    </para>
482
483    <synopsis>
484     void cs_perror(COMSTACK handle char *message);
485    </synopsis>
486
487    <para>
488     works like <function>perror(2)</function> and prints the
489     <literal>message</literal> argument, along with a system message, to
490     <literal>stderr</literal>. Use the character array
491    </para>
492
493    <synopsis>
494     extern const char *cs_errlist&lsqb;&rsqb;;
495    </synopsis>
496
497    <para>
498     to get hold of the message, if you want to process it differently.
499     The function
500    </para>
501
502    <synopsis>
503     const char *cs_stackerr(COMSTACK handle);
504    </synopsis>
505
506    <para>
507     Returns an error message from the lower layer, if one has been
508     provided.
509    </para>
510   </sect1>
511   <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
512
513      <synopsis>
514     #include &lt;comstack.h>
515      
516     #include &lt;tcpip.h>      /* this is for TCP/IP and SSL support */
517      
518     COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
519      
520     COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
521                                int protocol);
522     COMSTACK cs_create_host (const char *str, int blocking,
523                              void **vp);
524      
525     int cs_bind(COMSTACK handle, int mode);
526      
527     int cs_connect(COMSTACK handle, void *address);
528      
529     int cs_rcvconnect(COMSTACK handle);
530      
531     int cs_listen(COMSTACK handle);
532
533     COMSTACK cs_accept(COMSTACK handle);
534
535     int cs_put(COMSTACK handle, char *buf, int len);
536
537     int cs_get(COMSTACK handle, char **buf, int *size);
538
539     int cs_more(COMSTACK handle);
540
541     int cs_close(COMSTACK handle);
542
543     int cs_look(COMSTACK handle);
544
545     void *cs_straddr(COMSTACK handle, const char *str);
546
547     char *cs_addrstr(COMSTACK h);
548
549     extern int cs_errno;
550
551     void cs_perror(COMSTACK handle char *message);
552
553     const char *cs_stackerr(COMSTACK handle);
554
555     extern const char *cs_errlist[];
556    </synopsis>
557   </sect1>
558
559  </chapter>
560
561  <!-- Keep this comment at the end of the file
562  Local variables:
563  mode: sgml
564  sgml-omittag:t
565  sgml-shorttag:t
566  sgml-minimize-attributes:nil
567  sgml-always-quote-attributes:t
568  sgml-indent-step:1
569  sgml-indent-data:t
570  sgml-parent-document: "yaz.xml"
571  sgml-local-catalogs: nil
572  sgml-namecase-general:t
573  End:
574  -->
575