1NAL_CONNECTION_NEW(2)              distcache             NAL_CONNECTION_NEW(2)
2
3
4

NAME

6       NAL_CONNECTION_new, NAL_CONNECTION_free, NAL_CONNECTION_create,
7       NAL_CONNECTION_create_pair, NAL_CONNECTION_create_dummy, NAL_CONNEC‐
8       TION_set_size, NAL_CONNECTION_get_read, NAL_CONNECTION_get_send,
9       NAL_CONNECTION_io, NAL_CONNECTION_io_cap, NAL_CONNECTION_is_estab‐
10       lished, NAL_CONNECTION_add_to_selector, NAL_CONNECTION_del_from_selec‐
11       tor - libnal connection functions
12

SYNOPSIS

14        #include <libnal/nal.h>
15
16        #define NAL_SELECT_FLAG_READ  (unsigned int)0x0001
17        #define NAL_SELECT_FLAG_SEND  (unsigned int)0x0002
18        #define NAL_SELECT_FLAG_RW    (NAL_SELECT_FLAG_READ ⎪ NAL_SELECT_FLAG_SEND)
19
20        NAL_CONNECTION *NAL_CONNECTION_new(void);
21        void NAL_CONNECTION_free(NAL_CONNECTION *conn);
22        void NAL_CONNECTION_reset(NAL_CONNECTION *conn);
23        int NAL_CONNECTION_create(NAL_CONNECTION *conn, const NAL_ADDRESS *addr);
24        int NAL_CONNECTION_accept(NAL_CONNECTION *conn, NAL_LISTENER *list,
25                                       NAL_SELECTOR *sel);
26        int NAL_CONNECTION_create_pair(NAL_CONNECTION *conn1, NAL_CONNECTION *conn2,
27                                       unsigned int def_buffer_size);
28        #if 0
29        int NAL_CONNECTION_create_dummy(NAL_CONNECTION *conn,
30                                        unsigned int def_buffer_size);
31        #endif
32        int NAL_CONNECTION_set_size(NAL_CONNECTION *conn, unsigned int size);
33        NAL_BUFFER *NAL_CONNECTION_get_read(NAL_CONNECTION *conn);
34        NAL_BUFFER *NAL_CONNECTION_get_send(NAL_CONNECTION *conn);
35        const NAL_BUFFER *NAL_CONNECTION_get_read_c(const NAL_CONNECTION *conn);
36        const NAL_BUFFER *NAL_CONNECTION_get_send_c(const NAL_CONNECTION *conn);
37        int NAL_CONNECTION_io(NAL_CONNECTION *conn, NAL_SELECTOR *sel);
38        int NAL_CONNECTION_io_cap(NAL_CONNECTION *conn, NAL_SELECTOR *sel,
39                                  unsigned int max_read, unsigned int max_send);
40        int NAL_CONNECTION_is_established(const NAL_CONNECTION *conn);
41        void NAL_CONNECTION_add_to_selector(const NAL_CONNECTION *conn,
42                                            NAL_SELECTOR *sel);
43        void NAL_CONNECTION_add_to_selector_ex(const NAL_CONNECTION *conn,
44                                               NAL_SELECTOR *sel,
45                                               unsigned int flags);
46        void NAL_CONNECTION_del_from_selector(const NAL_CONNECTION *conn,
47                                              NAL_SELECTOR *sel);
48

DESCRIPTION

50       NAL_CONNECTION_new() allocates and initialises a new NAL_CONNECTION
51       object.
52
53       NAL_CONNECTION_free() destroys a NAL_CONNECTION object.
54
55       NAL_CONNECTION_reset() will, if necessary, cleanup any prior state in
56       conn so that it can be reused in NAL_CONNECTION_create(). Internally,
57       there are other optimisations and benefits to using NAL_CONNEC‐
58       TION_reset() instead of NAL_CONNECTION_free() and NAL_CONNECTION_new()
59       - the implementation can try to avoid repeated reallocation and reini‐
60       tialisation of state, only doing full cleanup and reinitialisation when
61       necessary.
62
63       NAL_CONNECTION_create() will attempt to connect to the address repre‐
64       sented by addr. If this succeeds, it means either that the underlying
65       connection of conn is established, or that a non-blocking connect was
66       successfully initiated but has not yet completed (it may still be
67       rejected by the peer eventually). Typically, unix domain sockets con‐
68       nect or fail immediately, and usually TCP/IPv4 connect non-blocking,
69       though this may not be true for some interfaces such as `localhost'.
70       NAL_CONNECTION_is_established() can be used to distinguish the differ‐
71       ence. The size of the connection's underlying read and send NAL_BUFFERs
72       is initialised to the default that was created in addr.  See the
73       "NOTES" section for more discussion of connection semantics.
74
75       NAL_CONNECTION_accept() will not block waiting for incoming connection
76       requests on list, but will accept any pending connection request that
77       had already been identified by a previous call to NAL_SELEC‐
78       TOR_select(2) on sel. See "NOTES".
79
80       NAL_CONNECTION_create_pair() will initialise conn1 and conn2 to be end-
81       points of a single connection. This is typically implemented using the
82       socketpair(2) function, and is designed to allow for an IPC mechanism
83       that integrates with libnal. def_buffer_size will control the size of
84       the read and send buffers of both connections if the functions succeed.
85       See the EXAMPLES section for some uses of ``pairs''.
86
87       NAL_CONNECTION_create_dummy() will implement a virtual FIFO that has no
88       underlying network resource associated with it. Writing data to the
89       connection amounts to pushing data onto the front of the FIFO, and
90       reading data from the connection amounts to popping data off the end of
91       the FIFO. The size of the FIFO is specified by def_buffer_size. See the
92       "BUGS" section for a note on using these connection types with
93       NAL_SELECTOR.
94
95       NAL_CONNECTION_set_size() will resize the read and send buffers of conn
96       to size. The default size of those buffers is inherited from the set‐
97       ting created in the NAL_ADDRESS that initialised conn, or if conn was
98       accepted from a NAL_LISTENER object, then from the address that created
99       the listener. The individual buffers can be resized independantly by
100       using the following two functions to obtain the buffesr and using
101       NAL_BUFFER functions directly.
102
103       NAL_CONNECTION_get_read() and NAL_CONNECTION_get_send() return the read
104       and send buffers of conn. This is how reading and writing is performed
105       on conn, as NAL_BUFFER functions may be used on these buffers directly.
106       NAL_CONNECTION_get_read_c() and NAL_CONNECTION_get_send_c() perform the
107       same function but on a constant conn parameter and returning constant
108       pointers to the corresponding buffers.
109
110       NAL_CONNECTION_io() will perform any network input/output that is pos‐
111       sible given the state in sel. Unless conn had been added to sel via
112       NAL_SELECTOR_add_conn() (or its `_ex' variant) and a resulting call to
113       NAL_SELECTOR_select() had revealed readability and/or writability on
114       conn, this function will silently succeed. Otherwise it will attempt to
115       perform whatever reading or writing was required. If this function
116       fails, that indicates that the connection is no longer valid - this
117       represents a disconnection by the peer, the result of a non-blocking
118       connect that had been initiated but was unable to connect, or some net‐
119       work error that makes conn unusable. See the "NOTES" section.
120
121       NAL_CONNECTION_io_cap() is a version of NAL_CONNECTION_io() that allows
122       the caller to specify a limit on the maximum amount conn should read
123       from, or send to, the network. Whether this amount is read or sent (or
124       even whether reading or sending takes place at all) depends on; the
125       data (and space) available is in the connection's buffers, what the
126       results of the last select on sel were, and how much data the host sys‐
127       tem's networking support will accept or provide to conn.
128
129       NAL_CONNECTION_is_established() is useful for determining when a non-
130       blocking connect has completed. See the "NOTES" section.
131
132       NAL_CONNECTION_add_to_selector() registers conn with the selector sel
133       for any events relevant to it. NAL_CONNECTION_del_from_selector() can
134       be used to reverse this if called before any subsequent call to
135       NAL_SELECTOR_select().  NAL_CONNECTION_add_to_selector_ex() extends
136       NAL_CONNECTION_add_to_selector() by allowing a bit-mask to be supplied
137       to control what events the connection can be selected on, these flags
138       are indicated above prefixed with NAL_SELECT_FLAG_.
139

RETURN VALUES

141       NAL_CONNECTION_new() returns a valid NAL_CONNECTION object on success,
142       NULL otherwise.
143
144       NAL_CONNECTION_free(), NAL_CONNECTION_reset(), NAL_CONNEC‐
145       TION_add_to_selector(), NAL_CONNECTION_add_to_selector_ex(), and
146       NAL_CONNECTION_del_from_selector() have no return value.
147
148       NAL_CONNECTION_get_read(), NAL_CONNECTION_get_send(), NAL_CONNEC‐
149       TION_get_read_c(), and NAL_CONNECTION_get_send_c() return pointers to
150       the connection's buffer objects or NULL for failure.
151
152       NAL_CONNECTION_accept() returns non-zero if a connection was accepted
153       and is represented by the provided NAL_CONNECTION object, or zero if no
154       connection attempt was pending (or if there was but an error prevented
155       the accept operation).
156
157       All other NAL_CONNECTION functions return zero for failure or false,
158       and non-zero for success or true.
159

NOTES

161       A NAL_CONNECTION object encapsulates two NAL_BUFFER objects and a non-
162       blocking socket. Any data that has been read from the socket is placed
163       in the read buffer, and applications write data into the send buffer
164       for it to be (eventually) written out to the socket. The NAL_SELECTOR
165       type provides the ability to poll for any requested network events and
166       then allow connections and listeners to perform their network
167       input/output based on the results.
168
169       NAL_CONNECTION_add_to_selector() uses the following logic; the connec‐
170       tion is always selected for exception events, and will be selected for
171       readability if its read buffer is not full and writability if its send
172       buffer is not empty.
173
174       NAL_CONNECTION_io() is used after calling NAL_CONNECTION_add_to_selec‐
175       tor() and a subsequent call to NAL_SELECTOR_select(). It observes the
176       following logic; if an exception event has occured it returns failure,
177       if readability is indicated it will read incoming data up to the limit
178       of the available space in the read buffer, and if writability is indi‐
179       cated it will send as much of the send buffer's data as possible. If
180       NAL_CONNECTION_io() returns failure, the connection is considered bro‐
181       ken for some reason and no further I/O operations should be attempted
182       (the behaviour is undefined). NB: The connection object is not automat‐
183       ically cleaned up so as to allow the caller to continue reading any
184       data in the read buffer and/or examine any unsent data in the send buf‐
185       fer.
186
187       The above is almost true, BTW :-) The special case is that of non-
188       blocking connects. If NAL_CONNECTION_create() cannot immediately con‐
189       nect without blocking, it will return success but subsequent calls to
190       NAL_CONNECTION_is_established() will reveal that the connection is not
191       yet complete. Any connection that is not complete will request selec‐
192       tion for sendability inside NAL_CONNECTION_add_to_selector(), whether
193       the application has provided data to send or not. The completion (or
194       failure) of the non-blocking connect will thus cause any subsequent
195       NAL_SELECTOR_select() operation to break. As with all other semantics,
196       it is the follow up call to NAL_CONNECTION_io() that changes the state
197       of the connection object - if it returns failure, the non-blocking con‐
198       nect failed. If it returns success, you should still call NAL_CONNEC‐
199       TION_is_established() to determine if the connection is complete, as
200       the selector could have broken because of signals or network events on
201       other objects.
202
203       NAL_CONNECTION_accept() will return immediately, and will only succeed
204       if the NAL_LISTENER object had already been added to the selector using
205       NAL_LISTENER_add_to_select(), the selector had been subsequently
206       selected using NAL_SELECTOR_select(2), and this indicated an incoming
207       connection request waiting on the listener.
208
209       It should be noted that the actual transport in use is virtualised to
210       allow for multiple transports and, because of this, multiple semantics
211       for how the network functionality behaves. TCP/IPv4 and unix domain
212       socket based connections, as well as connection pairs from NAL_CONNEC‐
213       TION_create_pair(), operate very much as described here. The FIFO con‐
214       nection type, created by NAL_CONNECTION_create_dummy() is not yet con‐
215       sistent with this and is described in the "BUGS" section.
216

BUGS

218       Dummy FIFO connections created using NAL_CONNECTION_create_dummy()
219       should be trivially selectable if anyone's daft enough to try. Ie. if
220       you add a dummy connection to a selector, the NAL_SELECTOR_select()
221       should break instantly if the FIFO is non-empty otherwise the FIFO
222       should have no influence at all on the real select(2). Right now,
223       NAL_CONNECTION_add_to_selector() silently ignores dummy connections
224       completely.
225

EXAMPLES

227       A typical state-machine implementation using a single connection is
228       illustrated here (without error-checking);
229
230           NAL_BUFFER *c_read, *c_send;
231           NAL_SELECTOR *sel = NAL_SELECTOR_new();
232           NAL_CONNECTION *conn = NAL_CONNECTION_new();
233           NAL_ADDRESS *addr = retrieve_the_desired_address();
234
235           /* Setup */
236           NAL_CONNECTION_create(conn, addr);
237           c_read = NAL_CONNECTION_get_read(conn);
238           c_send = NAL_CONNECTION_get_send(conn);
239
240           /* Loop */
241           do {
242               /* This is where the state-machine code should process as much data as
243                * possible from 'c_read' and/or produce as much output to 'c_send' as
244                * it can. */
245               ...
246               ... user code
247               ...
248               /* block on (relevant) network events for 'conn' */
249               NAL_CONNECTION_add_to_selector(conn, sel);
250               NAL_SELECTOR_select(sel, 0, 0);
251               /* Do network I/O after the above blocking select and continue looping
252                * only if the connection is still alive. */
253           } while(NAL_CONNECTION_io(conn, sel));
254
255       An example of using a connection pair (with 2 Kb read and send buffers
256       for each connection) to create IPC between a parent process and its
257       child (again, no error checking);
258
259           NAL_CONNECTION *ipc_to_parent = NAL_CONNECTION_new();
260           NAL_CONNECTION *ipc_to_child = NAL_CONNECTION_new();
261
262           /* Setup */
263           NAL_CONNECTION_create_pair(ipc_to_parent, ipc_to_child, 2048);
264
265           /* Create child process */
266           switch(fork()) {
267               case 0:
268                   /* Inside the child process, close our copy of the parent's side */
269                   NAL_CONNECTION_free(ipc_to_child);
270                   /* Do child process things, and use 'ipc_to_parent' to communicate
271                    * with the parent. */
272                   do_child_logic(ipc_to_parent);
273                   exit(0);
274               default:
275                   /* Inside the parent process, close our copy of the child's side */
276                   NAL_CONNECTION_free(ipc_to_parent);
277                   break;
278           }
279           /* Continue in the parent process, and use 'ipc_to_child' to communicate
280            * with the child. */
281           do_parent_logic(ipc_to_child);
282
283       Note that these connection pairs can also be a useful way of handling
284       process termination that allow you to bypass signal handling alto‐
285       gether. If a child process terminates, the connection between the pair
286       will be broken and so this will be noticed in the parent process by any
287       selector selecting on the ipc_to_child connection - the subsequent
288       NAL_CONNECTION_io() operation will fail indicating that the child
289       process is dead (or in the process of dying) and so the parent could
290       immediately call wait(2) or waitpid(2). Whether the SIGCHLD signal
291       arrives before the NAL_CONNECTION_io() call or not is not too impor‐
292       tant, at worst it might prematurely interrupt NAL_SELECTOR_select()
293       (causing it to return zero) so that a redundant loop of the state-
294       machine runs before the next select operation will notice the discon‐
295       nection. If you already need IPC between the parent and child for
296       exchange of data anyway, this mechanism could be useful in avoiding
297       global variables, signal handlers, and the associated difficulties.
298

SEE ALSO

300       NAL_CONNECTION_new(2) - Functions for the NAL_CONNECTION type.
301
302       NAL_LISTENER_new(2) - Functions for the NAL_LISTENER type.
303
304       NAL_SELECTOR_new(2) - Functions for the NAL_SELECTOR type.
305
306       NAL_BUFFER_new(2) - Functions for the NAL_BUFFER type.
307
308       distcache(8) - Overview of the distcache architecture.
309
310       http://www.distcache.org/ - Distcache home page.
311

AUTHOR

313       This toolkit was designed and implemented by Geoff Thorpe for Crypto‐
314       graphic Appliances Incorporated. Since the project was released into
315       open source, it has a home page and a project environment where devel‐
316       opment, mailing lists, and releases are organised. For problems with
317       the software or this man page please check for new releases at the
318       project web-site below, mail the users mailing list described there, or
319       contact the author at geoff@geoffthorpe.net.
320
321       Home Page: http://www.distcache.org
322
323
324
3251.4.5                             2004.03.23             NAL_CONNECTION_NEW(2)
Impressum