Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help

       NAL_CONNECTION_create_pair, NAL_CONNECTION_create_dummy,	NAL_CONNEC-
       TION_set_size, NAL_CONNECTION_get_read, NAL_CONNECTION_get_send,
       lished, NAL_CONNECTION_add_to_selector, NAL_CONNECTION_del_from_selec-
       tor - libnal connection functions

	#include <libnal/nal.h>

	#define	NAL_SELECT_FLAG_READ  (unsigned	int)0x0001
	#define	NAL_SELECT_FLAG_SEND  (unsigned	int)0x0002

	int NAL_CONNECTION_create(NAL_CONNECTION *conn,	const NAL_ADDRESS *addr);
				       NAL_SELECTOR *sel);
				       unsigned	int def_buffer_size);
	#if 0
	int NAL_CONNECTION_create_dummy(NAL_CONNECTION *conn,
					unsigned int def_buffer_size);
	int NAL_CONNECTION_set_size(NAL_CONNECTION *conn, unsigned int size);
	const NAL_BUFFER *NAL_CONNECTION_get_read_c(const NAL_CONNECTION *conn);
	const NAL_BUFFER *NAL_CONNECTION_get_send_c(const NAL_CONNECTION *conn);
				  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);

       NAL_CONNECTION_new() allocates and initialises a	new NAL_CONNECTION ob-

       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_re-
       set() instead of	NAL_CONNECTION_free() and NAL_CONNECTION_new() - the
       implementation can try to avoid repeated	reallocation and reinitialisa-
       tion of state, only doing full cleanup and reinitialisation when	neces-

       NAL_CONNECTION_create() will attempt to connect to the address repre-
       sented 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 re-
       jected 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_CON-
       NECTION_is_established()	can be used to distinguish the difference. The
       size of the connection's	underlying read	and send NAL_BUFFERs is	ini-
       tialised	to the default that was	created	in addr.  See the "NOTES" sec-
       tion 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_se-
       lect(2) on sel. See "NOTES".

       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_SE-

       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	set-
       ting 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 directly.

       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 pos-
       sible 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 net-
       work 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 connection's buffers, what the re-
       sults of	the last select	on sel were, and how much data the host	sys-
       tem's 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_SE-
       LECTOR_select().	 NAL_CONNECTION_add_to_selector_ex() extends NAL_CON-
       NECTION_add_to_selector() by allowing a bit-mask	to be supplied to con-
       trol what events	the connection can be selected on, these flags are in-
       dicated above prefixed with NAL_SELECT_FLAG_.

       NAL_CONNECTION_new() returns a valid NAL_CONNECTION object on success,
       NULL otherwise.

       TION_add_to_selector(), NAL_CONNECTION_add_to_selector_ex(), and
       NAL_CONNECTION_del_from_selector() have no return value.

       NAL_CONNECTION_get_read(), NAL_CONNECTION_get_send(), NAL_CONNEC-
       TION_get_read_c(), and NAL_CONNECTION_get_send_c() return pointers to
       the connection's	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 operation).

       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 in-
       put/output based	on the results.

       NAL_CONNECTION_add_to_selector()	uses the following logic; the connec-
       tion 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_selec-
       tor() 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	indi-
       cated it	will send as much of the send buffer's data as possible. If
       NAL_CONNECTION_io() returns failure, the	connection is considered bro-
       ken for some reason and no further I/O operations should	be attempted
       (the behaviour is undefined). NB: The connection	object is not automat-
       ically 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 buf-

       The above is almost true, BTW :-) The special case is that of non-
       blocking	connects. If NAL_CONNECTION_create() cannot immediately	con-
       nect 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 selec-
       tion 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 con-
       nect failed. If it returns success, you should still call NAL_CONNEC-
       TION_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	se-
       lected 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_CONNEC-
       TION_create_pair(), operate very	much as	described here.	The FIFO con-
       nection type, created by	NAL_CONNECTION_create_dummy() is not yet con-
       sistent with this and is	described in the "BUGS"	section.

       Dummy FIFO connections created using NAL_CONNECTION_create_dummy()
       should be trivially selectable if anyone's 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

       A typical state-machine implementation using a single connection	is il-
       lustrated here (without error-checking);

	   NAL_BUFFER *c_read, *c_send;
	   NAL_ADDRESS *addr = retrieve_the_desired_address();

	   /* Setup */
	   NAL_CONNECTION_create(conn, addr);
	   c_read = NAL_CONNECTION_get_read(conn);
	   c_send = NAL_CONNECTION_get_send(conn);

	   /* 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));

       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	error checking);

	   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 */
	   switch(fork()) {
	       case 0:
		   /* Inside the child process,	close our copy of the parent's side */
		   /* Do child process things, and use 'ipc_to_parent' to communicate
		    * with the parent. */
		   /* Inside the parent	process, close our copy	of the child's 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 alto-
       gether. 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 ar-
       rives 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 any-
       way, this mechanism could be useful in avoiding global variables, sig-
       nal handlers, and the associated	difficulties.

       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. - Distcache home page.

       This toolkit was	designed and implemented by Geoff Thorpe for Crypto-
       graphic Appliances Incorporated.	Since the project was released into
       open source, it has a home page and a project environment where devel-
       opment, 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

       Home Page:

1.5.1				  2004.10.19		 NAL_CONNECTION_NEW(2)


Want to link to this manual page? Use this URL:

home | help