From: Arran Cudbard-Bell Date: Fri, 12 Mar 2021 14:42:34 +0000 (+0000) Subject: Change process and signal functions to pass the current frame X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=934613f12b9419ebdee9674221be29ed2ec58c97;p=thirdparty%2Ffreeradius-server.git Change process and signal functions to pass the current frame For signal functions this is important because all frames are signalled. For process functions it removes significant amounts of boilerplate. --- diff --git a/src/lib/io/worker.c b/src/lib/io/worker.c index a6b1a990b92..f1a979f5683 100644 --- a/src/lib/io/worker.c +++ b/src/lib/io/worker.c @@ -1239,19 +1239,26 @@ void fr_worker_post_event(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void /** Asynchronously add a request_t to a worker thread * * When we don't know what the worker is... + * + * @param[in] request to add. + * @param[in] process module method to call when the request is executed. + * @param[in] uctx to pass to the process method. + * @return + * - 0 on success. + * - -1 on failure. */ -int fr_worker_request_add(request_t *request, module_method_t process, void *ctx) +int fr_worker_request_add(request_t *request, module_method_t process, void *uctx) { fr_worker_t *worker; fr_time_t now; - if (!request || !process) { + if (unlikely(!request || !process)) { fr_strerror_const("Invalid arguments"); return -1; } worker = thread_local_worker; - if (!worker) { + if (unlikely(!worker)) { fr_strerror_const("No worker has been defined"); return -1; } @@ -1262,7 +1269,7 @@ int fr_worker_request_add(request_t *request, module_method_t process, void *ctx fr_assert(request_is_internal(request)); request->async->process = process; - request->async->process_inst = ctx; + request->async->process_inst = uctx; worker_request_time_tracking_start(worker, request, now); diff --git a/src/lib/server/request.c b/src/lib/server/request.c index 6ac42046a52..d975472c869 100644 --- a/src/lib/server/request.c +++ b/src/lib/server/request.c @@ -553,6 +553,13 @@ int request_detach(request_t *child) fr_assert(request != NULL); + /* + * Let any signal handler that cares + * know that the child is about to + * be detached. + */ + unlang_interpret_signal(child, FR_SIGNAL_DETACH); + /* * Unlink the child from the parent. */ diff --git a/src/lib/server/signal.h b/src/lib/server/signal.h index c93a4912c11..b92f7be95c1 100644 --- a/src/lib/server/signal.h +++ b/src/lib/server/signal.h @@ -40,6 +40,7 @@ typedef enum fr_state_signal_t { /* server action */ ///< with this, the module should stop processing ///< the request and cleanup anything it's done. FR_SIGNAL_DUP, //!< A duplicate request was received. + FR_SIGNAL_DETACH //!< Request is being detached from its parent. } fr_state_signal_t; #ifdef __cplusplus diff --git a/src/lib/unlang/base.h b/src/lib/unlang/base.h index d2233fe7666..8856bd67efb 100644 --- a/src/lib/unlang/base.h +++ b/src/lib/unlang/base.h @@ -24,6 +24,7 @@ * @copyright 2016-2019 The FreeRADIUS server project */ #include +#include #include #include #include @@ -32,13 +33,8 @@ extern "C" { #endif -#define UNLANG_STACK_MAX (64) //!< The maximum depth of the stack. -#define UNLANG_FRAME_PRE_ALLOC (128) //!< How much memory we pre-alloc for each frame. - bool unlang_section(CONF_SECTION *cs); -void unlang_register(int type, unlang_op_t *op); - int unlang_init(void); void unlang_free(void); diff --git a/src/lib/unlang/call.c b/src/lib/unlang/call.c index e5eef50e63e..73ae1237316 100644 --- a/src/lib/unlang/call.c +++ b/src/lib/unlang/call.c @@ -30,13 +30,11 @@ RCSID("$Id$") #include "call_priv.h" #include "unlang_priv.h" -static unlang_action_t unlang_call_process(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_call_process(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_call_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_call_t); - unlang_t *instruction = frame->instruction; - unlang_group_t *g = unlang_generic_to_group(instruction); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); rlm_rcode_t rcode; unlang_action_t ua; @@ -83,13 +81,10 @@ static unlang_action_t unlang_call_process(rlm_rcode_t *p_result, request_t *req return UNLANG_ACTION_CALCULATE_RESULT; } -static unlang_action_t unlang_call_frame_init(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_call_frame_init(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_call_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_call_t); - unlang_t *instruction = frame->instruction; - unlang_group_t *g; unlang_call_t *gext; char const *server; @@ -105,7 +100,7 @@ static unlang_action_t unlang_call_frame_init(rlm_rcode_t *p_result, request_t * * can still be side effects from executing the virtual * server. */ - g = unlang_generic_to_group(instruction); + g = unlang_generic_to_group(frame->instruction); gext = unlang_group_to_call(g); server = cf_section_name2(gext->server_cs); @@ -141,7 +136,7 @@ static unlang_action_t unlang_call_frame_init(rlm_rcode_t *p_result, request_t * .prev_server_cs = request->server_cs, }; - return unlang_call_process(p_result, request); + return unlang_call_process(p_result, request, frame); } /** Push a call to a virtual server onto the stack for evaluation diff --git a/src/lib/unlang/caller.c b/src/lib/unlang/caller.c index a446d7f7992..821295b43aa 100644 --- a/src/lib/unlang/caller.c +++ b/src/lib/unlang/caller.c @@ -30,17 +30,10 @@ RCSID("$Id$") #include "unlang_priv.h" #include "group_priv.h" -static unlang_action_t unlang_caller(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_caller(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - - unlang_group_t *g; - unlang_caller_t *gext; - - g = unlang_generic_to_group(instruction); - gext = unlang_group_to_caller(g); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_caller_t *gext = unlang_group_to_caller(g); fr_assert(g->num_children > 0); /* otherwise the compilation is broken */ @@ -55,7 +48,7 @@ static unlang_action_t unlang_caller(rlm_rcode_t *p_result, request_t *request) /* * The dictionary matches. Go recurse into its' children. */ - return unlang_group(p_result, request); + return unlang_group(p_result, request, frame); } diff --git a/src/lib/unlang/condition.c b/src/lib/unlang/condition.c index d5292ae3c0c..963de7b9773 100644 --- a/src/lib/unlang/condition.c +++ b/src/lib/unlang/condition.c @@ -28,18 +28,12 @@ RCSID("$Id$") #include "group_priv.h" #include "unlang_priv.h" -static unlang_action_t unlang_if(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_if(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { int condition; - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_cond_t *gext = unlang_group_to_cond(g); - unlang_group_t *g; - unlang_cond_t *gext; - - g = unlang_generic_to_group(instruction); - gext = unlang_group_to_cond(g); fr_assert(gext->cond != NULL); condition = cond_eval(request, *p_result, gext->cond); @@ -79,7 +73,7 @@ static unlang_action_t unlang_if(rlm_rcode_t *p_result, request_t *request) /* * We took the "if". Go recurse into its' children. */ - return unlang_group(p_result, request); + return unlang_group(p_result, request, frame); } void unlang_condition_init(void) diff --git a/src/lib/unlang/foreach.c b/src/lib/unlang/foreach.c index 0dea4f91757..20c12dd7e1e 100644 --- a/src/lib/unlang/foreach.c +++ b/src/lib/unlang/foreach.c @@ -75,19 +75,11 @@ static int _free_unlang_frame_state_foreach(unlang_frame_state_foreach_t *state) return 0; } -static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { fr_pair_t *vp; - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_frame_state_foreach_t *foreach = NULL; - unlang_group_t *g; - - g = unlang_generic_to_group(instruction); - - foreach = talloc_get_type_abort(frame->state, unlang_frame_state_foreach_t); - + unlang_frame_state_foreach_t *foreach = talloc_get_type_abort(frame->state, unlang_frame_state_foreach_t); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); vp = fr_dcursor_current(&foreach->cursor); if (!vp) { *p_result = frame->result; @@ -126,24 +118,17 @@ static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *req } -static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame; - unlang_t *instruction; unlang_frame_state_foreach_t *foreach = NULL; - - unlang_group_t *g; - unlang_foreach_t *gext; + unlang_stack_t *stack = request->stack; + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_foreach_t *gext = unlang_group_to_foreach(g); int i, foreach_depth = 0; fr_pair_list_t vps; - frame = &stack->frame[stack->depth]; fr_pair_list_init(&vps); - instruction = frame->instruction; - g = unlang_generic_to_group(instruction); - gext = unlang_group_to_foreach(g); /* * Ensure any breaks terminate here... @@ -154,7 +139,7 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request) * Figure out foreach depth by walking back up the stack */ if (stack->depth > 0) for (i = (stack->depth - 1); i >= 0; i--) { - unlang_t *our_instruction; + unlang_t const *our_instruction; our_instruction = stack->frame[i].instruction; if (!our_instruction || (our_instruction->type != UNLANG_TYPE_FOREACH)) continue; foreach_depth++; @@ -166,7 +151,7 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request) return UNLANG_ACTION_CALCULATE_RESULT; } - MEM(frame->state = foreach = talloc_zero(stack, unlang_frame_state_foreach_t)); + MEM(frame->state = foreach = talloc_zero(request->stack, unlang_frame_state_foreach_t)); fr_pair_list_init(&foreach->vps); /* @@ -191,16 +176,12 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request) talloc_set_destructor(foreach, _free_unlang_frame_state_foreach); frame->process = unlang_foreach_next; - return unlang_foreach_next(p_result, request); + return unlang_foreach_next(p_result, request, frame); } -static unlang_action_t unlang_break(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_break(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - - RDEBUG2("%s", unlang_ops[instruction->type].name); + RDEBUG2("%s", unlang_ops[frame->instruction->type].name); *p_result = frame->result; @@ -208,7 +189,7 @@ static unlang_action_t unlang_break(rlm_rcode_t *p_result, request_t *request) * Stop at the next break point, or if we hit * the a top frame. */ - return unwind_to_break(stack); + return unwind_to_break(request->stack); } /** Implements the Foreach-Variable-X diff --git a/src/lib/unlang/function.c b/src/lib/unlang/function.c index f09405ea430..b0789f62b94 100644 --- a/src/lib/unlang/function.c +++ b/src/lib/unlang/function.c @@ -20,12 +20,13 @@ * @file unlang/function.c * @brief Unlang "function" keyword evaluation. - * @copyright 2018 The FreeRADIUS server project - * @copyright 2018 Arran Cudbard-Bell (a.cudbardb@freeradius.org) + * @copyright 2018,2021 The FreeRADIUS server project + * @copyright 2018,2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org) */ RCSID("$Id$") #include "unlang_priv.h" +#include "function.h" /* * Some functions differ mainly in their parsing @@ -33,6 +34,7 @@ RCSID("$Id$") typedef struct { unlang_function_t func; //!< To call when going down the stack. unlang_function_t repeat; //!< To call when going back up the stack. + unlang_function_signal_t signal; //!< Signal function to call. void *uctx; //!< Uctx to pass to function. } unlang_frame_state_func_t; @@ -56,15 +58,30 @@ static unlang_t function_instruction = { } }; +/** Generic signal handler + * + * @param[in] request being signalled. + * @param[in] frame being signalled. + * @param[in] action Type of signal. + */ +static void unlang_function_signal(request_t *request, + unlang_stack_frame_t *frame, fr_state_signal_t action) +{ + unlang_frame_state_func_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t); + + if (!state->signal) return; + + state->signal(request, action, state->uctx); +} + /** Call a generic function * - * @param[out] p_result The frame result. - * @param[in] request The current request. + * @param[out] p_result The frame result. + * @param[in] request The current request. + * @param[in] frame The current frame. */ -static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_func_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t); unlang_action_t ua; char const *caller; @@ -76,9 +93,9 @@ static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *re caller = request->module; request->module = NULL; if (!is_repeatable(frame)) { - ua = state->func(p_result, NULL, request, state->uctx); + ua = state->func(p_result, &frame->priority, request, state->uctx); } else { - ua = state->repeat(p_result, NULL, request, state->uctx); + ua = state->repeat(p_result, &frame->priority, request, state->uctx); } request->module = caller; @@ -94,12 +111,14 @@ static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *re * @param[in] func to call going up the stack. * @param[in] repeat function to call going back down the stack (may be NULL). * This may be the same as func. + * @param[in] signal function to call if the request is signalled. * @param[in] uctx to pass to func. * @return * - 0 on success. * - -1 on failure. */ -int unlang_interpret_push_function(request_t *request, unlang_function_t func, unlang_function_t repeat, void *uctx) +int unlang_interpret_push_function(request_t *request, unlang_function_t func, unlang_function_t repeat, + unlang_function_signal_t signal, void *uctx) { unlang_stack_t *stack = request->stack; unlang_stack_frame_t *frame; @@ -125,6 +144,7 @@ int unlang_interpret_push_function(request_t *request, unlang_function_t func, u state = frame->state; state->func = func; state->repeat = repeat; + state->signal = signal; state->uctx = uctx; return 0; @@ -136,6 +156,7 @@ void unlang_function_init(void) &(unlang_op_t){ .name = "function", .interpret = unlang_function_call, + .signal = unlang_function_signal, .debug_braces = false, .frame_state_size = sizeof(unlang_frame_state_func_t), .frame_state_name = "unlang_frame_state_func_t", diff --git a/src/lib/unlang/function.h b/src/lib/unlang/function.h new file mode 100644 index 00000000000..a4da0432c89 --- /dev/null +++ b/src/lib/unlang/function.h @@ -0,0 +1,62 @@ +#pragma once +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * $Id$ + * + * @file unlang/function.h + * @brief Declarations for generic unlang functions. + * + * @copyright 2021 The FreeRADIUS server project + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** A generic function pushed by a module or xlat to functions deeper in the C call stack to create resumption points + * + * @param[in] request The current request. + * @param[in,out] uctx Provided by whatever pushed the function. Is opaque to the + * interpreter, but should be usable by the function. + * All input (args) and output will be done using this structure. + * @return an #unlang_action_t. + */ +typedef unlang_action_t (*unlang_function_t)(rlm_rcode_t *p_result, int *priority, request_t *request, void *uctx); + +/** Function to call if the request was signalled + * + * @param[in] request The current request. + * @param[in] action We're being signalled with. + * @param[in,out] uctx Provided by whatever pushed the function. Is opaque to the + * interpreter, but should be usable by the function. + * All input (args) and output will be done using this structure. + */ +typedef void (*unlang_function_signal_t)(request_t *request, fr_state_signal_t action, void *uctx); + +int unlang_interpret_push_function(request_t *request, + unlang_function_t func, unlang_function_t repeat, + unlang_function_signal_t signal, void *uctx) + CC_HINT(warn_unused_result); + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/unlang/group.c b/src/lib/unlang/group.c index 5db60e7a5c8..079968fbbce 100644 --- a/src/lib/unlang/group.c +++ b/src/lib/unlang/group.c @@ -27,14 +27,9 @@ RCSID("$Id$") #include "unlang_priv.h" #include "group_priv.h" -unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request) +unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_group_t *g; - - g = unlang_generic_to_group(instruction); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); /* * The compiler catches most of these, EXCEPT for the @@ -42,7 +37,7 @@ unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request) * and can be empty. */ if (!g->children) { - RDEBUG2("} # %s ... ", instruction->debug_name); + RDEBUG2("} # %s ... ", frame->instruction->debug_name); return UNLANG_ACTION_EXECUTE_NEXT; } @@ -54,17 +49,14 @@ unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request) return UNLANG_ACTION_PUSHED_CHILD; } -static unlang_action_t unlang_policy(rlm_rcode_t *result, request_t *request) +static unlang_action_t unlang_policy(rlm_rcode_t *result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - /* * Ensure returns stop at the enclosing policy */ return_point_set(frame); - return unlang_group(result, request); + return unlang_group(result, request, frame); } diff --git a/src/lib/unlang/group_priv.h b/src/lib/unlang/group_priv.h index a0549fa6be3..2279be11398 100644 --- a/src/lib/unlang/group_priv.h +++ b/src/lib/unlang/group_priv.h @@ -29,7 +29,7 @@ extern "C" { #endif -unlang_action_t unlang_group(UNUSED rlm_rcode_t *p_result, request_t *request); +unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame); #ifdef __cplusplus } diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index dae86d677d0..6a8486b55ad 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -69,11 +69,8 @@ static void instruction_dump(request_t *request, unlang_t const *instruction) static void frame_dump(request_t *request, unlang_stack_frame_t *frame) { instruction_dump(request, frame->instruction); - unlang_stack_t *stack = request->stack; RINDENT(); - - RDEBUG("frame %zd", (frame - stack->frame)); if (frame->state) RDEBUG2("state %s (%p)", talloc_get_name(frame->state), frame->state); if (frame->next) { RDEBUG2("next %s", frame->next->debug_name); @@ -167,7 +164,7 @@ static inline void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t * - 0 on success. * - -1 on call stack too deep. */ -int unlang_interpret_push(request_t *request, unlang_t *instruction, +int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame) { unlang_stack_t *stack = request->stack; @@ -424,8 +421,8 @@ static inline void frame_pop(unlang_stack_t *stack) * was called. * - UNLANG_FRAME_ACTION_POP the final result has been calculated for this frame. */ -static inline unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame, - rlm_rcode_t *result, int *priority) +static inline CC_HINT(always_inline) +unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame, rlm_rcode_t *result, int *priority) { unlang_stack_t *stack = request->stack; @@ -458,7 +455,7 @@ static inline unlang_frame_action_t frame_eval(request_t *request, unlang_stack_ if (request->master_state == REQUEST_STOP_PROCESSING) { do_stop: frame->result = RLM_MODULE_FAIL; - frame->priority = 9999; + frame->priority = MOD_PRIORITY_MAX; RDEBUG4("** [%i] %s - STOP current subsection with (%s %d)", stack->depth, __FUNCTION__, @@ -481,7 +478,7 @@ static inline unlang_frame_action_t frame_eval(request_t *request, unlang_stack_ unlang_ops[instruction->type].name); fr_assert(frame->process != NULL); - action = frame->process(result, request); + action = frame->process(result, request, frame); RDEBUG4("** [%i] %s << %s (%d)", stack->depth, __FUNCTION__, fr_table_str_by_value(unlang_action_table, action, ""), *priority); @@ -624,7 +621,6 @@ static inline unlang_frame_action_t frame_eval(request_t *request, unlang_stack_ */ rlm_rcode_t unlang_interpret(request_t *request) { - int priority = -1; unlang_frame_action_t fa = UNLANG_FRAME_ACTION_NEXT; /* @@ -633,6 +629,8 @@ rlm_rcode_t unlang_interpret(request_t *request) unlang_stack_t *stack = request->stack; unlang_stack_frame_t *frame = &stack->frame[stack->depth]; /* Quiet static analysis */ + stack->priority = -1; /* Reset */ + #ifndef NDEBUG if (DEBUG_ENABLED5) DEBUG("###### unlang_interpret is starting"); DUMP_STACK; @@ -651,7 +649,7 @@ rlm_rcode_t unlang_interpret(request_t *request) fr_assert(stack->depth < UNLANG_STACK_MAX); frame = &stack->frame[stack->depth]; - fa = frame_eval(request, frame, &stack->result, &priority); + fa = frame_eval(request, frame, &stack->result, &stack->priority); /* * We were executing a frame, frame_eval() @@ -677,7 +675,7 @@ rlm_rcode_t unlang_interpret(request_t *request) * if we had performed a module call. */ stack->result = frame->result; - priority = frame->priority; + stack->priority = frame->priority; /* * Head on back up the stack @@ -720,7 +718,7 @@ rlm_rcode_t unlang_interpret(request_t *request) } } - fa = result_calculate(request, frame, &stack->result, &priority); + fa = result_calculate(request, frame, &stack->result, &stack->priority); /* * If we're continuing after popping a frame @@ -731,7 +729,7 @@ rlm_rcode_t unlang_interpret(request_t *request) RDEBUG4("** [%i] %s - continuing after subsection with (%s %d)", stack->depth, __FUNCTION__, fr_table_str_by_value(mod_rcode_table, stack->result, ""), - priority); + stack->priority); frame_next(stack, frame); /* * Else if we're really done with this frame @@ -756,21 +754,21 @@ rlm_rcode_t unlang_interpret(request_t *request) /* * Nothing in this section, use the top frame stack->result. */ - if ((priority < 0) || (stack->result == RLM_MODULE_UNKNOWN)) { + if ((stack->priority < 0) || (stack->result == RLM_MODULE_UNKNOWN)) { RDEBUG4("** [%i] %s - empty section, using stack result (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, stack->result, ""), priority); + fr_table_str_by_value(mod_rcode_table, stack->result, ""), stack->priority); stack->result = frame->result; - priority = frame->priority; + stack->priority = frame->priority; } - if (priority > frame->priority) { + if (stack->priority > frame->priority) { frame->result = stack->result; - frame->priority = priority; + frame->priority = stack->priority; RDEBUG4("** [%i] %s - over-riding stack->result from higher priority to (%s %d)", stack->depth, __FUNCTION__, fr_table_str_by_value(mod_rcode_table, stack->result, ""), - priority); + stack->priority); } /* @@ -779,7 +777,9 @@ rlm_rcode_t unlang_interpret(request_t *request) */ RDEBUG4("** [%i] %s - interpreter exiting, returning %s", stack->depth, __FUNCTION__, fr_table_str_by_value(mod_rcode_table, frame->result, "")); + stack->result = frame->result; + stack->depth--; DUMP_STACK; @@ -1095,7 +1095,7 @@ static void frame_signal(request_t *request, fr_state_signal_t action, int limit if (!frame->signal) continue; - frame->signal(request, action); + frame->signal(request, frame, action); } stack->depth = depth; /* Reset */ } @@ -1224,7 +1224,7 @@ void unlang_interpret_mark_resumable(request_t *request) } if (!unlang_request_is_scheduled(request)) { - RDEBUG3("marking as resumable"); + RDEBUG3("Marked as resumable"); } fr_assert(request->backlog != NULL); diff --git a/src/lib/unlang/interpret.h b/src/lib/unlang/interpret.h index 2fd8f3152ed..eccbfccba35 100644 --- a/src/lib/unlang/interpret.h +++ b/src/lib/unlang/interpret.h @@ -33,58 +33,8 @@ extern "C" { #define UNLANG_TOP_FRAME (true) #define UNLANG_SUB_FRAME (false) -/** Function to call when interpreting a frame - * - * @param[in,out] p_result Pointer to the current rcode, may be modified by the function. - * @param[in] request The current request. - * @return an action for the interpreter to perform. - */ -typedef unlang_action_t (*unlang_process_t)(rlm_rcode_t *p_result, request_t *request); - -/** Function to call if the initial function yielded and the request was signalled - * - * This is the operation specific cancellation function. This function will usually - * either call a more specialised cancellation function set when something like a module yielded, - * or just cleanup the state of the original #unlang_process_t. - * - * @param[in] request The current request. - * @param[in] action We're being signalled with. - */ -typedef void (*unlang_signal_t)(request_t *request, fr_state_signal_t action); - -/** A generic function pushed by a module or xlat to functions deeper in the C call stack to create resumption points - * - * @param[in] request The current request. - * @param[in,out] uctx Provided by whatever pushed the function. Is opaque to the - * interpreter, but should be usable by the function. - * All input (args) and output will be done using this structure. - * @return an #unlang_action_t. - */ -typedef unlang_action_t (*unlang_function_t)(rlm_rcode_t *p_result, int *priority, request_t *request, void *uctx); - -/** An unlang operation - * - * These are like the opcodes in other interpreters. Each operation, when executed - * will return an #unlang_action_t, which determines what the interpreter does next. - */ -typedef struct { - char const *name; //!< Name of the operation. - - unlang_process_t interpret; //!< Function to interpret the keyword - - unlang_signal_t signal; //!< Function to signal stop / dup / whatever - - bool debug_braces; //!< Whether the operation needs to print braces - ///< in debug mode. - - size_t frame_state_size; //!< size of instance data in the stack frame - - char const *frame_state_name; //!< talloc name of the frame instance data - - size_t frame_state_pool_objects; //!< How many sub-allocations we expect. - - size_t frame_state_pool_size; //!< The total size of the pool to alloc. -} unlang_op_t; +#define UNLANG_STACK_MAX (64) //!< The maximum depth of the stack. +#define UNLANG_FRAME_PRE_ALLOC (128) //!< How much memory we pre-alloc for each frame. /** Return whether a request is currently scheduled * @@ -94,10 +44,6 @@ static inline bool unlang_request_is_scheduled(request_t const *request) return (request->runnable_id >= 0); } -int unlang_interpret_push_function(request_t *request, - unlang_function_t func, unlang_function_t repeat, void *uctx) - CC_HINT(warn_unused_result); - int unlang_interpret_push_section(request_t *request, CONF_SECTION *cs, rlm_rcode_t default_action, bool top_frame) CC_HINT(warn_unused_result); diff --git a/src/lib/unlang/load_balance.c b/src/lib/unlang/load_balance.c index ae03113d8cc..00d1075d8f5 100644 --- a/src/lib/unlang/load_balance.c +++ b/src/lib/unlang/load_balance.c @@ -31,18 +31,11 @@ #define unlang_redundant_load_balance unlang_load_balance -static unlang_action_t unlang_load_balance_next(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_load_balance_next(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_frame_state_redundant_t *redundant; - - unlang_group_t *g; - - g = unlang_generic_to_group(instruction); - - redundant = talloc_get_type_abort(frame->state, unlang_frame_state_redundant_t); + unlang_frame_state_redundant_t *redundant = talloc_get_type_abort(frame->state, unlang_frame_state_redundant_t); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); #ifdef __clang_analyzer__ if (!redundant->found) { @@ -74,7 +67,7 @@ static unlang_action_t unlang_load_balance_next(rlm_rcode_t *p_result, request_t * process again. */ - fr_assert(instruction->type != UNLANG_TYPE_LOAD_BALANCE); /* this is never called again */ + fr_assert(frame->instruction->type != UNLANG_TYPE_LOAD_BALANCE); /* this is never called again */ /* * If the current child says "return", then do @@ -112,19 +105,14 @@ static unlang_action_t unlang_load_balance_next(rlm_rcode_t *p_result, request_t return UNLANG_ACTION_PUSHED_CHILD; } -static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; unlang_frame_state_redundant_t *redundant; - - unlang_group_t *g; - unlang_load_balance_t *gext = NULL; + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_load_balance_t *gext = NULL; uint32_t count = 0; - g = unlang_generic_to_group(instruction); if (!g->num_children) { *p_result = RLM_MODULE_NOOP; return UNLANG_ACTION_CALCULATE_RESULT; @@ -134,7 +122,8 @@ static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *req RDEBUG4("%s setting up", frame->instruction->debug_name); - redundant = talloc_get_type_abort(frame->state, unlang_frame_state_redundant_t); + redundant = talloc_get_type_abort(frame->state, + unlang_frame_state_redundant_t); if (gext && gext->vpt) { uint32_t hash, start; @@ -237,7 +226,7 @@ static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *req /* * Plain "load-balance". Just do one child. */ - if (instruction->type == UNLANG_TYPE_LOAD_BALANCE) { + if (frame->instruction->type == UNLANG_TYPE_LOAD_BALANCE) { if (unlang_interpret_push(request, redundant->found, frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { *p_result = RLM_MODULE_FAIL; @@ -254,7 +243,7 @@ static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *req redundant->child = NULL; frame->process = unlang_load_balance_next; - return unlang_load_balance_next(p_result, request); + return unlang_load_balance_next(p_result, request, frame); } void unlang_load_balance_init(void) diff --git a/src/lib/unlang/map.c b/src/lib/unlang/map.c index ba7db59485d..b1199745617 100644 --- a/src/lib/unlang/map.c +++ b/src/lib/unlang/map.c @@ -112,19 +112,18 @@ done: /** Create a list of modifications to apply to one or more fr_pair_t lists * - * @param[in] request The current request. * @param[out] p_result The rcode indicating what the result * of the operation was. + * @param[in] request The current request. + * @param[in] frame Current stack frame. * @return * - UNLANG_ACTION_CALCULATE_RESULT changes were applied. * - UNLANG_ACTION_PUSHED_CHILD async execution of an expansion is required. */ -static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_frame_state_update_t *update_state = frame->state; - map_t *map; + unlang_frame_state_update_t *update_state = talloc_get_type_abort(frame->state, unlang_frame_state_update_t); + map_t *map; /* * Iterate over the maps producing a set of modifications to apply. @@ -257,20 +256,16 @@ static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request * If one map fails in the evaluation phase, no more maps are processed, and the current * result is discarded. */ -static unlang_action_t unlang_update_state_init(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_update_state_init(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - - unlang_group_t *g = unlang_generic_to_group(instruction); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); unlang_map_t *gext = unlang_group_to_map(g); unlang_frame_state_update_t *update_state; /* * Initialise the frame state */ - MEM(frame->state = update_state = talloc_zero_pooled_object(stack, unlang_frame_state_update_t, + MEM(frame->state = update_state = talloc_zero_pooled_object(request->stack, unlang_frame_state_update_t, (sizeof(map_t) + (sizeof(tmpl_t) * 2) + 128), g->num_children)); /* 128 is for string buffers */ @@ -285,18 +280,14 @@ static unlang_action_t unlang_update_state_init(rlm_rcode_t *p_result, request_t * Call list_mod_create */ frame->process = list_mod_create; - return list_mod_create(p_result, request); + return list_mod_create(p_result, request, frame); } -static unlang_action_t map_proc_apply(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t map_proc_apply(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - - unlang_group_t *g = unlang_generic_to_group(instruction); - unlang_map_t *gext = unlang_group_to_map(g); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_map_t *gext = unlang_group_to_map(g); map_proc_inst_t *inst = gext->proc_inst; unlang_frame_state_map_proc_t *map_proc_state = talloc_get_type_abort(frame->state, unlang_frame_state_map_proc_t); @@ -317,13 +308,10 @@ static unlang_action_t map_proc_apply(rlm_rcode_t *p_result, request_t *request) return *p_result == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT; } -static unlang_action_t unlang_map_state_init(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_map_state_init(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_group_t *g = unlang_generic_to_group(instruction); - unlang_map_t *gext = unlang_group_to_map(g); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + unlang_map_t *gext = unlang_group_to_map(g); map_proc_inst_t *inst = gext->proc_inst; unlang_frame_state_map_proc_t *map_proc_state = talloc_get_type_abort(frame->state, unlang_frame_state_map_proc_t); @@ -382,7 +370,7 @@ static unlang_action_t unlang_map_state_init(rlm_rcode_t *p_result, request_t *r goto error; } - return map_proc_apply(p_result, request); + return map_proc_apply(p_result, request, frame); } void unlang_map_init(void) diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index f1692050271..c1684fc1279 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -550,11 +550,10 @@ unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, if (!subcs) { unlang_stack_t *stack = request->stack; unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_module_t *mc; + unlang_module_t *mc; - fr_assert(instruction->type == UNLANG_TYPE_MODULE); - mc = unlang_generic_to_module(instruction); + fr_assert(frame->instruction->type == UNLANG_TYPE_MODULE); + mc = unlang_generic_to_module(frame->instruction); /* * Be transparent to the resume function. @@ -606,12 +605,11 @@ static inline void safe_unlock(module_instance_t *instance) * If there is no #unlang_module_signal_t callback defined, the action is ignored. * * @param[in] request The current request. + * @param[in] frame current stack frame. * @param[in] action to signal. */ -static void unlang_module_signal(request_t *request, fr_state_signal_t action) +static void unlang_module_signal(request_t *request, unlang_stack_frame_t *frame, fr_state_signal_t action) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_module_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); unlang_module_t *mc = unlang_generic_to_module(frame->instruction); @@ -637,10 +635,9 @@ static void unlang_module_signal(request_t *request, fr_state_signal_t action) /** Return UNLANG_CALCULATE_RESULT only for async async calls * */ -static unlang_action_t unlang_module_resume_final(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_module_resume_final(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_module_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); request->rcode = state->rcode; @@ -653,15 +650,13 @@ static unlang_action_t unlang_module_resume_final(rlm_rcode_t *p_result, request /** Wrapper to call a module's resumption function * */ -static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_module_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); unlang_module_t *mc = unlang_generic_to_module(frame->instruction); char const *caller; rlm_rcode_t rcode = RLM_MODULE_NOOP; - int stack_depth = stack->depth; + int stack_depth = unlang_current_depth(request); unlang_action_t ua; fr_assert(state->resume != NULL); @@ -703,8 +698,8 @@ static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *re fr_table_str_by_value(mod_rcode_table, rcode, "")); if (ua == UNLANG_ACTION_YIELD) { - if (stack_depth < stack->depth) return UNLANG_ACTION_PUSHED_CHILD; - fr_assert(stack_depth == stack->depth); + if (stack_depth < unlang_current_depth(request)) return UNLANG_ACTION_PUSHED_CHILD; + fr_assert(stack_depth == unlang_current_depth(request)); *p_result = rcode; return UNLANG_ACTION_YIELD; } @@ -775,14 +770,11 @@ unlang_action_t unlang_module_yield(request_t *request, return UNLANG_ACTION_YIELD; } -static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { unlang_module_t *mc; - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; unlang_frame_state_module_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); - int stack_depth = stack->depth; + int stack_depth = unlang_current_depth(request); char const *caller; rlm_rcode_t rcode = RLM_MODULE_NOOP; unlang_action_t ua; @@ -795,10 +787,10 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request) * Process a stand-alone child, and fall through * to dealing with it's parent. */ - mc = unlang_generic_to_module(instruction); + mc = unlang_generic_to_module(frame->instruction); fr_assert(mc); - RDEBUG4("[%i] %s - %s (%s)", stack->depth, __FUNCTION__, + RDEBUG4("[%i] %s - %s (%s)", unlang_current_depth(request), __FUNCTION__, mc->instance->name, mc->instance->module->name); /* @@ -849,14 +841,14 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request) /* * Must be left at RDEBUG() level otherwise RDEBUG becomes pointless */ - RDEBUG("%s (%s)", instruction->name ? instruction->name : "", + RDEBUG("%s (%s)", frame->instruction->name ? frame->instruction->name : "", fr_table_str_by_value(mod_rcode_table, rcode, "")); if (ua == UNLANG_ACTION_YIELD) { state->thread->active_callers++; - if (stack_depth < stack->depth) return UNLANG_ACTION_PUSHED_CHILD; - fr_assert(stack_depth == stack->depth); + if (stack_depth < unlang_current_depth(request)) return UNLANG_ACTION_PUSHED_CHILD; + fr_assert(stack_depth == unlang_current_depth(request)); frame->process = unlang_module_resume; return UNLANG_ACTION_YIELD; } diff --git a/src/lib/unlang/module_priv.h b/src/lib/unlang/module_priv.h index bc0650c74b0..262bac1bdd3 100644 --- a/src/lib/unlang/module_priv.h +++ b/src/lib/unlang/module_priv.h @@ -65,10 +65,10 @@ typedef struct { /** @} */ } unlang_frame_state_module_t; -static inline unlang_module_t *unlang_generic_to_module(unlang_t *p) +static inline unlang_module_t *unlang_generic_to_module(unlang_t const *p) { fr_assert(p->type == UNLANG_TYPE_MODULE); - return talloc_get_type_abort(p, unlang_module_t); + return UNCONST(unlang_module_t *, talloc_get_type_abort_const(p, unlang_module_t)); } static inline unlang_t *unlang_module_to_generic(unlang_module_t *p) diff --git a/src/lib/unlang/parallel.c b/src/lib/unlang/parallel.c index 694d50561c3..f4216b9d440 100644 --- a/src/lib/unlang/parallel.c +++ b/src/lib/unlang/parallel.c @@ -66,10 +66,8 @@ static unlang_action_t unlang_parallel_child_done(UNUSED rlm_rcode_t *p_result, /** Run one or more sub-sections from the parallel section. * */ -static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_parallel_state_t *state = talloc_get_type_abort(frame->state, unlang_parallel_state_t); int i, priority; @@ -144,7 +142,7 @@ static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t */ if ((unlang_interpret_push(child, NULL, RLM_MODULE_NOOP, UNLANG_NEXT_STOP, UNLANG_TOP_FRAME) < 0) || - (unlang_interpret_push_function(child, unlang_parallel_child_done, NULL, &state->children[i]) < 0) || + (unlang_interpret_push_function(child, unlang_parallel_child_done, NULL, NULL, &state->children[i]) < 0) || (unlang_interpret_push(child, state->children[i].instruction, RLM_MODULE_FAIL, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0)) { @@ -265,7 +263,7 @@ static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t state->priority = priority; RDEBUG4("** [%i] %s - over-riding result from higher priority to (%s %d)", - stack->depth, __FUNCTION__, + unlang_current_depth(request), __FUNCTION__, fr_table_str_by_value(mod_rcode_table, result, ""), priority); } @@ -376,10 +374,8 @@ static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t /** Send a signal from parent request to all of it's children * */ -static void unlang_parallel_signal(request_t *request, fr_state_signal_t action) +static void unlang_parallel_signal(UNUSED request_t *request, unlang_stack_frame_t *frame, fr_state_signal_t action) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_parallel_state_t *state = talloc_get_type_abort(frame->state, unlang_parallel_state_t); int i; @@ -402,11 +398,9 @@ static void unlang_parallel_signal(request_t *request, fr_state_signal_t action) } } -static unlang_action_t unlang_parallel(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_parallel(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; + unlang_t const *instruction = frame->instruction; unlang_group_t *g; unlang_parallel_t *gext; @@ -452,7 +446,7 @@ static unlang_action_t unlang_parallel(rlm_rcode_t *p_result, request_t *request } frame->process = unlang_parallel_process; - return unlang_parallel_process(p_result, request); + return unlang_parallel_process(p_result, request, frame); } void unlang_parallel_init(void) diff --git a/src/lib/unlang/parallel_priv.h b/src/lib/unlang/parallel_priv.h index 1ce4b8cc501..905de8113d8 100644 --- a/src/lib/unlang/parallel_priv.h +++ b/src/lib/unlang/parallel_priv.h @@ -50,7 +50,7 @@ typedef struct { unlang_parallel_child_state_t state; //!< State of the child. request_t *child; //!< Child request. char *name; //!< Cache the request name. - unlang_t *instruction; //!< broken out of g->children + unlang_t const *instruction; //!< broken out of g->children } unlang_parallel_child_t; typedef struct { diff --git a/src/lib/unlang/return.c b/src/lib/unlang/return.c index 80ee008fd3f..355147a2ddf 100644 --- a/src/lib/unlang/return.c +++ b/src/lib/unlang/return.c @@ -27,13 +27,9 @@ RCSID("$Id$") #include "unlang_priv.h" #include "return_priv.h" -unlang_action_t unlang_return(rlm_rcode_t *p_result, request_t *request) +unlang_action_t unlang_return(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - - RDEBUG2("%s", unlang_ops[instruction->type].name); + RDEBUG2("%s", unlang_ops[frame->instruction->type].name); *p_result = frame->result; @@ -41,7 +37,7 @@ unlang_action_t unlang_return(rlm_rcode_t *p_result, request_t *request) * Stop at the next return point, or if we hit * the a top frame. */ - return unwind_to_return(stack); + return unwind_to_return(request->stack); } void unlang_return_init(void) diff --git a/src/lib/unlang/return_priv.h b/src/lib/unlang/return_priv.h index 94ea5218f79..eaaacd592c6 100644 --- a/src/lib/unlang/return_priv.h +++ b/src/lib/unlang/return_priv.h @@ -29,7 +29,7 @@ extern "C" { #endif -unlang_action_t unlang_return(UNUSED rlm_rcode_t *result, request_t *request); +unlang_action_t unlang_return(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame); #ifdef __cplusplus } diff --git a/src/lib/unlang/subrequest.c b/src/lib/unlang/subrequest.c index 91c6fc1f7b7..0128305d589 100644 --- a/src/lib/unlang/subrequest.c +++ b/src/lib/unlang/subrequest.c @@ -82,10 +82,8 @@ static void unlang_max_request_time(UNUSED fr_event_list_t *el, UNUSED fr_time_t /** Send a signal from parent request to subrequest * */ -static void unlang_subrequest_signal(request_t *request, fr_state_signal_t action) +static void unlang_subrequest_signal(UNUSED request_t *request, unlang_stack_frame_t *frame, fr_state_signal_t action) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_subrequest_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t); request_t *child = talloc_get_type_abort(state->child, request_t); @@ -96,10 +94,8 @@ static void unlang_subrequest_signal(request_t *request, fr_state_signal_t actio /** Process a subrequest until it either detaches, or is done. * */ -static unlang_action_t unlang_subrequest_process(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_subrequest_process(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_subrequest_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t); request_t *child = talloc_get_type_abort(state->child, request_t); unlang_group_t *g = unlang_generic_to_group(frame->instruction); @@ -193,10 +189,8 @@ static unlang_action_t unlang_subrequest_process(rlm_rcode_t *p_result, request_ } -static unlang_action_t unlang_subrequest_start(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_subrequest_start(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_subrequest_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t); request_t *child = state->child; @@ -214,15 +208,13 @@ static unlang_action_t unlang_subrequest_start(rlm_rcode_t *p_result, request_t log_request_pair_list(L_DBG_LVL_1, request, NULL, &child->request_pairs, NULL); frame->process = unlang_subrequest_process; - return unlang_subrequest_process(p_result, request); + return unlang_subrequest_process(p_result, request, frame); } -static unlang_action_t unlang_subrequest_state_init(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_subrequest_state_init(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; unlang_frame_state_subrequest_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t); request_t *child; @@ -230,12 +222,12 @@ static unlang_action_t unlang_subrequest_state_init(rlm_rcode_t *p_result, reque fr_pair_t *vp; unlang_group_t *g; - unlang_subrequest_t *gext; + unlang_subrequest_t *gext; /* * Initialize the state */ - g = unlang_generic_to_group(instruction); + g = unlang_generic_to_group(frame->instruction); if (!g->num_children) { *p_result = RLM_MODULE_NOOP; return UNLANG_ACTION_CALCULATE_RESULT; @@ -351,11 +343,11 @@ static unlang_action_t unlang_subrequest_state_init(rlm_rcode_t *p_result, reque * keyed off the exact subrequest keyword. */ state->session.enable = true; - state->session.unique_ptr = instruction; + state->session.unique_ptr = frame->instruction; state->session.unique_int = 0; frame->process = unlang_subrequest_start; - return unlang_subrequest_start(p_result, request); + return unlang_subrequest_start(p_result, request, frame); } /** Initialize a detached child @@ -413,12 +405,10 @@ int unlang_detached_child_init(request_t *request) return 0; } -static unlang_action_t unlang_detach(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_detach(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_detach_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_detach_t); - + unlang_stack_frame_t *parent_frame; unlang_frame_state_subrequest_t *parent_state; /* @@ -441,8 +431,7 @@ static unlang_action_t unlang_detach(rlm_rcode_t *p_result, request_t *request) /* * Get the PARENT's stack. */ - stack = request->parent->stack; - frame = &stack->frame[stack->depth]; + parent_frame = unlang_current_frame(request->parent); parent_state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t); if (!parent_state->detachable) { @@ -464,7 +453,7 @@ static unlang_action_t unlang_detach(rlm_rcode_t *p_result, request_t *request) */ fr_assert(parent_state->child == request); parent_state->child = NULL; - frame->signal = NULL; + parent_frame->signal = NULL; /* * Pass through whatever the previous instruction had as diff --git a/src/lib/unlang/switch.c b/src/lib/unlang/switch.c index 059a1f0317a..de731dfdfc5 100644 --- a/src/lib/unlang/switch.c +++ b/src/lib/unlang/switch.c @@ -30,11 +30,8 @@ RCSID("$Id$") #include "switch_priv.h" #include "unlang_priv.h" -static unlang_action_t unlang_switch(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_switch(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; unlang_t *this, *found, *null_case; unlang_group_t *switch_g; @@ -44,7 +41,7 @@ static unlang_action_t unlang_switch(rlm_rcode_t *p_result, request_t *request) map_t map; tmpl_t vpt, *switch_vpt; - switch_g = unlang_generic_to_group(instruction); + switch_g = unlang_generic_to_group(frame->instruction); switch_gext = unlang_group_to_switch(switch_g); memset(&cond, 0, sizeof(cond)); @@ -176,21 +173,16 @@ do_null_case: } -static unlang_action_t unlang_case(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_case(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_t *instruction = frame->instruction; - unlang_group_t *g; - - g = unlang_generic_to_group(instruction); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); if (!g->children) { *p_result = RLM_MODULE_NOOP; return UNLANG_ACTION_CALCULATE_RESULT; } - return unlang_group(p_result, request); + return unlang_group(p_result, request, frame); } void unlang_switch_init(void) diff --git a/src/lib/unlang/tmpl.c b/src/lib/unlang/tmpl.c index 12b48f91fa9..9fdc8e520df 100644 --- a/src/lib/unlang/tmpl.c +++ b/src/lib/unlang/tmpl.c @@ -76,12 +76,11 @@ static void unlang_tmpl_exec_cleanup(request_t *request) * If there is no #fr_unlang_tmpl_signal_t callback defined, the action is ignored. * * @param[in] request The current request. + * @param[in] frame being signalled. * @param[in] action to signal. */ -static void unlang_tmpl_signal(request_t *request, fr_state_signal_t action) +static void unlang_tmpl_signal(request_t *request, unlang_stack_frame_t *frame, fr_state_signal_t action) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); @@ -298,12 +297,9 @@ static void unlang_tmpl_exec_timeout( * called repeatedly until the resumption function returns a final * value. */ -static unlang_action_t unlang_tmpl_resume(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_tmpl_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, - unlang_frame_state_tmpl_t); + unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); if (state->out) fr_dlist_move(state->out, &state->box); @@ -325,10 +321,9 @@ static unlang_action_t unlang_tmpl_resume(rlm_rcode_t *p_result, request_t *requ /** Wrapper to call exec after the program has finished executing * */ -static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); @@ -411,19 +406,17 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques */ resume: frame->process = unlang_tmpl_resume; - return unlang_tmpl_resume(p_result, request); + return unlang_tmpl_resume(p_result, request, frame); } /** Wrapper to call exec after a tmpl has been expanded * */ -static unlang_action_t unlang_tmpl_exec_wait_resume(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_tmpl_exec_wait_resume(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, - unlang_frame_state_tmpl_t); + unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); pid_t pid; int *fd_p = NULL; @@ -490,12 +483,10 @@ static unlang_action_t unlang_tmpl_exec_wait_resume(rlm_rcode_t *p_result, reque /** Wrapper to call exec after a tmpl has been expanded * */ -static unlang_action_t unlang_tmpl_exec_nowait_resume(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_tmpl_exec_nowait_resume(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, - unlang_frame_state_tmpl_t); + unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); if (fr_exec_nowait(request, &state->box, state->vps) < 0) { RPEDEBUG("Failed executing program"); @@ -514,12 +505,9 @@ static unlang_action_t unlang_tmpl_exec_nowait_resume(rlm_rcode_t *p_result, req } -static unlang_action_t unlang_tmpl(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_tmpl(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; - unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, - unlang_frame_state_tmpl_t); + unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); unlang_tmpl_t *ut = unlang_generic_to_tmpl(frame->instruction); xlat_exp_t const *xlat; diff --git a/src/lib/unlang/unlang_priv.h b/src/lib/unlang/unlang_priv.h index 72a2f8e363c..f61d69a48a2 100644 --- a/src/lib/unlang/unlang_priv.h +++ b/src/lib/unlang/unlang_priv.h @@ -100,6 +100,7 @@ typedef enum { #define UNLANG_NORMAL_CHILD (false) typedef struct unlang_s unlang_t; +typedef struct unlang_stack_frame_s unlang_stack_frame_t; /** A node in a graph of #unlang_op_t (s) that we execute * @@ -157,6 +158,55 @@ typedef struct { xlat_flags_t flags; } unlang_tmpl_t; +/** Function to call when interpreting a frame + * + * @param[in,out] p_result Pointer to the current rcode, may be modified by the function. + * @param[in] request The current request. + * @param[in] frame being executed. + * + * @return an action for the interpreter to perform. + */ +typedef unlang_action_t (*unlang_process_t)(rlm_rcode_t *p_result, request_t *request, + unlang_stack_frame_t *frame); + +/** Function to call if the request was signalled + * + * This is the instruction specific cancellation function. + * This function will usually either call a more specialised cancellation function + * set when something like a module yielded, or just cleanup the state of the original + * #unlang_process_t. + * + * @param[in] request The current request. + * @param[in] frame being signalled. + * @param[in] action We're being signalled with. + */ +typedef void (*unlang_signal_t)(request_t *request, + unlang_stack_frame_t *frame, fr_state_signal_t action); + +/** An unlang operation + * + * These are like the opcodes in other interpreters. Each operation, when executed + * will return an #unlang_action_t, which determines what the interpreter does next. + */ +typedef struct { + char const *name; //!< Name of the operation. + + unlang_process_t interpret; //!< Function to interpret the keyword + + unlang_signal_t signal; //!< Function to signal stop / dup / whatever + + bool debug_braces; //!< Whether the operation needs to print braces + ///< in debug mode. + + size_t frame_state_size; //!< size of instance data in the stack frame + + char const *frame_state_name; //!< talloc name of the frame instance data + + size_t frame_state_pool_objects; //!< How many sub-allocations we expect. + + size_t frame_state_pool_size; //!< The total size of the pool to alloc. +} unlang_op_t; + /** Our interpreter stack, as distinct from the C stack * * We don't call the modules recursively. Instead we iterate over a list of #unlang_t and @@ -169,9 +219,9 @@ typedef struct { * through the server. Because the interpreter stack is distinct from the C stack, we can have * a single system thread with many thousands of pending requests. */ -typedef struct { - unlang_t *instruction; //!< The unlang node we're evaluating. - unlang_t *next; //!< The next unlang node we will evaluate +struct unlang_stack_frame_s { + unlang_t const *instruction; //!< The unlang node we're evaluating. + unlang_t const *next; //!< The next unlang node we will evaluate unlang_process_t process; //!< function to call for interpreting this stack frame unlang_signal_t signal; //!< function to call when signalling this stack frame @@ -187,19 +237,20 @@ typedef struct { */ void *state; - rlm_rcode_t result; //!< The result from executing the instruction. + rlm_rcode_t result; //!< The result from executing the instruction. int priority; //!< Result priority. When we pop this stack frame ///< this priority will be compared with the one of the ///< frame lower in the stack to determine if the ///< result stored in the lower stack frame should ///< be replaced. uint8_t uflags; //!< Unwind markers -} unlang_stack_frame_t; +}; /** An unlang stack associated with a request * */ typedef struct { + int priority; //!< Current priority. rlm_rcode_t result; //!< The current stack rcode. int depth; //!< Current depth we're executing at. uint8_t unwind; //!< Unwind to this frame if it exists. @@ -228,13 +279,13 @@ static inline void repeatable_clear(unlang_stack_frame_t *frame) { frame->uflags static inline void top_frame_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_TOP_FRAME; } static inline void break_point_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_BREAK_POINT; } static inline void return_point_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_RETURN_POINT; } -static inline void yielded_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_YIELDED; } +static inline void yielded_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_YIELDED; } -static inline bool is_repeatable(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_REPEAT; } -static inline bool is_top_frame(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_TOP_FRAME; } -static inline bool is_break_point(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_BREAK_POINT; } -static inline bool is_return_point(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_RETURN_POINT; } -static inline bool is_yielded(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_YIELDED; } +static inline bool is_repeatable(unlang_stack_frame_t const *frame) { return frame->uflags & UNWIND_FLAG_REPEAT; } +static inline bool is_top_frame(unlang_stack_frame_t const *frame) { return frame->uflags & UNWIND_FLAG_TOP_FRAME; } +static inline bool is_break_point(unlang_stack_frame_t const *frame) { return frame->uflags & UNWIND_FLAG_BREAK_POINT; } +static inline bool is_return_point(unlang_stack_frame_t const *frame) { return frame->uflags & UNWIND_FLAG_RETURN_POINT; } +static inline bool is_yielded(unlang_stack_frame_t const *frame) { return frame->uflags & UNWIND_FLAG_YIELDED; } static inline unlang_action_t unwind_to_break(unlang_stack_t *stack) { @@ -252,6 +303,20 @@ static inline unlang_action_t unwind_all(unlang_stack_t *stack) return UNLANG_ACTION_UNWIND; } +static inline unlang_stack_frame_t *unlang_current_frame(request_t *request) +{ + unlang_stack_t *stack = request->stack; + + return &stack->frame[stack->depth]; +} + +static inline int unlang_current_depth(request_t *request) +{ + unlang_stack_t *stack = request->stack; + + return stack->depth; +} + /** Different operations the interpreter can execute */ extern unlang_op_t unlang_ops[]; @@ -268,27 +333,27 @@ extern size_t mod_rcode_table_len; * * @{ */ -static inline unlang_group_t *unlang_generic_to_group(unlang_t *p) +static inline unlang_group_t *unlang_generic_to_group(unlang_t const *p) { fr_assert((p->type > UNLANG_TYPE_MODULE) && (p->type <= UNLANG_TYPE_POLICY)); - return (unlang_group_t *)p; + return UNCONST(unlang_group_t *, p); } -static inline unlang_t *unlang_group_to_generic(unlang_group_t *p) +static inline unlang_t *unlang_group_to_generic(unlang_group_t const *p) { - return (unlang_t *)p; + return UNCONST(unlang_t *, p); } -static inline unlang_tmpl_t *unlang_generic_to_tmpl(unlang_t *p) +static inline unlang_tmpl_t *unlang_generic_to_tmpl(unlang_t const *p) { fr_assert(p->type == UNLANG_TYPE_TMPL); - return talloc_get_type_abort(p, unlang_tmpl_t); + return UNCONST(unlang_tmpl_t *, talloc_get_type_abort_const(p, unlang_tmpl_t)); } -static inline unlang_t *unlang_tmpl_to_generic(unlang_tmpl_t *p) +static inline unlang_t *unlang_tmpl_to_generic(unlang_tmpl_t const *p) { - return (unlang_t *)p; + return UNCONST(unlang_t *, p); } /** @} */ @@ -296,7 +361,7 @@ static inline unlang_t *unlang_tmpl_to_generic(unlang_tmpl_t *p) * * @{ */ -int unlang_interpret_push(request_t *request, unlang_t *instruction, +int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame) CC_HINT(warn_unused_result); @@ -324,6 +389,8 @@ request_t *unlang_io_subrequest_alloc(request_t *parent, fr_dict_t const *names * * @{ */ +void unlang_register(int type, unlang_op_t *op); + void unlang_call_init(void); void unlang_caller_init(void); diff --git a/src/lib/unlang/xlat.c b/src/lib/unlang/xlat.c index 94be17fa4c3..73493e8fffb 100644 --- a/src/lib/unlang/xlat.c +++ b/src/lib/unlang/xlat.c @@ -227,10 +227,8 @@ int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, * Calls the xlat interpreter and translates its wants and needs into * unlang_action_t codes. */ -static unlang_action_t unlang_xlat(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_xlat(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_xlat_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t); xlat_exp_t const *child = NULL; xlat_action_t xa; @@ -290,12 +288,11 @@ static unlang_action_t unlang_xlat(rlm_rcode_t *p_result, request_t *request) * If there is no #xlat_func_signal_t callback defined, the action is ignored. * * @param[in] request The current request. + * @param[in] frame The current stack frame. * @param[in] action What the request should do (the type of signal). */ -static void unlang_xlat_signal(request_t *request, fr_state_signal_t action) +static void unlang_xlat_signal(request_t *request, unlang_stack_frame_t *frame, fr_state_signal_t action) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_xlat_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t); /* @@ -318,14 +315,13 @@ static void unlang_xlat_signal(request_t *request, fr_state_signal_t action) * - RLM_MODULE_YIELD if additional asynchronous * operations need to be performed. * @param[in] request to resume processing. + * @param[in] frame the current stack frame. * @return * - UNLANG_ACTION_YIELD if yielding. * - UNLANG_ACTION_CALCULATE_RESULT if done. */ -static unlang_action_t unlang_xlat_resume(rlm_rcode_t *p_result, request_t *request) +static unlang_action_t unlang_xlat_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_stack_t *stack = request->stack; - unlang_stack_frame_t *frame = &stack->frame[stack->depth]; unlang_frame_state_xlat_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t); xlat_action_t xa; diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c index be0cb8e36c8..82c981a2058 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c @@ -176,7 +176,7 @@ static unlang_action_t eap_tls_virtual_server(rlm_rcode_t *p_result, rlm_eap_tls /* * Catch the interpreter on the way back up the stack */ - if (unlang_interpret_push_function(request, NULL, eap_tls_virtual_server_result, eap_session) < 0) { + if (unlang_interpret_push_function(request, NULL, eap_tls_virtual_server_result, NULL, eap_session) < 0) { RETURN_MODULE_FAIL; }