27 RCSID(
"$Id: 929ecbc1efe3216dcb2d65570e0c360b5e752739 $")
29 #include <freeradius-devel/server/modpriv.h>
30 #include <freeradius-devel/server/request_data.h>
31 #include <freeradius-devel/server/rcode.h>
32 #include <freeradius-devel/unlang/call_env.h>
249 void const *rctx,
int fd)
342 .name = module_instance->
name,
343 .debug_name = module_instance->
name,
359 .instance = module_instance,
372 state = frame->
state;
387 talloc_steal(state, mc);
539 return resume(p_result,
632 if (!state->
signal)
return;
637 caller = request->module;
642 request->module = caller;
649 if (action == FR_SIGNAL_CANCEL) {
737 RWARN(
"Module %s or worker signalled to stop processing request", mc->
instance->
module->name);
740 *p_result = state->
rcode;
850 frame->
signal(request, frame, FR_SIGNAL_RETRY);
863 REDEBUG(
"Reached max_rtx_duration (%pVs > %pVs) - sending timeout signal",
868 REDEBUG(
"Reached max_rtx_count (%u > %u) - sending timeout signal",
873 frame->
signal(request, frame, FR_SIGNAL_TIMEOUT);
972 *p_result = state->
rcode;
1002 RPEDEBUG(
"Failed inserting event");
1075 .frame_state_type =
"unlang_frame_state_module_t",
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.
@ 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.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
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_event_fd_insert(...)
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
#define fr_event_timer_at(...)
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
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 unlang_interpret_push_section(request_t *request, CONF_SECTION *cs, rlm_rcode_t default_rcode, bool top_frame)
Push a configuration section onto the request stack for later interpretation.
#define RPEDEBUG(fmt,...)
void unlang_register(int type, unlang_op_t *op)
Register an operation with the interpreter.
int fr_event_timer_delete(fr_event_timer_t const **ev_p)
Delete a timer event from the event list.
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Stores all information relating to an event list.
static char * stack[MAX_STACK]
#define MODULE_CTX(_dl_inst, _thread, _env_data, _rctx)
Wrapper to create a module_ctx_t as a compound literal.
Declarations for the unlang module interface.
static unlang_module_t * unlang_generic_to_module(unlang_t const *p)
fr_event_timer_t const * ev
retry timer just for this module.
rlm_rcode_t rcode
the result, only for unlang_module_resume_final.
module_method_t resume
resumption handler
module_instance_t * instance
Global instance of the module we're calling.
static unlang_t * unlang_module_to_generic(unlang_module_t *p)
char const * previous_module
old request->module
fr_signal_t sigmask
Signals to block.
bool set_rcode
Overwrite the current rcode for the section with the module rcode.
call_env_result_t env_result
Result of the previous call environment expansion.
fr_retry_t retry
retry timers, etc.
void * env_data
Expanded per call "call environment" tmpls.
rlm_rcode_t * p_result
Where to store the result.
module_thread_instance_t * thread
thread-local data for this module.
unlang_t self
Common fields in all unlang_t tree nodes.
unlang_module_signal_t signal
for signal handlers
int unlang_indent
Record what this was when we entered the module.
module_method_t method
The entry point into the module.
void * rctx
for resume / signal
call_env_t const * call_env
The per call parsed call environment.
A call to a module method.
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_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_STOP_PROCESSING
void * request_data_get(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request.
#define request_data_talloc_add(_request, _unique_ptr, _unique_int, _type, _opaque, _free_on_replace, _free_on_parent, _persist)
Add opaque data to a request_t.
char const * name
Instance name e.g. user_database.
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
uint64_t active_callers
total number of times we've been called
bool force
Force the module to return a specific code.
dl_module_inst_t * dl_inst
Structure containing the module's instance data, configuration, and dl handle.
void * data
Thread specific instance data.
rlm_rcode_t code
Code module will return when 'force' has has been set to true.
module_t const * module
Public module structure.
unlang_action_t(* module_method_t)(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Module section callback.
pthread_mutex_t mutex
Used prevent multiple threads entering a thread unsafe module simultaneously.
module_thread_instance_t * module_thread(module_instance_t *mi)
Retrieve module/thread specific instance for a module.
static void unlang_module_event_timeout_handler(UNUSED fr_event_list_t *el, fr_time_t now, void *ctx)
Call the callback registered for a timeout event.
unlang_action_t unlang_module_yield_to_section(rlm_rcode_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)
int unlang_module_set_resume(request_t *request, module_method_t resume)
Change the resume function of a module.
unlang_module_fd_event_t fd_read
Function to call when FD is readable.
static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
void * env_data
Per call environment data.
static void unlang_event_fd_error_handler(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, UNUSED int fd_errno, void *ctx)
Call the callback registered for an I/O error event.
request_t * request
Request this event pertains to.
int unlang_module_fd_add(request_t *request, unlang_module_fd_event_t read, unlang_module_fd_event_t write, unlang_module_fd_event_t error, void const *rctx, int fd)
Set a callback for the request.
static int _unlang_event_free(unlang_module_event_t *ev)
Frees an unlang event, removing it from the request's event loop.
int unlang_module_timeout_delete(request_t *request, void const *ctx)
Delete a previously set timeout callback.
unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, bool *p_success, 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_event_fd_write_handler(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *ctx)
Call the callback registered for a write I/O event.
static void safe_lock(module_instance_t *mi)
int fd
File descriptor to wait on.
unlang_module_timeout_t timeout
Function to call on timeout.
dl_module_inst_t * dl_inst
Module instance to pass to callbacks.
unlang_module_fd_event_t fd_error
Function to call when FD has errored.
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.
void unlang_module_init(void)
void * thread
Thread specific module instance.
static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Wrapper to call a module's resumption function.
static unlang_action_t unlang_module_resume_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Cleanup after a yielded module completes.
static unlang_action_t unlang_module_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Cleanup after a module completes.
static void unlang_module_event_retry_handler(UNUSED fr_event_list_t *el, fr_time_t now, void *ctx)
Call the callback registered for a retry event.
fr_event_timer_t const * ev
Event in this worker's event heap.
int unlang_module_push(rlm_rcode_t *p_result, request_t *request, module_instance_t *module_instance, module_method_t method, bool top_frame)
Push a module or submodule onto the stack for evaluation.
int unlang_module_timeout_add(request_t *request, unlang_module_timeout_t callback, void const *rctx, fr_time_t when)
Set a timeout for the request.
static void unlang_event_fd_read_handler(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *ctx)
Call the callback registered for a read I/O event.
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.
static void safe_unlock(module_instance_t *mi)
unlang_module_fd_event_t fd_write
Function to call when FD is writable.
void const * rctx
rctx data to pass to callbacks.
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.
int unlang_module_fd_delete(request_t *request, void const *ctx, int fd)
Delete a previously set file descriptor callback.
Wrap an fr_event_timer_t providing data needed for unlang events.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
#define fr_time()
Allow us to arbitrarily manipulate time.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#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, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args)
Push a tmpl onto the stack for evaluation.
static fr_event_list_t * el
void(* unlang_module_fd_event_t)(module_ctx_t const *mctx, request_t *request, int fd)
A callback when the FD is ready for reading.
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.
void(* unlang_module_timeout_t)(module_ctx_t const *mctx, request_t *request, fr_time_t fired)
A callback when the the timeout occurs.
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, bool *p_success, 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.
#define MOD_ACTION_RETURN
static void return_point_set(unlang_stack_frame_t *frame)
unlang_actions_t actions
Priorities, etc. for the various return codes.
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)
rlm_rcode_t result
The result from executing the instruction.
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.
static unlang_stack_frame_t * frame_current(request_t *request)
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_t start
when we started the retransmission
fr_time_delta_t irt
Initial transmission time.
uint32_t mrc
Maximum retransmission count.
fr_retry_config_t const * config
master configuration
@ FR_RETRY_MRC
reached maximum retransmission count
@ FR_RETRY_MRD
reached maximum retransmission duration
uint32_t count
number of sent packets
fr_time_delta_t mrd
Maximum retransmission duration.
fr_time_t next
when the next timer should be set
#define fr_box_time_delta(_val)
static size_t char ** out