]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow modules to specify the size and type of the rctx to allocate
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 12 May 2025 20:10:55 +0000 (14:10 -0600)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 18 Jun 2025 12:52:55 +0000 (13:52 +0100)
This mostly saves on boilerplate at the top of every module call.

src/lib/server/module.h
src/lib/unlang/module.c
src/modules/rlm_ldap/rlm_ldap.c

index cc7497e52a80415f4e8f8c74a0f4f506d8ea5a35..6832ac7bc41ebf63685c9255bbc802b1d78cd19a 100644 (file)
@@ -176,6 +176,13 @@ struct module_method_binding_s {
        module_method_t                         method;                 //!< Module method to call
        call_env_method_t const                 *method_env;            //!< Method specific call_env.
 
+       size_t                                  rctx_size;              //!< If set, this overrides the module_t rctx_size.
+                                                                       ///< Instructs the module instruction to pre-allocate
+                                                                       ///< an rctx (available in mctx->rctx) before the module
+                                                                       ///< method is called.
+       char const                              *rctx_type;             //!< If rctx_size is used from the mmb, this sets the
+                                                                       ///< type of the rctx.
+
        fr_dlist_head_t                         same_name1;             //!< List of bindings with the same name1.  Only initialised
                                                                        ///< for the the first name1 binding.
                                                                        ///< DO NOT INITIALISE IN THE MODULE.
@@ -235,8 +242,19 @@ struct module_s {
 
        size_t                          thread_inst_size;       //!< Size of the module's thread-specific instance data.
        char const                      *thread_inst_type;      //!< talloc type to assign to thread instance data.
+
+       size_t                          rctx_size;              //!< Size of the module's thread-specific data.
+       char const                      *rctx_type;             //!< talloc type to assign to thread instance data.
 };
 
+#define TALLOCED_TYPE(_field, _ctype) \
+       ._field##_size = sizeof(_ctype), ._field##_type = #_ctype
+
+#define MODULE_BOOT(_ctype) TALLOCED_TYPE(boot, _ctype)
+#define MODULE_INST(_ctype) TALLOCED_TYPE(inst, _ctype)
+#define MODULE_THREAD_INST(_ctype) TALLOCED_TYPE(thread_inst, _ctype)
+#define MODULE_RCTX(_ctype) TALLOCED_TYPE(rctx, _ctype)
+
 /** What state the module instance is currently in
  *
  */
index 8fe8ae0e26696ae0534578b143899bac8cd21ed7..2aff535e756ad8c63bfb2b47b051560f9022aba9 100644 (file)
@@ -845,10 +845,46 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request,
         */
        if (fr_time_delta_ispos(frame->instruction->actions.retry.irt)) now = fr_time();
 
+       /*
+        *      Pre-allocate an rctx for the module, if it has one.
+        */
+       fr_assert_msg(state->rctx == NULL, "rctx should be NULL for initial module call");
+       {
+               size_t size = 0;
+               char const *type;
+
+               /*
+                *      Use the module method binding's rctx size in preference
+                *      to the one set for the module as a whole.
+                */
+               if (m->mmc.mmb.rctx_size) {
+                       size = m->mmc.mmb.rctx_size;
+                       type = m->mmc.mmb.rctx_type;
+               /*
+                *      Use the rctx from the module_t
+                *
+                *      The module is still fine to allocate the rctx itself
+                *      in the first module method call.
+                */
+               } else if(m->mmc.mi->exported->rctx_size) {
+                       size = m->mmc.mi->exported->rctx_size;
+                       type = m->mmc.mi->exported->rctx_type;
+               }
+
+               if (size > 0) {
+                       MEM(state->rctx = talloc_zero_array(state, uint8_t, size));
+                       if (!type) {
+                               talloc_set_name(state->rctx, "%s_rctx_t", m->mmc.mi->name);
+                       } else {
+                               talloc_set_name_const(state->rctx, type);
+                       }
+               }
+       }
+
        request->module = m->mmc.mi->name;
        safe_lock(m->mmc.mi);   /* Noop unless instance->mutex set */
        ua = m->mmc.mmb.method(&state->rcode,
-                              MODULE_CTX(m->mmc.mi, state->thread->data, state->env_data, NULL),
+                              MODULE_CTX(m->mmc.mi, state->thread->data, state->env_data, state->rctx),
                               request);
        safe_unlock(m->mmc.mi);
 
index cde79800863dae427a73b3b270cdf7d7696c5d01..59d091d7522bea9efe06ca5a52beb603e7fa5d36 100644 (file)
@@ -2868,17 +2868,15 @@ module_rlm_t rlm_ldap = {
                .magic                  = MODULE_MAGIC_INIT,
                .name                   = "ldap",
                .flags                  = 0,
-               .boot_size              = sizeof(rlm_ldap_boot_t),
-               .boot_type              = "rlm_ldap_boot_t",
-               .inst_size              = sizeof(rlm_ldap_t),
+               MODULE_BOOT(rlm_ldap_boot_t),
+               MODULE_INST(rlm_ldap_t),
                .config                 = module_config,
                .onload                 = mod_load,
                .unload                 = mod_unload,
                .bootstrap              = mod_bootstrap,
                .instantiate            = mod_instantiate,
                .detach                 = mod_detach,
-               .thread_inst_size       = sizeof(fr_ldap_thread_t),
-               .thread_inst_type       = "fr_ldap_thread_t",
+               MODULE_THREAD_INST(fr_ldap_thread_t),
                .thread_instantiate     = mod_thread_instantiate,
                .thread_detach          = mod_thread_detach,
        },