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