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

FreeBSD Manual Pages

  
 
  

home | help
NAL_CONNECTION_NEW(2)		   distcache		 NAL_CONNECTION_NEW(2)

NAME
       NAL_CONNECTION_new,     NAL_CONNECTION_free,	NAL_CONNECTION_create,
       NAL_CONNECTION_create_pair,  NAL_CONNECTION_create_dummy,   NAL_CONNEC-
       TION_set_size,	  NAL_CONNECTION_get_read,    NAL_CONNECTION_get_send,
       NAL_CONNECTION_io,   NAL_CONNECTION_io_cap,    NAL_CONNECTION_is_estab-
       lished,	NAL_CONNECTION_add_to_selector,	NAL_CONNECTION_del_from_selec-
       tor - libnal connection functions

SYNOPSIS
	#include <libnal/nal.h>

	#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)

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

DESCRIPTION
       NAL_CONNECTION_new() allocates and initialises a	new NAL_CONNECTION ob-
       ject.

       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-
       sary.

       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-
       LECTOR.

       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_.

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

       NAL_CONNECTION_free(),	     NAL_CONNECTION_reset(),	   NAL_CONNEC-
       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.

NOTES
       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
       buffer.

       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.

BUGS
       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
       completely.

EXAMPLES
       A typical state-machine implementation using a single connection	is il-
       lustrated 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 */
	   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 */
		   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);

       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.

SEE ALSO
       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.

AUTHOR
       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 geoff@geoffthorpe.net.

       Home Page: http://www.distcache.org

1.5.1				  2004.10.19		 NAL_CONNECTION_NEW(2)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=NAL_CONNECTION_new&sektion=2&manpath=FreeBSD+Ports+14.3.quarterly>

home | help