25RCSID(
"$Id: ea9d112b7a5cc6482b921bc383b5931d3a7c37a2 $")
27#include <freeradius-devel/unlang/action.h>
28#include <freeradius-devel/unlang/interpret.h>
29#include <freeradius-devel/util/timer.h>
30#include <freeradius-devel/server/base.h>
31#include <freeradius-devel/server/modpriv.h>
32#include <freeradius-devel/server/rcode.h>
33#include <freeradius-devel/unlang/xlat_func.h>
34#include <freeradius-devel/unlang/mod_action.h>
62#include <freeradius-devel/unlang/module_priv.h>
83 for (i = 0; i <= (
unsigned int)
stack->depth; i++) {
84 frame = &
stack->frame[i];
85 if (frame->
state && (ptr >= (
void *)frame->
state) &&
88 *chunk = frame->
state;
111 if (!mod_state->
rctx)
continue;
113 if ((ptr >= (
void *)mod_state->
rctx) &&
114 (ptr < ((
void *)((
uint8_t *)mod_state->
rctx + talloc_get_size(mod_state->
rctx))))) {
116 *chunk = mod_state->
rctx;
204 location, frame->
p_result, chunk ? talloc_get_name(chunk) :
"<none>"
229 if (op && op->
dump) op->
dump(request, frame);
238 RDEBUG2(
"----- Begin stack debug [depth %i] -----",
240 for (i =
stack->depth; i >= 0; i--) {
242 RDEBUG2(
"[%d] Frame contents", i);
245 RDEBUG2(
"----- End stack debug [depth %i] -------",
stack->depth);
257#define DUMP_STACK if (DEBUG_ENABLED5) stack_dump(request)
296 if (
DEBUG_ENABLED5)
RDEBUG3(
"unlang_interpret_push called with instruction type \"%s\" - args %s %s",
297 instruction ? instruction->
debug_name :
"<none>",
298 do_next_sibling ?
"UNLANG_NEXT_SIBLING" :
"UNLANG_NEXT_STOP",
299 conf->top_frame ?
"UNLANG_TOP_FRAME" :
"UNLANG_SUB_FRAME");
308 RERROR(
"Call stack is too deep");
318 memset(frame, 0,
sizeof(*frame));
322 if (do_next_sibling && instruction->
list) {
324 frame->
next = unlang_list_next(instruction->
list, instruction);
334 frame->
indent = request->log.indent;
336 if (!instruction)
return 0;
401 if (unlang_list_empty(&g->
children)) {
402 RDEBUG2(
"... ignoring empty subsection ...");
429 ref->
old_dict = request->local_dict;
447static inline CC_HINT(always_inline)
450 unlang_t const *instruction = frame->instruction;
455 RDEBUG4(
"** [%i] %s - unwinding frame",
stack->depth, __FUNCTION__);
464 RDEBUG4(
"** [%i] %s - skipping frame, no result set",
465 stack->depth, __FUNCTION__);
472 RDEBUG4(
"** [%i] %s - have (%s %s) frame or module returned (%s %s)",
473 stack->depth, __FUNCTION__,
487 RDEBUG3(
"Setting request->rcode to '%s'",
501 RDEBUG4(
"** [%i] %s - using default instruction priority for %s, %s",
502 stack->depth, __FUNCTION__,
518 RDEBUG4(
"** [%i] %s - action says to return with (%s %s)",
519 stack->depth, __FUNCTION__,
536 RDEBUG4(
"** [%i] %s - action says to return with (%s %s)",
537 stack->depth, __FUNCTION__,
548 RDEBUG4(
"** [%i] %s - action says to retry with",
549 stack->depth, __FUNCTION__);
573 RPEDEBUG(
"Failed inserting retry event");
630 RDEBUG4(
"** [%i] %s - overwriting existing result (%s %s) with higher priority (%s %s)",
631 stack->depth, __FUNCTION__,
636 *frame->p_result = *
result;
656static inline CC_HINT(always_inline)
679 RDEBUG4(
"** [%i] %s - using instruction priority for higher frame (%s, %s)",
680 stack->depth, __FUNCTION__,
730static inline CC_HINT(always_inline)
739 while (frame->instruction) {
740 unlang_t const *instruction = frame->instruction;
764 if (request->ins_max) {
765 request->ins_count++;
767 if (request->ins_count >= request->ins_max) {
768 RERROR(
"Failing request due to maximum instruction count %" PRIu64, request->ins_max);
813 ua = frame->process(&frame->scratch_result, request, frame);
817 RDEBUG4(
"** [%i] %s << %s (%s %s)",
stack->depth, __FUNCTION__,
848 "Instruction %s returned UNLANG_ACTION_PUSHED_CHILD, "
849 "but stack depth was not increased",
860 "Instruction %s returned UNLANG_ACTION_YIELD, but pushed additional "
861 "frames for evaluation. Instruction should return UNLANG_ACTION_PUSHED_CHILD "
862 "instead", instruction->
name);
865 RDEBUG4(
"** [%i] %s - yielding with current (%s %s)",
stack->depth, __FUNCTION__,
904 RDEBUG2(
"} # retrying the same section");
930 RDEBUG4(
"** [%i] %s - done current subsection with (%s %s), %s",
931 stack->depth, __FUNCTION__,
934 frame->p_result == &(frame->section_result) ?
"will set higher frame rcode" :
"will NOT set higher frame rcode (p_result)");
969 fr_assert_msg(intp,
"request has no interpreter associated");
971 RDEBUG4(
"** [%i] %s - interpret entered",
stack->depth, __FUNCTION__);
978 RDEBUG4(
"** [%i] %s - frame action %s",
stack->depth, __FUNCTION__,
982 RDEBUG4(
"** [%i] %s - frame action next",
stack->depth, __FUNCTION__);
990 RDEBUG4(
"** [%i] %s - frame action %s",
stack->depth, __FUNCTION__,
1006 RDEBUG4(
"** [%i] %s - frame popped",
stack->depth + 1, __FUNCTION__);
1029 if (private_result) {
1040 fa =
result_pop(request, frame, §ion_result);
1065 DEBUG4(
"** [%i] %s - continuing after subsection with (%s %s)",
1066 stack->depth, __FUNCTION__,
1077 RDEBUG4(
"** [%i] %s - done current subsection with (%s %s)",
1078 stack->depth, __FUNCTION__,
1090 RDEBUG4(
"** [%i] %s - interpret yielding",
stack->depth, __FUNCTION__);
1106 RDEBUG4(
"** [%i] %s - interpret exiting, returning (%s)",
stack->depth, __FUNCTION__,
1138 .debug_name =
"empty-group",
1170 REDEBUG(
"Failed to find pre-compiled unlang for section %s %s { ... }",
1198 RDEBUG4(
"** [%i] %s - substack begins",
stack->depth, __FUNCTION__);
1216 static unlang_t unlang_instruction = {
1237 stack->frame[0].p_result = &
stack->frame[0].section_result;
1240 stack->frame[0].instruction = &unlang_instruction;
1258 switch (request->type) {
1278static inline CC_HINT(always_inline)
1302 request->priority = priority;
1335 (void)talloc_get_type_abort(request,
request_t);
1360 for (i =
depth; i >= limit; i--) {
1361 frame = &
stack->frame[i];
1363 frame->
signal(request, frame, action);
1467 RDEBUG(
"retry timeout reached, signalling interpreter to cancel.");
1482 RDEBUG(
"Maximum timeout reached, signalling interpreter to stop the request.");
1501 TALLOC_CTX *frame_ctx;
1506 frame_ctx = frame->
state;
1507 if (!frame_ctx) frame_ctx =
stack;
1510 if (!frame->
retry)
return -1;
1529 return stack->depth;
1639 RDEBUG3(
"Not marking request %s as runnable due to%s%s",
1642 " it not being yielded " :
"", scheduled ?
" it already being scheduled" :
"");
1646 RDEBUG3(
"Interpreter - Request marked as runnable");
1662 if (frame->
state)
return (TALLOC_CTX *)frame->
state;
1669 return (TALLOC_CTX *)(frame->
state = talloc_new(request));
1691 RDEBUG2(
"Request canceled by dynamic timeout");
1750 RPERROR(
"Failed inserting cancellation event");
1756 RPERROR(
"Failed associating cancellation event with request");
1799 char const *
fmt = arg->vb_strvalue;
1807 while (*
fmt ==
'.') {
1838 if (strcmp(
fmt,
"depth") == 0) {
1839 fr_value_box_int32(vb, NULL,
depth,
false);
1846 if (strcmp(
fmt,
"module") == 0) {
1855 if (strcmp(
fmt,
"name") == 0) {
1857 strlen(instruction->
name),
false) < 0)
goto error;
1864 if (strcmp(
fmt,
"processing_stage") == 0) {
1873 if (strcmp(
fmt,
"rcode") == 0) {
1882 if (strcmp(
fmt,
"server") == 0) {
1893 if (strcmp(
fmt,
"type") == 0) {
1903 if (!instruction->
ci) {
1912 if (strcmp(
fmt,
"line") == 0) {
1913 fr_value_box_int32(vb, NULL,
cf_lineno(instruction->
ci),
false);
1921 if (strcmp(
fmt,
"filename") == 0) {
2013 if (!
stack->intp)
return NULL;
2015 return stack->intp->el;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_EXECUTE_NEXT
Execute the next unlang_t.
@ UNLANG_ACTION_STOP_PROCESSING
Break out of processing the current request (unwind).
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ 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 * fmt
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
#define cf_data_find(_cf, _type, _name)
fr_table_num_sorted_t const mod_rcode_table[]
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static int fr_dcursor_insert(fr_dcursor_t *cursor, void *v)
Insert directly after the current item.
#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...
static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Get information about the interpreter state.
void unlang_interpret_request_prioritise(request_t *request, uint32_t priority)
static size_t unlang_action_table_len
void stack_dump_with_actions(request_t *request)
static fr_table_num_ordered_t const unlang_frame_action_table[]
static void unlang_interpret_request_detach(request_t *request)
Tell the interpreter to detach the request.
rlm_rcode_t unlang_interpret(request_t *request, bool running)
Run the interpreter for a current request.
bool unlang_request_is_done(request_t const *request)
Return whether a request has been marked done.
static void stack_dump_body(request_t *request, bool with_actions)
static unlang_group_t empty_group
unlang_result_t * unlang_interpret_result(request_t *request)
Get the last instruction result OR the last frame that was popped.
static int find_p_result_location(p_result_location_t *location, void **chunk, request_t *request, void *ptr)
Try and figure out where p_result points to.
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout)
Set a timeout for a request.
void unlang_interpret_request_done(request_t *request)
Indicate to the caller of the interpreter that this request is complete.
static unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame)
Evaluates all the unlang nodes in a section.
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
unlang_interpret_t * unlang_interpret_get(request_t *request)
Get the interpreter set for a request.
int unlang_interpret_stack_depth(request_t *request)
Return the depth of the request's stack.
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
static xlat_arg_parser_t const unlang_interpret_xlat_args[]
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
bool unlang_request_is_scheduled(request_t const *request)
Return whether a request is currently scheduled.
int unlang_interpret_init_global(TALLOC_CTX *ctx)
void stack_dump(request_t *request)
@ P_RESULT_LOCATION_FRAME
@ P_RESULT_LOCATION_FUNCTION_RCTX
@ P_RESULT_LOCATION_UNKNOWN
@ P_RESULT_LOCATION_SCRATCH
@ P_RESULT_LOCATION_MODULE_RCTX
@ P_RESULT_LOCATION_STATE
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
fr_dict_t const * old_dict
the previous dictionary for the request
void * unlang_interpret_stack_alloc(TALLOC_CTX *ctx)
Allocate a new unlang stack.
void unlang_interpret_set_thread_default(unlang_interpret_t *intp)
Set the default interpreter for this thread.
static fr_table_num_ordered_t const p_result_location_table[]
unlang_mod_action_t unlang_interpret_priority(request_t *request)
Get the last instruction priority OR the last frame that was popped.
static void instruction_retry_handler(UNUSED fr_timer_list_t *tl, UNUSED fr_time_t now, void *ctx)
unlang_interpret_t * unlang_interpret_init(TALLOC_CTX *ctx, fr_event_list_t *el, unlang_request_func_t *funcs, void *uctx)
Initialize a unlang compiler / interpret.
static void instruction_timeout_handler(UNUSED fr_timer_list_t *tl, UNUSED fr_time_t now, void *ctx)
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
int unlang_interpret_push_instruction(unlang_result_t *p_result, request_t *request, void *instruction, unlang_frame_conf_t const *conf)
Push an instruction onto the request stack for later interpretation.
static void unlang_cancel_event(UNUSED fr_timer_list_t *tl, UNUSED fr_time_t now, void *uctx)
Signal the request to stop executing.
void unlang_interpret_signal(request_t *request, fr_signal_t action)
Send a signal (usually stop) to a request.
static xlat_arg_parser_t const unlang_cancel_xlat_args[]
int unlang_interpret_push_section(unlang_result_t *p_result, request_t *request, CONF_SECTION *cs, unlang_frame_conf_t const *conf)
Push a configuration section onto the request stack for later interpretation.
static unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t *frame, unlang_result_t *result)
Update the current result after each instruction, and after popping each stack frame.
static fr_table_num_ordered_t const unlang_action_table[]
static int _local_variables_free(unlang_variable_ref_t *ref)
static size_t p_result_location_table_len
static void instruction_dump(request_t *request, unlang_t const *instruction)
bool unlang_interpret_is_resumable(request_t *request)
Check if a request as resumable.
int unlang_interpret_push(unlang_result_t *p_result, request_t *request, unlang_t const *instruction, unlang_frame_conf_t const *conf, bool do_next_sibling)
Push a new frame onto the stack.
static void instruction_done_debug(request_t *request, unlang_stack_frame_t *frame, unlang_t const *instruction)
request_t * request
the request
static unlang_frame_action_t result_pop(request_t *request, unlang_stack_frame_t *frame, unlang_result_t *result)
Function called to merge inter-stack-frame results.
void unlang_stack_signal(request_t *request, fr_signal_t action, int limit)
Delivers a frame to one or more frames in the stack.
static xlat_action_t unlang_cancel_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Allows a request to dynamically alter its own lifetime.
static size_t unlang_frame_action_table_len
rlm_rcode_t unlang_interpret_rcode(request_t *request)
Get the last instruction result OR the last frame that was popped.
static void frame_dump(request_t *request, unlang_stack_frame_t *frame, bool with_actions)
unlang_action_t unlang_interpret_push_children(unlang_result_t *p_result, request_t *request, rlm_rcode_t default_rcode, bool do_next_sibling)
Push the children of the current frame onto a new frame onto the stack.
static void actions_dump(request_t *request, unlang_t const *instruction)
static _Thread_local unlang_interpret_t * intp_thread_default
The default interpreter instance for this thread.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
unlang_result_t default_result
The default result for the frame.
#define UNLANG_STACK_MAX
The maximum depth of the stack.
unlang_request_prioritise_t prioritise
Function to re-priotise a request in the runnable queue.
unlang_mod_action_t priority
The priority or action for that rcode.
#define UNLANG_RESULT_NOT_SET
#define FRAME_CONF(_default_rcode, _top_frame)
unlang_request_done_t done_internal
Function called when an internal request completes.
unlang_request_resume_t resume
Function called when a request is resumed.
unlang_request_done_t done_external
Function called when a external request completes.
unlang_request_init_t detach
Function called when a request is detached.
unlang_request_runnable_t mark_runnable
Function called when a request needs to be added back to the runnable queue.
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
unlang_request_yield_t yield
Function called when a request yields.
unlang_request_done_t done_detached
Function called when a detached request completes.
unlang_request_scheduled_t scheduled
Function to check if a request is already scheduled.
#define UNLANG_RESULT_RCODE(_x)
unlang_request_init_t init_internal
Function called to initialise an internal request.
struct unlang_interpret_s unlang_interpret_t
Interpreter handle.
Configuration structure to make it easier to pass configuration options to initialise the frame with.
External functions provided by the owner of the interpret.
Private declarations for the unlang interpreter.
unlang_request_func_t funcs
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define DEBUG_ENABLED5
True if global debug level 1-5 messages are enabled.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
unlang_op_t unlang_ops[UNLANG_TYPE_MAX]
Different operations the interpreter can execute.
Stores all information relating to an event list.
static char * stack[MAX_STACK]
@ 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.
static uint8_t depth(fr_minmax_heap_index_t i)
const char * mod_action_name[MOD_PRIORITY_MAX+1]
#define DEFAULT_MOD_ACTIONS
@ MOD_ACTION_NOT_SET
default "not set by anything"
@ MOD_ACTION_RETURN
stop processing the section, and return the rcode with unset priority
@ MOD_ACTION_REJECT
change the rcode to REJECT, with unset priority
@ MOD_ACTION_RETRY
retry the instruction, MUST also set a retry config
#define MOD_ACTION_VALID(_x)
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
Declarations for the unlang module interface.
void * rctx
for resume / signal
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
#define RDEBUG_ENABLED2()
fr_table_num_sorted_t const rcode_table[]
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_TIMEOUT
Module (or section) timed out.
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
#define REQUEST_VERIFY(_x)
@ REQUEST_TYPE_EXTERNAL
A request received on the wire.
@ REQUEST_TYPE_INTERNAL
A request generated internally.
@ REQUEST_TYPE_DETACHED
A request that was generated internally, but is now detached (not associated with a parent request....
#define request_is_detachable(_x)
@ REQUEST_DONE
Request has completed.
@ REQUEST_STOP_PROCESSING
Request has been signalled to stop.
void * request_data_get(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request.
#define request_data_add(_request, _unique_ptr, _unique_int, _opaque, _free_on_replace, _free_on_parent, _persist)
Add opaque data to a request_t.
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
@ FR_SIGNAL_DETACH
Request is being detached from its parent.
fr_aka_sim_id_type_t type
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 fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
#define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
#define fr_time_delta_eq(_a, _b)
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
#define fr_time_sub(_a, _b)
Subtract one time from another.
A time delta, a difference in time measured in nanoseconds.
fr_time_t fr_timer_when(fr_timer_t *ev)
Internal timestamp representing when the timer should fire.
static fr_event_list_t * el
static unlang_result_t result
uint8_t required
Argument must be present, and non-empty.
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
Private interpreter structures and functions.
#define unlang_frame_perf_resume(_x)
unlang_result_t section_result
The aggregate result of executing all siblings in this section.
static void frame_pop(request_t *request, unlang_stack_t *stack)
Pop a stack frame, removing any associated dynamically allocated state.
static void frame_next(unlang_stack_t *stack, unlang_stack_frame_t *frame)
Advance to the next sibling instruction.
@ UNLANG_FRAME_FLAG_NONE
No flags.
static bool is_repeatable(unlang_stack_frame_t const *frame)
#define UNLANG_NEXT_SIBLING
unlang_result_t * p_result
Where to write the result of executing the current instruction.
static void repeatable_clear(unlang_stack_frame_t *frame)
static unlang_action_t unwind_to_depth(unlang_stack_t *stack, unsigned int to_depth)
Mark up frames as cancelled so they're immediately popped by the interpreter.
unlang_retry_t * retry
if the frame is being retried.
unlang_signal_t signal
function to call when signalling this stack frame
char const * debug_name
Printed in log messages when the node is executed.
void * state
Stack frame specialisations.
unlang_mod_actions_t actions
Priorities, etc. for the various return codes.
static void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t *frame)
Initialise memory and instruction for a frame when a new instruction is to be evaluated.
unlang_dump_t dump
Dump additional information about the frame state.
static unlang_t * unlang_group_to_generic(unlang_group_t const *p)
rindent_t indent
Indent level of the request when the frame was created.
unlang_process_t interpret
Function to interpret the keyword.
unlang_result_t scratch_result
The result of executing the current instruction.
int depth
of this retry structure
CONF_ITEM * ci
used to generate this item
static bool is_top_frame(unlang_stack_frame_t const *frame)
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
static unlang_stack_frame_t * frame_current(request_t *request)
static bool is_private_result(unlang_stack_frame_t const *frame)
char const * name
Unknown...
static bool is_break_point(unlang_stack_frame_t const *frame)
#define has_debug_braces(_thing)
@ UNLANG_TYPE_GROUP
Grouping section.
@ UNLANG_TYPE_MODULE
Module method.
unlang_t const * instruction
The unlang node we're evaluating.
static bool is_rcode_set(unlang_stack_frame_t const *frame)
static bool is_yielded(unlang_stack_frame_t const *frame)
static void top_frame_set(unlang_stack_frame_t *frame)
unlang_variable_t * variables
rarely used, so we don't usually need it
char const * name
Name of the keyword.
unlang_frame_action_t
Allows the frame evaluator to signal the interpreter.
@ UNLANG_FRAME_ACTION_POP
Pop the current frame, and check the next one further up in the stack for what to do next.
@ UNLANG_FRAME_ACTION_YIELD
Temporarily return control back to the caller on the C stack.
@ UNLANG_FRAME_ACTION_NEXT
Process the next instruction at this level.
@ UNLANG_FRAME_ACTION_RETRY
retry the current frame
static void yielded_set(unlang_stack_frame_t *frame)
static bool is_continue_point(unlang_stack_frame_t const *frame)
static void yielded_clear(unlang_stack_frame_t *frame)
#define unlang_frame_perf_yield(_x)
#define unlang_frame_perf_cleanup(_x)
unlang_t const * next
The next unlang node we will evaluate.
fr_dict_t * dict
our dictionary
static bool is_return_point(unlang_stack_frame_t const *frame)
unlang_process_t process
function to call for interpreting this stack frame
unlang_type_t type
The specialisation of this node.
unlang_frame_flag_t flag
Flags that mark up the frame for various things such as being the point where break,...
unlang_list_t * list
so we have fewer run-time dereferences
static bool is_unwinding(unlang_stack_frame_t const *frame)
Generic representation of a grouping.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
fr_pair_t * fr_pair_list_tail(fr_pair_list_t const *list)
Get the tail of a valuepair list.
fr_pair_t * fr_pair_list_prev(fr_pair_list_t const *list, fr_pair_t const *item))
Get the previous item in a valuepair list before a specific entry.
uint32_t mrc
Maximum retransmission count.
@ FR_RETRY_MRC
reached maximum retransmission count
@ FR_RETRY_MRD
reached maximum retransmission duration
fr_time_delta_t mrd
Maximum retransmission duration.
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.