1 <!-- $Id: comstack.xml,v 1.11 2004-05-10 10:46:26 adam Exp $ -->
2 <chapter id="comstack"><title>The COMSTACK Module</title>
4 <sect1 id="comstack.synopsis"><title>Synopsis (blocking mode)</title>
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;
17 stack = cs_create(tcpip_type, 1, PROTO_Z3950);
19 perror("cs_create"); /* use perror() here since we have no stack yet */
23 server_address_ip = cs_addrstr (stack, server_address_str);
25 status = cs_connect(stack, server_address_ip);
27 cs_perror(stack, "cs_connect");
31 status = cs_put(stack, protocol_package, protocol_package_length);
33 cs_perror(stack, "cs_put");
37 /* Now get a response */
39 length_incoming = cs_get(stack, &buf, &size);
40 if (!length_incoming) {
41 fprintf(stderr, "Connection closed\n");
43 } else if (length_incoming < 0) {
44 cs_perror(stack, "cs_get");
48 /* Do stuff with buf here */
58 <sect1 id="comstack.introduction"><title>Introduction</title>
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.
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
75 There hasn't been interest in the XTImOSI stack for some years.
76 Therefore, it is no longer supported.
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.
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.
102 <sect1 id="comstack.common"><title>Common Functions</title>
104 <sect2><title>Managing Endpoints</title>
107 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
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:
117 <varlistentry><term><literal>tcpip_type</literal></term>
118 <listitem><para>TCP/IP (BER over TCP/IP or HTTP over TCP/IP)
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.
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>.
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.
146 int cs_close(COMSTACK handle);
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>
154 <literal>handle</literal>
155 should not be referenced again after this call.
160 We really need a soft disconnect, don't we?
165 <sect2><title>Data Exchange</title>
168 int cs_put(COMSTACK handle, char *buf, int len);
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).
186 int cs_get(COMSTACK handle, char **buf, int *size);
190 Receives a PDU or HTTP Response from the peer. Returns the number of
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
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.
209 See also the <function>cs_more()</function> function below.
213 int cs_more(COMSTACK handle);
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>
229 <function>cs_get()</function>
230 can be used to immediately fetch the new package. For the
232 subsystem, the function should always return 0, but if you want your
233 stuff to be protocol independent, you should use it.
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.
250 int cs_look(COMSTACK handle);
254 This function is useful when you're operating in nonblocking
256 <function>select(2)</function>
257 tells you there's something happening on the line. It returns one of
258 the following values:
262 <varlistentry><term>CS_NONE</term><listitem><para>
263 No event is pending. The data found on the line was not a
265 </para></listitem></varlistentry>
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>
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
278 </para></listitem></varlistentry>
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>
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>
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.
303 int cs_fileno(COMSTACK h);
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).
315 <sect1 id="comstack.client"><title>Client Side</title>
318 int cs_connect(COMSTACK handle, void *address);
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.
332 int cs_rcvconnect(COMSTACK handle);
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.
343 <sect1 id="comstack.server"><title>Server Side</title>
346 To establish a server under the <application>inetd</application>
351 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
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>.
364 int cs_bind(COMSTACK handle, void *address, int mode)
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>.
374 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
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.
385 COMSTACK cs_accept(COMSTACK handle);
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>.
402 char *cs_addrstr(COMSTACK);
406 on an established connection to retrieve the host-name of the remote host.
410 <para>You may need to use this function with some care if your
411 name server service is slow or unreliable
416 <sect1 id="comstack.addresses"><title>Addresses</title>
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.
426 void *cs_straddr(COMSTACK handle, const char *str);
430 The format for TCP/IP and SSL addresses is:
434 <host> [ ':' <portnum> ]
438 The <literal>hostname</literal> can be either a domain name or an
439 IP address. The port number, if omitted, defaults to 210.
443 For TCP/IP and SSL transport modes, the special hostname "@"
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.
450 For UNIX sockets, the format of an address is the socket filename.
454 When a connection has been established, you can use
458 char *cs_addrstr(COMSTACK h);
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
468 A fairly recent addition to the &comstack; module is the utility
472 COMSTACK cs_create_host (const char *str, int blocking, void **vp);
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
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>.
493 <sect1 id="comstack.ssl"><title>SSL</title>
496 void *cs_get_ssl(COMSTACK cs);
498 Returns the SSL handle, <literal>SSL *</literal> for comstack. If comstack
499 is not of type SSL, NULL is returned.
504 int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
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.
514 int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
516 Sets SSL certificate for comstack as a PEM file. This function
517 returns 1 for success; 0 for failure.
523 int cs_get_ssl_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
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;
534 <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
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
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
552 void cs_perror(COMSTACK handle char *message);
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
562 extern const char *cs_errlist[];
566 to get hold of the message, if you want to process it differently.
571 const char *cs_stackerr(COMSTACK handle);
575 Returns an error message from the lower layer, if one has been
579 <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
582 #include <yaz/comstack.h>
584 #include <yaz/tcpip.h> /* this is for TCP/IP and SSL support */
585 #include <yaz/unix.h> /* this is for UNIX sockeL support */
588 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
590 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
592 COMSTACK cs_create_host (const char *str, int blocking,
595 int cs_bind(COMSTACK handle, int mode);
597 int cs_connect(COMSTACK handle, void *address);
599 int cs_rcvconnect(COMSTACK handle);
601 int cs_listen(COMSTACK handle);
603 COMSTACK cs_accept(COMSTACK handle);
605 int cs_put(COMSTACK handle, char *buf, int len);
607 int cs_get(COMSTACK handle, char **buf, int *size);
609 int cs_more(COMSTACK handle);
611 int cs_close(COMSTACK handle);
613 int cs_look(COMSTACK handle);
615 void *cs_straddr(COMSTACK handle, const char *str);
617 char *cs_addrstr(COMSTACK h);
621 void cs_perror(COMSTACK handle char *message);
623 const char *cs_stackerr(COMSTACK handle);
625 extern const char *cs_errlist[];
631 <!-- Keep this comment at the end of the file
636 sgml-minimize-attributes:nil
637 sgml-always-quote-attributes:t
640 sgml-parent-document: "yaz.xml"
641 sgml-local-catalogs: nil
642 sgml-namecase-general:t