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