1 /* distcache, Distributed Session Caching technology
2  * Copyright (C) 2000-2003  Geoff Thorpe, and Cryptographic Appliances, Inc.
3  * Copyright (C) 2004       The Distcache.org project
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; using version 2.1 of the License. The copyright holders
8  * may elect to allow the application of later versions of the License to this
9  * software, please contact the author (geoff@distcache.org) if you wish us to
10  * review any later version released by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #ifndef HEADER_LIBNAL_NAL_DEVEL_H
22 #define HEADER_LIBNAL_NAL_DEVEL_H
23 
24 #ifndef HEADER_LIBNAL_NAL_H
25 	#error "Must include libnal/nal.h prior to libnal/nal_devel.h"
26 #endif
27 
28 /* Predeclare our vtable types */
29 typedef struct st_NAL_ADDRESS_vtable NAL_ADDRESS_vtable;
30 typedef struct st_NAL_LISTENER_vtable NAL_LISTENER_vtable;
31 typedef struct st_NAL_CONNECTION_vtable NAL_CONNECTION_vtable;
32 typedef struct st_NAL_SELECTOR_vtable NAL_SELECTOR_vtable;
33 
34 /* selectors implement their own storage of the listener and connection
35  * registries. To allow them to avoid doing searches on every loop operation,
36  * we let them tag connections/listeners with an opaque 'token' value when
37  * adding objects. This makes it easier for these objects to interact without
38  * lookups. (NB, the struct is just to improve type-safety.) */
39 typedef struct { int foo; } *NAL_SELECTOR_TOKEN;
40 #define NAL_SELECTOR_TOKEN_NULL	(NAL_SELECTOR_TOKEN)NULL
41 
42 /* Notes about vtables:
43  * on_create() - [COMPULSORY]
44  *   Called during assignment of the vtable to an object. If this is an object
45  *   being reused with the same vtable, the vtdata will be that left by the
46  *   on_reset() call, otherwise it will be zeroed.
47  * on_destroy() - [COMPULSORY]
48  *   Called to cleanup vtdata before unmapping a vtable from an object. It
49  *   should clean up all resources as there will be no other (guaranteed)
50  *   opportunity to touch the vtdata after this call.
51  * on_reset() - [COMPULSORY]
52  *   Called to reset an object for future use. This can be used, for example,
53  *   to "close" resources without deallocating them. The implementation will
54  *   next have its on_create() handler called (if the object is reused with the
55  *   same vtable) or on_destroy() handler called (if the object is being
56  *   destroyed or used with a different vtable).
57  * pre_close() - [OPTIONAL]
58  *   Called prior to a _reset or _destroy operation. By the time an on_destroy()
59  *   or on_reset() handler is called, the destruction process is already
60  *   underway and any data that is the domain of the framework (rather than
61  *   the vtable) may have already been cleaned up.
62  */
63 
64 /***************/
65 /* NAL_ADDRESS */
66 /***************/
67 
68 struct st_NAL_ADDRESS_vtable {
69 	/* As we have a global list of available types, this gives namespace */
70 	const char *unique_name;
71 	/* The size of "vtdata" the NAL_ADDRESS should provide */
72 	size_t vtdata_size;
73 	/* NULL-terminated array of string prefixes that correspond to this
74 	 * vtable. Should include trailing colon. */
75 	const char **prefixes;
76 	/* (De)Initialisations */
77 	int (*on_create)(NAL_ADDRESS *addr);
78 	void (*on_destroy)(NAL_ADDRESS *addr);
79 	void (*on_reset)(NAL_ADDRESS *addr);
80 	void (*pre_close)(NAL_ADDRESS *addr);
81 	/* Handlers for NAL_ADDRESS functionality */
82 	int (*parse)(NAL_ADDRESS *addr, const char *addr_string);
83 	int (*can_connect)(const NAL_ADDRESS *addr);
84 	int (*can_listen)(const NAL_ADDRESS *addr);
85 	const NAL_LISTENER_vtable *(*create_listener)(const NAL_ADDRESS *addr);
86 	const NAL_CONNECTION_vtable *(*create_connection)(const NAL_ADDRESS *addr);
87 	struct st_NAL_ADDRESS_vtable *next;
88 };
89 int nal_address_set_vtable(NAL_ADDRESS *addr, const NAL_ADDRESS_vtable *vt);
90 const NAL_ADDRESS_vtable *nal_address_get_vtable(const NAL_ADDRESS *addr);
91 void *nal_address_get_vtdata(const NAL_ADDRESS *addr);
92 const NAL_LISTENER_vtable *nal_address_get_listener(const NAL_ADDRESS *addr);
93 const NAL_CONNECTION_vtable *nal_address_get_connection(const NAL_ADDRESS *addr);
94 
95 /****************/
96 /* NAL_LISTENER */
97 /****************/
98 
99 struct st_NAL_LISTENER_vtable {
100 	/* The size of "vtdata" the NAL_LISTENER should provide */
101 	size_t vtdata_size;
102 	/* (De)Initialisations */
103 	int (*on_create)(NAL_LISTENER *);
104 	void (*on_destroy)(NAL_LISTENER *);
105 	void (*on_reset)(NAL_LISTENER *);
106 	void (*pre_close)(NAL_LISTENER *);
107 	/* Handlers for NAL_LISTENER functionality */
108 	int (*listen)(NAL_LISTENER *, const NAL_ADDRESS *);
109 	const NAL_CONNECTION_vtable *(*pre_accept)(NAL_LISTENER *);
110 	int (*finished)(const NAL_LISTENER *);
111 	/* Called before/after (un)binding (from/)to a selector */
112 	int (*pre_selector_add)(NAL_LISTENER *, NAL_SELECTOR *);
113 	int (*post_selector_add)(NAL_LISTENER *, NAL_SELECTOR *,
114 				NAL_SELECTOR_TOKEN);
115 	void (*pre_selector_del)(NAL_LISTENER *, NAL_SELECTOR *,
116 				NAL_SELECTOR_TOKEN);
117 	void (*post_selector_del)(NAL_LISTENER *, NAL_SELECTOR *);
118 	/* Called before/after a select */
119 	void (*pre_select)(NAL_LISTENER *, NAL_SELECTOR *, NAL_SELECTOR_TOKEN);
120 	void (*post_select)(NAL_LISTENER *, NAL_SELECTOR *, NAL_SELECTOR_TOKEN);
121 	/* Extensions that may not be meaningful, case-by-case */
122 	int (*set_fs_owner)(NAL_LISTENER *, const char *ownername,
123 				const char *groupname);
124 	int (*set_fs_perms)(NAL_LISTENER *, const char *octal_string);
125 };
126 int nal_listener_set_vtable(NAL_LISTENER *, const NAL_LISTENER_vtable *);
127 const NAL_LISTENER_vtable *nal_listener_get_vtable(const NAL_LISTENER *);
128 void *nal_listener_get_vtdata(const NAL_LISTENER *);
129 const NAL_CONNECTION_vtable *nal_listener_pre_accept(NAL_LISTENER *);
130 void nal_listener_pre_select(NAL_LISTENER *);
131 void nal_listener_post_select(NAL_LISTENER *);
132 NAL_SELECTOR *nal_listener_get_selector(const NAL_LISTENER *,
133 					NAL_SELECTOR_TOKEN *);
134 void nal_listener_set_selector_raw(NAL_LISTENER *, NAL_SELECTOR *,
135 					NAL_SELECTOR_TOKEN);
136 
137 /******************/
138 /* NAL_CONNECTION */
139 /******************/
140 
141 struct st_NAL_CONNECTION_vtable {
142 	/* The size of "vtdata" the NAL_CONNECTION should provide */
143 	size_t vtdata_size;
144 	/* (De)Initialisations */
145 	int (*on_create)(NAL_CONNECTION *);
146 	void (*on_destroy)(NAL_CONNECTION *);
147 	void (*on_reset)(NAL_CONNECTION *);
148 	void (*pre_close)(NAL_CONNECTION *);
149 	/* after NAL_ADDRESS_vtable->create_connection() */
150 	int (*connect)(NAL_CONNECTION *, const NAL_ADDRESS *);
151 	/* after NAL_LISTENER_vtable->pre_accept() */
152 	int (*accept)(NAL_CONNECTION *, const NAL_LISTENER *);
153 	/* Handlers for NAL_CONNECTION functionality */
154 	int (*set_size)(NAL_CONNECTION *, unsigned int);
155 	NAL_BUFFER *(*get_read)(const NAL_CONNECTION *);
156 	NAL_BUFFER *(*get_send)(const NAL_CONNECTION *);
157 	int (*is_established)(const NAL_CONNECTION *);
158 	/* Called before/after (un)binding (from/)to a selector */
159 	int (*pre_selector_add)(NAL_CONNECTION *, NAL_SELECTOR *);
160 	int (*post_selector_add)(NAL_CONNECTION *, NAL_SELECTOR *,
161 				NAL_SELECTOR_TOKEN);
162 	void (*pre_selector_del)(NAL_CONNECTION *, NAL_SELECTOR *,
163 				NAL_SELECTOR_TOKEN);
164 	void (*post_selector_del)(NAL_CONNECTION *, NAL_SELECTOR *);
165 	/* Called before/after a 'select', depending on the selector model.
166 	 * 'pre_select' allows the connection to register specific events if
167 	 * appropriate (eg. this would apply for a select/poll-style selector
168 	 * but (perhaps) not for a win32 messagepump mode). 'post_select' can
169 	 * be called 0, 1, or many times to allow the connection to
170 	 * collect/send data. */
171 	void (*pre_select)(NAL_CONNECTION *, NAL_SELECTOR *, NAL_SELECTOR_TOKEN);
172 	void (*post_select)(NAL_CONNECTION *, NAL_SELECTOR *, NAL_SELECTOR_TOKEN);
173 	/* Expose results of 'post_select' I/O and/or do post-processing. This
174 	 * is the hook from the caller's NAL_CONNECTION_io() API, whereas the
175 	 * 'pre_select' and 'post_select' handlers are internal to the blocking
176 	 * NAL_SELECTOR_select() logic. */
177 	int (*do_io)(NAL_CONNECTION *);
178 };
179 int nal_connection_set_vtable(NAL_CONNECTION *, const NAL_CONNECTION_vtable *);
180 const NAL_CONNECTION_vtable *nal_connection_get_vtable(const NAL_CONNECTION *);
181 void *nal_connection_get_vtdata(const NAL_CONNECTION *);
182 void nal_connection_pre_select(NAL_CONNECTION *);
183 void nal_connection_post_select(NAL_CONNECTION *);
184 NAL_SELECTOR *nal_connection_get_selector(const NAL_CONNECTION *,
185 					NAL_SELECTOR_TOKEN *);
186 void nal_connection_set_selector_raw(NAL_CONNECTION *, NAL_SELECTOR *,
187 					NAL_SELECTOR_TOKEN);
188 
189 /***************************/
190 /* Builtin address vtables */
191 /***************************/
192 
193 /* Returns the (linked-list of) address types currently available. */
194 const NAL_ADDRESS_vtable *NAL_ADDRESS_vtable_builtins(void);
195 /* Links in one or more new address types making them immediately available. */
196 void NAL_ADDRESS_vtable_link(NAL_ADDRESS_vtable *vt);
197 
198 /****************/
199 /* NAL_SELECTOR */
200 /****************/
201 
202 /* vtables */
203 const NAL_SELECTOR_vtable *sel_fdselect(void);
204 const NAL_SELECTOR_vtable *sel_fdpoll(void);
205 
206 /* The "type" of a selector */
207 typedef enum {
208 	/* Invalid/uninitialised place-holder */
209 	NAL_SELECTOR_TYPE_ERROR = 0,
210 	/* Intermediaire, listeners/conns can set it on first-use */
211 	NAL_SELECTOR_TYPE_DYNAMIC,
212 	/* Standard BSD(4.4) select */
213 	NAL_SELECTOR_TYPE_FDSELECT,
214 	/* poll(2) */
215 	NAL_SELECTOR_TYPE_FDPOLL,
216 	/* Custom implementation types start here */
217 	NAL_SELECTOR_TYPE_CUSTOM = 100
218 } NAL_SELECTOR_TYPE;
219 
220 /* general-purpose "ctrl" commands are scoped as follows */
221 typedef enum {
222 	/* Control commands specific to fdselect and fdpoll start here */
223 	NAL_SELECTOR_CTRL_FD = 0x0100,
224 	/* Custom commands start here */
225 	NAL_SELECTOR_CTRL_CUSTOM = 0x0800
226 } NAL_SELECTOR_CTRL_TYPE;
227 
228 struct st_NAL_SELECTOR_vtable {
229 	/* The size of "vtdata" the NAL_SELECTOR should provide */
230 	size_t vtdata_size;
231 	/* (De)Initialisations */
232 	int (*on_create)(NAL_SELECTOR *);
233 	void (*on_destroy)(NAL_SELECTOR *);
234 	void (*on_reset)(NAL_SELECTOR *);
235 	void (*pre_close)(NAL_SELECTOR *);
236 	/* Handlers for NAL_SELECTOR functionality */
237 	NAL_SELECTOR_TYPE (*get_type)(const NAL_SELECTOR *);
238 	int (*select)(NAL_SELECTOR *, unsigned long usec_timeout, int use_timeout);
239 	unsigned int (*num_objects)(const NAL_SELECTOR *);
240 	NAL_SELECTOR_TOKEN (*add_listener)(NAL_SELECTOR *, NAL_LISTENER *);
241 	NAL_SELECTOR_TOKEN (*add_connection)(NAL_SELECTOR *, NAL_CONNECTION *);
242 	void (*del_listener)(NAL_SELECTOR *, NAL_LISTENER *, NAL_SELECTOR_TOKEN);
243 	void (*del_connection)(NAL_SELECTOR *, NAL_CONNECTION *, NAL_SELECTOR_TOKEN);
244 	/* General purpose hook for implementation-specifics. Returns zero if
245 	 * the integer (command) parameter is not understood. Other "return"
246 	 * information should be handled in the opaque void* reference. */
247 	int (*ctrl)(NAL_SELECTOR *, int, void *);
248 };
249 /* used from NAL_SELECTOR API */
250 NAL_SELECTOR *nal_selector_new(const NAL_SELECTOR_vtable *);
251 const NAL_SELECTOR_vtable *nal_selector_get_vtable(const NAL_SELECTOR *);
252 void *nal_selector_get_vtdata(const NAL_SELECTOR *);
253 /* used from inside NAL_CONNECTION/NAL_LISTENER implementations */
254 NAL_SELECTOR_TYPE nal_selector_get_type(const NAL_SELECTOR *);
255 int nal_selector_ctrl(NAL_SELECTOR *, int, void *);
256 int nal_selector_dynamic_set(NAL_SELECTOR *, const NAL_SELECTOR_vtable *);
257 
258 #endif /* !defined(HEADER_LIBNAL_NAL_DEVEL_H) */
259