1 <!-- $Id: comstack.xml,v 1.9 2002-08-17 07:55:51 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. At present, the
64 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)
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.
126 <varlistentry><term><literal>unix_type</literal></term>
127 <listitem><para>Unix socket (unix only). Fast 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>.
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><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 from the peer. Returns the number of bytes read.
190 In nonblocking mode, it is possible that not all of the packet can be
191 read at once. In this case, the function returns 1. To simplify the
192 interface, the function is
193 responsible for managing the size of the buffer. It will be reallocated
194 if necessary to contain large packages, and will sometimes be moved
195 around internally by the subsystem when partial packages are read. Before
197 <function>cs_get</function>
198 for the fist time, the buffer can be initialized to the null pointer,
199 and the length should also be set to 0 - cs_get will perform a
200 <function>malloc(2)</function>
201 on the buffer for you. When a full buffer has been read, the size of
202 the package is returned (which will always be greater than 1). -1
203 indicates an error condition.
207 See also the <function>cs_more()</function> function below.
211 int cs_more(COMSTACK handle);
215 The <function>cs_more()</function> function should be used in conjunction
216 with <function>cs_get</function> and
217 <function>select(2)</function>.
218 The <function>cs_get()</function> function will sometimes
219 (notably in the TCP/IP mode) read more than a single protocol package
220 off the network. When this happens, the extra package is stored
221 by the subsystem. After calling <function>cs_get()</function>, and before
222 waiting for more input, You should always call
223 <function>cs_more()</function>
224 to check if there's a full protocol package already read. If
225 <function>cs_more()</function>
227 <function>cs_get()</function>
228 can be used to immediately fetch the new package. For the
230 subsystem, the function should always return 0, but if you want your
231 stuff to be protocol independent, you should use it.
236 The <function>cs_more()</function>
237 function is required because the RFC1729-method
238 does not provide a way of separating individual PDUs, short of
239 partially decoding the BER. Some other implementations will carefully
240 nibble at the packet by calling
241 <function>read(2)</function>
242 several times. This was felt to be too inefficient (or at least
243 clumsy) - hence the call for this extra function.
248 int cs_look(COMSTACK handle);
252 This function is useful when you're operating in nonblocking
254 <function>select(2)</function>
255 tells you there's something happening on the line. It returns one of
256 the following values:
260 <varlistentry><term>CS_NONE</term><listitem><para>
261 No event is pending. The data found on the line was not a
263 </para></listitem></varlistentry>
265 <varlistentry><term>CS_CONNECT</term><listitem><para>
266 A response to your connect request has been received. Call
267 <function>cs_rcvconnect</function>
268 to process the event and to finalize the connection establishment.
269 </para></listitem></varlistentry>
271 <varlistentry><term>CS_DISCON</term><listitem><para>
272 The other side has closed the connection (or maybe sent a disconnect
273 request - but do we care? Maybe later). Call
274 <function>cs_close</function> to close your end of the association
276 </para></listitem></varlistentry>
278 <varlistentry><term>CS_LISTEN</term><listitem><para>
279 A connect request has been received.
280 Call <function>cs_listen</function> to process the event.
281 </para></listitem></varlistentry>
283 <varlistentry><term>CS_DATA</term><listitem><para>
284 There's data to be found on the line.
285 Call <function>cs_get</function> to get it.
286 </para></listitem></varlistentry>
291 You should be aware that even if
292 <function>cs_look()</function>
293 tells you that there's an event event pending, the corresponding
294 function may still return and tell you there was nothing to be found.
295 This means that only part of a package was available for reading. The
296 same event will show up again, when more data has arrived.
301 int cs_fileno(COMSTACK h);
305 Returns the file descriptor of the association. Use this when
306 file-level operations on the endpoint are required
307 (<function>select(2)</function> operations, specifically).
313 <sect1 id="comstack.client"><title>Client Side</title>
316 int cs_connect(COMSTACK handle, void *address);
320 Initiate a connection with the target at <literal>address</literal>
321 (more on addresses below). The function will return 0 on success, and 1 if
322 the operation does not complete immediately (this will only
323 happen on a nonblocking endpoint). In this case, use
324 <function>cs_rcvconnect</function> to complete the operation,
325 when <function>select(2)</function> or <function>poll(2)</function>
326 reports input pending on the association.
330 int cs_rcvconnect(COMSTACK handle);
334 Complete a connect operation initiated by <function>cs_connect()</function>.
335 It will return 0 on success; 1 if the operation has not yet completed (in
336 this case, call the function again later); -1 if an error has occurred.
341 <sect1 id="comstack.server"><title>Server Side</title>
344 To establish a server under the <application>inetd</application>
349 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
354 The <literal>socket</literal> parameter is an established socket (when
355 your application is invoked from <application>inetd</application>, the
356 socket will typically be 0.
357 The following parameters are identical to the ones for
358 <function>cs_create</function>.
362 int cs_bind(COMSTACK handle, void *address, int mode)
366 Binds a local address to the endpoint. Read about addresses below. The
367 <literal>mode</literal> parameter should be either
368 <literal>CS_CLIENT</literal> or <literal>CS_SERVER</literal>.
372 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
376 Call this to process incoming events on an endpoint that has been
377 bound in listening mode. It will return 0 to indicate that the connect
378 request has been received, 1 to signal a partial reception, and -1 to
379 indicate an error condition.
383 COMSTACK cs_accept(COMSTACK handle);
387 This finalizes the server-side association establishment, after
388 cs_listen has completed successfully. It returns a new connection
389 endpoint, which represents the new association. The application will
390 typically wish to fork off a process to handle the association at this
391 point, and continue listen for new connections on the old
392 <literal>handle</literal>.
400 char *cs_addrstr(COMSTACK);
404 on an established connection to retrieve the host-name of the remote host.
408 <para>You may need to use this function with some care if your
409 name server service is slow or unreliable
414 <sect1 id="comstack.addresses"><title>Addresses</title>
417 The low-level format of the addresses are different depending on the
418 mode of communication you have chosen. A function is provided by each
419 of the lower layers to map a user-friendly string-form address to the
420 binary form required by the lower layers.
424 void *cs_straddr(COMSTACK handle, const char *str);
428 The format for TCP/IP and SSL addresses is:
432 <host> [ ':' <portnum> ]
436 The <literal>hostname</literal> can be either a domain name or an
437 IP address. The port number, if omitted, defaults to 210.
441 For TCP/IP and SSL transport modes, the special hostname "@"
442 is mapped to any local address
443 (the manifest constant <literal>INADDR_ANY</literal>).
444 It is used to establish local listening endpoints in the server role.
448 For UNIX sockets, the format of an address is the socket filename.
452 When a connection has been established, you can use
456 char *cs_addrstr(COMSTACK h);
460 to retrieve the host name of the peer system. The function returns
461 a pointer to a static area, which is overwritten on the next call
466 A fairly recent addition to the &comstack; module is the utility
470 COMSTACK cs_create_host (const char *str, int blocking, void **vp);
473 which is just a wrapper for <function>cs_create</function> and
474 <function>cs_straddr</function>. The <parameter>str</parameter>
475 is similar to that described for <function>cs_straddr</function>
476 but with a prefix denoting the &comstack; type. Prefixes supported
477 are <literal>tcp:</literal>, <literal>unix:</literal> and
478 <literal>ssl:</literal> for TCP/IP, UNIX and SSL respectively.
479 If no prefix is given, then TCP/IP is used.
480 The <parameter>blocking</parameter> is passed to
481 function <function>cs_create</function>. The third parameter
482 <parameter>vp</parameter> is a pointer to &comstack; stack type
484 For SSL (ssl_type) <parameter>vp</parameter> is an already create
485 OpenSSL CTX. For TCP/IP and UNIX <parameter>vp</parameter>
486 is unused (can be set to <literal>NULL</literal>.
491 <sect1 id="comstack.diagnostics"><title>Diagnostics</title>
494 All functions return -1 if an error occurs. Typically, the functions
495 will return 0 on success, but the data exchange functions
496 (<function>cs_get</function>, <function>cs_put</function>,
497 <function>cs_more</function>) follow special rules. Consult their
502 When a function (including the data exchange functions) reports an
503 error condition, use the function
504 <function>cs_errno()</function> to determine the cause of the
505 problem. The function
509 void cs_perror(COMSTACK handle char *message);
513 works like <function>perror(2)</function> and prints the
514 <literal>message</literal> argument, along with a system message, to
515 <literal>stderr</literal>. Use the character array
519 extern const char *cs_errlist[];
523 to get hold of the message, if you want to process it differently.
528 const char *cs_stackerr(COMSTACK handle);
532 Returns an error message from the lower layer, if one has been
536 <sect1 id="comstack.summary"><title>Summary and Synopsis</title>
539 #include <yaz/comstack.h>
541 #include <yaz/tcpip.h> /* this is for TCP/IP and SSL support */
542 #include <yaz/unix.h> /* this is for UNIX sockeL support */
545 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
547 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
549 COMSTACK cs_create_host (const char *str, int blocking,
552 int cs_bind(COMSTACK handle, int mode);
554 int cs_connect(COMSTACK handle, void *address);
556 int cs_rcvconnect(COMSTACK handle);
558 int cs_listen(COMSTACK handle);
560 COMSTACK cs_accept(COMSTACK handle);
562 int cs_put(COMSTACK handle, char *buf, int len);
564 int cs_get(COMSTACK handle, char **buf, int *size);
566 int cs_more(COMSTACK handle);
568 int cs_close(COMSTACK handle);
570 int cs_look(COMSTACK handle);
572 void *cs_straddr(COMSTACK handle, const char *str);
574 char *cs_addrstr(COMSTACK h);
578 void cs_perror(COMSTACK handle char *message);
580 const char *cs_stackerr(COMSTACK handle);
582 extern const char *cs_errlist[];
588 <!-- Keep this comment at the end of the file
593 sgml-minimize-attributes:nil
594 sgml-always-quote-attributes:t
597 sgml-parent-document: "yaz.xml"
598 sgml-local-catalogs: nil
599 sgml-namecase-general:t