📄 modcall.c
字号:
case MOD_LOAD_BALANCE: case MOD_REDUNDANT_LOAD_BALANCE: q = NULL; for(p = g->children; p; p = p->next) { if (!q) { q = p; count = 1; continue; } count++; if ((count * (fr_rand() & 0xffff)) < (uint32_t) 0x10000) { q = p; } } stack.children[stack.pointer] = q; break; case MOD_SWITCH: radius_xlat(buffer, sizeof(buffer), child->name, request, NULL); null_case = q = NULL; for(p = g->children; p; p = p->next) { if (!p->name) { if (!null_case) null_case = p; continue; } if (strcmp(buffer, p->name) == 0) { q = p; break; } } if (!q) q = null_case; stack.children[stack.pointer] = q; break; default: DEBUG2("Internal sanity check failed in modcall %d", child->type); exit(1); /* internal sanity check failure */ break; } stack.start[stack.pointer] = stack.children[stack.pointer]; DEBUG2("%.*s- entering %s %s", stack.pointer, modcall_spaces, group_name[child->type], child->name ? child->name : ""); /* * Catch the special case of a NULL group. */ if (!stack.children[stack.pointer]) { /* * Print message for NULL group */ DEBUG2("%.*s- %s %s returns %s", stack.pointer + 1, modcall_spaces, group_name[child->type], child->name ? child->name : "", fr_int2str(rcode_table, stack.result[stack.pointer], "??")); goto do_return; } /* * The child may be a group, so we want to * recurse into it's children, rather than * falling through to the code below. */ continue; } /* * Process a stand-alone child, and fall through * to dealing with it's parent. */ sp = mod_callabletosingle(child); myresult = call_modsingle(child->method, sp, request, default_component_results[component]); handle_result: DEBUG2("%.*s[%s] returns %s", stack.pointer + 1, modcall_spaces, child->name ? child->name : "", fr_int2str(rcode_table, myresult, "??")); /* * This is a bit of a hack... */ if (component != RLM_COMPONENT_SESS) request->simul_max = myresult; /* * FIXME: Allow modules to push a modcallable * onto this stack. This should simplify * configuration a LOT! * * Once we do that, we can't do load-time * checking of the maximum stack depth, and we've * got to cache the stack pointer before storing * myresult. * * Also, if the stack changed, we need to set * children[ptr] to NULL, and process the next * entry on the stack, rather than falling * through to finalize the processing of this * entry. * * Don't put "myresult" on the stack here, * we have to do so with priority. */ /* * We roll back up the stack at this point. */ unroll: /* * The child's action says return. Do so. */ if (child->actions[myresult] == MOD_ACTION_RETURN) { stack.result[stack.pointer] = myresult; stack.children[stack.pointer] = NULL; goto do_return; } /* * If "reject", break out of the loop and return * reject. */ if (child->actions[myresult] == MOD_ACTION_REJECT) { stack.children[stack.pointer] = NULL; stack.result[stack.pointer] = RLM_MODULE_REJECT; goto do_return; } /* * Otherwise, the action is a number, the * preference level of this return code. If no * higher preference has been seen yet, remember * this one. */ if (child->actions[myresult] >= stack.priority[stack.pointer]) { stack.result[stack.pointer] = myresult; stack.priority[stack.pointer] = child->actions[myresult]; } next_section: /* * No parent, we must be done. */ if (!parent) { rad_assert(stack.pointer == 0); myresult = stack.result[0]; break; } rad_assert(child != NULL); /* * Go to the "next" child, whatever that is. */ switch (parent->type) { case MOD_IF: case MOD_ELSE: case MOD_ELSIF: case MOD_CASE: case MOD_GROUP: case MOD_POLICY: /* same as MOD_GROUP */ stack.children[stack.pointer] = child->next; break; case MOD_SWITCH: case MOD_LOAD_BALANCE: stack.children[stack.pointer] = NULL; break; case MOD_REDUNDANT_LOAD_BALANCE: if (child->next) { stack.children[stack.pointer] = child->next; } else { modgroup *g = mod_callabletogroup(parent); stack.children[stack.pointer] = g->children; } if (stack.children[stack.pointer] == stack.start[stack.pointer]) { stack.children[stack.pointer] = NULL; } break; default: DEBUG2("Internal sanity check failed in modcall next %d", child->type); exit(1); } /* * No child, we're done this group, and we return * "myresult" to the caller by pushing it back up * the stack. */ if (!stack.children[stack.pointer]) { do_return: rad_assert(stack.pointer > 0); myresult = stack.result[stack.pointer]; stack.pointer--; if (stack.pointer == 0) break; DEBUG2("%.*s- %s %s returns %s", stack.pointer + 1, modcall_spaces, group_name[parent->type], parent->name ? parent->name : "", fr_int2str(rcode_table, myresult, "??")); if ((parent->type == MOD_IF) || (parent->type == MOD_ELSIF)) { if_taken = was_if = TRUE; } else { if_taken = was_if = FALSE; } /* * Unroll the stack. */ child = stack.children[stack.pointer]; parent = child->parent; goto unroll; } } /* loop until done */ return myresult;}#if 0static const char *action2str(int action){ static char buf[32]; if(action==MOD_ACTION_RETURN) return "return"; if(action==MOD_ACTION_REJECT) return "reject"; snprintf(buf, sizeof buf, "%d", action); return buf;}/* If you suspect a bug in the parser, you'll want to use these dump * functions. dump_tree should reproduce a whole tree exactly as it was found * in radiusd.conf, but in long form (all actions explicitly defined) */static void dump_mc(modcallable *c, int indent){ int i; if(c->type==MOD_SINGLE) { modsingle *single = mod_callabletosingle(c); DEBUG("%.*s%s {", indent, "\t\t\t\t\t\t\t\t\t\t\t", single->modinst->name); } else { modgroup *g = mod_callabletogroup(c); modcallable *p; DEBUG("%.*s%s {", indent, "\t\t\t\t\t\t\t\t\t\t\t", group_name[c->type]); for(p = g->children;p;p = p->next) dump_mc(p, indent+1); } for(i = 0; i<RLM_MODULE_NUMCODES; ++i) { DEBUG("%.*s%s = %s", indent+1, "\t\t\t\t\t\t\t\t\t\t\t", fr_int2str(rcode_table, i, "??"), action2str(c->actions[i])); } DEBUG("%.*s}", indent, "\t\t\t\t\t\t\t\t\t\t\t");}static void dump_tree(int comp, modcallable *c){ DEBUG("[%s]", comp2str[comp]); dump_mc(c, 0);}#else#define dump_tree(a, b)#endif/* These are the default actions. For each component, the group{} block * behaves like the code from the old module_*() function. redundant{} and * append{} are based on my guesses of what they will be used for. --Pac. */static const intdefaultactions[RLM_COMPONENT_COUNT][GROUPTYPE_COUNT][RLM_MODULE_NUMCODES] ={ /* authenticate */ { /* group */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ 1, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ 1, /* noop */ 1 /* updated */ }, /* redundant */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ }, /* append */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ 2, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ } }, /* authorize */ { /* group */ { MOD_ACTION_RETURN, /* reject */ MOD_ACTION_RETURN, /* fail */ 3, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ 1, /* notfound */ 2, /* noop */ 4 /* updated */ }, /* redundant */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ }, /* append */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ 2, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ } }, /* preacct */ { /* group */ { MOD_ACTION_RETURN, /* reject */ MOD_ACTION_RETURN, /* fail */ 2, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ 1, /* noop */ 3 /* updated */ }, /* redundant */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ }, /* append */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ 2, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ } }, /* accounting */ { /* group */ { MOD_ACTION_RETURN, /* reject */ MOD_ACTION_RETURN, /* fail */ 2, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ 1, /* noop */ 3 /* updated */ }, /* redundant */ { 1, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ 1, /* invalid */ 1, /* userlock */ 1, /* notfound */ 2, /* noop */ 4 /* updated */ }, /* append */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ 2, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ } }, /* checksimul */ { /* group */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ }, /* redundant */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ }, /* append */ { MOD_ACTION_RETURN, /* reject */ 1, /* fail */ MOD_ACTION_RETURN, /* ok */ MOD_ACTION_RETURN, /* handled */ MOD_ACTION_RETURN, /* invalid */ MOD_ACTION_RETURN, /* userlock */ MOD_ACTION_RETURN, /* notfound */ MOD_ACTION_RETURN, /* noop */ MOD_ACTION_RETURN /* updated */ } }, /* pre-proxy */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -