28#include <freeradius-devel/server/cf_util.h>
29#include <freeradius-devel/server/map_proc.h>
30#include <freeradius-devel/server/modpriv.h>
31#include <freeradius-devel/util/debug.h>
32#include <freeradius-devel/unlang/base.h>
33#include <freeradius-devel/io/listen.h>
92#define UNLANG_NEXT_STOP (false)
93#define UNLANG_NEXT_SIBLING (true)
95#define UNLANG_DETACHABLE (true)
96#define UNLANG_NORMAL_CHILD (false)
251#define unlang_frame_perf_init(_x)
252#define unlang_frame_perf_yield(_x)
253#define unlang_frame_perf_resume(_x)
254#define unlang_frame_perf_cleanup(_x)
329#define MOD_NUM_TYPES (UNLANG_TYPE_XLAT + 1)
334#define UNWIND_FLAG_NONE 0x00
335#define UNWIND_FLAG_REPEAT 0x01
336#define UNWIND_FLAG_TOP_FRAME 0x02
340#define UNWIND_FLAG_BREAK_POINT 0x04
341#define UNWIND_FLAG_RETURN_POINT 0x08
342#define UNWIND_FLAG_NO_CLEAR 0x10
343#define UNWIND_FLAG_YIELDED 0x20
414#ifdef HAVE_TALLOC_ZERO_POOLED_OBJECT
432 talloc_set_name_const(frame->
state,
name);
457 talloc_free_children(frame->
state);
458 TALLOC_FREE(frame->
state);
497 TALLOC_FREE(frame->
retry);
560 rlm_rcode_t default_rcode,
bool do_next_sibling,
bool top_frame)
561 CC_HINT(warn_unused_result);
565 CC_HINT(warn_unused_result);
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_UNWIND
Break out of the current group.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
#define UNLANG_STACK_MAX
The maximum depth of the stack.
static char * stack[MAX_STACK]
rlm_rcode_t
Return codes indicating the result of the module call.
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
fr_aka_sim_id_type_t type
An element in a lexicographically sorted array of name to num mappings.
#define talloc_get_type_abort_const
#define UNWIND_FLAG_RETURN_POINT
'return' stops here.
#define unlang_frame_perf_resume(_x)
size_t frame_state_pool_objects
How many sub-allocations we expect.
void unlang_register(int type, unlang_op_t *op)
Register an operation with the interpreter.
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.
static unlang_action_t unwind_to_return(unlang_stack_t *stack)
void unlang_switch_init(void)
static bool is_repeatable(unlang_stack_frame_t const *frame)
#define UNWIND_FLAG_TOP_FRAME
are we the top frame of the stack? If true, causes the interpreter to stop interpreting and return,...
unlang_interpret_t * intp
Interpreter that the request is currently associated with.
static void repeatable_clear(unlang_stack_frame_t *frame)
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.
char const * frame_state_type
talloc name of the frame instance data
char const * type_name
Talloc type name.
void * state
Stack frame specialisations.
void unlang_foreach_init(TALLOC_CTX *ctx)
unlang_mod_actions_t actions
Priorities, etc. for the various return codes.
void(* unlang_signal_t)(request_t *request, unlang_stack_frame_t *frame, fr_signal_t action)
Function to call if the request was signalled.
unlang_t * parent
Previous node.
void unlang_limit_init(void)
unlang_action_t(* unlang_process_t)(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Function to call when interpreting a frame.
unlang_signal_t signal
Function to signal stop / dup / whatever.
int unlang_subrequest_op_init(void)
Initialise subrequest ops.
size_t frame_state_size
size of instance data in the stack frame
char const * thread_inst_type
fr_dict_attr_t const * root
the root of our dictionary
rlm_rcode_t result
The current stack rcode.
int(* unlang_thread_instantiate_t)(unlang_t const *instruction, void *thread_inst)
void unlang_timeout_init(void)
static void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t *frame)
void unlang_frame_signal(request_t *request, fr_signal_t action, int limit)
Send a signal (usually stop) to a request.
#define unlang_frame_perf_init(_x)
bool rcode_set
Set request->rcode to the result of this operation.
void unlang_edit_init(void)
void unlang_tmpl_init(void)
void unlang_call_init(void)
int priority
Result priority.
void unlang_map_init(void)
#define UNWIND_FLAG_YIELDED
frame has yielded
bool closed
whether or not this section is closed to new statements
unlang_dump_t dump
Dump additional information about the frame state.
static unlang_t * unlang_group_to_generic(unlang_group_t const *p)
static unlang_action_t unwind_all(unlang_stack_t *stack)
void unlang_condition_init(void)
#define UNWIND_FLAG_NO_CLEAR
Keep unwinding, don't clear the unwind flag.
uint8_t unwind
Unwind to this frame if it exists.
#define UNWIND_FLAG_BREAK_POINT
'break' stops here.
unlang_t ** tail
pointer to the tail which gets updated
static void top_frame_clear(unlang_stack_frame_t *frame)
unlang_process_t interpret
Function to interpret the keyword.
uint8_t uflags
Unwind markers.
int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame)
Push a new frame onto the stack.
int depth
of this retry structure
static void frame_cleanup(unlang_stack_frame_t *frame)
Cleanup any lingering frame state.
static unlang_t * unlang_tmpl_to_generic(unlang_tmpl_t const *p)
void unlang_op_free(void)
void unlang_load_balance_init(void)
static void break_point_clear(unlang_stack_frame_t *frame)
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)
void(* unlang_dump_t)(request_t *request, unlang_stack_frame_t *frame)
Custom callback for dumping information about frame state.
unsigned int number
unique node number
#define UNWIND_FLAG_REPEAT
Repeat the frame on the way up the stack.
void unlang_group_init(void)
size_t mod_rcode_table_len
void unlang_parallel_init(void)
static unlang_stack_frame_t * frame_current(request_t *request)
fr_event_timer_t const * ev
void unlang_transaction_init(void)
static void stack_unwind_break_clear(unlang_stack_t *stack)
static void return_point_set(unlang_stack_frame_t *frame)
int depth
Current depth we're executing at.
char const * name
Unknown...
request_t * unlang_io_subrequest_alloc(request_t *parent, fr_dict_t const *namespace, bool detachable)
Allocate a child request based on the parent.
static int stack_depth_current(request_t *request)
static bool is_break_point(unlang_stack_frame_t const *frame)
void unlang_return_init(void)
void unlang_detach_init(void)
Initialise subrequest ops.
unlang_type_t
Types of unlang_t nodes.
@ UNLANG_TYPE_SWITCH
Switch section.
@ UNLANG_TYPE_TRANSACTION
transactions for editing lists
@ UNLANG_TYPE_SUBREQUEST
create a child subrequest
@ UNLANG_TYPE_UPDATE
Update block.
@ UNLANG_TYPE_ELSIF
!Condition && Condition.
@ UNLANG_TYPE_ELSE
!Condition.
@ UNLANG_TYPE_LOAD_BALANCE
Load balance section.
@ UNLANG_TYPE_DETACH
detach a child
@ UNLANG_TYPE_GROUP
Grouping section.
@ UNLANG_TYPE_POLICY
Policy section.
@ UNLANG_TYPE_TMPL
asynchronously expand a tmpl_t
@ UNLANG_TYPE_CASE
Case section (within a UNLANG_TYPE_SWITCH).
@ UNLANG_TYPE_LIMIT
limit number of requests in a section
@ UNLANG_TYPE_BREAK
Break statement (within a UNLANG_TYPE_FOREACH).
@ UNLANG_TYPE_TRY
try / catch blocks
@ UNLANG_TYPE_CALL
call another virtual server
@ UNLANG_TYPE_RETURN
Return statement.
@ UNLANG_TYPE_REDUNDANT
exactly like group, but with different default return codes
@ UNLANG_TYPE_IF
Condition.
@ UNLANG_TYPE_XLAT
Represents one level of an xlat expansion.
@ UNLANG_TYPE_NULL
unlang type not set.
@ UNLANG_TYPE_MAP
Mapping section (like UNLANG_TYPE_UPDATE, but uses values from a map_proc_t call).
@ UNLANG_TYPE_CALLER
conditionally check parent dictionary type
@ UNLANG_TYPE_TIMEOUT
time-based timeouts.
@ UNLANG_TYPE_MODULE
Module method.
@ UNLANG_TYPE_REDUNDANT_LOAD_BALANCE
Redundant load balance section.
@ UNLANG_TYPE_CATCH
catch a previous try
@ UNLANG_TYPE_FUNCTION
Internal call to a function or submodule.
@ UNLANG_TYPE_EDIT
edit VPs in place. After 20 years!
@ UNLANG_TYPE_FOREACH
Foreach section.
@ UNLANG_TYPE_PARALLEL
execute statements in parallel
static void frame_repeat(unlang_stack_frame_t *frame, unlang_process_t process)
Mark the current stack frame up for repeat, and set a new process function.
unlang_t const * instruction
The unlang node we're evaluating.
bool debug_braces
Whether the operation needs to print braces in debug mode.
size_t len
Total length of the unlang_group_t + specialisation struct.
void unlang_try_init(void)
static void break_point_set(unlang_stack_frame_t *frame)
static bool is_yielded(unlang_stack_frame_t const *frame)
void unlang_catch_init(void)
size_t frame_state_pool_size
The total size of the pool to alloc.
unlang_type_t type
Keyword.
static void top_frame_set(unlang_stack_frame_t *frame)
unlang_variable_t * variables
rarely used, so we don't usually need it
static unlang_tmpl_t * unlang_generic_to_tmpl(unlang_t const *p)
void unlang_module_init(void)
unlang_t const * instruction
instruction which we're executing
unlang_action_t unlang_interpret_push_children(rlm_rcode_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.
rlm_rcode_t result
The result from executing the instruction.
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)
void unlang_function_init(void)
static void yielded_clear(unlang_stack_frame_t *frame)
#define unlang_frame_perf_yield(_x)
int priority
Current priority.
static bool is_stack_unwinding_to_return(unlang_stack_t *stack)
static bool is_stack_unwinding_to_top_frame(unlang_stack_t *stack)
size_t pool_len
How much additional space to allocate for extensions.
unsigned pool_headers
How much additional space to allocate for chunk headers.
#define unlang_frame_perf_cleanup(_x)
unlang_t const * next
The next unlang node we will evaluate.
unlang_op_t unlang_ops[]
Different operations the interpreter can execute.
fr_table_num_sorted_t const mod_rcode_table[]
static void stack_unwind_return_clear(unlang_stack_t *stack)
static bool is_stack_unwinding_to_break(unlang_stack_t *stack)
int max_attr
1..N local attributes have been defined
unlang_thread_instantiate_t thread_instantiate
per-thread instantiation function
fr_dict_t * dict
our dictionary
void * unlang_thread_instance(unlang_t const *instruction)
Get the thread-instance data for an instruction.
static bool is_return_point(unlang_stack_frame_t const *frame)
static void return_point_clear(unlang_stack_frame_t *frame)
static void repeatable_set(unlang_stack_frame_t *frame)
void unlang_subrequest_op_free(void)
void unlang_caller_init(void)
static unlang_action_t unwind_to_break(unlang_stack_t *stack)
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.
static void stack_unwind_top_frame_clear(unlang_stack_t *stack)
void * thread_inst
thread-specific instance data
Describes how to allocate an unlang_group_t with additional memory keyword specific data.
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.