25RCSID(
"$Id: 409bfbb8ed0632c557dae94e0bc74c496ef5a72d $")
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;
206 location, frame->
result_p, chunk ? talloc_get_name(chunk) :
"<none>"
231 if (op && op->
dump) op->
dump(request, frame);
240 RDEBUG2(
"----- Begin stack debug [depth %i] -----",
242 for (i =
stack->depth; i >= 0; i--) {
244 RDEBUG2(
"[%d] Frame contents", i);
247 RDEBUG2(
"----- End stack debug [depth %i] -------",
stack->depth);
259#define DUMP_STACK if (DEBUG_ENABLED5) stack_dump(request)
300 if (
DEBUG_ENABLED5)
RDEBUG3(
"unlang_interpret_push called with instruction type \"%s\" - args %s %s",
301 instruction ? instruction->
debug_name :
"<none>",
302 do_next_sibling ?
"UNLANG_NEXT_SIBLING" :
"UNLANG_NEXT_STOP",
303 conf->top_frame ?
"UNLANG_TOP_FRAME" :
"UNLANG_SUB_FRAME");
312 RERROR(
"Call stack is too deep");
322 memset(frame, 0,
sizeof(*frame));
326 if (do_next_sibling) {
339 frame->
indent = request->log.indent;
341 if (!instruction)
return 0;
407 RDEBUG2(
"... ignoring empty subsection ...");
434 ref->
old_dict = request->local_dict;
452static inline CC_HINT(always_inline)
455 unlang_t const *instruction = frame->instruction;
460 RDEBUG4(
"** [%i] %s - unwinding frame",
stack->depth, __FUNCTION__);
469 RDEBUG4(
"** [%i] %s - skipping frame, no result set",
470 stack->depth, __FUNCTION__);
474 RDEBUG4(
"** [%i] %s - have (%s %d) frame or module returned (%s %d)",
475 stack->depth, __FUNCTION__,
488 if (
is_rcode_set(frame) && (request->rcode != result->rcode)) {
489 RDEBUG3(
"Setting request->rcode to '%s'",
491 request->rcode = result->rcode;
501 RDEBUG4(
"** [%i] %s - using default instruction priority for %s, %d",
502 stack->depth, __FUNCTION__,
512 switch (result->priority) {
518 RDEBUG4(
"** [%i] %s - action says to return with (%s %d)",
519 stack->depth, __FUNCTION__,
524 frame_result->
rcode = result->rcode;
537 RDEBUG4(
"** [%i] %s - action says to return with (%s %d)",
538 stack->depth, __FUNCTION__,
550 RDEBUG4(
"** [%i] %s - action says to retry with",
551 stack->depth, __FUNCTION__);
575 RPEDEBUG(
"Failed inserting retry event");
628 if (result->priority >= frame_result->
priority) {
629 RDEBUG4(
"** [%i] %s - overwriting existing result (%s %d) with higher priority (%s %d)",
630 stack->depth, __FUNCTION__,
635 *frame->result_p = *result;
655static inline CC_HINT(always_inline)
672 our_result.
priority = frame->instruction->actions.actions[result->rcode];
675 RDEBUG4(
"** [%i] %s - using instruction priority for higher frame (%s, %d)",
676 stack->depth, __FUNCTION__,
726static inline CC_HINT(always_inline)
735 while (frame->instruction) {
736 unlang_t const *instruction = frame->instruction;
760 if (request->ins_max) {
761 request->ins_count++;
763 if (request->ins_count >= request->ins_max) {
764 RERROR(
"Failing request due to maximum instruction count %" PRIu64, request->ins_max);
809 ua = frame->process(&frame->scratch_result, request, frame);
811 RDEBUG4(
"** [%i] %s << %s (%s %d)",
stack->depth, __FUNCTION__,
845 "Instruction %s returned UNLANG_ACTION_PUSHED_CHILD, "
846 "but stack depth was not increased",
857 "Instruction %s returned UNLANG_ACTION_YIELD, but pushed additional "
858 "frames for evaluation. Instruction should return UNLANG_ACTION_PUSHED_CHILD "
859 "instead", instruction->
name);
862 RDEBUG4(
"** [%i] %s - yielding with current (%s %d)",
stack->depth, __FUNCTION__,
898 RDEBUG2(
"} # retrying the same section");
922 RDEBUG4(
"** [%i] %s - done current subsection with (%s %d), %s",
923 stack->depth, __FUNCTION__,
925 frame->result_p->priority,
926 frame->result_p == &(frame->section_result) ?
"will set higher frame rcode" :
"will NOT set higher frame rcode (result_p)");
961 fr_assert_msg(intp,
"request has no interpreter associated");
963 RDEBUG4(
"** [%i] %s - interpret entered",
stack->depth, __FUNCTION__);
970 RDEBUG4(
"** [%i] %s - frame action %s",
stack->depth, __FUNCTION__,
974 RDEBUG4(
"** [%i] %s - frame action next",
stack->depth, __FUNCTION__);
982 RDEBUG4(
"** [%i] %s - frame action %s",
stack->depth, __FUNCTION__,
998 RDEBUG4(
"** [%i] %s - frame popped",
stack->depth, __FUNCTION__);
1021 if (private_result) {
1032 fa =
result_pop(request, frame, §ion_result);
1055 DEBUG4(
"** [%i] %s - continuing after subsection with (%s %d)",
1056 stack->depth, __FUNCTION__,
1067 RDEBUG4(
"** [%i] %s - done current subsection with (%s %d)",
1068 stack->depth, __FUNCTION__,
1080 RDEBUG4(
"** [%i] %s - interpret yielding",
stack->depth, __FUNCTION__);
1096 RDEBUG4(
"** [%i] %s - interpret exiting, returning (%s)",
stack->depth, __FUNCTION__,
1122 .debug_name =
"empty-group",
1154 REDEBUG(
"Failed to find pre-compiled unlang for section %s %s { ... }",
1182 RDEBUG4(
"** [%i] %s - substack begins",
stack->depth, __FUNCTION__);
1200 static unlang_t unlang_instruction = {
1242 stack->frame[0].result_p = &
stack->frame[0].section_result;
1247 stack->frame[0].instruction = &unlang_instruction;
1265 switch (request->type) {
1285static inline CC_HINT(always_inline)
1309 request->async->priority = priority;
1342 (void)talloc_get_type_abort(request,
request_t);
1367 for (i =
depth; i >= limit; i--) {
1368 frame = &
stack->frame[i];
1370 frame->
signal(request, frame, action);
1474 RDEBUG(
"retry timeout reached, signalling interpreter to cancel.");
1490 RDEBUG(
"Maximum timeout reached, signalling interpreter to stop the request.");
1514 if (!frame->
retry)
return -1;
1533 return stack->depth;
1643 RDEBUG3(
"Not marking request %s as runnable due to%s%s",
1646 " it not being yielded " :
"", scheduled ?
" it already being scheduled" :
"");
1650 RDEBUG3(
"Interpreter - Request marked as runnable");
1666 if (frame->
state)
return (TALLOC_CTX *)frame->
state;
1673 return (TALLOC_CTX *)(frame->
state = talloc_new(request));
1695 RDEBUG2(
"Request canceled by dynamic timeout");
1754 RPERROR(
"Failed inserting cancellation event");
1760 RPERROR(
"Failed associating cancellation event with request");
1803 char const *
fmt = arg->vb_strvalue;
1811 while (*
fmt ==
'.') {
1842 if (strcmp(
fmt,
"depth") == 0) {
1843 fr_value_box_int32(vb, NULL,
depth,
false);
1850 if (strcmp(
fmt,
"module") == 0) {
1859 if (strcmp(
fmt,
"name") == 0) {
1861 strlen(instruction->
name),
false) < 0)
goto error;
1868 if (strcmp(
fmt,
"processing_stage") == 0) {
1877 if (strcmp(
fmt,
"rcode") == 0) {
1886 if (strcmp(
fmt,
"server") == 0) {
1897 if (strcmp(
fmt,
"type") == 0) {
1907 if (!instruction->
ci) {
1916 if (strcmp(
fmt,
"line") == 0) {
1917 fr_value_box_int32(vb, NULL,
cf_lineno(instruction->
ci),
false);
1925 if (strcmp(
fmt,
"filename") == 0) {
2017 if (!
stack->intp)
return NULL;
2019 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 char buffer[256]
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_action_table[]
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 fr_table_num_ordered_t const result_p_location_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.
static int find_result_p_location(result_p_location_t *location, void **chunk, request_t *request, void *ptr)
Try and figure out where result_p points to.
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.
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)
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.
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 result_p_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.
static void instruction_done_debug(request_t *request, unlang_stack_frame_t *frame, unlang_t const *instruction)
int unlang_interpret_push(unlang_result_t *result_p, request_t *request, unlang_t const *instruction, unlang_frame_conf_t const *conf, bool do_next_sibling)
Push a new frame onto the stack.
@ RESULT_P_LOCATION_SCRATCH
@ RESULT_P_LOCATION_MODULE_RCTX
@ RESULT_P_LOCATION_STATE
@ RESULT_P_LOCATION_FRAME
@ RESULT_P_LOCATION_FUNCTION_RCTX
@ RESULT_P_LOCATION_UNKNOWN
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.
#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 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.
rlm_rcode_t default_rcode
The default return code for the frame.
unlang_request_scheduled_t scheduled
Function to check if a request is already scheduled.
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)
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_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_TIMEOUT
Module (or section) timed out.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
#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.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
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
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.
unlang_t * next
Next node (executed on UNLANG_ACTION_EXECUTE_NEXT et al).
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.
unlang_result_t * result_p
Where to write the result of executing the current instruction.
static bool is_repeatable(unlang_stack_frame_t const *frame)
#define UNLANG_NEXT_SIBLING
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 operation.
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_t * children
Children beneath this group.
unlang_frame_flag_t flag
Flags that mark up the frame for various things such as being the point where break,...
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.