Port fix for #945 from v3.0.x branch
authorAlan T. DeKok <aland@freeradius.org>
Sun, 5 Apr 2015 13:57:04 +0000 (09:57 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 5 Apr 2015 13:57:04 +0000 (09:57 -0400)
src/main/modcall.c

index 32d3471..f2e15ee 100644 (file)
@@ -396,14 +396,14 @@ typedef struct modcall_stack_entry_t {
 
 
 static int modcall_recurse(REQUEST *request, int component, int depth,
-                           modcall_stack_entry_t *entry);
+                          modcall_stack_entry_t *entry, int do_next_sibling);
 
 /*
  *     Call a child of a block.
  */
 static void modcall_child(REQUEST *request, int component, int depth,
                          modcall_stack_entry_t *entry, modcallable *c,
-                         int *result)
+                         int *result, int do_next_sibling)
 {
        modcall_stack_entry_t *next;
 
@@ -421,7 +421,7 @@ static void modcall_child(REQUEST *request, int component, int depth,
        next->priority = 0;
 
        if (!modcall_recurse(request, component,
-                            depth, next)) {
+                            depth, next, do_next_sibling)) {
                *result = RLM_MODULE_FAIL;
                 return;
        }
@@ -435,7 +435,7 @@ static void modcall_child(REQUEST *request, int component, int depth,
  *     Interpret the various types of blocks.
  */
 static int modcall_recurse(REQUEST *request, int component, int depth,
-                           modcall_stack_entry_t *entry)
+                          modcall_stack_entry_t *entry, int do_next_sibling)
 {
        int if_taken, was_if;
        modcallable *c;
@@ -627,7 +627,7 @@ redo:
                MOD_LOG_OPEN_BRACE(group_name[c->type]);
                modcall_child(request, component,
                              depth + 1, entry, g->children,
-                             &result);
+                             &result, TRUE);
                MOD_LOG_CLOSE_BRACE();
                goto calculate_result;
        } /* MOD_GROUP */
@@ -680,7 +680,7 @@ redo:
                MOD_LOG_OPEN_BRACE(group_name[c->type]);
                modcall_child(request, component,
                              depth + 1, entry, found,
-                             &result);
+                             &result, TRUE);
                MOD_LOG_CLOSE_BRACE();
                goto calculate_result;
        } /* MOD_SWITCH */
@@ -713,28 +713,23 @@ redo:
                if (c->type == MOD_LOAD_BALANCE) {
                        modcall_child(request, component,
                                      depth + 1, entry, found,
-                                     &result);
+                                     &result, FALSE);
                                               
                } else {
-                       int i;
+                       this = found;
 
-                       /*
-                        *      Loop over all children in this
-                        *      section.  If we get FAIL, then
-                        *      continue.  Otherwise, stop.
-                        */
-                       for (i = 0; i < count; i++) {
+                       do {
                                modcall_child(request, component,
                                              depth + 1, entry, found,
-                                             &result);
+                                             &result, FALSE);
                                if (found->actions[result] == MOD_ACTION_RETURN) {
                                        priority = -1;
                                        break;
                                }
 
-                               found = found->next;
-                               if (!found) found = g->children;
-                       }
+                               this = this->next;
+                               if (!this) this = g->children;
+                       } while (this != found);
                }
                MOD_LOG_CLOSE_BRACE();
                goto calculate_result;
@@ -843,9 +838,11 @@ calculate_result:
        if (c->type == MOD_CASE) return TRUE;
 
 next_sibling:
-       entry->c = entry->c->next;
+       if (do_next_sibling) {
+               entry->c = entry->c->next;
 
-       if (entry->c) goto redo;
+               if (entry->c) goto redo;
+       }
 
        /*
         *      And we're done!
@@ -876,7 +873,7 @@ int modcall(int component, modcallable *c, REQUEST *request)
        /*
         *      Call the main handler.
         */
-       if (!modcall_recurse(request, component, 0, &stack[0])) {
+       if (!modcall_recurse(request, component, 0, &stack[0], TRUE)) {
                return RLM_MODULE_FAIL;
        }