From: Alan T. DeKok Date: Sat, 20 Aug 2022 13:06:33 +0000 (-0400) Subject: temporary migration tools X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b47335e43abf566ab4d98aaf1408e3e602bcc4b;p=thirdparty%2Ffreeradius-server.git temporary migration tools where we can enable / disable flatten / nested pairs at run time. --- diff --git a/src/bin/radiusd.c b/src/bin/radiusd.c index 73927c5e4ac..c2dd55cb402 100644 --- a/src/bin/radiusd.c +++ b/src/bin/radiusd.c @@ -816,8 +816,13 @@ int main(int argc, char *argv[]) schedule->stats_interval = config->stats_interval; schedule->network.max_outstanding = config->max_requests; - schedule->worker.max_requests = config->max_requests; - schedule->worker.max_request_time = config->max_request_time; + +#define COPY(_x) schedule->worker._x = config->_x + COPY(max_requests); + COPY(max_request_time); + COPY(unflatten_after_decode); + COPY(unflatten_before_encode); + COPY(flatten_before_encode); /* * Single server mode: use the global event list. diff --git a/src/lib/io/worker.c b/src/lib/io/worker.c index cb0af370569..fd5bcf4e498 100644 --- a/src/lib/io/worker.c +++ b/src/lib/io/worker.c @@ -541,6 +541,13 @@ static void worker_send_reply(fr_worker_t *worker, request_t *request, size_t si ssize_t slen = 0; fr_listen_t const *listen = request->async->listen; + if (worker->config.flatten_before_encode) { + fr_pair_flatten(request->pair_list.reply); + + } else if (worker->config.unflatten_before_encode) { + fr_pair_unflatten(request->pair_list.reply); + } /* else noop */ + if (listen->app->encode) { slen = listen->app->encode(listen->app_instance, request, reply->m.data, reply->m.rb_size); @@ -720,6 +727,10 @@ nak: return; } + if (worker->config.unflatten_after_decode) { + fr_pair_unflatten(request->pair_list.request); + } + /* * Set the entry point for this virtual server. */ diff --git a/src/lib/io/worker.h b/src/lib/io/worker.h index c40b06880b2..21ad5422563 100644 --- a/src/lib/io/worker.h +++ b/src/lib/io/worker.h @@ -65,6 +65,10 @@ typedef struct { fr_time_delta_t max_request_time; //!< maximum time a request can be processed + bool unflatten_after_decode; //!< the worker will call "unflatten" after protocol decoding + bool flatten_before_encode; //!< the worker will call "flatten" before all encoding + bool unflatten_before_encode; //!< the worker will call "unflatten" before all encoding + size_t talloc_pool_size; //!< for each request } fr_worker_config_t; diff --git a/src/lib/server/main_config.c b/src/lib/server/main_config.c index 36b4b77bb7f..0dfba227bb3 100644 --- a/src/lib/server/main_config.c +++ b/src/lib/server/main_config.c @@ -174,6 +174,16 @@ static const CONF_PARSER thread_config[] = { CONF_PARSER_TERMINATOR }; +static const CONF_PARSER migrate_config[] = { + { FR_CONF_OFFSET("unflatten_after_decode", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, unflatten_after_decode) }, + { FR_CONF_OFFSET("unflatten_before_encode", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, unflatten_before_encode) }, + { FR_CONF_OFFSET("flatten_before_encode", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, flatten_before_encode) }, + { FR_CONF_OFFSET("tmpl_tokenize_all_nested", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, tmpl_tokenize_all_nested) }, + { FR_CONF_OFFSET("parse_new_conditions", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, parse_new_conditions) }, + { FR_CONF_OFFSET("use_new_conditions", FR_TYPE_BOOL | FR_TYPE_HIDDEN, main_config_t, use_new_conditions) }, + CONF_PARSER_TERMINATOR +}; + static const CONF_PARSER server_config[] = { /* * FIXME: 'prefix' is the ONLY one which should be @@ -203,6 +213,8 @@ static const CONF_PARSER server_config[] = { { FR_CONF_POINTER("thread", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) thread_config, .ident2 = CF_IDENT_ANY }, + { FR_CONF_POINTER("migrate", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) migrate_config, .ident2 = CF_IDENT_ANY }, + CONF_PARSER_TERMINATOR }; diff --git a/src/lib/server/main_config.h b/src/lib/server/main_config.h index c335052b8df..8a8af7cd379 100644 --- a/src/lib/server/main_config.h +++ b/src/lib/server/main_config.h @@ -150,6 +150,15 @@ struct main_config_s { uint32_t max_workers; //!< for the scheduler fr_time_delta_t stats_interval; //!< for the scheduler + /* + * Migration tools + */ + bool unflatten_after_decode; //!< the worker will call "unflatten" after protocol decoding + bool flatten_before_encode; //!< the worker will call "flatten" before all encoding + bool unflatten_before_encode; //!< the worker will call "unflatten" before all encoding + bool tmpl_tokenize_all_nested; //!< tmpl_tokenize will create nested tmpls instead of flat ones + bool parse_new_conditions; //!< the new xlat expressions will be parsed, but not used. + bool use_new_conditions; //!< the new xlat expressions will be used for conditions, instead of the old code }; void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config); diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index 0b68b3b876b..008a84749af 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -1874,8 +1874,10 @@ do_suffix: * each tmpl talloc pool, unless the attribute * reference list contains a group, there's no performance * penalty in repeatedly allocating and freeing this ar. + * + * Flatten / nested migration hack. :( */ - if ((filter == TMPL_ATTR_REF_NO_FILTER) && (ar->type == TMPL_ATTR_TYPE_NORMAL)) { + if ((main_config && main_config->tmpl_tokenize_all_nested) || ((filter == TMPL_ATTR_REF_NO_FILTER) && (ar->type == TMPL_ATTR_TYPE_NORMAL))) { TALLOC_FREE(ar); } else { our_parent = da; /* Only update the parent if we're not stripping */ diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 83cd8efac08..08089475894 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -1139,6 +1139,98 @@ static xlat_action_t xlat_func_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcur return XLAT_ACTION_DONE; } +/** Flatten a given group. + * + * This is a temporary function for migration purposes + * + * Example: +@verbatim +"%(flatten:&request)" +@endverbatim + * + * @ingroup xlat_functions + */ +static xlat_action_t xlat_func_flatten(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, + UNUSED xlat_ctx_t const *xctx, + request_t *request, fr_value_box_list_t *in) +{ + fr_pair_t *vp; + tmpl_t *vpt; + fr_value_box_t *attr = fr_dlist_head(in); + char const *fmt; + + fmt = attr->vb_strvalue; + if (tmpl_afrom_attr_str(request, NULL, &vpt, fmt, + &(tmpl_rules_t){ + .attr = { + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_AUTO + } + }) <= 0) { + RPEDEBUG("Invalid input"); + return XLAT_ACTION_FAIL; + } + + if ((tmpl_find_vp(&vp, request, vpt) < 0) || + (vp->da->type != FR_TYPE_GROUP)) { + REDEBUG("Can't find '%s', or it's not a group", fmt); + talloc_free(vpt); + return XLAT_ACTION_FAIL; + } + + fr_pair_flatten(vp); + + talloc_free(vpt); + + return XLAT_ACTION_DONE; +} + +/** Unflatten a given group. + * + * This is a temporary function for migration purposes + * + * Example: +@verbatim +"%(unflatten:&request)" +@endverbatim + * + * @ingroup xlat_functions + */ +static xlat_action_t xlat_func_unflatten(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, + UNUSED xlat_ctx_t const *xctx, + request_t *request, fr_value_box_list_t *in) +{ + fr_pair_t *vp; + tmpl_t *vpt; + fr_value_box_t *attr = fr_dlist_head(in); + char const *fmt; + + fmt = attr->vb_strvalue; + if (tmpl_afrom_attr_str(request, NULL, &vpt, fmt, + &(tmpl_rules_t){ + .attr = { + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_AUTO + } + }) <= 0) { + RPEDEBUG("Invalid input"); + return XLAT_ACTION_FAIL; + } + + if ((tmpl_find_vp(&vp, request, vpt) < 0) || + (vp->da->type != FR_TYPE_GROUP)) { + REDEBUG("Can't find '%s', or it's not a group", fmt); + talloc_free(vpt); + return XLAT_ACTION_FAIL; + } + + fr_pair_unflatten(vp); + + talloc_free(vpt); + + return XLAT_ACTION_DONE; +} + static xlat_action_t xlat_func_untaint(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in) @@ -3840,6 +3932,12 @@ do { \ XLAT_REGISTER_ARGS("subst", xlat_func_subst, xlat_func_subst_args); XLAT_REGISTER_ARGS("trigger", trigger_xlat, trigger_xlat_args); + /* + * Temporary functions for migration. + */ + XLAT_REGISTER_ARGS("flatten", xlat_func_flatten, xlat_func_debug_attr_args); /* takes an attribute reference */ + XLAT_REGISTER_ARGS("unflatten", xlat_func_unflatten, xlat_func_debug_attr_args); /* takes an attribute reference */ + xlat = xlat_register(NULL, "untaint", xlat_func_untaint, NULL); xlat_internal(xlat); xlat = xlat_register(NULL, "taint", xlat_func_taint, NULL); diff --git a/src/tests/keywords/edit-list-star b/src/tests/keywords/edit-list-star new file mode 100644 index 00000000000..4b58fc1ef6c --- /dev/null +++ b/src/tests/keywords/edit-list-star @@ -0,0 +1,23 @@ +# +# PRE: edit-leaf-star +# +&Tmp-Group-0.Tmp-Integer-0 := { 1, 3, 5, 7, 11 } +&Tmp-Integer-1 := 0 + +# +# Do operations on sets of inputs. +# +&Tmp-Integer-1 += &Tmp-Group-0.Tmp-Integer-0[*] +if (&Tmp-Integer-1 != 27) { + test_fail +} + +&Tmp-Group-1 := &Tmp-Group-0 +&Tmp-Integer-1 := 0 + +&Tmp-Integer-1 += &Tmp-Group-1.Tmp-Integer-0[*] +if (&Tmp-Integer-1 != 27) { + test_fail +} + +success