From: Alan T. DeKok Date: Thu, 14 Sep 2017 16:53:23 +0000 (-0400) Subject: add UNLANG_TYPE_CALL to the parser X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f1e11ba4a61ff8908f7e42e98f0d7dcfa405a2a;p=thirdparty%2Ffreeradius-server.git add UNLANG_TYPE_CALL to the parser and bare-bones interpreter --- diff --git a/src/include/interpreter.h b/src/include/interpreter.h index ebe0d6b0751..006162700f3 100644 --- a/src/include/interpreter.h +++ b/src/include/interpreter.h @@ -69,6 +69,7 @@ typedef enum { //!< values from a #map_proc_t call). UNLANG_TYPE_SUBREQUEST, //!< create a child subrequest UNLANG_TYPE_DETACH, //!< detach a child + UNLANG_TYPE_CALL, //!< call another virtual server #endif UNLANG_TYPE_POLICY, //!< Policy section. UNLANG_TYPE_XLAT_INLINE, //!< xlat statement, inline in "unlang" diff --git a/src/main/unlang_compile.c b/src/main/unlang_compile.c index b4d7730825a..d0461b24fef 100644 --- a/src/main/unlang_compile.c +++ b/src/main/unlang_compile.c @@ -2556,6 +2556,66 @@ static unlang_t *compile_subrequest(unlang_t *parent, unlang_compile_t *unlang_c } +static unlang_t *compile_call(unlang_t *parent, unlang_compile_t *unlang_ctx, CONF_SECTION *cs, + unlang_group_type_t group_type, unlang_group_type_t parentgroup_type, unlang_type_t mod_type) +{ + ssize_t slen; + char const *name2; + unlang_group_t *g; + unlang_t *c; + FR_TOKEN type; + + name2 = cf_section_name2(cs); + if (!name2) { + cf_log_err(cs, "'call' must be given with a server.PACKET argument"); + return NULL; + } + + type = cf_section_name2_quote(cs); + if (type != T_BARE_WORD) { + cf_log_err(cs, "The arguments to 'call' cannot by a quoted string or a dynamic value"); + return NULL; + } + + g = group_allocate(parent, cs, group_type, mod_type); + if (!g) return NULL; + + slen = tmpl_afrom_str(g, &g->vpt, name2, strlen(name2), type, REQUEST_CURRENT, PAIR_LIST_REQUEST, true); + if (slen < 0) { + char *spaces, *text; + + fr_canonicalize_error(cs, &spaces, &text, slen, fr_strerror()); + + cf_log_err(cs, "Syntax error"); + cf_log_err(cs, "%s", name2); + cf_log_err(cs, "%s^ %s", spaces, text); + + talloc_free(g); + talloc_free(spaces); + talloc_free(text); + + return NULL; + } + + /* + * Convert TMPL_TYPE_UNPARSED (it might have been + * an attribute) to TMPL_TYPE_DATA, with + * FR_TYPE_STRING data. + */ + tmpl_cast_in_place_str(g->vpt); + + /* + * @todo - look up server && packet type + */ + + c = unlang_group_to_generic(g); + c->name = unlang_ops[c->type].name; + c->debug_name = c->name; + + return compile_children(g, parent, unlang_ctx, group_type, parentgroup_type); +} + + /** Load a named module from "instantiate" or "policy". * * If it's "foo.method", look for "foo", and return "method" as the method @@ -2718,6 +2778,7 @@ static modcall_compile_t compile_table[] = { { "switch", compile_switch, UNLANG_GROUP_TYPE_SIMPLE, UNLANG_TYPE_SWITCH, REQUIRE_CHILDREN }, { "parallel", compile_parallel, UNLANG_GROUP_TYPE_SIMPLE, UNLANG_TYPE_PARALLEL, REQUIRE_CHILDREN }, { "subrequest", compile_subrequest, UNLANG_GROUP_TYPE_SIMPLE, UNLANG_TYPE_SUBREQUEST, REQUIRE_CHILDREN }, + { "call", compile_call, UNLANG_GROUP_TYPE_SIMPLE, UNLANG_TYPE_CALL, ALLOW_EMPTY_GROUP }, { NULL, NULL, 0, UNLANG_TYPE_NULL } }; diff --git a/src/main/unlang_interpret.c b/src/main/unlang_interpret.c index f4eac42c21a..65b1896a38c 100644 --- a/src/main/unlang_interpret.c +++ b/src/main/unlang_interpret.c @@ -707,6 +707,25 @@ static unlang_action_t unlang_detach(REQUEST *request, unlang_stack_t *stack, return UNLANG_ACTION_CALCULATE_RESULT; } +static unlang_action_t unlang_call(REQUEST *request, unlang_stack_t *stack, + UNUSED rlm_rcode_t *presult, UNUSED int *priority) +{ + unlang_stack_frame_t *frame = &stack->frame[stack->depth]; + unlang_t *instruction = frame->instruction; + unlang_group_t *g; + + g = unlang_generic_to_group(instruction); + rad_assert(g->children != NULL); + + rad_assert(request->async->process == unlang_process_continue); + + RDEBUG("FAKING CALL TO %s", g->vpt->name); + + unlang_push(stack, g->children, frame->result, UNLANG_NEXT_CONTINUE, UNLANG_SUB_FRAME); + return UNLANG_ACTION_PUSHED_CHILD; +} + + static unlang_action_t unlang_subrequest(REQUEST *request, unlang_stack_t *stack, rlm_rcode_t *presult, int *priority) { @@ -1796,6 +1815,11 @@ unlang_op_t unlang_ops[] = { .func = unlang_detach, .debug_braces = false }, + [UNLANG_TYPE_CALL] = { + .name = "call", + .func = unlang_call, + .debug_braces = true + }, #endif [UNLANG_TYPE_XLAT_INLINE] = { .name = "xlat_inline",