for a way to regain one global configuration for `Access-Request`
packets.
-=== Instantiate Section
-
-The `instantiate` section has been removed. It originally started out
-as a way to ensure that modules were instantiated in a particular
-order. As of 3.0.9, listing modules in the `instantiate` section was
-no longer necessary. The functionality was left in version 3 for
-compatibility, but has now been removed from version 4.
-
-The other use of the `instantiate` section was to define "virtual"
-modules for dynamic expansion. That functionality has been moved to
-the `mods-available/` and `mods-enabled/` directories. i.e. in
-version 4, just list the virtual module in a file, as if it was a real
-module.
-
-See the xref:mods-available/redundantsql.adoc[redundant_sql module]
-for more information.
-
== Virtual Servers
There are some changes to the virtual servers in `v4`. First, every
*** xref:mods-available/redis.adoc[REDIS Module]
*** xref:mods-available/redis_ippool.adoc[Redis IP Pool Module]
*** xref:mods-available/rediswho.adoc[REDISWho Module]
-*** xref:mods-available/redundant_sql.adoc[redundant_sql Module]
*** xref:mods-available/rest.adoc[Rest Module]
*** xref:mods-available/mruby.adoc[Ruby Module]
*** xref:mods-available/smbpasswd.adoc[SMBPasswd Module]
+++ /dev/null
-
-
-
-
-= redundant_sql Module
-
-The `redundant_sql` module handles SQL expansions in a redundant manner.
-
-
-This configuration can be thought of as a `virtual` module.
-
-e.g. If you have two redundant SQL servers, and you want to use
-them in the authorize and accounting sections, you could place a
-`redundant` block in each section, containing the exact same text.
-Or, you could uncomment the following lines, and list
-`redundant_sql` in the authorize and accounting sections.
-
-The `virtual` module defined here can also be used with dynamic
-expansions, under a few conditions:
-
- * The section is one of `group`, `redundant`, `load-balance`, or
- `redundant-load-balance`
- * The section contains module names ONLY, and no sub-sections
- * All modules in the section are using the same
- driver, e.g. They are all sql, or all ldap, etc.
-
-When those conditions are satisfied, the server will
-automatically register a dynamic expansion, using the
-name of the `virtual` module. In the example below,
-it will be `redundant_sql`. You can then use this expansion
-just like any other:
-
- update reply {
- Filter-Id := "%{redundant_sql: ... }"
- }
-
-In this example, the expansion is done via module `sql1`, and if
-that expansion fails, using module `sql2`.
-
-For best results, configure the `pool` subsection of the module so
-that `retry_delay` is non-zero. That will allow the redundant
-block to quickly ignore all "down" SQL databases. If instead we
-have `retry_delay = 0`, then every time the redundant block is
-used, the server will try to open a connection to every `down`
-database, causing problems.
-
-
-== Default Configuration
-
-```
-redundant redundant_sql {
- sql1
- sql2
-}
-```
num_workers:: The worker threads can be varied. It should be
-at least one, and no more than 128. Since each request is
+at least one, and no more than 32. Since each request is
non-blocking, there is no reason to run hundreds of threads
as in v3.
-When set to 0 the number of workers will be set from the number
-of cores available on the system.
-
-
-
-openssl_async_pool_init:: Controls the initial number of async
-contexts that are allocated when a worker thread is created.
-One async context is required for every TLS session (every
-RADSEC connection, every TLS based method still in progress).
-
-
-
-openssl_async_pool_max:: Controls the maximum number of async
-contexts which are allocated to a worker thread.
-If the maximum is reached, then no more TLS sessions can be
-created.
-
-Note: Setting this to 0 will mean unlimited async contexts
-will be created. But as of 3.0.0, OpenSSL has no mechanism
-to shrink the async pool. This means if there's a
-significant traffic spike the process will continue to use
-large amounts of memory until it's restarted.
-
.SNMP notifications.
}
$INCLUDE clients.conf
thread pool {
-# num_networks = 1
- num_workers = 0
-# openssl_async_pool_init = 64
-# openssl_async_pool_max = 1024
+ num_networks = 1
+ num_workers = 4
}
#$INCLUDE trigger.conf
modules {
+++ /dev/null
-# -*- text -*-
-#
-#
-# $Id$
-
-#######################################################################
-#
-# = redundant_sql Module
-#
-# The `redundant_sql` module handles SQL expansions in a redundant manner.
-#
-#
-# This configuration can be thought of as a `virtual` module.
-#
-# e.g. If you have two redundant SQL servers, and you want to use
-# them in the authorize and accounting sections, you could place a
-# `redundant` block in each section, containing the exact same text.
-# Or, you could uncomment the following lines, and list
-# `redundant_sql` in the authorize and accounting sections.
-#
-# The `virtual` module defined here can also be used with dynamic
-# expansions, under a few conditions:
-#
-# * The section is one of `group`, `redundant`, `load-balance`, or
-# `redundant-load-balance`
-# * The section contains module names ONLY, and no sub-sections
-# * All modules in the section are using the same
-# driver, e.g. They are all sql, or all ldap, etc.
-#
-# When those conditions are satisfied, the server will
-# automatically register a dynamic expansion, using the
-# name of the `virtual` module. In the example below,
-# it will be `redundant_sql`. You can then use this expansion
-# just like any other:
-#
-# update reply {
-# Filter-Id := "%{redundant_sql: ... }"
-# }
-#
-# In this example, the expansion is done via module `sql1`, and if
-# that expansion fails, using module `sql2`.
-#
-# For best results, configure the `pool` subsection of the module so
-# that `retry_delay` is non-zero. That will allow the redundant
-# block to quickly ignore all "down" SQL databases. If instead we
-# have `retry_delay = 0`, then every time the redundant block is
-# used, the server will try to open a connection to every `down`
-# database, causing problems.
-#
-redundant redundant_sql {
- sql1
- sql2
-}
$INCLUDE mods-enabled/
}
+#
+# .Instantiation
+#
+# This section orders the loading of the modules. Modules
+# listed here will get loaded BEFORE the later sections like
+# authorize, authenticate, etc. get examined.
+#
+# This section is not strictly needed. When a section like
+# authorize refers to a module, it's automatically loaded and
+# initialized. However, some modules may not be listed in any
+# of the following sections, so they can be listed here.
+#
+# Also, listing modules here ensures that you have control over
+# the order in which they are initialized. If one module needs
+# something defined by another module, you can list them in order
+# here, and ensure that the configuration will be OK.
+#
+# After the modules listed here have been loaded, all of the modules
+# in the "mods-enabled" directory will be loaded. Loading the
+# "mods-enabled" directory means that unlike Version 2, you usually
+# don't need to list modules here.
+#
+instantiate {
+ #
+ # We list the counter module here so that it registers
+ # the check_name attribute before any module which sets
+ # it.
+ #
+# dailycounter
+
+ #
+ # subsections here can be thought of as `virtual` modules.
+ #
+ # e.g. If you have two redundant SQL servers, and you want to
+ # use them in the authorize and accounting sections, you could
+ # place a `redundant` block in each section, containing the
+ # exact same text. Or, you could uncomment the following
+ # lines, and list `redundant_sql` in the authorize and
+ # accounting sections.
+ #
+ # The `virtual` module defined here can also be used with
+ # dynamic expansions, under a few conditions:
+ #
+ # * The section is `redundant`, or `load-balance`, or
+ # `redundant-load-balance`
+ # * The section contains modules ONLY, and no sub-sections
+ # * All modules in the section are using the same rlm_
+ # driver, e.g. They are all sql, or all ldap, etc.
+ #
+ # When those conditions are satisfied, the server will
+ # automatically register a dynamic expansion, using the
+ # name of the `virtual` module. In the example below,
+ # it will be `redundant_sql`. You can then use this expansion
+ # just like any other:
+ #
+ # update reply {
+ # Filter-Id := "%{redundant_sql: ... }"
+ # }
+ #
+ # In this example, the expansion is done via module `sql1`,
+ # and if that expansion fails, using module `sql2`.
+ #
+ # For best results, configure the `pool` subsection of the
+ # module so that `retry_delay` is non-zero. That will allow
+ # the redundant block to quickly ignore all "down" SQL
+ # databases. If instead we have `retry_delay = 0`, then
+ # every time the redundant block is used, the server will try
+ # to open a connection to every `down` database, causing
+ # problems.
+ #
+# redundant redundant_sql {
+# sql1
+# sql2
+# }
+}
+
######################################################################
#
# .Policies
/*
* Instantiate the modules
*/
- if (modules_instantiate(cs) < 0) return -1;
+ if (modules_instantiate() < 0) return -1;
/*
* Call xlat instantiation functions (after the xlats have been compiled)
static int _module_instantiate(void *instance);
-static int virtual_module_instantiate(CONF_SECTION *vm_cs);
-
/*
* Ordered by component
*/
* Allows the module to initialise connection pools, and complete any registrations that depend on
* attributes created during the bootstrap phase.
*
- * @param[in] root of the server configuration.
* @return
* - 0 on success.
* - -1 on failure.
*/
-int modules_instantiate(CONF_SECTION *root)
+int modules_instantiate(void)
{
- void *instance;
- CONF_ITEM *ci;
- CONF_SECTION *modules;
+ void *instance;
fr_rb_iter_inorder_t iter;
DEBUG2("#### Instantiating modules ####");
}
}
- modules = cf_section_find(root, "modules", NULL);
- if (!modules) return 0;
-
- /*
- * Instantiate the virtual modules.
- */
- for (ci = cf_item_next(modules, NULL);
- ci != NULL;
- ci = cf_item_next(modules, ci)) {
- char const *name;
- CONF_SECTION *subcs;
-
- if (!cf_item_is_section(ci)) continue;
-
- subcs = cf_item_to_section(ci);
-
- /*
- * If it's not an unlang keyword, then skip it.
- * It must be a module we already checked.
- */
- name = cf_section_name1(subcs);
- if (!unlang_compile_is_keyword(name)) continue;
-
- if (virtual_module_instantiate(subcs) < 0) return -1;
- }
-
return 0;
}
return mi;
}
-/** Instantiate a virtual module from an instantiate section
+/** Bootstrap a virtual module from an instantiate section
*
- * @param[in] cs that defines the virtual module.
+ * @param[in] vm_cs that defines the virtual module.
* @return
* - 0 on success.
* - -1 on failure.
*/
-static int virtual_module_instantiate(CONF_SECTION *cs)
+static int virtual_module_bootstrap(CONF_SECTION *vm_cs)
{
char const *name;
bool all_same = true;
module_t const *last = NULL;
CONF_ITEM *sub_ci = NULL;
CONF_PAIR *cp;
- module_instance_t *mi;
+ module_instance_t *instance;
- name = cf_section_name1(cs);
+ name = cf_section_name1(vm_cs);
/*
* Groups, etc. must have a name.
(strcmp(name, "redundant") == 0) ||
(strcmp(name, "redundant-load-balance") == 0) ||
(strcmp(name, "load-balance") == 0)) {
- name = cf_section_name2(cs);
+ name = cf_section_name2(vm_cs);
if (!name) {
- cf_log_err(cs, "Keyword module must have a second name");
+ cf_log_err(vm_cs, "Subsection must have a name");
return -1;
}
- /*
- * name2 was already checked in modules_bootstrap()
- */
- fr_assert(!unlang_compile_is_keyword(name));
+ if (unlang_compile_is_keyword(name)) {
+ is_reserved:
+ cf_log_err(vm_cs, "Virtual modules cannot overload unlang keywords");
+ return -1;
+ }
} else {
- cf_log_err(cs, "Module names cannot be unlang keywords '%s'", name);
- return -1;
- }
-
- /*
- * Ensure that the module doesn't exist.
- */
- mi = module_by_name(NULL, name);
- if (mi) {
- ERROR("Duplicate module \"%s\" in file %s[%d] and file %s[%d]",
- name,
- cf_filename(cs),
- cf_lineno(cs),
- cf_filename(mi->dl_inst->conf),
- cf_lineno(mi->dl_inst->conf));
- return -1;
+ goto is_reserved;
}
/*
* Ensure that the modules we reference here exist.
*/
- while ((sub_ci = cf_item_next(cs, sub_ci))) {
+ while ((sub_ci = cf_item_next(vm_cs, sub_ci))) {
if (cf_item_is_pair(sub_ci)) {
cp = cf_item_to_pair(sub_ci);
if (cf_pair_value(cp)) {
- cf_log_err(sub_ci, "Cannot set return codes in a %s block", cf_section_name1(cs));
+ cf_log_err(sub_ci, "Cannot set return codes in a %s block", cf_section_name1(vm_cs));
return -1;
}
*
* Note that we don't care what the method is, just that it exists.
*/
- mi = module_by_name_and_method(NULL, NULL, NULL, NULL, cf_pair_attr(cp));
- if (!mi) {
+ instance = module_by_name_and_method(NULL, NULL, NULL, NULL, cf_pair_attr(cp));
+ if (!instance) {
cf_log_err(sub_ci, "Module instance \"%s\" referenced in %s block, does not exist",
- cf_pair_attr(cp), cf_section_name1(cs));
+ cf_pair_attr(cp), cf_section_name1(vm_cs));
return -1;
}
if (all_same) {
if (!last) {
- last = mi->module;
- } else if (last != mi->module) {
+ last = instance->module;
+ } else if (last != instance->module) {
last = NULL;
all_same = false;
}
/*
* Register a redundant xlat
*/
- if (all_same && (xlat_register_legacy_redundant(cs) < 0)) return -1;
+ if (all_same && (xlat_register_legacy_redundant(vm_cs) < 0)) return -1;
return 0;
}
*/
int modules_bootstrap(CONF_SECTION *root)
{
- CONF_ITEM *ci;
+ CONF_ITEM *ci, *next;
CONF_SECTION *cs, *modules;
/*
*/
for (ci = cf_item_next(modules, NULL);
ci != NULL;
- ci = cf_item_next(modules, ci)) {
+ ci = next) {
char const *name;
CONF_SECTION *subcs;
module_instance_t *instance;
+ next = cf_item_next(modules, ci);
+
if (!cf_item_is_section(ci)) continue;
subcs = cf_item_to_section(ci);
- /*
- * name2 can't be a keyword
- */
name = cf_section_name2(subcs);
if (name && unlang_compile_is_keyword(name)) {
invalid_name:
}
name = cf_section_name1(subcs);
-
- /*
- * For now, ignore name1 which is a keyword.
- */
- if (unlang_compile_is_keyword(name)) {
- if (!cf_section_name2(subcs)) {
- cf_log_err(subcs, "Missing second name at '%s'", name);
- return -1;
- }
- continue;
- }
+ if (unlang_compile_is_keyword(name)) goto invalid_name;
/*
* Skip inline templates, and disallow "template { ... }"
instance = module_bootstrap(NULL, subcs);
if (!instance) return -1;
+
+ if (!next || !cf_item_is_section(next)) continue;
+ }
+
+ /*
+ * Look for the 'instantiate' section, which tells us
+ * the instantiation order of the modules, and also allows
+ * us to load modules with no authorize/authenticate/etc.
+ * sections.
+ */
+ cs = cf_section_find(root, "instantiate", NULL);
+ if (cs) {
+ cf_log_debug(cs, " instantiate {");
+ ci = NULL;
+
+ /*
+ * Loop over the items in the 'instantiate' section.
+ */
+ while ((ci = cf_item_next(cs, ci))) {
+ CONF_SECTION *vm_cs;
+
+ /*
+ * Skip sections and "other" stuff.
+ * Sections will be handled later, if
+ * they're referenced at all...
+ */
+ if (cf_item_is_pair(ci)) {
+ cf_log_warn(ci, "Only virtual modules can be instantiated "
+ "with the instantiate section");
+ continue;
+ }
+
+ /*
+ * Skip section
+ */
+ if (!cf_item_is_section(ci)) continue;
+
+ vm_cs = cf_item_to_section(ci);
+ cf_log_debug(ci, "Instantiating virtual module \"%s %s\"",
+ cf_section_name1(vm_cs), cf_section_name2(vm_cs));
+
+ /*
+ * Can only be "redundant" or
+ * "load-balance" or
+ * "redundant-load-balance"
+ */
+ if (virtual_module_bootstrap(cf_item_to_section(ci)) < 0) return -1;
+ }
+
+ cf_log_debug(cs, " }");
}
cf_log_debug(modules, " } # modules");
void modules_thread_detach(void);
-int modules_instantiate(CONF_SECTION *root) CC_HINT(nonnull);
+int modules_instantiate(void) CC_HINT(nonnull);
module_instance_t *module_bootstrap(module_instance_t const *parent, CONF_SECTION *cs) CC_HINT(nonnull(2));