From: Arran Cudbard-Bell Date: Thu, 3 Jun 2021 23:23:11 +0000 (-0500) Subject: Fix multiple issues with unlang function calls and make the code a bit more understan... X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=51d0e0b97736317bb369ebebdb82ece5bf548e98;p=thirdparty%2Ffreeradius-server.git Fix multiple issues with unlang function calls and make the code a bit more understandable --- diff --git a/src/lib/unlang/function.c b/src/lib/unlang/function.c index 12daba5cd39..64adfa62b64 100644 --- a/src/lib/unlang/function.c +++ b/src/lib/unlang/function.c @@ -32,7 +32,6 @@ RCSID("$Id$") * Some functions differ mainly in their parsing */ typedef struct { - bool done_func; //!< Set to true after func has been executed. 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. @@ -75,6 +74,27 @@ static void unlang_function_signal(request_t *request, state->signal(request, action, state->uctx); } +static unlang_action_t unlang_function_call_repeat(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) +{ + unlang_action_t ua; + unlang_frame_state_func_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t); + char const *caller; + + *p_result = RLM_MODULE_NOOP; /* Avoid asserts */ + + /* + * Don't let the callback mess with the current + * module permanently. + */ + caller = request->module; + request->module = NULL; + RDEBUG4("Calling repeat function %p", state->repeat); + ua = state->repeat(p_result, &frame->priority, request, state->uctx); + request->module = caller; + + return ua; +} + /** Call a generic function * * @param[out] p_result The frame result. @@ -83,21 +103,26 @@ static void unlang_function_signal(request_t *request, */ static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { - unlang_frame_state_func_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t); unlang_action_t ua; + unlang_frame_state_func_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t); char const *caller; + *p_result = RLM_MODULE_NOOP; /* Avoid asserts */ + /* * Don't let the callback mess with the current * module permanently. */ caller = request->module; request->module = NULL; - if (!state->done_func && state->func) { - ua = state->func(p_result, &frame->priority, request, state->uctx); - state->done_func = true; - } else { - ua = state->repeat(p_result, &frame->priority, request, state->uctx); + + RDEBUG4("Calling function %p", state->func); + ua = state->func(p_result, &frame->priority, request, state->uctx); + if (ua != UNLANG_ACTION_STOP_PROCESSING) { + if (state->repeat) { + frame->process = unlang_function_call_repeat; + repeatable_set(frame); + } } request->module = caller; @@ -149,6 +174,11 @@ int unlang_interpret_push_function(request_t *request, unlang_function_t func, u state->signal = signal; state->uctx = uctx; + /* + * Just skip to the repeat state directly + */ + if (!func && repeat) frame->process = unlang_function_call_repeat; + return 0; }