27RCSID(
"$Id: 5344ccd236941b12eb224b8321011792f0b7e91e $")
29#include <freeradius-devel/io/schedule.h>
30#include <freeradius-devel/server/base.h>
31#include <freeradius-devel/unlang/xlat_priv.h>
51 return CMP(a->
node->call.id, b->node->call.id);
64 return CMP(a->
node->call.id, b->node->call.id);
81 DEBUG4(
"Cleaning up xlat thread instance (%p/%p)", xt, xt->
data);
105 size_t extra_headers = 0;
106 size_t extra_mem = 0;
123 extra_mem +=
sizeof(*call->
func->
mctx);
126 if (extra_headers || extra_mem) {
145 talloc_set_name(xt->
data,
"xlat_%s_thread_t", call->
func->
name);
165 DEBUG4(
"Alloced xlat thread instance (%p/%p)", xt, xt->
data);
187 call = &xi->
node->call;
199 DEBUG4(
"Cleaning up xlat instance (%p/%p)", xi, xi->
data);
217 (void)talloc_get_type_abort(node,
xlat_exp_t);
243 talloc_set_name(xi->
data,
"xlat_%s_t", call->
func->
name);
252 "Method environment for module %s, xlat %s declared, "
271 .dict_def = call->dict,
272 .list_def = request_attr_request
310 return node->group->instantiated;
340 TALLOC_FREE(call->
inst);
384 if (
head->flags.needs_resolving) {
388 if (
head->instantiated)
return 0;
391 if (ret < 0)
return ret;
393 head->instantiated =
true;
460 DEBUG3(
"Instantiating xlat \"%s\" node %p, instance %p, new thread instance %p",
529 fr_assert(!xi->node->flags.needs_resolving);
554 fr_assert(!node->call.func->thread_detach);
556 if (node->call.inst) {
558 if (ret < 0)
return ret;
560 talloc_set_destructor(node->call.inst, NULL);
561 TALLOC_FREE(node->call.inst);
564 if (node->call.thread_inst) {
565 if (!node->call.ephemeral) {
567 if (ret < 0)
return ret;
570 talloc_set_destructor(node->call.thread_inst, NULL);
571 TALLOC_FREE(node->call.inst);
595 static uint64_t call_id;
606 DEBUG3(
"Instantiating xlat \"%s\" node %p, new instance %p", call->
func->
name, node, call->
inst);
618 node->call.id = call_id++;
622 TALLOC_FREE(call->
inst);
636 return node->group->instantiated;
663 "xlat.runtime_el likely not set in tmpl rules when it should've been. "
664 "Use unlang_interpret_event_list() to get the current event list from the request");
672 if (
head->instantiated)
return 0;
679 if (ret < 0)
return ret;
681 head->instantiated =
true;
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
call_env_t * call_env_alloc(TALLOC_CTX *ctx, char const *name, call_env_method_t const *call_env_method, tmpl_rules_t const *t_rules, CONF_SECTION *cs, call_env_ctx_t const *cec)
Given a call_env_method, parse all call_env_pair_t in the context of a specific call to an xlat or mo...
Structures and functions for handling call environments.
@ CALL_ENV_CTX_TYPE_XLAT
The callenv is registered to an xlat.
size_t inst_size
Size of per call env.
struct call_env_ctx_s call_env_ctx_t
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
void * fr_heap_pop(fr_heap_t **hp)
Remove a node from the heap.
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
static bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
static void * fr_heap_peek_at(fr_heap_t *h, fr_heap_index_t idx)
Peek at a specific index in the heap.
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
#define fr_heap_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init)
Creates a heap that verifies elements are of a specific talloc type.
#define fr_heap_foreach(_heap, _type, _data)
Iterate over the contents of a heap.
Stores all information relating to an event list.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
static module_ctx_t * module_ctx_from_inst(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx)
Allocate a module calling ctx on the heap based on an instance ctx.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
char const * name
Instance name e.g. user_database.
CONF_SECTION * conf
Module's instance configuration.
void * data
Thread specific instance data.
static module_thread_instance_t * module_thread(module_instance_t const *mi)
Retrieve module/thread specific instance for a module.
Optional arguments passed to vp_tmpl functions.
#define talloc_get_type_abort_const
#define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
static fr_event_list_t * el
fr_heap_index_t idx
Entry in heap of xlat instances.
xlat_exp_t * node
Node this data relates to.
void * data
Thread specific instance data.
xlat_exp_t const * node
Node this data relates to.
fr_heap_index_t idx
Entry in heap of xlat thread instances.
fr_event_list_t * el
Event list associated with this thread.
void * data
xlat node specific instance data.
#define XLAT_VERIFY(_node)
int xlat_resolve(xlat_exp_head_t *head, xlat_res_rules_t const *xr_rules)
Walk over an xlat tree recursively, resolving any unresolved functions or references.
call_env_t const * call_env
Per call environment.
module_ctx_t const * mctx
A synthesised module calling ctx containing module global and thread instance data.
Instance data for an xlat expansion node.
Thread specific instance data for xlat expansion node.
#define XLAT_THREAD_INST_CTX(_inst, _thread, _ex, _mctx, _el, _uctx)
Wrapper to create a xlat_thread_inst_ctx_t as a compound literal.
#define XLAT_INST_CTX(_inst, _ex, _mctx, _uctx)
Wrapper to create a xlat_inst_ctx_t as a compound literal.
int xlat_eval_walk(xlat_exp_head_t *head, xlat_walker_t walker, xlat_type_t type, void *uctx)
Walk over all xlat nodes (depth first) in a xlat expansion, calling a callback.
xlat_thread_inst_t * xlat_thread_instance_find(xlat_exp_t const *node)
Retrieve xlat/thread specific instance data.
static int _xlat_inst_detach(xlat_inst_t *xi)
Destructor for xlat_inst_t.
int xlat_instance_register_func(xlat_exp_t *node)
Callback for creating "permanent" instance data for a xlat_exp_t.
void xlat_thread_detach(void)
Destroy any thread specific xlat instances.
static int xlat_instance_register(xlat_exp_head_t *head)
Create instance data for "permanent" xlats.
static int _xlat_instantiate_ephemeral_walker(xlat_exp_t *node, void *uctx)
Callback for creating "ephemeral" instance data for a xlat_exp_t.
static int xlat_instantiate_ephemeral(xlat_exp_head_t *head, fr_event_list_t *el)
Create instance data for "ephemeral" xlats.
int xlat_instantiate(void)
Call instantiation functions for all registered, "permanent" xlats.
static int8_t _xlat_inst_cmp(void const *one, void const *two)
Compare two xlat instances based on node pointer.
static int8_t _xlat_thread_inst_cmp(void const *one, void const *two)
Compare two thread instances based on node pointer.
int xlat_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Create thread specific instance tree and create thread instances.
static int _xlat_inst_walker(xlat_exp_t *node, UNUSED void *uctx)
static xlat_inst_t * xlat_inst_alloc(xlat_exp_t *node)
Allocate instance data for an xlat expansion.
static int _xlat_thread_inst_detach(xlat_thread_inst_t *xt)
Destructor for xlat_thread_inst_t.
void xlat_instances_free(void)
Walk over all registered instance data and free them explicitly.
static fr_heap_t * xlat_inst_tree
Holds instance data created by xlat_instantiate.
static int xlat_instantiate_init(void)
Initialise the xlat instance data code.
int xlat_finalize(xlat_exp_head_t *head, fr_event_list_t *runtime_el)
Bootstrap static xlats, or instantiate ephemeral ones.
static _Thread_local fr_heap_t * xlat_thread_inst_tree
Holds thread specific instance data created by xlat_instantiate.
int xlat_instance_unregister_func(xlat_exp_t *node)
Remove a node from the list of xlat instance data.
static xlat_thread_inst_t * xlat_thread_inst_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, xlat_inst_t *xi)
Create thread instances where needed.
char const * name
Name of xlat function.
char const * thread_inst_type
C type of thread instance structure.
module_inst_ctx_t * mctx
Original module instantiation ctx if this xlat was registered by a module.
bool ephemeral
Instance data is ephemeral (not inserted) into the instance tree.
xlat_instantiate_t instantiate
Instantiation function.
size_t thread_inst_size
Size of the thread instance data to pre-allocate.
xlat_detach_t detach
Destructor for when xlat instances are freed.
void * thread_uctx
uctx to pass to instantiation functions.
call_env_method_t const * call_env_method
Optional tmpl expansions performed before calling the xlat.
size_t inst_size
Size of instance data to pre-allocate.
@ XLAT_GROUP
encapsulated string of xlats
@ XLAT_INVALID
Bad expansion.
xlat_thread_instantiate_t thread_instantiate
Thread instantiation function.
xlat_thread_inst_t * thread_inst
Thread specific instance.
xlat_inst_t * inst
Instance data for the xlat_t.
char const * inst_type
C type of instance structure.
xlat_t const * func
The xlat expansion to expand format with.
uint64_t id
Identifier unique to each permanent xlat node.
xlat_type_t _CONST type
type of this expansion.
xlat_thread_detach_t thread_detach
Destructor for when xlat thread instance data is freed.
void * uctx
uctx to pass to instantiation functions.