1 <chapter id="comstack"><title>The COMSTACK Module</title>
3 <sect1 id="comstack.synopsis"><title>Synopsis (blocking mode)</title>
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;
16 stack = cs_create(tcpip_type, 1, PROTO_Z3950);
18 perror("cs_create"); /* use perror() here since we have no stack yet */
22 server_address_ip = cs_addrstr (stack, server_address_str);
24 status = cs_connect(stack, server_address_ip);
26 cs_perror(stack, "cs_connect");
30 status = cs_put(stack, protocol_package, protocol_package_length);
32 cs_perror(stack, "cs_put");
36 /* Now get a response */
38 length_incoming = cs_get(stack, &buf, &size);
39 if (!length_incoming) {
40 fprintf(stderr, "Connection closed\n");
42 } else if (length_incoming < 0) {
43 cs_perror(stack, "cs_get");
47 /* Do stuff with buf here */
57 <sect1 id="comstack.introduction"><title>Introduction</title>
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.
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
74 There hasn't been interest in the XTImOSI stack for some years.
75 Therefore, it is no longer supported.
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.
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.
101 <sect1 id="comstack.common"><title>Common Functions</title>
103 <sect2 id="comstack.managing.endpoints"><title>Managing Endpoints</title>
106 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
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:
116 <varlistentry><term><literal>tcpip_type</literal></term>
117 <listitem><para>TCP/IP (BER over TCP/IP or HTTP over TCP/IP)
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.
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>.
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.
145 int cs_close(COMSTACK handle);
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>
153 <literal>handle</literal>
154 should not be referenced again after this call.
159 We really need a soft disconnect, don't we?
164 <sect2 id="comstack.data.exchange"><title>Data Exchange</title>
167 int cs_put(COMSTACK handle, char *buf, int len);
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).
185 int cs_get(COMSTACK handle, char **buf, int *size);
189 Receives a PDU or HTTP Response from the peer. Returns the number of
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
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.
208 See also the <function>cs_more()</function> function below.
212 int cs_more(COMSTACK handle);
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>
228 <function>cs_get()</function>
229 can be used to immediately fetch the new package. For the
231 subsystem, the function should always return 0, but if you want your
232 stuff to be protocol independent, you should use it.
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.
249 int cs_look(COMSTACK handle);
253 This function is useful when you're operating in nonblocking
255 <function>select(2)</function>
256 tells you there's something happening on the line. It returns one of
257 the following values:
261 <varlistentry><term>CS_NONE</term><listitem><para>
262 No event is pending. The data found on the line was not a
264 </para></listitem></varlistentry>
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>
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
277 </para></listitem></varlistentry>
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>
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>
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.
302 int cs_fileno(COMSTACK h);
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).
314 <sect1 id="comstack.client"><title>Client Side</title>
317 int cs_connect(COMSTACK handle, void *address);
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.
331 int cs_rcvconnect(COMSTACK handle);
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.
342 <sect1 id="comstack.server"><title>Server Side</title>
345 To establish a server under the <application>inetd</application>
350 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
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>.
363 int cs_bind(COMSTACK handle, void *address, int mode)
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>.
373 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
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.
384 COMSTACK cs_accept(COMSTACK handle);
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>.
401 char *cs_addrstr(COMSTACK);
405 on an established connection to retrieve the host-name of the remote host.
409 <para>You may need to use this function with some care if your
410 name server service is slow or unreliable
415 <sect1 id="comstack.addresses"><title>Addresses</title>
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.
425 void *cs_straddr(COMSTACK handle, const char *str);
429 The format for TCP/IP and SSL addresses is:
433 <host> [ ':' <portnum> ]
437 The <literal>hostname</literal> can be either a domain name or an
438 IP address. The port number, if omitted, defaults to 210.
442 For TCP/IP and SSL transport modes, the special hostname "@"
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.
449 For UNIX sockets, the format of an address is the socket filename.
453 When a connection has been established, you can use
457 char *cs_addrstr(COMSTACK h);
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
467 A fairly recent addition to the &comstack; module is the utility
471 COMSTACK cs_create_host (const char *str, int blocking, void **vp);
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
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>.
492 <sect1 id="comstack.ssl"><title>SSL</title>
495 void *cs_get_ssl(COMSTACK cs);
497 Returns the SSL handle, <literal>SSL *</literal> for comstack. If comstack
498 is not of type SSL, NULL is returned.
503 int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
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.
513 int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
515 Sets SSL certificate for comstack as a PEM file. This function
516 returns 1 for success; 0 for failure.
522 int cs_get_ssl_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
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;
533 <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
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
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
551 void cs_perror(COMSTACK handle char *message);
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
561 extern const char *cs_errlist[];
565 to get hold of the message, if you want to process it differently.
570 const char *cs_stackerr(COMSTACK handle);
574 Returns an error message from the lower layer, if one has been
578 <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
581 #include <yaz/comstack.h>
583 #include <yaz/tcpip.h> /* this is for TCP/IP and SSL support */
584 #include <yaz/unix.h> /* this is for UNIX sockeL support */
587 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
589 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
591 COMSTACK cs_create_host (const char *str, int blocking,
594 int cs_bind(COMSTACK handle, int mode);
596 int cs_connect(COMSTACK handle, void *address);
598 int cs_rcvconnect(COMSTACK handle);
600 int cs_listen(COMSTACK handle);
602 COMSTACK cs_accept(COMSTACK handle);
604 int cs_put(COMSTACK handle, char *buf, int len);
606 int cs_get(COMSTACK handle, char **buf, int *size);
608 int cs_more(COMSTACK handle);
610 int cs_close(COMSTACK handle);
612 int cs_look(COMSTACK handle);
614 void *cs_straddr(COMSTACK handle, const char *str);
616 char *cs_addrstr(COMSTACK h);
620 void cs_perror(COMSTACK handle char *message);
622 const char *cs_stackerr(COMSTACK handle);
624 extern const char *cs_errlist[];
630 <!-- Keep this comment at the end of the file
635 sgml-minimize-attributes:nil
636 sgml-always-quote-attributes:t
639 sgml-parent-document: "yaz.xml"
640 sgml-local-catalogs: nil
641 sgml-namecase-general:t