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