26RCSID(
"$Id: f804355df75a2140071ff02f19327fb23128fdfa $")
28#include <freeradius-devel/server/modpriv.h>
29#include <freeradius-devel/server/request_data.h>
68 .debug_name = mi->
name,
103 talloc_steal(
state, mc);
133 state->resume = resume;
248 request->rcode = default_rcode;
277 state->env_data, rctx),
304 if (!
state->retry_cb)
return;
322 state->retry_cb(mctx, request, &
state->retry);
340 state->retry_cb = NULL;
341 state->retry.config = NULL;
343 return state->retry_resume(p_result, mctx, request);
384 state->retry_cb = retry;
385 state->retry_resume = resume;
388 state->request = request;
395 if (!
state->retry.config) {
441 fr_assert_msg(0,
"unlang_module_yield called on a non-module frame");
448 state->resume = resume;
470 state->signal = signal;
471 state->sigmask = sigmask;
516 if (!
state->signal)
return;
525 TALLOC_FREE(
state->ev);
531 caller = request->module;
547 state->thread->active_callers--;
548 state->signal = NULL;
551 request->module = caller;
572 request->module =
state->previous_module;
584 state->thread->active_callers--;
603 resume =
state->resume;
610 state->resume = NULL;
628 if (!
state->resume) {
650 if (!
state->resume) {
667 request->module =
state->previous_module;
672 request->module =
state->previous_module;
683 request->module =
state->previous_module;
704 if (
state->retry_cb) {
744 RDEBUG(
"Reached max_rtx_duration (%pVs > %pVs) - sending timeout",
749 RDEBUG(
"Reached max_rtx_count %u- sending timeout",
750 state->retry.config->mrc);
757 if (
state->retry_cb) {
777 state->previous_module = request->module;
780 state->unlang_indent = request->log.indent.unlang;
805 if (
state->thread->force) {
812 if (!
state->env_data) {
836 state->thread->total_calls++;
878 talloc_set_name_const(
state->rctx,
type);
898 if (!
state->resume) {
921 state->thread->active_callers++;
939 if (!
state->resume) {
974 request->module =
state->previous_module;
999 .unlang_name =
"unlang_module_t",
1002 .frame_state_type =
"unlang_frame_state_module_t",
#define RETURN_UNLANG_ACTION_FATAL
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_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.
unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *env_result, void **env_data, call_env_t const *call_env)
Initialise the expansion of a call environment.
A section grouping multiple CONF_PAIR.
fr_table_num_sorted_t const mod_rcode_table[]
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
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.
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.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
#define FRAME_CONF(_default_rcode, _top_frame)
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
#define RPEDEBUG(fmt,...)
void unlang_register(unlang_op_t *op)
Register an operation with the interpreter.
static char * stack[MAX_STACK]
@ MOD_ACTION_NOT_SET
default "not set by anything"
#define MOD_ACTIONS_FAIL_TIMEOUT_RETURN
void * rctx
Resume ctx that a module previously set.
#define MODULE_CTX(_mi, _thread, _env_data, _rctx)
Wrapper to create a module_ctx_t as a compound literal.
Temporary structure to hold arguments for module calls.
Declarations for the unlang module interface.
static unlang_t * unlang_module_to_generic(unlang_module_t *p)
static unlang_module_t * unlang_generic_to_module(unlang_t const *p)
module_method_call_t mmc
Everything needed to call a module method.
unlang_t self
Common fields in all unlang_t tree nodes.
call_env_t const * call_env
The per call parsed call environment.
A call to a module method.
module_instance_t * mi
The process modules also push module calls onto the stack for execution.
module_method_binding_t mmb
Method we're calling.
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_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.
#define REQUEST_VERIFY(_x)
size_t rctx_size
Size of the module's thread-specific data.
char const * name
Instance name e.g. user_database.
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
module_flags_t flags
Flags that control how a module starts up and how a module is called.
bool force
Force the module to return a specific code.
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.
char const * rctx_type
talloc type to assign to thread instance data.
module_method_t method
Module method to call.
void * data
Thread specific instance data.
call_env_method_t const * method_env
Method specific call_env.
static module_thread_instance_t * module_thread(module_instance_t const *mi)
Retrieve module/thread specific instance for a module.
rlm_rcode_t rcode
Code module will return when 'force' has has been set to true.
size_t rctx_size
If set, this overrides the module_t rctx_size.
char const * rctx_type
If rctx_size is used from the mmb, this sets the type of the rctx.
module_t * exported
Public module structure.
pthread_mutex_t mutex
Used prevent multiple threads entering a thread unsafe module simultaneously.
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_RETRY
a retry timer has hit
@ FR_SIGNAL_TIMEOUT
a retry timeout or max count has hit
@ FR_SIGNAL_CANCEL
Request has been cancelled.
int unlang_module_set_resume(request_t *request, module_method_t resume)
Change the resume function of a module.
static unlang_action_t unlang_module(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
static void safe_lock(module_instance_t *mi)
static void unlang_module_event_retry_handler(UNUSED fr_timer_list_t *tl, fr_time_t now, void *ctx)
Call the callback registered for a retry event.
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.
unlang_action_t unlang_module_yield_to_retry(request_t *request, module_method_t resume, unlang_module_retry_t retry, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx, fr_retry_config_t const *retry_cfg)
Yield a request back to the interpreter, with retries.
void unlang_module_init(void)
static unlang_action_t unlang_module_done(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Cleanup after a module completes.
static unlang_action_t unlang_module_resume(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Wrapper to call a module's resumption function.
void unlang_module_retry_now(module_ctx_t const *mctx, request_t *request)
Run the retry handler.
static unlang_action_t unlang_module_resume_done(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Cleanup after a yielded module completes.
unlang_action_t unlang_module_yield_to_section(unlang_result_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
static unlang_action_t unlang_module_retry_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Cancel the retry timer on resume.
unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt, unlang_tmpl_args_t *args, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Push a pre-compiled tmpl and resumption state onto the stack for evaluation.
int unlang_module_push(unlang_result_t *p_result, request_t *request, module_instance_t *mi, module_method_t method, bool top_frame)
Push a module or submodule onto the stack for evaluation.
static void safe_unlock(module_instance_t *mi)
unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *exp, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Push a pre-compiled xlat and resumption state onto the stack for evaluation.
static void unlang_module_signal(request_t *request, unlang_stack_frame_t *frame, fr_signal_t action)
Send a signal (usually stop) to a request.
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define fr_time_wrap(_time)
#define fr_time_delta_ispos(_a)
#define fr_time_gt(_a, _b)
#define fr_time_sub(_a, _b)
Subtract one time from another.
int unlang_tmpl_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args, bool top_frame)
Push a tmpl onto the stack for evaluation.
void(* unlang_module_retry_t)(module_ctx_t const *mctx, request_t *request, fr_retry_t const *retry)
A callback when a retry happens.
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.
Functions to allow tmpls to push resumption frames onto the stack and inform the interpreter about th...
Arguments for evaluating different types of tmpls.
int unlang_xlat_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
Push a pre-compiled xlat onto the stack for evaluation.
unlang_signal_t signal
function to call when signalling this stack frame
void * state
Stack frame specialisations.
unlang_mod_actions_t actions
Priorities, etc. for the various return codes.
static void unlang_type_init(unlang_t *unlang, unlang_t *parent, unlang_type_t type)
unlang_result_t scratch_result
The result of executing the current instruction.
char const * name
Unknown...
static int stack_depth_current(request_t *request)
@ UNLANG_TYPE_MODULE
Module method.
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.
static bool is_yielded(unlang_stack_frame_t const *frame)
@ UNLANG_OP_FLAG_RETURN_POINT
Return point.
@ UNLANG_OP_FLAG_RCODE_SET
Set request->rcode to the result of this operation.
@ UNLANG_OP_FLAG_INTERNAL
it's not a real keyword
static void repeatable_set(unlang_stack_frame_t *frame)
unlang_process_t process
function to call for interpreting this stack frame
unlang_type_t type
The specialisation of this node.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
fr_retry_state_t fr_retry_next(fr_retry_t *r, fr_time_t now)
Initialize a retransmission counter.
void fr_retry_init(fr_retry_t *r, fr_time_t now, fr_retry_config_t const *config)
Initialize a retransmission counter.
fr_time_delta_t irt
Initial transmission time.
@ FR_RETRY_MRC
reached maximum retransmission count
@ FR_RETRY_MRD
reached maximum retransmission duration
#define fr_box_time_delta(_val)
static size_t char ** out