25RCSID(
"$Id: 06851b77d75d9812802e3fff61bf1945d12f1f96 $")
27#define LOG_PREFIX mctx->mi->name
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/server/module_rlm.h>
31#include <freeradius-devel/server/modpriv.h>
32#include <freeradius-devel/util/debug.h>
33#include <freeradius-devel/util/types.h>
34#include <freeradius-devel/unlang/xlat_func.h>
58 fr_value_box_list_t
key;
150 if (
unlikely((ret = func(ctx, &key_tmpl, t_rules, ci, cec, rule)) < 0))
return ret;
157 if (
inst->driver->key_parse)
return 0;
167 cf_log_err(ci,
"Driver only allows key type '%s', got '%s'",
173 cf_log_perr(ci,
"Can't convert key type '%s' to '%s'",
189 rctx->
rctx = driver_rctx;
203 if (!
inst->driver->acquire) {
208 return inst->driver->acquire(
out, &
inst->config,
inst->driver_submodule->data, request);
216 if (!
inst->driver->release)
return;
217 if (!handle || !*handle)
return;
219 inst->driver->release(&
inst->config,
inst->driver_submodule->data, request, *handle);
230 return inst->driver->reconnect(handle, &
inst->config,
inst->driver_submodule->data, request);
243 if (
inst->driver->alloc)
return inst->driver->alloc(&
inst->config,
inst->driver_submodule->data, request);
264 if (!c || !*c || !
inst->driver->free)
return;
266 inst->driver->free(*c);
283 RDEBUG2(
"Merging cache entry into request");
285 while ((map = map_list_next(&c->
maps, map))) {
305 if (
inst->config.stats) {
331 RDEBUG2(
"Found entry for \"%pV\", but it expired %pV ago at %pV (packet received %pV). Removing it",
349 RDEBUG2(
"Found entry for \"%pV\", but it was created before the current epoch. Removing it",
353 RDEBUG2(
"Found entry for \"%pV\"", key);
371 ret =
inst->driver->find_resume(&c, &
inst->config,
inst->driver_submodule->data, request, *handle, rctx);
377 RDEBUG2(
"No cache entry found for \"%pV\"", key);
395 if (!
inst->driver->find_cancel)
return;
397 inst->driver->find_cancel(&
inst->config,
inst->driver_submodule->data, request, rctx->
handle, rctx->
rctx);
419 ret =
inst->driver->find(&c, out_rctx, &
inst->config,
inst->driver_submodule->data, request, *handle, key);
430 RDEBUG2(
"No cache entry found for \"%pV\"", key);
454 ret =
inst->driver->expire_resume(&
inst->config,
inst->driver_submodule->data, request, handle, rctx);
475 if (!
inst->driver->expire_cancel)
return;
477 inst->driver->expire_cancel(&
inst->config,
inst->driver_submodule->data, request, rctx->
handle, rctx->
rctx);
492 RDEBUG2(
"Expiring cache entry");
493 for (;;)
switch (
inst->driver->expire(rctx_out, &
inst->config,
inst->driver_submodule->data, request, *handle, key)) {
520 ret =
inst->driver->insert_resume(&c, &
inst->config,
inst->driver_submodule->data, request, *handle, rctx);
542 if (!
inst->driver->insert_cancel)
return;
544 inst->driver->insert_cancel(&
inst->config,
inst->driver_submodule->data, request, rctx->
handle, rctx->
rctx);
558 map_t const *map = NULL;
567 if ((
inst->config.max_entries > 0) &&
inst->driver->count &&
568 (
inst->driver->count(&
inst->config,
inst->driver_submodule->data, request, *handle) >
inst->config.max_entries)) {
569 RWDEBUG(
"Cache is full: %d entries",
inst->config.max_entries);
577 map_list_init(&c->
maps);
579 RERROR(
"Failed copying key");
590 RDEBUG2(
"Creating new cache entry");
596 if (!maps)
goto skip_maps;
602 pool = talloc_pool(NULL, 2048);
603 while ((map = map_list_next(maps, map))) {
613 if (
map_to_vp(pool, &to_cache, request, map, NULL) < 0) {
627 case FR_CACHE_STATUS_ONLY:
628 case FR_CACHE_MERGE_NEW:
629 case FR_CACHE_ENTRY_HITS:
642 map_list_init(&c_map->
child);
647 switch (map->
lhs->type) {
676 REDEBUG(
"Failed copying attribute value");
688 map_list_insert_tail(&c->
maps, c_map);
690 talloc_free_children(pool);
700 if (
vp &&
vp->vp_bool) merge =
true;
707 ret =
inst->driver->insert(out_rctx, &
inst->config,
inst->driver_submodule->data, request, *handle, c);
731 if (!
inst->driver->set_ttl) {
734 ret =
inst->driver->insert_resume(&c, &
inst->config,
inst->driver_submodule->data, request, handle, rctx);
761 if (
inst->driver->set_ttl)
return;
762 if (!
inst->driver->insert_cancel)
return;
764 inst->driver->insert_cancel(&
inst->config,
inst->driver_submodule->data, request, rctx->
handle, rctx->
rctx);
780 if (!
inst->driver->set_ttl)
for (;;) {
783 ret =
inst->driver->insert(out_rctx, &
inst->config,
inst->driver_submodule->data, request, *handle, c);
808 ret =
inst->driver->set_ttl(&
inst->config,
inst->driver_submodule->data, request, *handle, c);
828#define FIXUP_KEY(_fail, _invalid) \
829if ((fr_value_box_list_num_elements(&env->key) > 1) && \
830 (fr_value_box_list_concat_in_place(key, key, &env->key, FR_TYPE_STRING, \
831 FR_VALUE_BOX_LIST_FREE, true, SIZE_MAX) < 0)) { \
832 REDEBUG("Failed concatenating values to form the key"); \
835if (fr_type_is_variable_size(key->type) && (key->vb_length == 0)) { \
836 REDEBUG("Zero length key string is invalid"); \
865 switch (
vp->
da->attr) {
867 case FR_CACHE_STATUS_ONLY:
868 case FR_CACHE_ALLOW_MERGE:
869 case FR_CACHE_ALLOW_INSERT:
870 case FR_CACHE_MERGE_NEW:
887 switch (tmp->
rcode) {
927 switch (tmp->
rcode) {
1012 switch (tmp->
rcode) {
1060 switch (tmp->
rcode) {
1152 switch (p_result->
rcode) {
1204 void *driver_rctx = NULL;
1223 if (
vp &&
vp->vp_bool) {
1262 if (
vp->vp_int32 == 0) {
1264 }
else if (
vp->vp_int32 < 0) {
1299 &(
cache_rctx_t){.uctx = ctx, .ttl = ttl, .entry = entry});
1314 switch (result->
rcode) {
1329 while ((map = map_list_next(&c->
maps, map))) {
1335 RPEDEBUG(
"Failed copying value from cache entry");
1387 void *driver_rctx = NULL;
1407 .dict_def = request->local_dict,
1408 .list_def = request_attr_request,
1428 .rctx = driver_rctx,
1444 switch (result->
rcode) {
1485 void *driver_rctx = NULL;
1506 .rctx = driver_rctx,
1538 switch (
vp->
da->attr) {
1540 case FR_CACHE_STATUS_ONLY:
1541 case FR_CACHE_ALLOW_MERGE:
1542 case FR_CACHE_ALLOW_INSERT:
1543 case FR_CACHE_MERGE_NEW:
1600 void *driver_rctx = NULL;
1629 RDEBUG2(
"Entry not found to load");
1753 bool expire =
false;
1760 ttl =
inst->config.ttl;
1763 if (
vp->vp_int32 == 0) {
1769 }
else if (
vp->vp_int32 < 0) {
1793 RDEBUG3(
"Expiring cache entry");
1872 void *driver_rctx = NULL;
1905 switch (p_result->
rcode) {
1920 ttl =
inst->config.ttl;
1922 if (
vp && (
vp->vp_int32 > 0)) {
1973 void *driver_rctx = NULL;
2020 REDEBUG2(
"Entry not found to delete");
2066 void *driver_rctx = NULL;
2117 ttl =
inst->config.ttl;
2120 if (
vp->vp_int32 < 0) {
2175 void *driver_rctx = NULL;
2217 talloc_free_children(
inst);
2230 cf_log_err(map->
ci,
"Destination must be an attribute ref or a list");
2253 MEM(maps = talloc(parsed, map_list_t));
2254 map_list_init(maps);
2263 if (map_list_empty(maps)) {
2264 cf_log_err(update,
"Update section must not be empty");
2294 if (
inst->config.epoch != 0) {
2295 cf_log_err(
conf,
"Must not set 'epoch' in the configuration files");
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
static int const char char buffer[256]
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
void call_env_parsed_free(call_env_parsed_head_t *parsed, call_env_parsed_t *ptr)
Remove a call_env_parsed_t from the list of parsed call envs.
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
int call_env_parse_pair(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED call_env_ctx_t const *cec, call_env_parser_t const *rule)
Standard function we use for parsing call env pairs.
#define CALL_ENV_TERMINATOR
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
call_env_parser_t const * env
Parsing rules for call method env.
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
module_instance_t const * mi
Module instance that the callenv is registered to.
#define FR_CALL_ENV_SUBSECTION_FUNC(_name, _name2, _flags, _func)
Specify a call_env_parser_t which parses a subsection using a callback function.
int(* call_env_parse_pair_t)(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_PAIR.
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
#define CONF_PARSER_TERMINATOR
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_perr(_cf, _fmt,...)
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
static bool fr_dict_attr_is_top_level(fr_dict_attr_t const *da)
Return true if this attribute is parented directly off the dictionary root.
#define DICT_AUTOLOAD_TERMINATOR
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static xlat_action_t cache_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Allow single attribute values to be retrieved from the cache.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RPEDEBUG(fmt,...)
#define REDEBUG2(fmt,...)
#define RINDENT()
Indent R* messages by one level.
int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, UNUSED void *uctx)
Convert a map to a fr_pair_t.
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION const *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert map_t to fr_pair_t (s) and add them to a request_t.
ssize_t map_print(fr_sbuff_t *out, map_t const *map)
Print a map to a string.
void map_debug_log(request_t *request, map_t const *map, fr_pair_t const *vp)
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_BOOL
A truth value.
static bool is_printable(void const *value, size_t len)
Check whether the string is made up of printable UTF8 chars.
int unlang_fixup_update(map_t *map, void *ctx)
Validate and fixup a map that's part of an update section.
void * env_data
Per call environment data.
module_instance_t const * mi
Instance of the module being instantiated.
void * rctx
Resume ctx that a module previously set.
module_instance_t * mi
Module instance to detach.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for detach calls.
Temporary structure to hold arguments for instantiation calls.
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
int module_rlm_submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic conf_parser_t func for loading drivers.
module_t common
Common fields presented by all modules.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
static const conf_parser_t config[]
#define pair_update_request(_attr, _da)
#define RDEBUG_ENABLED2()
#define RETURN_UNLANG_INVALID
#define RETURN_UNLANG_RCODE(_rcode)
#define RETURN_UNLANG_NOTFOUND
#define RETURN_UNLANG_FAIL
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
#define RETURN_UNLANG_NOOP
static int cache_acquire(rlm_cache_handle_t **out, rlm_cache_t const *inst, request_t *request)
Get exclusive use of a handle to access the cache.
fr_value_box_list_t key
To lookup the cache entry with.
static int mod_cache_it_merge_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, NDEBUG_UNUSED rlm_cache_handle_t *handle, cache_it_ctx_t *ctx, rlm_cache_entry_t *c)
static unlang_action_t mod_method_clear_find_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, fr_value_box_t const *key, rlm_cache_entry_t *entry)
Common result handdling after clear method does a find.
static unlang_action_t mod_method_update_find_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, cache_call_env_t *env, rlm_cache_entry_t *entry)
Common result handdling after update method does a find.
static int mod_cache_it_find_results(unlang_result_t *p_result, unlang_result_t *tmp, NDEBUG_UNUSED rlm_cache_t const *inst, NDEBUG_UNUSED rlm_cache_handle_t *handle, cache_it_ctx_t *ctx)
static int mod_detach(module_detach_ctx_t const *mctx)
Free any memory allocated under the instance.
static xlat_action_t cache_xlat_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
static unlang_action_t cache_expire(unlang_result_t *p_result, void **rctx_out, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, fr_value_box_t const *key)
Expire a cache entry (removing it from the datastore)
static fr_dict_attr_t const * attr_cache_allow_merge
static int cache_key_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
static unlang_action_t mod_method_store(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Create a cache entry if it does not already exist.
static int cache_update_section_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
void * uctx
Module method context.
static unlang_action_t mod_cache_it_insert_results(unlang_result_t *p_result, unlang_result_t *tmp, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *c)
void * rctx
Driver resume context.
static unlang_action_t mod_method_status(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Get the status by ${key} (without load)
static unlang_action_t mod_method_ttl_find_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *entry)
Common result handling after ttl method does a find.
static fr_dict_attr_t const * attr_cache_ttl
static unlang_action_t cache_module_yield(request_t *request, rlm_cache_handle_t *handle, fr_value_box_t const *key, rlm_cache_entry_t *entry, fr_time_delta_t *ttl, module_method_t resume, unlang_module_signal_t cancel, void *driver_rctx, void *uctx)
static unlang_action_t mod_method_load(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Load the avps by ${key}.
static xlat_action_t cache_ttl_get_xlat_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
rlm_cache_handle_t * handle
static unlang_action_t mod_method_load_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *entry)
Common result handling for load method.
static unlang_action_t mod_cache_it_ttl_results(unlang_result_t *p_result, unlang_result_t *tmp, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, cache_rctx_t *rctx)
static fr_dict_attr_t const * attr_cache_merge_new
static unlang_action_t cache_find_resume(unlang_result_t *p_result, rlm_cache_entry_t **out, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, fr_value_box_t const *key, void *rctx)
Resume callback after async cache find.
static void cache_release(rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle)
Release a handle we previously acquired.
static fr_dict_t const * dict_freeradius
static unlang_action_t cache_expire_resume(unlang_result_t *p_result, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, void *rctx)
Resume callback after async cache expire.
static int cache_verify(map_t *map, void *uctx)
Verify that a map in the cache section makes sense.
static void cache_set_ttl_cancel(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
map_list_t * maps
Attribute map applied to cache entries.
static unlang_action_t mod_method_ttl_find_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_method_clear_expire_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_cache_it_merge_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static void cache_find_cancel(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
static rlm_cache_entry_t * cache_alloc(rlm_cache_t const *inst, request_t *request)
Allocate a cache entry.
#define FIXUP_KEY(_fail, _invalid)
Macro to reduce boilerplate in all the module methods / xlat functions If multiple values are in the ...
static fr_dict_attr_t const * attr_cache_allow_insert
fr_value_box_t const * key
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Register module xlats.
static void cache_insert_cancel(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
static unlang_action_t mod_cache_it_ttl_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static void cache_expire_cancel(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
static fr_dict_attr_t const * attr_cache_status_only
static unlang_action_t cache_insert_resume(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t **handle, fr_time_delta_t *ttl, void *rctx)
static unlang_action_t mod_method_store_find_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static void cache_free(rlm_cache_t const *inst, rlm_cache_entry_t **c)
Free memory associated with a cache entry.
static unlang_action_t mod_method_update_expire_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t cache_insert(unlang_result_t *p_result, void **out_rctx, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, fr_value_box_t const *key, map_list_t const *maps, fr_time_delta_t ttl)
Create and insert a cache entry.
static unlang_action_t cache_find(unlang_result_t *p_result, rlm_cache_entry_t **out, void **out_rctx, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, fr_value_box_t const *key)
Find a cached entry.
static unlang_action_t cache_set_ttl_resume(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, void *rctx)
static unlang_action_t mod_cache_it_expire_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_attr_t const * attr_cache_entry_hits
static unlang_action_t cache_find_results(unlang_result_t *p_result, rlm_cache_entry_t **out, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, fr_value_box_t const *key, rlm_cache_entry_t *c)
Process results of cache find - either synchronous or async.
static unlang_action_t mod_cache_it_find_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_cache_it_expire_results(unlang_result_t *p_result, unlang_result_t *tmp, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *entry)
static unlang_action_t mod_method_ttl(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Change the TTL on an existing entry.
static xlat_arg_parser_t const cache_xlat_args[]
static unlang_action_t mod_method_store_find_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, cache_call_env_t *env, rlm_cache_entry_t *entry)
Common result handdling after store method does a find.
static unlang_action_t mod_method_status_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *entry)
Common result handling for status method.
static int cache_reconnect(rlm_cache_handle_t **handle, rlm_cache_t const *inst, request_t *request)
Reconnect an suspected inviable handle.
static xlat_action_t cache_xlat_results(TALLOC_CTX *ctx, unlang_result_t *result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *c, tmpl_t *target, fr_dcursor_t *out)
static unlang_action_t mod_method_clear(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Delete the entries by ${key}.
static const call_env_method_t cache_method_env
fr_dict_attr_autoload_t rlm_cache_dict_attr[]
static unlang_action_t cache_set_ttl(unlang_result_t *p_result, void **out_rctx, rlm_cache_t const *inst, request_t *request, rlm_cache_handle_t **handle, rlm_cache_entry_t *c)
Update the TTL of an entry.
fr_dict_autoload_t rlm_cache_dict[]
static unlang_action_t mod_method_update(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Create, or update a cache entry.
static xlat_action_t cache_ttl_get_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
static unlang_action_t mod_method_common_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static rlm_rcode_t cache_merge(rlm_cache_t const *inst, request_t *request, rlm_cache_entry_t *c)
Merge a cached entry into a request_t.
static unlang_action_t mod_method_update_find_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static void cache_unref(request_t *request, rlm_cache_t const *inst, rlm_cache_entry_t *entry, rlm_cache_handle_t *handle)
Release the allocated resources and cleanup the avps.
static unlang_action_t mod_method_ttl_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
int submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static const conf_parser_t module_config[]
static unlang_action_t mod_method_status_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_method_common_results(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *entry)
Common result handling for any module method which returns updated for success.
rlm_cache_entry_t * entry
static unlang_action_t mod_method_load_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_method_clear_find_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_instantiate(module_inst_ctx_t const *mctx)
Create a new rlm_cache_instance.
static unlang_action_t mod_cache_it(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Do caching checks.
static xlat_action_t cache_ttl_get_xlat_results(TALLOC_CTX *ctx, unlang_result_t *result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *c, fr_dcursor_t *out)
static unlang_action_t mod_cache_it_ttl(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, cache_rctx_t *rctx)
static unlang_action_t mod_cache_it_expire(unlang_result_t *p_result, request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, cache_rctx_t *rctx)
static unlang_action_t mod_cache_it_insert_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_cache_it_finish(request_t *request, rlm_cache_t const *inst, rlm_cache_handle_t *handle, rlm_cache_entry_t *c)
Additional resume context used by mod_cache_it.
Resume context when driver is async.
fr_value_box_t key
Key used to identify entry.
map_list_t maps
Head of the maps list.
fr_unix_time_t created
When the entry was created.
long long int hits
How many times the entry has been retrieved.
@ CACHE_RECONNECT
Handle needs to be reconnected.
@ CACHE_YIELD
The driver has pushed an async.
@ CACHE_OK
Cache entry found/updated.
@ CACHE_MISS
Cache entry notfound.
fr_unix_time_t expires
When the entry expires.
Configuration for the rlm_cache module.
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
char const * name
Instance name e.g. user_database.
CONF_SECTION * conf
Module's instance configuration.
size_t inst_size
Size of the module's instance data.
void * data
Module's instance data.
unlang_action_t(* module_method_t)(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Module section callback.
void * boot
Data allocated during the boostrap phase.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
module_t * exported
Public module structure.
Named methods exported by a module.
#define tmpl_value(_tmpl)
tmpl_t * tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len)
Create a new heap allocated tmpl_t.
#define tmpl_is_attr(vpt)
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_DATA
Value in native boxed format.
int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list, fr_dict_attr_t const *da)
Create a new tmpl from a list tmpl and a da.
static bool tmpl_attr_tail_da_is_structural(tmpl_t const *vpt)
Return true if the last attribute reference is a structural attribute.
static bool tmpl_is_list(tmpl_t const *vpt)
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
static fr_type_t tmpl_cast_get(tmpl_t *vpt)
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
int tmpl_cast_set(tmpl_t *vpt, fr_type_t type)
Set a cast for a tmpl.
fr_type_t tmpl_expanded_type(tmpl_t const *vpt)
Return the native data type of the expression.
Optional arguments passed to vp_tmpl functions.
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
eap_aka_sim_process_conf_t * inst
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
map_list_t child
parent map, for nested ones
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
CONF_ITEM * ci
Config item that the map was created from.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define talloc_get_type_abort_const
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_wrap(_time)
#define fr_time_delta_ispos(_a)
static fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
#define fr_unix_time_sub(_a, _b)
Subtract one time from another.
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
#define fr_unix_time_lt(_a, _b)
#define fr_unix_time_add(_a, _b)
Add a time/time delta together.
A time delta, a difference in time measured in nanoseconds.
const bool fr_assignment_op[T_TOKEN_LAST]
char const * fr_tokens[T_TOKEN_LAST]
void(* unlang_module_signal_t)(module_ctx_t const *mctx, request_t *request, fr_signal_t action)
A callback when the request gets a fr_signal_t.
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
unsigned int required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_YIELD
An xlat function pushed a resume frame onto the stack.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumed by an xlat function.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_time_delta(_val)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
#define fr_box_time(_val)
static size_t char ** out
#define fr_box_date(_val)
void * rctx
Resume context.
void * env_data
Expanded call env data.
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.