1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 #ifndef MEMCACHED_EXTENSION_H 3 #define MEMCACHED_EXTENSION_H 4 5 #ifndef __cplusplus 6 #include <stdbool.h> 7 #endif 8 9 #include <stdint.h> 10 #include <memcached/engine_common.h> 11 #include <memcached/protocol_binary.h> 12 #include <memcached/types.h> 13 #include <memcached/server_api.h> 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /** 20 * \defgroup Extension Generic Extensions API 21 * \addtogroup Extension 22 * @{ 23 * 24 * Definition of the generic extension API to memcached. 25 */ 26 27 /** 28 * Response codes for extension operations. 29 */ 30 typedef enum { 31 /** The command executed successfully */ 32 EXTENSION_SUCCESS = 0x00, 33 /** A fatal error occurred, and the server should shut down as soon 34 * as possible */ 35 EXTENSION_FATAL = 0xfe, 36 /** Generic failure. */ 37 EXTENSION_FAILED = 0xff 38 } EXTENSION_ERROR_CODE; 39 40 typedef enum { 41 /** 42 * A generic extention that don't provide a functionality to the 43 * memcached core, but lives in the memcached address space. 44 */ 45 EXTENSION_DAEMON = 0x00, 46 /** 47 * A log consumer 48 */ 49 EXTENSION_LOGGER, 50 /** 51 * Command extension for the ASCII protocol 52 */ 53 EXTENSION_ASCII_PROTOCOL, 54 /** 55 * Command extension for the binary protocol 56 */ 57 EXTENSION_BINARY_PROTOCOL 58 } extension_type_t; 59 60 /** 61 * Deamon extensions should provide the following descriptor when 62 * they register themselves. 63 */ 64 typedef struct extension_daemon_descriptor { 65 /** 66 * Get the name of the descriptor. The memory area returned by this 67 * function has to be valid until the descriptor is unregistered. 68 */ 69 const char* (*get_name)(void); 70 71 /** 72 * Deamon descriptors are stored in a linked list in the memcached 73 * core by using this pointer. Please do not modify this pointer 74 * by yourself until you have unregistered the descriptor. 75 * The <b>only</b> time it is safe for an extension to walk this 76 * list is during initialization of the modules. 77 */ 78 struct extension_daemon_descriptor *next; 79 } EXTENSION_DAEMON_DESCRIPTOR; 80 81 typedef enum { 82 EXTENSION_LOG_DETAIL, 83 EXTENSION_LOG_DEBUG, 84 EXTENSION_LOG_INFO, 85 EXTENSION_LOG_WARNING 86 } EXTENSION_LOG_LEVEL; 87 88 /** 89 * Log extensions should provide the following rescriptor when 90 * they register themselves. Please note that if you register a log 91 * extension it will <u>replace</u> old one. If you want to be nice to 92 * the user you should allow your logger to be chained. 93 * 94 * Please note that the memcached server will <b>not</b> call the log 95 * function if the verbosity level is too low. This is a perfomance 96 * optimization from the core to avoid potential formatting of output 97 * that may be thrown away. 98 */ 99 typedef struct { 100 /** 101 * Get the name of the descriptor. The memory area returned by this 102 * function has to be valid until the descriptor is unregistered. 103 */ 104 const char* (*get_name)(void); 105 106 /** 107 * Add an entry to the log. 108 * @param severity the severity for this log entry 109 * @param client_cookie the client we're serving (may be NULL if not 110 * known) 111 * @param fmt format string to add to the log 112 */ 113 void (*log)(EXTENSION_LOG_LEVEL severity, 114 const void* client_cookie, 115 const char *fmt, ...); 116 } EXTENSION_LOGGER_DESCRIPTOR; 117 118 typedef struct { 119 EXTENSION_LOGGER_DESCRIPTOR* (*get_logger)(void); 120 EXTENSION_LOG_LEVEL (*get_level)(void); 121 void (*set_level)(EXTENSION_LOG_LEVEL severity); 122 } SERVER_LOG_API; 123 124 typedef struct { 125 char *value; 126 size_t length; 127 } token_t; 128 129 /** 130 * ASCII protocol extensions must provide the following descriptor to 131 * extend the capabilities of the ascii protocol. The memcached core 132 * will probe each command in the order they are registered, so you should 133 * register the most likely command to be used first (or you could register 134 * only one descriptor and do a better dispatch routine inside your own 135 * implementation of accept / execute). 136 */ 137 typedef struct extension_ascii_protocol_descriptor { 138 /** 139 * Get the name of the descriptor. The memory area returned by this 140 * function has to be valid until the descriptor is unregistered. 141 * 142 * @param cmd_cookie cookie registered with the command 143 */ 144 const char* (*get_name)(const void *cmd_cookie); 145 146 /** 147 * Called by the server to determine if the command in argc, argv should 148 * be process by this handler. 149 * 150 * If the command accepts out-of-band data (like add / append / prepend 151 * / replace / set), the command must set the datapointer and ndata 152 * to the number of bytes it want to read (remember to account for 153 * the trailing "\r\n" ;-)) 154 * 155 * If you need extra data, you should copy all of the argc/argv info 156 * you may need to execute the command, because those parameters will 157 * be 0 and NULL when execute is invoked... 158 * 159 * @param cmd_cookie cookie registered with the command 160 * @param cookie identifying the client connection 161 * @param argc the number of arguments 162 * @param argv the argument vector 163 * @param ndata the number of bytes in out-of-band data (OUT) 164 * @param ptr where the core shall write the data (OUT) 165 * @param noreply is this a noreply command or not... 166 * @return true if the command should be handled by this command handler 167 */ 168 bool (*accept)(const void *cmd_cookie, 169 void *cookie, 170 int argc, 171 token_t *argv, 172 size_t *ndata, 173 char **ptr); 174 175 /** 176 * execute the command. 177 * 178 * @param cmd_cookie cookie registered with the command 179 * @param cookie identifying the client connection 180 * @param argc the number of arguments 181 * @param argv the argument vector 182 * @param response_handler callback to add data to the return buffer 183 * @return Error code for the operation 184 */ 185 ENGINE_ERROR_CODE (*execute)(const void *cmd_cookie, 186 const void *cookie, 187 int argc, token_t *argv, 188 ENGINE_ERROR_CODE (*response_handler)(const void *cookie, 189 int nbytes, 190 const char *dta)); 191 192 /** 193 * abort the command. 194 * 195 * @param cmd_cookie cookie registered with the command 196 * @param cookie identifying the client connection 197 */ 198 void (*abort)(const void *cmd_cookie, const void *cookie); 199 200 /** 201 * cookie for the command. This is the cookie passed to accept and 202 * execute, so that you can register the same functions for multiple 203 * commands (but tell them apart during invokations). 204 */ 205 const void *cookie; 206 207 /** 208 * Deamon descriptors are stored in a linked list in the memcached 209 * core by using this pointer. Please do not modify this pointer 210 * by yourself until you have unregistered the descriptor. 211 * The <b>only</b> time it is safe for an extension to walk this 212 * list is during initialization of the modules. 213 */ 214 struct extension_ascii_protocol_descriptor *next; 215 } EXTENSION_ASCII_PROTOCOL_DESCRIPTOR; 216 217 218 typedef struct extension_binary_protocol_descriptor EXTENSION_BINARY_PROTOCOL_DESCRIPTOR; 219 220 typedef ENGINE_ERROR_CODE (*BINARY_COMMAND_CALLBACK)(EXTENSION_BINARY_PROTOCOL_DESCRIPTOR *descriptor, 221 ENGINE_HANDLE* handle, 222 const void* cookie, 223 protocol_binary_request_header *request, 224 ADD_RESPONSE response); 225 226 /** 227 * ASCII protocol extensions must provide the following descriptor to 228 * extend the capabilities of the ascii protocol. The memcached core 229 * will probe each command in the order they are registered, so you should 230 * register the most likely command to be used first (or you could register 231 * only one descriptor and do a better dispatch routine inside your own 232 * implementation of accept / execute). 233 */ 234 struct extension_binary_protocol_descriptor { 235 /** 236 * Get the name of the descriptor. The memory area returned by this 237 * function has to be valid until the descriptor is unregistered. 238 */ 239 const char* (*get_name)(void); 240 241 void (*setup)(void (*add)(EXTENSION_BINARY_PROTOCOL_DESCRIPTOR *descriptor, 242 uint8_t cmd, 243 BINARY_COMMAND_CALLBACK new_handler)); 244 245 /** 246 * Deamon descriptors are stored in a linked list in the memcached 247 * core by using this pointer. Please do not modify this pointer 248 * by yourself until you have unregistered the descriptor. 249 * The <b>only</b> time it is safe for an extension to walk this 250 * list is during initialization of the modules. 251 */ 252 struct extension_binary_protocol_descriptor *next; 253 }; 254 255 /** 256 * The signature for the "memcached_extensions_initialize" function 257 * exported from the loadable module. 258 * 259 * @param config configuration for this extension 260 * @param GET_SERVER_API pointer to a function to get a specific server 261 * API from. server_extension_api contains functions 262 * to register extensions. 263 * @return one of the error codes above. 264 */ 265 typedef EXTENSION_ERROR_CODE (*MEMCACHED_EXTENSIONS_INITIALIZE)(const char *config, GET_SERVER_API get_server_api); 266 267 268 /** 269 * The API provided by the server to manipulate the list of server 270 * server extensions. 271 */ 272 typedef struct { 273 /** 274 * Register an extension 275 * 276 * @param type The type of extension to register (ex: daemon, logger etc) 277 * @param extension The extension to register 278 * @return true if success, false otherwise 279 */ 280 bool (*register_extension)(extension_type_t type, void *extension); 281 282 /** 283 * Unregister an extension 284 * 285 * @param type The type of extension to unregister 286 * @param extension The extension to unregister 287 */ 288 void (*unregister_extension)(extension_type_t type, void *extension); 289 290 /** 291 * Get the registered extension for a certain type. This is useful 292 * if you would like to replace one of the handlers with your own 293 * extension to proxy functionality. 294 * 295 * @param type The type of extension to get 296 * @param extension Pointer to the registered event. Please note that 297 * if the extension allows for multiple instances of the 298 * extension there will be a "next" pointer inside the element 299 * that can be used for object traversal. 300 */ 301 void *(*get_extension)(extension_type_t type); 302 } SERVER_EXTENSION_API; 303 304 /** 305 * @} 306 */ 307 308 #ifdef __cplusplus 309 } 310 #endif 311 312 #endif 313