rlm_rcode_t module_unlang_push_function(REQUEST *request,
unlang_function_t func,
+ unlang_function_t repeat,
fr_module_unlang_resume_t resume,
fr_module_unlang_signal_t signal, void *rctx);
///< in debug mode.
} unlang_op_t;
-void unlang_push_function(REQUEST *request, unlang_function_t func, void *uctx);
+void unlang_push_function(REQUEST *request, unlang_function_t func, unlang_function_t repeat, void *uctx);
void unlang_push_section(REQUEST *request, CONF_SECTION *cs, rlm_rcode_t default_action);
* - RLM_MODULE_YIELD.
*/
rlm_rcode_t module_unlang_push_function(REQUEST *request,
- unlang_function_t func,
+ unlang_function_t func, unlang_function_t repeat,
fr_module_unlang_resume_t resume,
fr_module_unlang_signal_t signal, void *rctx)
{
*/
(void) unlang_module_yield(request, resume, signal, rctx);
- unlang_push_function(request, func, rctx);
+ unlang_push_function(request, func, repeat, rctx);
return RLM_MODULE_YIELD; /* This may allow us to do optimisations in future */
}
}
typedef struct {
- unlang_function_t func; //!< To call.
+ unlang_function_t func; //!< To call when going down the stack.
+ unlang_function_t repeat; //!< To call when going back up the stack.
void *uctx; //!< Uctx to pass to function.
} unlang_frame_state_func_t;
unlang_t *instruction = frame->instruction;
unlang_action_t ua;
- ua = state->func(request, state->uctx);
+ if (!frame->repeat) {
+ ua = state->func(request, state->uctx);
+ } else {
+ ua = state->repeat(request, state->uctx);
+ }
/*
* The success/failure of these functions
* deeper in the C call stack to establish a new resumption point.
*
* @param[in] request The current request.
- * @param[in] func to call.
+ * @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] uctx to pass to func.
*/
-void unlang_push_function(REQUEST *request, unlang_function_t func, void *uctx)
+void unlang_push_function(REQUEST *request, unlang_function_t func, unlang_function_t repeat, void *uctx)
{
unlang_stack_t *stack = request->stack;
unlang_stack_frame_t *frame;
unlang_push(stack, &function_instruction, RLM_MODULE_UNKNOWN, UNLANG_NEXT_STOP, false);
frame = &stack->frame[stack->depth];
+ /*
+ * Tell the interpreter to call unlang_function_call
+ * again when going back up the stack.
+ */
+ if (repeat) frame->repeat = true;
+
/*
* Allocate state
*/
MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_func_t));
state->func = func;
+ state->repeat = repeat;
state->uctx = uctx;
}
rctx->rcode = RLM_MODULE_UNKNOWN;
request->module = method->submodule->name;
- return module_unlang_push_function(request, eap_call_submodule, mod_authenticate_result, NULL, rctx);
+ return module_unlang_push_function(request, eap_call_submodule, eap_call_submodule,
+ mod_authenticate_result, NULL, rctx);
}
static rlm_rcode_t mod_authenticate(void *instance, UNUSED void *thread, REQUEST *request)