]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add and use unlang_interpret_push_children()
authorAlan T. DeKok <aland@freeradius.org>
Wed, 20 Sep 2023 20:51:14 +0000 (16:51 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 23 Sep 2023 11:57:14 +0000 (07:57 -0400)
which pushes the children of the current frame.  This wrapper
function simplifies a bunch of keyword code.

subrequest does not use this, as it pushes another frame
before pushing the children.  Perhaps that should instead be a
resume function?

src/lib/unlang/call.c
src/lib/unlang/compile.c
src/lib/unlang/foreach.c
src/lib/unlang/group.c
src/lib/unlang/interpret.c
src/lib/unlang/limit.c
src/lib/unlang/timeout.c
src/lib/unlang/unlang_priv.h

index 36ef94a064e67fcc49730a96ba33319be65fe931..83074ae6c809e56f0aceae968a41aed0129e9fd5 100644 (file)
@@ -52,22 +52,13 @@ static unlang_action_t unlang_call_finalize(UNUSED rlm_rcode_t *p_result, reques
 static unlang_action_t unlang_call_children(rlm_rcode_t *p_result, request_t *request,
                                            unlang_stack_frame_t *frame)
 {
-       unlang_group_t                  *g = unlang_generic_to_group(frame->instruction);
-
-       fr_assert(g->children);
+       frame_repeat(frame, unlang_call_finalize);
 
        /*
         *      Push the contents of the call { } section onto the stack.
         *      This gets executed after the server returns.
         */
-       if (unlang_interpret_push(request, g->children, frame->result,
-                                 UNLANG_NEXT_SIBLING, UNLANG_SUB_FRAME) < 0) {
-               *p_result = RLM_MODULE_FAIL;
-               return UNLANG_ACTION_STOP_PROCESSING;
-       }
-
-       frame_repeat(frame, unlang_call_finalize);
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING);
 }
 
 
index 078360595be42bb3438f72bc79d0df032125a07c..1d92c9049d1f9781927fb8ddfc6881337a9ebcf5 100644 (file)
@@ -1719,6 +1719,8 @@ static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx
                .local = true,
        };
 
+       fr_assert(unlang_ops[parent->type].debug_braces);
+
        /*
         *      The variables exist in the parent block.
         */
index 68938e1d12b2d6519e0cee358eacebf91744d4a7..59ae416e8a3717cd38bd2c94844e8e60ea138eed 100644 (file)
@@ -78,7 +78,6 @@ static int _free_unlang_frame_state_foreach(unlang_frame_state_foreach_t *state)
 static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_frame_state_foreach_t    *state = talloc_get_type_abort(frame->state, unlang_frame_state_foreach_t);
-       unlang_group_t                  *g = unlang_generic_to_group(frame->instruction);
        fr_pair_t                       *vp;
 
        if (is_stack_unwinding_to_break(request->stack)) return UNLANG_ACTION_CALCULATE_RESULT;
@@ -111,17 +110,12 @@ static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *req
        RDEBUG2("# looping with: Foreach-Variable-%d = %pV", state->depth, &vp->data);
 #endif
 
+       repeatable_set(frame);
+
        /*
         *      Push the child, and yield for a later return.
         */
-       if (unlang_interpret_push(request, g->children, frame->result, UNLANG_NEXT_SIBLING, UNLANG_SUB_FRAME) < 0) {
-               *p_result = RLM_MODULE_FAIL;
-               return UNLANG_ACTION_STOP_PROCESSING;
-       }
-
-       repeatable_set(frame);
-
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING);
 }
 
 
@@ -217,17 +211,12 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request,
 
        frame->process = unlang_foreach_next;
 
+       repeatable_set(frame);
+
        /*
         *      Push the child, and go process it.
         */
-       if (unlang_interpret_push(request, g->children, frame->result, UNLANG_NEXT_SIBLING, UNLANG_SUB_FRAME) < 0) {
-               *p_result = RLM_MODULE_FAIL;
-               return UNLANG_ACTION_STOP_PROCESSING;
-       }
-
-       repeatable_set(frame);
-
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING);
 }
 
 static unlang_action_t unlang_break(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
index 7f4e4a4484bd58084d3771b1d07dc8bc1db3d568..d94120dd86f80d930be81037487de3c84eae018e 100644 (file)
@@ -29,24 +29,7 @@ RCSID("$Id$")
 
 unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
-       unlang_group_t          *g = unlang_generic_to_group(frame->instruction);
-
-       /*
-        *      The compiler catches most of these, EXCEPT for the
-        *      top-level 'recv Access-Request' etc.  Which can exist,
-        *      and can be empty.
-        */
-       if (!g->children) {
-               RDEBUG2("<ignoring empty subsection>");
-               return UNLANG_ACTION_EXECUTE_NEXT;
-       }
-
-       if (unlang_interpret_push(request, g->children, frame->result, UNLANG_NEXT_SIBLING, UNLANG_SUB_FRAME) < 0) {
-               *p_result = RLM_MODULE_FAIL;
-               return UNLANG_ACTION_STOP_PROCESSING;
-       }
-
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING);
 }
 
 static unlang_action_t unlang_policy(rlm_rcode_t *result, request_t *request, unlang_stack_frame_t *frame)
index da7ce7d316d489568ec4a147374b48c2c774a860..d6b791b3ac18aba2c163da71cb96fdbf179c580b 100644 (file)
@@ -210,6 +210,46 @@ int unlang_interpret_push(request_t *request, unlang_t const *instruction,
        return 0;
 }
 
+/** Push the children of the current frame onto a new frame onto the stack
+ *
+ * @param[in] request          to push the frame onto.
+ * @param[in] default_rcode    The default result.
+ * @param[in] do_next_sibling  Whether to only execute the first node in the #unlang_t program
+ *                             or to execute subsequent nodes.
+ * @return
+ *     - UNLANG_ACTION_PUSHED_CHILD on success.
+ *     - UNLANG_ACTION_EXECUTE_NEXT do nothing, but just go to the next sibling instruction
+ *     - UNLANG_ACTION_STOP_PROCESSING, fatal error, usually stack overflow.
+ */
+unlang_action_t unlang_interpret_push_children(rlm_rcode_t *p_result, request_t *request,
+                                             rlm_rcode_t default_rcode, bool do_next_sibling)
+{
+       unlang_stack_t          *stack = request->stack;
+       unlang_stack_frame_t    *frame = &stack->frame[stack->depth];   /* Quiet static analysis */
+       unlang_group_t          *g;
+
+       fr_assert(unlang_ops[frame->instruction->type].debug_braces);
+
+       g = unlang_generic_to_group(frame->instruction);
+
+       /*
+        *      The compiler catches most of these, EXCEPT for the
+        *      top-level 'recv Access-Request' etc.  Which can exist,
+        *      and can be empty.
+        */
+       if (!g->children) {
+               RDEBUG2("<ignoring empty subsection>");
+               return UNLANG_ACTION_EXECUTE_NEXT;
+       }
+
+       if (unlang_interpret_push(request, g->children, default_rcode, do_next_sibling, UNLANG_SUB_FRAME) < 0) {
+               *p_result = RLM_MODULE_FAIL;
+               return UNLANG_ACTION_STOP_PROCESSING;
+       }
+
+       return UNLANG_ACTION_PUSHED_CHILD;
+}
+
 static void instruction_timeout_handler(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *ctx);
 
 /** Update the current result after each instruction, and after popping each stack frame
index aececa084d913979bbdfad6a2864ccc520eafb49..670851dd2fd7433033b9f341c8ab759f6772e746 100644 (file)
@@ -66,25 +66,20 @@ static unlang_action_t unlang_limit_resume_done(UNUSED rlm_rcode_t *p_result, UN
 static unlang_action_t unlang_limit_enforce(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_frame_state_limit_t      *state = talloc_get_type_abort(frame->state, unlang_frame_state_limit_t);
-       unlang_group_t                  *g;
+       unlang_action_t                 action;
 
        state->thread = unlang_thread_instance(frame->instruction);
        fr_assert(state->thread != NULL);
 
        if (state->thread->active_callers >= state->limit) return UNLANG_ACTION_FAIL;
 
-       g = unlang_generic_to_group(frame->instruction);
-
-       if (unlang_interpret_push(request, g->children, frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) {
-               *p_result = RLM_MODULE_FAIL;
-               return UNLANG_ACTION_STOP_PROCESSING;
-       }
+       frame_repeat(frame, unlang_limit_resume_done);
 
-       state->thread->active_callers++;
+       action = unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_STOP);
 
-       frame_repeat(frame, unlang_limit_resume_done);
+       state->thread->active_callers += (action == UNLANG_ACTION_PUSHED_CHILD);
 
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return action;
 }
 
 static unlang_action_t unlang_limit_xlat_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
index c5b565dd87ef68af87ab59579e0fe9ac595b3567..c5bd1325eeb21f76a4453dbf64e7449798524151 100644 (file)
@@ -74,7 +74,6 @@ static unlang_action_t unlang_timeout_resume_done(UNUSED rlm_rcode_t *p_result,
 static unlang_action_t unlang_timeout_set(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_frame_state_timeout_t    *state = talloc_get_type_abort(frame->state, unlang_frame_state_timeout_t);
-       unlang_group_t                  *g;
        fr_time_t timeout;
 
        /*
@@ -87,13 +86,6 @@ static unlang_action_t unlang_timeout_set(rlm_rcode_t *p_result, request_t *requ
        if (fr_event_timer_at(state, unlang_interpret_event_list(request), &state->ev, timeout,
                              unlang_timeout_handler, state) < 0) {
                RPEDEBUG("Failed inserting event");
-               goto fail;
-       }
-
-       g = unlang_generic_to_group(frame->instruction);
-
-       if (unlang_interpret_push(request, g->children, frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) {
-       fail:
                *p_result = RLM_MODULE_FAIL;
                return UNLANG_ACTION_STOP_PROCESSING;
        }
@@ -101,7 +93,7 @@ static unlang_action_t unlang_timeout_set(rlm_rcode_t *p_result, request_t *requ
        frame_repeat(frame, unlang_timeout_resume_done);
        state->success = true;
 
-       return UNLANG_ACTION_PUSHED_CHILD;
+       return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_STOP);
 }
 
 static unlang_action_t unlang_timeout_xlat_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
index dfb1ab1f8dd91ac1487c63a3d816cfa18854ee89..e01d6f02b87d43ec6b30fe779ef0e494ba961cf6 100644 (file)
@@ -565,6 +565,10 @@ 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);
 
+int            unlang_interpret_push_children(rlm_rcode_t *p_result, request_t *request,
+                                              rlm_rcode_t default_rcode, bool do_next_sibling)
+                                              CC_HINT(warn_unused_result);
+
 int            unlang_op_init(void);
 
 void           unlang_op_free(void);