24 #include <libmemcached/memcached.h>
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/rad_assert.h>
30 #include "../../rlm_cache.h"
31 #include "../../serialize.h"
67 memcached_return_t ret;
69 sandle = memcached(driver->
options, talloc_array_length(driver->
options) -1);
71 ERROR(
"rlm_cache_memcached: Failed creating memcached connection");
76 ret = memcached_behavior_set(sandle, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, (uint64_t)
FR_TIMEVAL_TO_MS(timeout));
77 if (ret != MEMCACHED_SUCCESS) {
78 ERROR(
"rlm_cache_memcached: Failed setting connection timeout: %s: %s", memcached_strerror(sandle, ret),
79 memcached_last_error_message(sandle));
81 memcached_free(sandle);
85 ret = memcached_version(sandle);
86 if (ret != MEMCACHED_SUCCESS) {
87 ERROR(
"rlm_cache_memcached: Failed getting server info: %s: %s", memcached_strerror(sandle, ret),
88 memcached_last_error_message(sandle));
105 static bool version_done;
108 memcached_return_t ret;
121 INFO(
"rlm_cache_memcached: libmemcached version: %s", memcached_lib_version());
126 ret = libmemcached_check_configuration(driver->
options, talloc_array_length(driver->
options) -1,
127 buffer,
sizeof(buffer));
128 if (ret != MEMCACHED_SUCCESS) {
129 ERROR(
"rlm_cache_memcached: Failed validating options string: %s", buffer);
133 snprintf(buffer,
sizeof(buffer),
"rlm_cache (%s)", config->
name);
136 if (!driver->
pool)
return -1;
141 ERROR(
"rlm_cache_memcached: max_entries is not supported by this driver");
162 REQUEST *request,
void *handle, uint8_t
const *key,
size_t key_len)
166 memcached_return_t mret;
175 from_store = memcached_get(mandle->
handle, (
char const *)key, key_len, &len, &flags, &mret);
177 if (mret == MEMCACHED_NOTFOUND)
return CACHE_MISS;
179 RERROR(
"Failed retrieving entry: %s: %s", memcached_strerror(mandle->
handle, mret),
180 memcached_last_error_message(mandle->
handle));
184 RDEBUG2(
"Retrieved %zu bytes from memcached", len);
195 c->
key = talloc_memdup(c, key, key_len);
210 memcached_return_t ret;
215 pool = talloc_pool(NULL, 1024);
225 to_store ? to_store :
"",
226 to_store ? talloc_array_length(to_store) - 1 : 0, c->
expires, 0);
228 if (ret != MEMCACHED_SUCCESS) {
229 RERROR(
"Failed storing entry: %s: %s", memcached_strerror(mandle->
handle, ret),
230 memcached_last_error_message(mandle->
handle));
243 REQUEST *request,
void *handle, uint8_t
const *key,
size_t key_len)
247 memcached_return_t ret;
249 ret = memcached_delete(mandle->
handle, (
char const *)key, key_len, 0);
251 case MEMCACHED_SUCCESS:
254 case MEMCACHED_DATA_DOES_NOT_EXIST:
258 RERROR(
"Failed deleting entry: %s", memcached_last_error_message(mandle->
handle));
319 .
name =
"rlm_cache_memcached",
static void cache_entry_free(rlm_cache_entry_t *c)
Locate a cache entry in memcached.
static const CONF_PARSER driver_config[]
int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t const *c)
Serialize a cache entry as a humanly readable string.
static cache_status_t cache_entry_expire(UNUSED rlm_cache_config_t const *config, UNUSED void *driver_inst, REQUEST *request, void *handle, uint8_t const *key, size_t key_len)
Call delete the cache entry from memcached.
#define CONF_PARSER_TERMINATOR
static cache_status_t cache_entry_find(rlm_cache_entry_t **out, UNUSED rlm_cache_config_t const *config, UNUSED void *driver_inst, REQUEST *request, void *handle, uint8_t const *key, size_t key_len)
Locate a cache entry in memcached.
uint32_t max_entries
Maximum entries allowed.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
struct rlm_cache_memcached rlm_cache_memcached_t
static int mod_instantiate(CONF_SECTION *conf, rlm_cache_config_t const *config, void *driver_inst)
Create a new rlm_cache_memcached instance.
Defines a CONF_PAIR to C data type mapping.
size_t key_len
Length of key data.
struct rlm_cache_memcached_handle rlm_cache_memcached_handle_t
char const * options
Connection options.
fr_connection_pool_t * module_connection_pool_init(CONF_SECTION *module, void *opaque, fr_connection_create_t c, fr_connection_alive_t a, char const *prefix)
Initialise a module specific connection pool.
time_t expires
When the entry expires.
static void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
Create a new memcached handle.
static int mod_conn_reconnect(void **handle, UNUSED rlm_cache_config_t const *config, void *driver_inst, UNUSED REQUEST *request)
Reconnect a memcached handle.
static int _mod_conn_free(rlm_cache_memcached_handle_t *mandle)
Free a connection handle.
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
char const * fr_strerror(void)
Get the last library error.
static int mod_conn_get(void **handle, UNUSED rlm_cache_config_t const *config, void *driver_inst, UNUSED REQUEST *request)
Get a memcached handle.
Cache entry found/updated.
#define FR_CONF_OFFSET(_n, _t, _s, _f)
char const * name
Name of xlat function to register.
static void mod_conn_release(UNUSED rlm_cache_config_t const *config, void *driver_inst, UNUSED REQUEST *request, rlm_cache_handle_t *handle)
Release a memcached handle.
fr_connection_pool_t * pool
void * fr_connection_get(fr_connection_pool_t *pool)
Reserve a connection in the connection pool.
int fr_talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link a parent and a child context, so the child is freed before the parent.
#define PW_TYPE_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
void fr_connection_release(fr_connection_pool_t *pool, void *conn)
Release a connection.
#define FR_TIMEVAL_TO_MS(_x)
String of printable characters.
char const * name
Driver name.
static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config, UNUSED void *driver_inst, REQUEST *request, void *handle, const rlm_cache_entry_t *c)
Insert a new entry into the data store.
uint8_t const * key
Key used to identify entry.
void * fr_connection_reconnect(fr_connection_pool_t *pool, void *conn)
Reconnect a suspected inviable connection.
int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
Converts a serialized cache entry back into a structure.
cache_driver_t rlm_cache_memcached
Configuration for the rlm_cache module.