.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.13 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "NAL_CONNECTION_NEW 2" .TH NAL_CONNECTION_NEW 2 "2004.03.23" "1.4.5" "distcache" .SH "NAME" NAL_CONNECTION_new, NAL_CONNECTION_free, NAL_CONNECTION_create, NAL_CONNECTION_create_pair, NAL_CONNECTION_create_dummy, NAL_CONNECTION_set_size, NAL_CONNECTION_get_read, NAL_CONNECTION_get_send, NAL_CONNECTION_io, NAL_CONNECTION_io_cap, NAL_CONNECTION_is_established, NAL_CONNECTION_add_to_selector, NAL_CONNECTION_del_from_selector \- libnal connection functions .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #include .Ve .PP .Vb 3 \& #define NAL_SELECT_FLAG_READ (unsigned int)0x0001 \& #define NAL_SELECT_FLAG_SEND (unsigned int)0x0002 \& #define NAL_SELECT_FLAG_RW (NAL_SELECT_FLAG_READ | NAL_SELECT_FLAG_SEND) .Ve .PP .Vb 28 \& NAL_CONNECTION *NAL_CONNECTION_new(void); \& void NAL_CONNECTION_free(NAL_CONNECTION *conn); \& void NAL_CONNECTION_reset(NAL_CONNECTION *conn); \& int NAL_CONNECTION_create(NAL_CONNECTION *conn, const NAL_ADDRESS *addr); \& int NAL_CONNECTION_accept(NAL_CONNECTION *conn, NAL_LISTENER *list, \& NAL_SELECTOR *sel); \& int NAL_CONNECTION_create_pair(NAL_CONNECTION *conn1, NAL_CONNECTION *conn2, \& unsigned int def_buffer_size); \& #if 0 \& int NAL_CONNECTION_create_dummy(NAL_CONNECTION *conn, \& unsigned int def_buffer_size); \& #endif \& int NAL_CONNECTION_set_size(NAL_CONNECTION *conn, unsigned int size); \& NAL_BUFFER *NAL_CONNECTION_get_read(NAL_CONNECTION *conn); \& NAL_BUFFER *NAL_CONNECTION_get_send(NAL_CONNECTION *conn); \& const NAL_BUFFER *NAL_CONNECTION_get_read_c(const NAL_CONNECTION *conn); \& const NAL_BUFFER *NAL_CONNECTION_get_send_c(const NAL_CONNECTION *conn); \& int NAL_CONNECTION_io(NAL_CONNECTION *conn, NAL_SELECTOR *sel); \& int NAL_CONNECTION_io_cap(NAL_CONNECTION *conn, NAL_SELECTOR *sel, \& unsigned int max_read, unsigned int max_send); \& int NAL_CONNECTION_is_established(const NAL_CONNECTION *conn); \& void NAL_CONNECTION_add_to_selector(const NAL_CONNECTION *conn, \& NAL_SELECTOR *sel); \& void NAL_CONNECTION_add_to_selector_ex(const NAL_CONNECTION *conn, \& NAL_SELECTOR *sel, \& unsigned int flags); \& void NAL_CONNECTION_del_from_selector(const NAL_CONNECTION *conn, \& NAL_SELECTOR *sel); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fINAL_CONNECTION_new()\fR allocates and initialises a new \fB\s-1NAL_CONNECTION\s0\fR object. .PP \&\fINAL_CONNECTION_free()\fR destroys a \fB\s-1NAL_CONNECTION\s0\fR object. .PP \&\fINAL_CONNECTION_reset()\fR will, if necessary, cleanup any prior state in \fBconn\fR so that it can be reused in \fINAL_CONNECTION_create()\fR. Internally, there are other optimisations and benefits to using \fINAL_CONNECTION_reset()\fR instead of \&\fINAL_CONNECTION_free()\fR and \fINAL_CONNECTION_new()\fR \- the implementation can try to avoid repeated reallocation and reinitialisation of state, only doing full cleanup and reinitialisation when necessary. .PP \&\fINAL_CONNECTION_create()\fR will attempt to connect to the address represented by \&\fBaddr\fR. If this succeeds, it means either that the underlying connection of \&\fBconn\fR is established, or that a non-blocking connect was successfully initiated but has not yet completed (it may still be rejected by the peer eventually). Typically, unix domain sockets connect or fail immediately, and usually TCP/IPv4 connect non\-blocking, though this may not be true for some interfaces such as `localhost'. \fINAL_CONNECTION_is_established()\fR can be used to distinguish the difference. The size of the connection's underlying read and send \fB\s-1NAL_BUFFER\s0\fRs is initialised to the default that was created in \fBaddr\fR. See the \*(L"\s-1NOTES\s0\*(R" section for more discussion of connection semantics. .PP \&\fINAL_CONNECTION_accept()\fR will not block waiting for incoming connection requests on \fBlist\fR, but will accept any pending connection request that had already been identified by a previous call to \fINAL_SELECTOR_select\fR\|(2) on \fBsel\fR. See \&\*(L"\s-1NOTES\s0\*(R". .PP \&\fINAL_CONNECTION_create_pair()\fR will initialise \fBconn1\fR and \fBconn2\fR to be end-points of a single connection. This is typically implemented using the \&\fIsocketpair\fR\|(2) function, and is designed to allow for an \s-1IPC\s0 mechanism that integrates with \fIlibnal\fR. \fBdef_buffer_size\fR will control the size of the read and send buffers of both connections if the functions succeed. See the \&\s-1EXAMPLES\s0 section for some uses of ``pairs''. .PP \&\fINAL_CONNECTION_create_dummy()\fR will implement a virtual \s-1FIFO\s0 that has no underlying network resource associated with it. Writing data to the connection amounts to pushing data onto the front of the \s-1FIFO\s0, and reading data from the connection amounts to popping data off the end of the \s-1FIFO\s0. The size of the \&\s-1FIFO\s0 is specified by \fBdef_buffer_size\fR. See the \*(L"\s-1BUGS\s0\*(R" section for a note on using these connection types with \fB\s-1NAL_SELECTOR\s0\fR. .PP \&\fINAL_CONNECTION_set_size()\fR will resize the read and send buffers of \fBconn\fR to \&\fBsize\fR. The default size of those buffers is inherited from the setting created in the \fB\s-1NAL_ADDRESS\s0\fR that initialised \fBconn\fR, or if \fBconn\fR was accepted from a \fB\s-1NAL_LISTENER\s0\fR object, then from the address that created the listener. The individual buffers can be resized independantly by using the following two functions to obtain the buffesr and using \fB\s-1NAL_BUFFER\s0\fR functions directly. .PP \&\fINAL_CONNECTION_get_read()\fR and \fINAL_CONNECTION_get_send()\fR return the read and send buffers of \fBconn\fR. This is how reading and writing is performed on \fBconn\fR, as \&\fB\s-1NAL_BUFFER\s0\fR functions may be used on these buffers directly. \&\fINAL_CONNECTION_get_read_c()\fR and \fINAL_CONNECTION_get_send_c()\fR perform the same function but on a constant \fBconn\fR parameter and returning constant pointers to the corresponding buffers. .PP \&\fINAL_CONNECTION_io()\fR will perform any network input/output that is possible given the state in \fBsel\fR. Unless \fBconn\fR had been added to \fBsel\fR via \&\fINAL_SELECTOR_add_conn()\fR (or its `_ex' variant) and a resulting call to \&\fINAL_SELECTOR_select()\fR had revealed readability and/or writability on \fBconn\fR, this function will silently succeed. Otherwise it will attempt to perform whatever reading or writing was required. If this function fails, that indicates that the connection is no longer valid \- this represents a disconnection by the peer, the result of a non-blocking connect that had been initiated but was unable to connect, or some network error that makes \fBconn\fR unusable. See the \*(L"\s-1NOTES\s0\*(R" section. .PP \&\fINAL_CONNECTION_io_cap()\fR is a version of \fINAL_CONNECTION_io()\fR that allows the caller to specify a limit on the maximum amount \fBconn\fR should read from, or send to, the network. Whether this amount is read or sent (or even whether reading or sending takes place at all) depends on; the data (and space) available is in the connection's buffers, what the results of the last select on \fBsel\fR were, and how much data the host system's networking support will accept or provide to \fBconn\fR. .PP \&\fINAL_CONNECTION_is_established()\fR is useful for determining when a non-blocking connect has completed. See the \*(L"\s-1NOTES\s0\*(R" section. .PP \&\fINAL_CONNECTION_add_to_selector()\fR registers \fBconn\fR with the selector \fBsel\fR for any events relevant to it. \fINAL_CONNECTION_del_from_selector()\fR can be used to reverse this if called before any subsequent call to \fINAL_SELECTOR_select()\fR. \&\fINAL_CONNECTION_add_to_selector_ex()\fR extends \fINAL_CONNECTION_add_to_selector()\fR by allowing a bit-mask to be supplied to control what events the connection can be selected on, these flags are indicated above prefixed with \&\fI\s-1NAL_SELECT_FLAG_\s0\fR. .SH "RETURN VALUES" .IX Header "RETURN VALUES" \&\fINAL_CONNECTION_new()\fR returns a valid \fB\s-1NAL_CONNECTION\s0\fR object on success, \s-1NULL\s0 otherwise. .PP \&\fINAL_CONNECTION_free()\fR, \fINAL_CONNECTION_reset()\fR, \&\fINAL_CONNECTION_add_to_selector()\fR, \fINAL_CONNECTION_add_to_selector_ex()\fR, and \&\fINAL_CONNECTION_del_from_selector()\fR have no return value. .PP \&\fINAL_CONNECTION_get_read()\fR, \fINAL_CONNECTION_get_send()\fR, \&\fINAL_CONNECTION_get_read_c()\fR, and \fINAL_CONNECTION_get_send_c()\fR return pointers to the connection's buffer objects or \s-1NULL\s0 for failure. .PP \&\fINAL_CONNECTION_accept()\fR returns non-zero if a connection was accepted and is represented by the provided \fB\s-1NAL_CONNECTION\s0\fR object, or zero if no connection attempt was pending (or if there was but an error prevented the accept operation). .PP All other \fB\s-1NAL_CONNECTION\s0\fR functions return zero for failure or false, and non-zero for success or true. .SH "NOTES" .IX Header "NOTES" A \fB\s-1NAL_CONNECTION\s0\fR object encapsulates two \fB\s-1NAL_BUFFER\s0\fR objects and a non-blocking socket. Any data that has been read from the socket is placed in the read buffer, and applications write data into the send buffer for it to be (eventually) written out to the socket. The \fB\s-1NAL_SELECTOR\s0\fR type provides the ability to poll for any requested network events and then allow connections and listeners to perform their network input/output based on the results. .PP \&\fINAL_CONNECTION_add_to_selector()\fR uses the following logic; the connection is always selected for exception events, and will be selected for readability if its read buffer is not full and writability if its send buffer is not empty. .PP \&\fINAL_CONNECTION_io()\fR is used after calling \fINAL_CONNECTION_add_to_selector()\fR and a subsequent call to \fINAL_SELECTOR_select()\fR. It observes the following logic; if an exception event has occured it returns failure, if readability is indicated it will read incoming data up to the limit of the available space in the read buffer, and if writability is indicated it will send as much of the send buffer's data as possible. If \fINAL_CONNECTION_io()\fR returns failure, the connection is considered broken for some reason and no further I/O operations should be attempted (the behaviour is undefined). \s-1NB:\s0 The connection object is not automatically cleaned up so as to allow the caller to continue reading any data in the read buffer and/or examine any unsent data in the send buffer. .PP The above is almost true, \s-1BTW\s0 :\-) The special case is that of non-blocking connects. If \fINAL_CONNECTION_create()\fR cannot immediately connect without blocking, it will return success but subsequent calls to \&\fINAL_CONNECTION_is_established()\fR will reveal that the connection is not yet complete. Any connection that is not complete will request selection for sendability inside \fINAL_CONNECTION_add_to_selector()\fR, whether the application has provided data to send or not. The completion (or failure) of the non-blocking connect will thus cause any subsequent \fINAL_SELECTOR_select()\fR operation to break. As with all other semantics, it is the follow up call to \&\fINAL_CONNECTION_io()\fR that changes the state of the connection object \- if it returns failure, the non-blocking connect failed. If it returns success, you should still call \fINAL_CONNECTION_is_established()\fR to determine if the connection is complete, as the selector could have broken because of signals or network events on other objects. .PP \&\fINAL_CONNECTION_accept()\fR will return immediately, and will only succeed if the \&\fB\s-1NAL_LISTENER\s0\fR object had already been added to the selector using \&\fINAL_LISTENER_add_to_select()\fR, the selector had been subsequently selected using \&\fINAL_SELECTOR_select\fR\|(2), and this indicated an incoming connection request waiting on the listener. .PP It should be noted that the actual transport in use is virtualised to allow for multiple transports and, because of this, multiple semantics for how the network functionality behaves. TCP/IPv4 and unix domain socket based connections, as well as connection pairs from \fINAL_CONNECTION_create_pair()\fR, operate very much as described here. The \s-1FIFO\s0 connection type, created by \&\fINAL_CONNECTION_create_dummy()\fR is not yet consistent with this and is described in the \*(L"\s-1BUGS\s0\*(R" section. .SH "BUGS" .IX Header "BUGS" Dummy \s-1FIFO\s0 connections created using \fINAL_CONNECTION_create_dummy()\fR should be trivially selectable if anyone's daft enough to try. Ie. if you add a dummy connection to a selector, the \fINAL_SELECTOR_select()\fR should break instantly if the \s-1FIFO\s0 is non-empty otherwise the \s-1FIFO\s0 should have no influence at all on the real \fIselect\fR\|(2). Right now, \fINAL_CONNECTION_add_to_selector()\fR silently ignores dummy connections completely. .SH "EXAMPLES" .IX Header "EXAMPLES" A typical state-machine implementation using a single connection is illustrated here (without error\-checking); .PP .Vb 4 \& NAL_BUFFER *c_read, *c_send; \& NAL_SELECTOR *sel = NAL_SELECTOR_new(); \& NAL_CONNECTION *conn = NAL_CONNECTION_new(); \& NAL_ADDRESS *addr = retrieve_the_desired_address(); .Ve .PP .Vb 4 \& /* Setup */ \& NAL_CONNECTION_create(conn, addr); \& c_read = NAL_CONNECTION_get_read(conn); \& c_send = NAL_CONNECTION_get_send(conn); .Ve .PP .Vb 14 \& /* Loop */ \& do { \& /* This is where the state-machine code should process as much data as \& * possible from 'c_read' and/or produce as much output to 'c_send' as \& * it can. */ \& ... \& ... user code \& ... \& /* block on (relevant) network events for 'conn' */ \& NAL_CONNECTION_add_to_selector(conn, sel); \& NAL_SELECTOR_select(sel, 0, 0); \& /* Do network I/O after the above blocking select and continue looping \& * only if the connection is still alive. */ \& } while(NAL_CONNECTION_io(conn, sel)); .Ve .PP An example of using a connection pair (with 2 Kb read and send buffers for each connection) to create \s-1IPC\s0 between a parent process and its child (again, no error checking); .PP .Vb 2 \& NAL_CONNECTION *ipc_to_parent = NAL_CONNECTION_new(); \& NAL_CONNECTION *ipc_to_child = NAL_CONNECTION_new(); .Ve .PP .Vb 2 \& /* Setup */ \& NAL_CONNECTION_create_pair(ipc_to_parent, ipc_to_child, 2048); .Ve .PP .Vb 17 \& /* Create child process */ \& switch(fork()) { \& case 0: \& /* Inside the child process, close our copy of the parent's side */ \& NAL_CONNECTION_free(ipc_to_child); \& /* Do child process things, and use 'ipc_to_parent' to communicate \& * with the parent. */ \& do_child_logic(ipc_to_parent); \& exit(0); \& default: \& /* Inside the parent process, close our copy of the child's side */ \& NAL_CONNECTION_free(ipc_to_parent); \& break; \& } \& /* Continue in the parent process, and use 'ipc_to_child' to communicate \& * with the child. */ \& do_parent_logic(ipc_to_child); .Ve .PP Note that these connection pairs can also be a useful way of handling process termination that allow you to bypass signal handling altogether. If a child process terminates, the connection between the pair will be broken and so this will be noticed in the parent process by any selector selecting on the \&\fBipc_to_child\fR connection \- the subsequent \fINAL_CONNECTION_io()\fR operation will fail indicating that the child process is dead (or in the process of dying) and so the parent could immediately call \fIwait\fR\|(2) or \fIwaitpid\fR\|(2). Whether the \s-1SIGCHLD\s0 signal arrives before the \fINAL_CONNECTION_io()\fR call or not is not too important, at worst it might prematurely interrupt \fINAL_SELECTOR_select()\fR (causing it to return zero) so that a redundant loop of the state-machine runs before the next select operation will notice the disconnection. If you already need \s-1IPC\s0 between the parent and child for exchange of data anyway, this mechanism could be useful in avoiding global variables, signal handlers, and the associated difficulties. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fINAL_CONNECTION_new\fR\|(2) \- Functions for the \s-1NAL_CONNECTION\s0 type. .PP \&\fINAL_LISTENER_new\fR\|(2) \- Functions for the \s-1NAL_LISTENER\s0 type. .PP \&\fINAL_SELECTOR_new\fR\|(2) \- Functions for the \s-1NAL_SELECTOR\s0 type. .PP \&\fINAL_BUFFER_new\fR\|(2) \- Functions for the \s-1NAL_BUFFER\s0 type. .PP \&\fIdistcache\fR\|(8) \- Overview of the distcache architecture. .PP \&\fIhttp://www.distcache.org/\fR \- Distcache home page. .SH "AUTHOR" .IX Header "AUTHOR" This toolkit was designed and implemented by Geoff Thorpe for Cryptographic Appliances Incorporated. Since the project was released into open source, it has a home page and a project environment where development, mailing lists, and releases are organised. For problems with the software or this man page please check for new releases at the project web-site below, mail the users mailing list described there, or contact the author at \fIgeoff@geoffthorpe.net\fR. .PP Home Page: \fIhttp://www.distcache.org\fR