From: Arran Cudbard-Bell Date: Mon, 12 May 2025 20:10:55 +0000 (-0600) Subject: Allow modules to specify the size and type of the rctx to allocate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39a3fd7b7234157b3ca787a7207c5667e896d405;p=thirdparty%2Ffreeradius-server.git Allow modules to specify the size and type of the rctx to allocate This mostly saves on boilerplate at the top of every module call. --- diff --git a/src/lib/server/module.h b/src/lib/server/module.h index cc7497e52a8..6832ac7bc41 100644 --- a/src/lib/server/module.h +++ b/src/lib/server/module.h @@ -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 * */ diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index 8fe8ae0e266..2aff535e756 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -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); diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index cde79800863..59d091d7522 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -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, },