]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
temporary migration tools
authorAlan T. DeKok <aland@freeradius.org>
Sat, 20 Aug 2022 13:06:33 +0000 (09:06 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 22 Aug 2022 00:34:08 +0000 (20:34 -0400)
where we can enable / disable flatten / nested pairs at run time.

src/bin/radiusd.c
src/lib/io/worker.c
src/lib/io/worker.h
src/lib/server/main_config.c
src/lib/server/main_config.h
src/lib/server/tmpl_tokenize.c
src/lib/unlang/xlat_builtin.c
src/tests/keywords/edit-list-star [new file with mode: 0644]

index 73927c5e4aca89f3823ba97391ba5657ae72f966..c2dd55cb4023f1e01c25f94b8df43322e0e6c2c8 100644 (file)
@@ -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.
index cb0af3705690a918ea7f72fb95e949ef0c8f5a73..fd5bcf4e498ac087afe392b113da756b77108394 100644 (file)
@@ -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.
         */
index c40b06880b2abea21a7e537f233d9db9542b83e7..21ad54225633e7a15d5f5ac7a6d176c9ca160197 100644 (file)
@@ -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;
 
index 36b4b77bb7f05af5a3cb1755094fadc691034414..0dfba227bb39b47cbb75ebb7401092b2cda496b4 100644 (file)
@@ -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
 };
 
index c335052b8df14ad3de2217ab6a0cf357e90c5cc6..8a8af7cd3795a9925ff13677d0231e0f30ab53c8 100644 (file)
@@ -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);
index 0b68b3b876ba95c21d5987cd0641e387e8bc3a42..008a84749af462d5006950651751bbf929b89464 100644 (file)
@@ -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 */
index 83cd8efac08727dfc58d9e2fac59cedc8fa3db97..08089475894b0483273198c08fce0b553ce664fb 100644 (file)
@@ -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 (file)
index 0000000..4b58fc1
--- /dev/null
@@ -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