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

  
 
  

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

NAME
     NAL_CONNECTION_new, NAL_CONNECTION_free, NAL_CONNECTION_create, NAL_CONNEC-
     TION_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_CONNEC-
     TION_add_to_selector, NAL_CONNECTION_del_from_selector - 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 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 connection's 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  re-
     quests on list, but will accept any pending connection request that had al-
     ready  been identified by a previous call to NAL_SELECTOR_select(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  EX-
     AMPLES section for some uses of ``pairs''.

     NAL_CONNECTION_create_dummy() will implement a virtual FIFO that has no un-
     derlying  network	resource associated with it. Writing data to the connec-
     tion 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  cre-
     ated 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_CONNEC-
     TION_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_SELEC-
     TOR_add_conn()  (or  its  `_ex' variant) and a resulting call to NAL_SELEC-
     TOR_select() had revealed readability  and/or  writability  on  conn,  this
     function  will silently succeed. Otherwise it will attempt to perform what-
     ever reading or writing was required. If this function  fails,  that  indi-
     cates that the connection is no longer valid - this represents a disconnec-
     tion by the peer, the result of a non-blocking connect that had been initi-
     ated but was unable to connect, or some network error that makes conn unus-
     able. 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 results of the last  se-
     lect  on  sel  were, and how much data the host system's networking support
     will accept or provide to conn.

     NAL_CONNECTION_is_established() is useful for determining when a non-block-
     ing 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_se-
     lect().	  NAL_CONNECTION_add_to_selector_ex()	  extends    NAL_CONNEC-
     TION_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_SELECT_FLAG_.

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

     NAL_CONNECTION_free(), NAL_CONNECTION_reset(), NAL_CONNECTION_add_to_selec-
     tor(), NAL_CONNECTION_add_to_selector_ex(), and NAL_CONNECTION_del_from_se-
     lector() 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 connec-
     tion 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 connec-
     tions  and listeners to perform their network input/output based on the re-
     sults.

     NAL_CONNECTION_add_to_selector() uses the following logic;  the  connection
     is always selected for exception events, and will be selected for readabil-
     ity  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 buffer's 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_CONNEC-
     TION_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  pro-
     vided  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_CONNEC-
     TION_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 net-
     work 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 re-
     quest 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  de-
     scribed 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 in-
     stantly if the FIFO is non-empty otherwise the FIFO should have  no  influ-
     ence  at all on the real select(2). Right now, NAL_CONNECTION_add_to_selec-
     tor() silently ignores dummy connections completely.

EXAMPLES
     A typical state-machine implementation using a single connection is  illus-
     trated 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 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() opera-
     tion 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_SE-
     LECTOR_select() (causing it to return zero) so that a redundant loop of the
     state-machine runs before the next select operation will notice the discon-
     nection.  If you already need IPC between the parent and child for exchange
     of data anyway, this mechanism could be useful  in  avoiding  global  vari-
     ables, signal 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 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 geoff@ge-
     offthorpe.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+15.1.quarterly>

home | help