Manual Reference Pages - NAL_CONNECTION_NEW (2)
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
#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)
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,
int NAL_CONNECTION_create_pair(NAL_CONNECTION *conn1, NAL_CONNECTION *conn2,
unsigned int def_buffer_size);
int NAL_CONNECTION_create_dummy(NAL_CONNECTION *conn,
unsigned int def_buffer_size);
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,
void NAL_CONNECTION_add_to_selector_ex(const NAL_CONNECTION *conn,
unsigned int flags);
void NAL_CONNECTION_del_from_selector(const NAL_CONNECTION *conn,
NAL_CONNECTION_new() allocates and initialises a new NAL_CONNECTION object.
NAL_CONNECTION_free() destroys a NAL_CONNECTION object.
NAL_CONNECTION_reset() will, if necessary, cleanup any prior state in conn
so that it can be reused in NAL_CONNECTION_create(). Internally, there are
other optimisations and benefits to using NAL_CONNECTION_reset() instead of
NAL_CONNECTION_free() and NAL_CONNECTION_new() - the implementation can try to
avoid repeated reallocation and reinitialisation of state, only doing full
cleanup and reinitialisation when necessary.
NAL_CONNECTION_create() will attempt to connect to the address represented by
addr. If this succeeds, it means either that the underlying connection of
conn 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. NAL_CONNECTION_is_established() can be used to
distinguish the difference. The size of the connections underlying read and
send NAL_BUFFERs is initialised to the default that was created in addr.
See the NOTES section for more discussion of connection semantics.
NAL_CONNECTION_accept() will not block waiting for incoming connection requests
on list, but will accept any pending connection request that had already
been identified by a previous call to NAL_SELECTOR_select(2) on sel. See
NAL_CONNECTION_create_pair() will initialise conn1 and conn2 to be
end-points of a single connection. This is typically implemented using the
socketpair(2) function, and is designed to allow for an IPC mechanism that
integrates with libnal. def_buffer_size will control the size of the read
and send buffers of both connections if the functions succeed. See the
EXAMPLES section for some uses of pairs.
NAL_CONNECTION_create_dummy() will implement a virtual FIFO that has no
underlying network resource associated with it. Writing data to the connection
amounts to pushing data onto the front of the FIFO, and reading data from the
connection amounts to popping data off the end of the FIFO. The size of the
FIFO is specified by def_buffer_size. See the BUGS section for a note
on using these connection types with NAL_SELECTOR.
NAL_CONNECTION_set_size() will resize the read and send buffers of conn to
size. The default size of those buffers is inherited from the setting
created in the NAL_ADDRESS that initialised conn, or if conn was
accepted from a NAL_LISTENER 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 NAL_BUFFER functions
NAL_CONNECTION_get_read() and NAL_CONNECTION_get_send() return the read and send
buffers of conn. This is how reading and writing is performed on conn, as
NAL_BUFFER functions may be used on these buffers directly.
NAL_CONNECTION_get_read_c() and NAL_CONNECTION_get_send_c() perform the same
function but on a constant conn parameter and returning constant pointers to
the corresponding buffers.
NAL_CONNECTION_io() will perform any network input/output that is possible
given the state in sel. Unless conn had been added to sel via
NAL_SELECTOR_add_conn() (or its _ex variant) and a resulting call to
NAL_SELECTOR_select() had revealed readability and/or writability on conn,
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 conn
unusable. See the NOTES section.
NAL_CONNECTION_io_cap() is a version of NAL_CONNECTION_io() that allows the
caller to specify a limit on the maximum amount conn 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 connections buffers, what the results of the last select
on sel were, and how much data the host systems networking support will
accept or provide to conn.
NAL_CONNECTION_is_established() is useful for determining when a non-blocking
connect has completed. See the NOTES section.
NAL_CONNECTION_add_to_selector() registers conn with the selector sel for
any events relevant to it. NAL_CONNECTION_del_from_selector() can be used to
reverse this if called before any subsequent call to NAL_SELECTOR_select().
NAL_CONNECTION_add_to_selector_ex() extends NAL_CONNECTION_add_to_selector() 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
NAL_CONNECTION_new() returns a valid NAL_CONNECTION object on success, NULL
NAL_CONNECTION_add_to_selector(), NAL_CONNECTION_add_to_selector_ex(), and
NAL_CONNECTION_del_from_selector() have no return value.
NAL_CONNECTION_get_read_c(), and NAL_CONNECTION_get_send_c() return pointers to
the connections buffer objects or NULL for failure.
NAL_CONNECTION_accept() returns non-zero if a connection was accepted and is
represented by the provided NAL_CONNECTION object, or zero if no connection
attempt was pending (or if there was but an error prevented the accept
All other NAL_CONNECTION functions return zero for failure or false, and
non-zero for success or true.
A NAL_CONNECTION object encapsulates two NAL_BUFFER 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 NAL_SELECTOR 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.
NAL_CONNECTION_add_to_selector() 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.
NAL_CONNECTION_io() is used after calling NAL_CONNECTION_add_to_selector() and
a subsequent call to NAL_SELECTOR_select(). 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
buffers data as possible. If NAL_CONNECTION_io() returns failure, the
connection is considered broken for some reason and no further I/O operations
should be attempted (the behaviour is undefined). NB: 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.
The above is almost true, BTW :-) The special case is that of non-blocking
connects. If NAL_CONNECTION_create() cannot immediately connect without
blocking, it will return success but subsequent calls to
NAL_CONNECTION_is_established() will reveal that the connection is not yet
complete. Any connection that is not complete will request selection for
sendability inside NAL_CONNECTION_add_to_selector(), whether the application
has provided data to send or not. The completion (or failure) of the
non-blocking connect will thus cause any subsequent NAL_SELECTOR_select()
operation to break. As with all other semantics, it is the follow up call to
NAL_CONNECTION_io() 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 NAL_CONNECTION_is_established() to determine if the
connection is complete, as the selector could have broken because of signals or
network events on other objects.
NAL_CONNECTION_accept() will return immediately, and will only succeed if the
NAL_LISTENER object had already been added to the selector using
NAL_LISTENER_add_to_select(), the selector had been subsequently selected using
NAL_SELECTOR_select(2), and this indicated an incoming connection request
waiting on the listener.
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 NAL_CONNECTION_create_pair(),
operate very much as described here. The FIFO connection type, created by
NAL_CONNECTION_create_dummy() is not yet consistent with this and is described
in the BUGS section.
Dummy FIFO connections created using NAL_CONNECTION_create_dummy() should be
trivially selectable if anyones daft enough to try. Ie. if you add a dummy
connection to a selector, the NAL_SELECTOR_select() should break instantly if
the FIFO is non-empty otherwise the FIFO should have no influence at all on the
real select(2). Right now, NAL_CONNECTION_add_to_selector() silently ignores
dummy connections completely.
A typical state-machine implementation using a single connection is illustrated
here (without error-checking);
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();
/* Setup */
c_read = NAL_CONNECTION_get_read(conn);
c_send = NAL_CONNECTION_get_send(conn);
/* Loop */
/* 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_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));
An example of using a connection pair (with 2 Kb read and send buffers for each
connection) to create IPC between a parent process and its child (again, no
NAL_CONNECTION *ipc_to_parent = NAL_CONNECTION_new();
NAL_CONNECTION *ipc_to_child = NAL_CONNECTION_new();
/* Setup */
NAL_CONNECTION_create_pair(ipc_to_parent, ipc_to_child, 2048);
/* Create child process */
/* Inside the child process, close our copy of the parents side */
/* Do child process things, and use ipc_to_parent to communicate
* with the parent. */
/* Inside the parent process, close our copy of the childs side */
/* Continue in the parent process, and use ipc_to_child to communicate
* with the child. */
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
ipc_to_child connection - the subsequent NAL_CONNECTION_io() operation will
fail indicating that the child process is dead (or in the process of dying) and
so the parent could immediately call wait(2) or waitpid(2). Whether the SIGCHLD
signal arrives before the NAL_CONNECTION_io() call or not is not too important,
at worst it might prematurely interrupt NAL_SELECTOR_select() (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 IPC between
the parent and child for exchange of data anyway, this mechanism could be
useful in avoiding global variables, signal handlers, and the associated
NAL_CONNECTION_new(2) - Functions for the NAL_CONNECTION type.
NAL_LISTENER_new(2) - Functions for the NAL_LISTENER type.
NAL_SELECTOR_new(2) - Functions for the NAL_SELECTOR type.
NAL_BUFFER_new(2) - Functions for the NAL_BUFFER type.
distcache(8) - Overview of the distcache architecture.
http://www.distcache.org/ - Distcache home page.
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 firstname.lastname@example.org.
Home Page: http://www.distcache.org
|1.4.5 ||NAL_CONNECTION_NEW (2) ||2004.03.23 |
Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.