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) {
24 fprintf(stderr, "cs_straddr: address could not be resolved\n");
28 status = cs_connect(stack, server_address_ip);
30 fprintf(stderr, "cs_connect: %s\n", cs_strerror(stack));
34 status = cs_rcvconnect(stack);
36 fprintf(stderr, "cs_rcvconnect: %s\n", cs_strerror(stack));
40 status = cs_put(stack, protocol_package, protocol_package_length);
42 fprintf(stderr, "cs_put: %s\n", cs_strerror(stack));
46 /* Now get a response */
47 length_incoming = cs_get(stack, &buf, &size);
48 if (!length_incoming) {
49 fprintf(stderr, "Connection closed\n");
51 } else if (length_incoming < 0) {
52 fprintf(stderr, "cs_get: %s\n", cs_strerror(stack));
57 fwrite(buf, length_incoming, 1, stdout);
68 <sect1 id="comstack.introduction"><title>Introduction</title>
72 subsystem provides a transparent interface to different types of transport
73 stacks for the exchange of BER-encoded data and HTTP packets.
74 At present, the RFC1729 method (BER over TCP/IP), local UNIX socket and an
75 experimental SSL stack are supported, but others may be added in time.
77 module is to provide a simple interface by hiding unused options and
78 facilities of the underlying libraries. This is always done at the risk
79 of losing generality, and it may prove that the interface will need
85 There hasn't been interest in the XTImOSI stack for some years.
86 Therefore, it is no longer supported.
91 The interface is implemented in such a fashion that only the
92 sub-layers constructed to the transport methods that you wish to
93 use in your application are linked in.
97 You will note that even though simplicity was a goal in the design,
98 the interface is still orders of magnitudes more complex than the
99 transport systems found in many other packages. One reason is that
100 the interface needs to support the somewhat different requirements of
101 the different lower-layer communications stacks; another important
102 reason is that the interface seeks to provide a more or less
103 industrial-strength approach to asynchronous event-handling.
104 When no function is allowed to block, things get more complex -
105 particularly on the server side.
106 We urge you to have a look at the demonstration client and server
107 provided with the package. They are meant to be easily readable and
108 instructive, while still being at least moderately useful.
112 <sect1 id="comstack.common"><title>Common Functions</title>
114 <sect2 id="comstack.managing.endpoints"><title>Managing Endpoints</title>
117 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
121 Creates an instance of the protocol stack - a communications endpoint.
122 The <literal>type</literal> parameter determines the mode
123 of communication. At present the following values are supported:
127 <varlistentry><term><literal>tcpip_type</literal></term>
128 <listitem><para>TCP/IP (BER over TCP/IP or HTTP over TCP/IP)
131 <varlistentry><term><literal>ssl_type</literal></term>
132 <listitem><para>Secure Socket Layer (SSL). This COMSTACK
133 is experimental and is not fully implemented. If
134 HTTP is used, this effectively is HTTPS.
137 <varlistentry><term><literal>unix_type</literal></term>
138 <listitem><para>Unix socket (unix only). Local Transfer via
139 file socket. See <citerefentry><refentrytitle>unix</refentrytitle>
140 <manvolnum>7</manvolnum></citerefentry>.
146 The <function>cs_create</function> function returns a null-pointer
147 if a system error occurs.
148 The <literal>blocking</literal> parameter should be one if
149 you wish the association to operate in blocking mode, zero otherwise.
150 The <literal>protocol</literal> field should be
151 <literal>PROTO_Z3950</literal> or <literal>PROTO_HTTP</literal>.
152 Protocol <literal>PROTO_SR</literal> is no longer supported.
156 void cs_close(COMSTACK handle);
160 Closes the connection (as elegantly as the lower layers will permit),
161 and releases the resources pointed to by the
162 <literal>handle</literal>
164 <literal>handle</literal>
165 should not be referenced again after this call.
170 We really need a soft disconnect, don't we?
175 <sect2 id="comstack.data.exchange"><title>Data Exchange</title>
178 int cs_put(COMSTACK handle, char *buf, int len);
183 <literal>buf</literal>
184 down the wire. In blocking mode, this function will return only when a
185 full buffer has been written, or an error has occurred. In nonblocking
186 mode, it's possible that the function will be unable to send the full
187 buffer at once, which will be indicated by a return value of 1. The
188 function will keep track of the number of octets already written; you
189 should call it repeatedly with the same values of <literal>buf</literal>
190 and <literal>len</literal>, until the buffer has been transmitted.
191 When a full buffer has been sent, the function will return 0 for
192 success. -1 indicates an error condition (see below).
196 int cs_get(COMSTACK handle, char **buf, int *size);
200 Receives a PDU or HTTP Response from the peer. Returns the number of
202 In nonblocking mode, it is possible that not all of the packet can be
203 read at once. In this case, the function returns 1. To simplify the
204 interface, the function is
205 responsible for managing the size of the buffer. It will be reallocated
206 if necessary to contain large packages, and will sometimes be moved
207 around internally by the subsystem when partial packages are read. Before
209 <function>cs_get</function>
210 for the fist time, the buffer can be initialized to the null pointer,
211 and the length should also be set to 0 - cs_get will perform a
212 <function>malloc(2)</function>
213 on the buffer for you. When a full buffer has been read, the size of
214 the package is returned (which will always be greater than 1). -1
215 indicates an error condition.
219 See also the <function>cs_more()</function> function below.
223 int cs_more(COMSTACK handle);
227 The <function>cs_more()</function> function should be used in conjunction
228 with <function>cs_get</function> and
229 <function>select(2)</function>.
230 The <function>cs_get()</function> function will sometimes
231 (notably in the TCP/IP mode) read more than a single protocol package
232 off the network. When this happens, the extra package is stored
233 by the subsystem. After calling <function>cs_get()</function>, and before
234 waiting for more input, You should always call
235 <function>cs_more()</function>
236 to check if there's a full protocol package already read. If
237 <function>cs_more()</function>
239 <function>cs_get()</function>
240 can be used to immediately fetch the new package. For the
242 subsystem, the function should always return 0, but if you want your
243 stuff to be protocol independent, you should use it.
248 The <function>cs_more()</function>
249 function is required because the RFC1729-method
250 does not provide a way of separating individual PDUs, short of
251 partially decoding the BER. Some other implementations will carefully
252 nibble at the packet by calling
253 <function>read(2)</function>
254 several times. This was felt to be too inefficient (or at least
255 clumsy) - hence the call for this extra function.
260 int cs_look(COMSTACK handle);
264 This function is useful when you're operating in nonblocking
266 <function>select(2)</function>
267 tells you there's something happening on the line. It returns one of
268 the following values:
272 <varlistentry><term>CS_NONE</term><listitem><para>
273 No event is pending. The data found on the line was not a
275 </para></listitem></varlistentry>
277 <varlistentry><term>CS_CONNECT</term><listitem><para>
278 A response to your connect request has been received. Call
279 <function>cs_rcvconnect</function>
280 to process the event and to finalize the connection establishment.
281 </para></listitem></varlistentry>
283 <varlistentry><term>CS_DISCON</term><listitem><para>
284 The other side has closed the connection (or maybe sent a disconnect
285 request - but do we care? Maybe later). Call
286 <function>cs_close</function> to close your end of the association
288 </para></listitem></varlistentry>
290 <varlistentry><term>CS_LISTEN</term><listitem><para>
291 A connect request has been received.
292 Call <function>cs_listen</function> to process the event.
293 </para></listitem></varlistentry>
295 <varlistentry><term>CS_DATA</term><listitem><para>
296 There's data to be found on the line.
297 Call <function>cs_get</function> to get it.
298 </para></listitem></varlistentry>
303 You should be aware that even if
304 <function>cs_look()</function>
305 tells you that there's an event event pending, the corresponding
306 function may still return and tell you there was nothing to be found.
307 This means that only part of a package was available for reading. The
308 same event will show up again, when more data has arrived.
313 int cs_fileno(COMSTACK h);
317 Returns the file descriptor of the association. Use this when
318 file-level operations on the endpoint are required
319 (<function>select(2)</function> operations, specifically).
325 <sect1 id="comstack.client"><title>Client Side</title>
328 int cs_connect(COMSTACK handle, void *address);
332 Initiate a connection with the target at <literal>address</literal>
333 (more on addresses below). The function will return 0 on success, and 1 if
334 the operation does not complete immediately (this will only
335 happen on a nonblocking endpoint). In this case, use
336 <function>cs_rcvconnect</function> to complete the operation,
337 when <function>select(2)</function> or <function>poll(2)</function>
338 reports input pending on the association.
342 int cs_rcvconnect(COMSTACK handle);
346 Complete a connect operation initiated by <function>cs_connect()</function>.
347 It will return 0 on success; 1 if the operation has not yet completed (in
348 this case, call the function again later); -1 if an error has occurred.
353 <sect1 id="comstack.server"><title>Server Side</title>
356 To establish a server under the <application>inetd</application>
361 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
366 The <literal>socket</literal> parameter is an established socket (when
367 your application is invoked from <application>inetd</application>, the
368 socket will typically be 0.
369 The following parameters are identical to the ones for
370 <function>cs_create</function>.
374 int cs_bind(COMSTACK handle, void *address, int mode)
378 Binds a local address to the endpoint. Read about addresses below. The
379 <literal>mode</literal> parameter should be either
380 <literal>CS_CLIENT</literal> or <literal>CS_SERVER</literal>.
384 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
388 Call this to process incoming events on an endpoint that has been
389 bound in listening mode. It will return 0 to indicate that the connect
390 request has been received, 1 to signal a partial reception, and -1 to
391 indicate an error condition.
395 COMSTACK cs_accept(COMSTACK handle);
399 This finalizes the server-side association establishment, after
400 cs_listen has completed successfully. It returns a new connection
401 endpoint, which represents the new association. The application will
402 typically wish to fork off a process to handle the association at this
403 point, and continue listen for new connections on the old
404 <literal>handle</literal>.
412 const char *cs_addrstr(COMSTACK);
416 on an established connection to retrieve the host-name of the remote host.
420 <para>You may need to use this function with some care if your
421 name server service is slow or unreliable
426 <sect1 id="comstack.addresses"><title>Addresses</title>
429 The low-level format of the addresses are different depending on the
430 mode of communication you have chosen. A function is provided by each
431 of the lower layers to map a user-friendly string-form address to the
432 binary form required by the lower layers.
436 void *cs_straddr(COMSTACK handle, const char *str);
440 The format for TCP/IP and SSL addresses is:
444 <host> [ ':' <portnum> ]
448 The <literal>hostname</literal> can be either a domain name or an
449 IP address. The port number, if omitted, defaults to 210.
453 For TCP/IP and SSL, the special hostnames <literal>@</literal>,
454 maps to <literal>IN6ADDR_ANY_INIT</literal> with
455 IPV4 binding as well (bindv6only=0),
456 The special hostname <literal>@4</literal> binds to
457 <literal>INADDR_ANY</literal> (IPV4 only listener).
458 The special hostname <literal>@6</literal> binds to
459 <literal>IN6ADDR_ANY_INIT</literal> with bindv6only=1 (IPV6 only listener).
463 For UNIX sockets, the format of an address is the socket filename.
467 When a connection has been established, you can use
471 const char *cs_addrstr(COMSTACK h);
475 to retrieve the host name of the peer system. The function returns
476 a pointer to a static area, which is overwritten on the next call
481 A fairly recent addition to the &comstack; module is the utility
485 COMSTACK cs_create_host (const char *str, int blocking, void **vp);
488 which is just a wrapper for <function>cs_create</function> and
489 <function>cs_straddr</function>. The <parameter>str</parameter>
490 is similar to that described for <function>cs_straddr</function>
491 but with a prefix denoting the &comstack; type. Prefixes supported
492 are <literal>tcp:</literal>, <literal>unix:</literal> and
493 <literal>ssl:</literal> for TCP/IP, UNIX and SSL respectively.
494 If no prefix is given, then TCP/IP is used.
495 The <parameter>blocking</parameter> is passed to
496 function <function>cs_create</function>. The third parameter
497 <parameter>vp</parameter> is a pointer to &comstack; stack type
499 Parameter <parameter>vp</parameter> is reserved for future use.
500 Set it to <literal>NULL</literal>.
505 <sect1 id="comstack.ssl"><title>SSL</title>
508 void *cs_get_ssl(COMSTACK cs);
510 Returns the SSL handle, <literal>SSL *</literal> for comstack. If comstack
511 is not of type SSL, NULL is returned.
516 int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
518 Sets SSL context for comstack. The parameter is expected to be of type
519 <literal>SSL_CTX *</literal>. This function should be called just
520 after comstack has been created (before connect, bind, etc).
521 This function returns 1 for success; 0 for failure.
526 int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
528 Sets SSL certificate for comstack as a PEM file. This function
529 returns 1 for success; 0 for failure.
535 int cs_get_ssl_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
537 This function returns the peer certificate. If successful,
538 <literal>*buf</literal> and <literal>*len</literal> holds
539 X509 buffer and length respectively. Buffer should be freed
540 with <literal>xfree</literal>. This function returns 1 for success;
546 <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
549 All functions return -1 if an error occurs. Typically, the functions
550 will return 0 on success, but the data exchange functions
551 (<function>cs_get</function>, <function>cs_put</function>,
552 <function>cs_more</function>) follow special rules. Consult their
557 The error code for the COMSTACK can be retrieved using C macro
558 <function>cs_errno</function> which will return one
559 of the error codes <literal>CSYSERR</literal>,
560 <literal>CSOUTSTATE</literal>,
561 <literal>CSNODATA</literal>, ...
565 int cs_errno(COMSTACK handle);
569 You can the textual representation of the error code
570 by using <function>cs_errmsg</function> - which
571 works like <function>strerror(3)</function>
575 const char *cs_errmsg(int n);
579 It is also possible to get straight to the textual represenataion
580 without the error code by using
581 <function>cs_strerror</function>.
585 const char *cs_strerror(COMSTACK h);
589 <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
592 #include <yaz/comstack.h>
594 #include <yaz/tcpip.h> /* this is for TCP/IP and SSL support */
595 #include <yaz/unix.h> /* this is for UNIX socket support */
597 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
599 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
601 COMSTACK cs_create_host(const char *str, int blocking,
604 int cs_bind(COMSTACK handle, int mode);
606 int cs_connect(COMSTACK handle, void *address);
608 int cs_rcvconnect(COMSTACK handle);
610 int cs_listen(COMSTACK handle);
612 COMSTACK cs_accept(COMSTACK handle);
614 int cs_put(COMSTACK handle, char *buf, int len);
616 int cs_get(COMSTACK handle, char **buf, int *size);
618 int cs_more(COMSTACK handle);
620 void cs_close(COMSTACK handle);
622 int cs_look(COMSTACK handle);
624 void *cs_straddr(COMSTACK handle, const char *str);
626 const char *cs_addrstr(COMSTACK h);
633 <!-- Keep this comment at the end of the file
638 sgml-minimize-attributes:nil
639 sgml-always-quote-attributes:t
642 sgml-parent-document: "yaz.xml"
643 sgml-local-catalogs: nil
644 sgml-namecase-general:t