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