1 <chapter id="comstack"><title>The COMSTACK Module</title>
3 <sect1 id="comstack.synopsis"><title>Synopsis (blocking mode)</title>
5 <programlisting><![CDATA[
8 int size = 0, length_incoming;
9 char server_address_str[] = "localhost:9999";
10 void *server_address_ip;
13 char *protocol_package = "GET / HTTP/1.0\r\n\r\n";
14 int protocol_package_length = strlen(protocol_package);
16 stack = cs_create(tcpip_type, 1, PROTO_HTTP);
18 perror("cs_create"); /* use perror() here since we have no stack yet */
22 server_address_ip = cs_straddr(stack, server_address_str);
23 if (!server_address_ip)
25 fprintf(stderr, "cs_straddr: address could not be resolved\n");
29 status = cs_connect(stack, server_address_ip);
31 fprintf(stderr, "cs_connect: %s\n", cs_strerror(stack));
35 status = cs_put(stack, protocol_package, protocol_package_length);
37 fprintf(stderr, "cs_put: %s\n", cs_strerror(stack));
40 /* Now get a response */
42 length_incoming = cs_get(stack, &buf, &size);
43 if (!length_incoming) {
44 fprintf(stderr, "Connection closed\n");
46 } else if (length_incoming < 0) {
47 fprintf(stderr, "cs_get: %s\n", cs_strerror(stack));
52 fwrite(buf, length_incoming, 1, stdout);
63 <sect1 id="comstack.introduction"><title>Introduction</title>
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.
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
80 There hasn't been interest in the XTImOSI stack for some years.
81 Therefore, it is no longer supported.
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.
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.
107 <sect1 id="comstack.common"><title>Common Functions</title>
109 <sect2 id="comstack.managing.endpoints"><title>Managing Endpoints</title>
112 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
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:
122 <varlistentry><term><literal>tcpip_type</literal></term>
123 <listitem><para>TCP/IP (BER over TCP/IP or HTTP over TCP/IP)
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.
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>.
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.
151 void cs_close(COMSTACK handle);
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>
159 <literal>handle</literal>
160 should not be referenced again after this call.
165 We really need a soft disconnect, don't we?
170 <sect2 id="comstack.data.exchange"><title>Data Exchange</title>
173 int cs_put(COMSTACK handle, char *buf, int len);
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).
191 int cs_get(COMSTACK handle, char **buf, int *size);
195 Receives a PDU or HTTP Response from the peer. Returns the number of
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
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.
214 See also the <function>cs_more()</function> function below.
218 int cs_more(COMSTACK handle);
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>
234 <function>cs_get()</function>
235 can be used to immediately fetch the new package. For the
237 subsystem, the function should always return 0, but if you want your
238 stuff to be protocol independent, you should use it.
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.
255 int cs_look(COMSTACK handle);
259 This function is useful when you're operating in nonblocking
261 <function>select(2)</function>
262 tells you there's something happening on the line. It returns one of
263 the following values:
267 <varlistentry><term>CS_NONE</term><listitem><para>
268 No event is pending. The data found on the line was not a
270 </para></listitem></varlistentry>
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>
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
283 </para></listitem></varlistentry>
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>
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>
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.
308 int cs_fileno(COMSTACK h);
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).
320 <sect1 id="comstack.client"><title>Client Side</title>
323 int cs_connect(COMSTACK handle, void *address);
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.
337 int cs_rcvconnect(COMSTACK handle);
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.
348 <sect1 id="comstack.server"><title>Server Side</title>
351 To establish a server under the <application>inetd</application>
356 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
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>.
369 int cs_bind(COMSTACK handle, void *address, int mode)
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>.
379 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
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.
390 COMSTACK cs_accept(COMSTACK handle);
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>.
407 const char *cs_addrstr(COMSTACK);
411 on an established connection to retrieve the host-name of the remote host.
415 <para>You may need to use this function with some care if your
416 name server service is slow or unreliable
421 <sect1 id="comstack.addresses"><title>Addresses</title>
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.
431 void *cs_straddr(COMSTACK handle, const char *str);
435 The format for TCP/IP and SSL addresses is:
439 <host> [ ':' <portnum> ]
443 The <literal>hostname</literal> can be either a domain name or an
444 IP address. The port number, if omitted, defaults to 210.
448 For TCP/IP and SSL transport modes, the special hostname "@"
449 is mapped to any local address
450 (the manifest constant <literal>INADDR_ANY</literal>).
451 It is used to establish local listening endpoints in the server role.
455 For UNIX sockets, the format of an address is the socket filename.
459 When a connection has been established, you can use
463 const char *cs_addrstr(COMSTACK h);
467 to retrieve the host name of the peer system. The function returns
468 a pointer to a static area, which is overwritten on the next call
473 A fairly recent addition to the &comstack; module is the utility
477 COMSTACK cs_create_host (const char *str, int blocking, void **vp);
480 which is just a wrapper for <function>cs_create</function> and
481 <function>cs_straddr</function>. The <parameter>str</parameter>
482 is similar to that described for <function>cs_straddr</function>
483 but with a prefix denoting the &comstack; type. Prefixes supported
484 are <literal>tcp:</literal>, <literal>unix:</literal> and
485 <literal>ssl:</literal> for TCP/IP, UNIX and SSL respectively.
486 If no prefix is given, then TCP/IP is used.
487 The <parameter>blocking</parameter> is passed to
488 function <function>cs_create</function>. The third parameter
489 <parameter>vp</parameter> is a pointer to &comstack; stack type
491 For SSL (ssl_type) <parameter>vp</parameter> is an already create
492 OpenSSL CTX. For TCP/IP and UNIX <parameter>vp</parameter>
493 is unused (can be set to <literal>NULL</literal>.
498 <sect1 id="comstack.ssl"><title>SSL</title>
501 void *cs_get_ssl(COMSTACK cs);
503 Returns the SSL handle, <literal>SSL *</literal> for comstack. If comstack
504 is not of type SSL, NULL is returned.
509 int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
511 Sets SSL context for comstack. The parameter is expected to be of type
512 <literal>SSL_CTX *</literal>. This function should be called just
513 after comstack has been created (before connect, bind, etc).
514 This function returns 1 for success; 0 for failure.
519 int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
521 Sets SSL certificate for comstack as a PEM file. This function
522 returns 1 for success; 0 for failure.
528 int cs_get_ssl_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
530 This function returns the peer certificate. If successful,
531 <literal>*buf</literal> and <literal>*len</literal> holds
532 X509 buffer and length respectively. Buffer should be freed
533 with <literal>xfree</literal>. This function returns 1 for success;
539 <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
542 All functions return -1 if an error occurs. Typically, the functions
543 will return 0 on success, but the data exchange functions
544 (<function>cs_get</function>, <function>cs_put</function>,
545 <function>cs_more</function>) follow special rules. Consult their
550 The error code for the COMSTACK can be retrieved using C macro
551 <function>cs_errno</function> which will return one
552 of the error codes <literal>CSYSERR</literal>,
553 <literal>CSOUTSTATE</literal>,
554 <literal>CSNODATA</literal>, ...
558 int cs_errno(COMSTACK handle);
562 You can the textual representation of the error code
563 by using <function>cs_errmsg</function> - which
564 works like <function>strerror(3)</function>
568 const char *cs_errmsg(int n);
572 It is also possible to get straight to the textual represenataion
573 without the error code by using
574 <function>cs_strerror</function>.
578 const char *cs_strerror(COMSTACK h);
582 <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
585 #include <yaz/comstack.h>
587 #include <yaz/tcpip.h> /* this is for TCP/IP and SSL support */
588 #include <yaz/unix.h> /* this is for UNIX socket support */
590 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
592 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
594 COMSTACK cs_create_host(const char *str, int blocking,
597 int cs_bind(COMSTACK handle, int mode);
599 int cs_connect(COMSTACK handle, void *address);
601 int cs_rcvconnect(COMSTACK handle);
603 int cs_listen(COMSTACK handle);
605 COMSTACK cs_accept(COMSTACK handle);
607 int cs_put(COMSTACK handle, char *buf, int len);
609 int cs_get(COMSTACK handle, char **buf, int *size);
611 int cs_more(COMSTACK handle);
613 void cs_close(COMSTACK handle);
615 int cs_look(COMSTACK handle);
617 void *cs_straddr(COMSTACK handle, const char *str);
619 const char *cs_addrstr(COMSTACK h);
626 <!-- Keep this comment at the end of the file
631 sgml-minimize-attributes:nil
632 sgml-always-quote-attributes:t
635 sgml-parent-document: "yaz.xml"
636 sgml-local-catalogs: nil
637 sgml-namecase-general:t