1NAL_LISTENER_NEW(2)                distcache               NAL_LISTENER_NEW(2)
2
3
4

NAME

6       NAL_LISTENER_new, NAL_LISTENER_free, NAL_LISTENER_create - libnal lis‐
7       tener functions
8

SYNOPSIS

10        #include <libnal/nal.h>
11
12        NAL_LISTENER *NAL_LISTENER_new(void);
13        void NAL_LISTENER_free(NAL_LISTENER *list);
14        void NAL_LISTENER_reset(NAL_LISTENER *list);
15        int NAL_LISTENER_create(NAL_LISTENER *list, const NAL_ADDRESS *addr);
16        void NAL_LISTENER_add_to_selector(const NAL_LISTENER *list,
17                                          NAL_SELECTOR *sel);
18        void NAL_LISTENER_del_from_selector(const NAL_LISTENER *list,
19                                            NAL_SELECTOR *sel);
20
21        int NAL_LISTENER_set_fs_owner(NAL_LISTENER *list,
22                                      const char *ownername,
23                                      const char *groupname);
24        int NAL_LISTENER_set_fs_perms(NAL_LISTENER *list,
25                                      const char *octal_string);
26

DESCRIPTION

28       NAL_LISTENER_new() allocates and initialises a new NAL_LISTENER object.
29
30       NAL_LISTENER_free() destroys a NAL_LISTENER object.
31
32       NAL_LISTENER_reset() will, if necessary, cleanup any prior state in
33       list so that it can be reused in NAL_LISTENER_create(). Internally,
34       there are other optimisations and benefits to using NAL_LIS‐
35       TENER_reset() instead of NAL_LISTENER_free() and NAL_LISTENER_new() -
36       the implementation can try to avoid repeated reallocation and reini‐
37       tialisation of state, only doing full cleanup and reinitialisation when
38       necessary.
39
40       NAL_LISTENER_create() will attempt to create and bind a listener to the
41       address represented by addr. Semantics of how this binding works with
42       respect to exclusion of other listeners depends on the transport and
43       host system.  Generally, libnal should follow the standard behaviour of
44       the underlying system.
45
46       NAL_LISTENER_add_to_selector() registers list with the selector sel for
47       any events relevant to it. NAL_LISTENER_del_from_selector() can be used
48       to reverse this if called before any subsequent call to NAL_SELEC‐
49       TOR_select().
50
51       NAL_LISTENER_set_fs_owner() and NAL_LISTENER_set_fs_perms() will only
52       have meaning to listener objects created for address types that use the
53       file-system (unix domain sockets). If ownername is non-NULL, the owner
54       of the socket file is changed to the supplied user name. If groupname
55       is non-NULL, the group of the socket file is changed to the supplied
56       group name, and otherwise the group may be changed to the default group
57       of the user ownername.  octal_string is a base-8 number in string form
58       specifying the permission flags to apply to the socket file, such as
59       "660" for example.
60

RETURN VALUES

62       NAL_LISTENER_new() returns a valid NAL_LISTENER object on success, NULL
63       otherwise.
64
65       NAL_LISTENER_free(), NAL_LISTENER_reset(), NAL_LISTENER_add_to_selec‐
66       tor(), and NAL_LISTENER_del_from_selector() have no return value.
67
68       All other NAL_LISTENER functions return zero for failure, and non-zero
69       for success.
70

EXAMPLES

72       A typical state-machine implementation that processes up to 10 connec‐
73       tions at a time from a listener is illustrated here (without
74       error-checking);
75
76           NAL_CONNECTION *conn[10];
77           int loop, conns_used = 0;
78           NAL_SELECTOR *sel = NAL_SELECTOR_new();
79           NAL_LISTENER *list = NAL_LISTENER_new();
80           NAL_ADDRESS *addr = retrieve_the_desired_address();
81
82           /* Setup */
83           list = NAL_LISTENER_create(list, addr);
84           conn[0] = NAL_CONNECTION_new();
85           ...
86           conn[9] = NAL_CONNECTION_new();
87
88        loop:
89           /* select for active connections and 'list' if we aren't full */
90           if(conns_used < 10) NAL_LISTENER_add_to_selector(list, sel);
91           for(loop = 0; loop < conns_used; loop++)
92               NAL_CONNECTION_add_to_selector(conn[loop], sel);
93           /* block on (relevant) network events */
94           NAL_SELECTOR_select(sel);
95           /* process active connections */
96           for(loop = 0; loop < conns_used; loop++) {
97               if(!NAL_CONNECTION_io(conn[loop], sel)) {
98        user_disconnect:
99                   /* connection broken */
100                   NAL_CONNECTION_free(conn[loop]);
101                   /* shift the array left (if necessary) */
102                   if(loop < --conns_used)
103                       memmove(conn + loop, conn + (loop + 1),
104                           (conns_used - loop) * sizeof(NAL_CONNECTION *));
105                   /* Recreate the empty connection slot */
106                   conn[conns_used] = NAL_CONNECTION_new();
107                   /* loop shouldn't be incremented in this case */
108                   loop--;
109               } else {
110                   /* Do any logic required here using the connection's buffers and
111                    * disconnect if desired. */
112                   if(!do_user_logic(conn[loop]))
113                       goto user_disconnect;
114               }
115           }
116           /* process incoming connections */
117           if(NAL_CONNECTION_accept(conns[conns_used], list, sel))
118               conns_used++;
119           /* End of loop */
120           goto loop;
121
122       The complication in the above example is mostly associated with main‐
123       taining the array of allocated NAL_CONNECTION objects, and keeping the
124       active ones left-aligned in the array. A simpler example follows where
125       it is assumed do_connection() is some function that will take a
126       NAL_CONNECTION object, start a new thread for processing it, and clean
127       up the connection object when finishing;
128
129           NAL_CONNECTION *conn = NULL;
130           NAL_SELECTOR *sel = NAL_SELECTOR_new();
131           NAL_LISTENER *list = NAL_LISTENER_new();
132           NAL_ADDRESS *addr = retrieve_the_desired_address();
133
134           /* Setup */
135           list = NAL_LISTENER_create(list, addr);
136
137           while(1) {
138               if(!conn) conn = NAL_CONNECTION_new();
139               NAL_LISTENER_add_to_selector(list, sel);
140               NAL_SELECTOR_select(sel);
141               if(NAL_CONNECTION_accept(list, sel, conn)) {
142                   /* start worker thread for 'conn' */
143                   do_connection(conn);
144                   /* 'conn' is used, ensure a new one is created */
145                   conn = NULL;
146               }
147           }
148

SEE ALSO

150       NAL_ADDRESS_new(2) - Functions for the NAL_ADDRESS type.
151
152       NAL_CONNECTION_new(2) - Functions for the NAL_CONNECTION type.
153
154       NAL_SELECTOR_new(2) - Functions for the NAL_SELECTOR type.
155
156       NAL_BUFFER_new(2) - Functions for the NAL_BUFFER type.
157
158       distcache(8) - Overview of the distcache architecture.
159
160       http://www.distcache.org/ - Distcache home page.
161

AUTHOR

163       This toolkit was designed and implemented by Geoff Thorpe for Crypto‐
164       graphic Appliances Incorporated. Since the project was released into
165       open source, it has a home page and a project environment where devel‐
166       opment, mailing lists, and releases are organised. For problems with
167       the software or this man page please check for new releases at the
168       project web-site below, mail the users mailing list described there, or
169       contact the author at geoff@geoffthorpe.net.
170
171       Home Page: http://www.distcache.org
172
173
174
1751.4.5                             2004.03.23               NAL_LISTENER_NEW(2)
Impressum