The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
module.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: f67f5eb9a1f9d64897f7eca03729bf90258e9c9c $
19  *
20  * @file src/lib/server/module.c
21  * @brief Defines functions for module initialisation
22  *
23  * @copyright 2016,2024 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24  * @copyright 2003,2006,2016 The FreeRADIUS server project
25  * @copyright 2000 Alan DeKok (aland@freeradius.org)
26  * @copyright 2000 Alan Curry (pacman@world.std.com)
27  */
28 
29 RCSID("$Id: f67f5eb9a1f9d64897f7eca03729bf90258e9c9c $")
30 
31 #include <freeradius-devel/server/base.h>
32 #include <freeradius-devel/server/cf_file.h>
33 #include <freeradius-devel/server/modpriv.h>
34 #include <freeradius-devel/server/module_rlm.h>
35 #include <freeradius-devel/server/radmin.h>
36 #include <freeradius-devel/server/request_data.h>
37 #include <freeradius-devel/server/module.h>
38 #include <freeradius-devel/util/strerror.h>
39 #include <freeradius-devel/util/talloc.h>
40 #include <freeradius-devel/unlang/xlat_func.h>
41 
42 #include <talloc.h>
43 #include <sys/mman.h>
44 
46 
47 /** Heap of all lists/modules used to get a common index with mlg_thread->inst_list
48  */
50 
51 /** An array of thread-local module lists
52 *
53 * The indexes in this array are identical to module_list_global, allowing
54 * O(1) lookups. Arrays are used here as there's no performance penalty
55 * once they're populated.
56 */
58 
59 static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
60 static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions);
61 static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info);
62 static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
63 static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info);
64 
66  {
67  .parent = "show module",
68  .add_name = true,
69  .name = "status",
70  .func = cmd_show_module_status,
71  .help = "Show the status of a particular module.",
72  .read_only = true,
73  },
74 
75  {
76  .parent = "show module",
77  .add_name = true,
78  .name = "config",
79  .func = cmd_show_module_config,
80  .help = "Show configuration for a module",
81  // @todo - do tab expand, by walking over the whole module list...
82  .read_only = true,
83  },
84 
85  {
86  .parent = "set module",
87  .add_name = true,
88  .name = "status",
89  .syntax = "(alive|disallow|fail|reject|handled|invalid|notfound|noop|ok|updated)",
90  .func = cmd_set_module_status,
91  .help = "Change module status to fixed value.",
92  .read_only = false,
93  },
94 
96 };
97 
99  {
100  .parent = "show",
101  .name = "module",
102  .help = "Show information about modules.",
103  .tab_expand = module_name_tab_expand,
104  .read_only = true,
105  },
106 
107  // @todo - what if there's a module called "list" ?
108  {
109  .parent = "show module",
110  .name = "list",
111  .func = cmd_show_module_list,
112  .help = "Show the list of modules loaded in the server.",
113  .read_only = true,
114  },
115 
116  {
117  .parent = "set",
118  .name = "module",
119  .help = "Change module settings.",
120  .tab_expand = module_name_tab_expand,
121  .read_only = false,
122  },
123 
124 
126 };
127 
128 static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
129 {
130  module_instance_t *mi = ctx;
131 
132  fr_assert(mi->conf != NULL);
133 
134  (void) cf_section_write(fp, mi->conf, 0);
135 
136  return 0;
137 }
138 
139 static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx,
140  fr_cmd_info_t *info, int max_expansions, char const **expansions)
141 {
142  char const *text;
143  int count;
144 
145  if (info->argc <= 0) return 0;
146 
147  text = info->argv[info->argc - 1];
148  count = 0;
149 
151  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
152 
153  if (count >= max_expansions) {
154  break;
155  }
156  if (fr_command_strncmp(text, mi->name)) {
157  expansions[count] = strdup(mi->name);
158  count++;
159  }
160  }}
161 
162  return count;
163 }
164 
165 static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
166 {
168  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
169 
170  fprintf(fp, "\t%s\n", mi->name);
171  }}
172 
173  return 0;
174 }
175 
176 static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
177 {
178  module_instance_t *mi = ctx;
179 
180  if (!mi->force) {
181  fprintf(fp, "alive\n");
182  return 0;
183  }
184 
185  fprintf(fp, "%s\n", fr_table_str_by_value(rcode_table, mi->code, "<invalid>"));
186 
187  return 0;
188 }
189 
190 static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
191 {
192  module_instance_t *mi = ctx;
193  rlm_rcode_t rcode;
194 
195  if (strcmp(info->argv[0], "alive") == 0) {
196  mi->force = false;
197  return 0;
198  }
199 
201  if (rcode == RLM_MODULE_NOT_SET) {
202  fprintf(fp_err, "Unknown status '%s'\n", info->argv[0]);
203  return -1;
204  }
205 
206  mi->code = rcode;
207  mi->force = true;
208 
209  return 0;
210 }
211 
212 /** dl module tracking
213  *
214  * This is used by all module lists, irrespecitve of their type, and is thread safe.
215  */
217 
218 /** Callback to initialise any global structures required for the module list
219  *
220  * @param[in] ml to initialise global data for.
221  * @return
222  * - 0 on success.
223  * - -1 on failure.
224  */
225 typedef int (*module_list_init_t)(module_list_t *ml);
226 
227 /** Callback to free any global structures associated with the module list
228  *
229  * @param[in] ml to free.
230  */
231 typedef void (*module_list_free_t)(module_list_t *ml);
232 
233 /** Callback to add data for a module
234  *
235  * @param[in] mi to add data for.
236  * Use mi->ml for the module list.
237  * Use mi->data to access the data.
238  * @return
239  * - 0 on success.
240  * - -1 on failure.
241  */
243 
244 /** Callback to del data for a module
245  *
246  * @param[in] mi to add data to (use mi->ml for the module list).
247  *
248  */
250 
251 /** Callback to initialise a list for thread-local data, called once per thread
252  *
253  * @param[in] ctx talloc context for thread-local data.
254  * May be modified by the init function if the
255  * module_thread_instance_t need to be parented
256  * by another ctx.
257  * @param[in] ml to initialise thread-local data for.
258  * @return
259  * - 0 on success.
260  * - -1 on failure.
261  */
262 typedef int (*module_list_thread_init_t)(TALLOC_CTX **ctx, module_list_t const *ml);
263 
264 /** Callback to free thread-local structures, called once per thread as the thread is being destroyed
265  *
266  * @param[in] ml to free thread-local data for.
267  */
269 
270 /** Callback to add thread-local data for a module
271  *
272  * @param[in] ti to add data for.
273  * Use `ti->mi->ml` for the module list.
274  * Use `ti->mi` for the module instance.
275  * Use `ti->data` for the thread specific data.
276  * @return
277  * - 0 on success.
278  * - -1 on failure.
279  */
281 
282 /** Callback to remove thread-local data for a module
283  *
284  * @param[in] ti to del data for.
285  * Use `ti->mi->ml` for the module list.
286  * Use `ti->mi` for the module instance.
287  * Use `ti->data` for the thread specific data.
288  */
290 
291 /** Structure to hold callbacks for a module list type
292  *
293  * We care about performance for module lists, as they're used heavily at runtime.
294  *
295  * As much as possible we try to avoid jumping through unecessary functions and
296  * unecessary switch statements.
297  *
298  * This structure contains callbacks which change how the module list operates,
299  * making it either a global module list, or a thread-local module list, i.e. one
300  * which only be used by a single thread.
301  *
302  * Instances of this structure are created in this compilation unit, and exported
303  * for the caller to pass into module_list_alloc().
304  */
306  size_t list_size; //!< Size of talloc_chunk to allocate for the module_list_t.
307 
308  module_list_init_t init; //!< Initialise any global structures required for thread-local lookups.
309  module_list_free_t free; //!< Free any global structures required for thread-local lookups.
310 
311  size_t inst_size; //!< Size of talloc chunk to allocate for the module_instance_t.
312  ///< allows over-allocation if list types want to append fields.
313  module_list_data_add_t data_add; //!< Record that module data has been added.
314  module_list_data_del_t data_del; //!< Record that module data has been removed.
315 
316  /** Callbacks to manage thread-local data
317  */
318  struct {
319  module_list_thread_init_t init; //!< Initialise any thread-local structures required for thread-local lookups.
320  module_list_thread_free_t free; //!< Free any thread-local structures.
321 
322  module_list_thread_data_add_t data_add; //!< Add thread-local data for a module.
323  module_list_thread_data_get_t data_get; //!< Retrieve thread local-data for a module.
324  module_list_thread_data_del_t data_del; //!< Remove (but not free) thread-local data for a module.
325 
326  void *data; //!< Pointer to hold any global resources for the thread-local implementation.
328 };
329 
330 typedef struct {
331  module_instance_t mi; //!< Common module instance fields. Must come first.
332 
333  fr_heap_index_t inst_idx; //!< Entry in the bootstrap/instantiation heap.
334  //!< should be an identical value to the thread-specific
335  ///< data for this module.
337 
338 /** Sort module instance data first by list then by number
339  *
340  * The module's position in the global instance heap informs of us
341  * of its position in the thread-specific heap, which allows for
342  * O(1) lookups.
343  */
344 static int8_t _mlg_module_instance_cmp(void const *one, void const *two)
345 {
348  int8_t ret;
349 
350  fr_assert(a->ml && b->ml);
351 
352  ret = CMP(a->ml, b->ml);
353  if (ret != 0) return 0;
354 
355  return CMP(a->number, b->number);
356 }
357 
358 /** Free the global module index
359  *
360  */
361 static int _mlg_global_free(UNUSED void *uctx)
362 {
363  return talloc_free(mlg_index);
364 }
365 
366 /** Initialise the global module index
367  *
368  */
369 static int _mlg_global_init(UNUSED void *uctx)
370 {
372  return 0;
373 }
374 
375 /** Global initialisation for index heap and module array
376  *
377  */
379 {
380  /*
381  * Create the global module heap we use for
382  * common indexes in the thread-specific
383  * heaps.
384  */
386 
387  return 0;
388 }
389 
390 /** Add the unique index value so we can do thread local lookups
391  *
392  */
394 {
395  /*
396  * Insert the module into the global heap so
397  * we can get common thread-local indexes.
398  */
399  if (fr_heap_insert(&mlg_index, mi) < 0) {
400  ERROR("Failed inserting into global module index");
401  return -1;
402  }
403 
404  return 0;
405 }
406 
408 {
409  mlg_module_instance_t *mlg_mi = (mlg_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
410 
411  if (!fr_heap_entry_inserted(mlg_mi->inst_idx)) return;
412 
413  if (fr_heap_extract(&mlg_index, mi) == 0) return;
414 
415  fr_assert(0);
416 }
417 
418 /** Free the thread local heap on exit
419  *
420  * All thread local module lists should have been destroyed by this point
421  */
422 static int _module_thread_inst_list_free(void *tilp)
423 {
424  module_thread_instance_t **til = talloc_get_type_abort(tilp, module_thread_instance_t *);
425  size_t i, len = talloc_array_length(til);
426  unsigned int found = 0;
427 
428  for (i = 0; i < len; i++) if (til[i]) found++;
429 
430  if (!fr_cond_assert_msg(found == 0,
431  "Thread local array has %u non-null elements remaining on exit. This is a leak",
432  found)) {
433  return -1;
434  }
435 
436  return talloc_free(til);
437 }
438 
439 /** Allocate a thread-local array to hold thread data for each module thats been instantiated
440  *
441  * @param[in] ctx Talloc context for the thread-local data.
442  * Mutated by this function so that thread local data is allocated
443  * beneath the array.
444  * @param[in] ml Module list to initialise the thread-local data for.
445  */
446 static int mlg_thread_init(UNUSED TALLOC_CTX **ctx, UNUSED module_list_t const *ml)
447 {
448  /*
449  * Initialise the thread specific tree if this is the
450  * first time through or if everything else was
451  * de-initialised.
452  */
453  if (!mlg_thread_inst_list) {
455 
456  MEM(arr = talloc_zero_array(NULL, module_thread_instance_t *, fr_heap_num_elements(mlg_index)));
457 
459  }
460 
461  return 0;
462 }
463 
464 /** Retrieve the thread-specific data for a module from the thread-local array of instance data
465  *
466  * This looks complex, but it's just asserts for sanity. This is really only returning an array offset.
467  *
468  * @param[in] mi Module instance to get the thread-specific data for.
469  */
471 {
472  mlg_module_instance_t *mlg_mi = (mlg_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
474 
475  fr_assert_msg(mlg_mi->inst_idx <= talloc_array_length(mlg_thread_inst_list),
476  "module instance index %u must be <= thread local array %zu",
477  mlg_mi->inst_idx, talloc_array_length(mlg_thread_inst_list));
478 
480  "mismatch between global module heap (%u entries) and thread local (%zu entries)",
481  fr_heap_num_elements(mlg_index), talloc_array_length(mlg_thread_inst_list));
482 
483  ti = talloc_get_type_abort(mlg_thread_inst_list[mlg_mi->inst_idx - 1], module_thread_instance_t);
484  fr_assert_msg(ti->mi == mi, "thread/module mismatch thread %s (%p), module %s (%p)",
485  ti->mi->name, ti->mi, mi->name, mi);
486 
487  return ti;
488 }
489 
491 {
493  mlg_thread_inst_list[mlg_mi->inst_idx - 1] = ti;
494  return 0;
495 }
496 
498 {
500  mlg_thread_inst_list[mlg_mi->inst_idx - 1] = NULL;
501 }
502 
503 /** Callbacks for a global module list
504  */
506  .init = mlg_init,
507 
508  .inst_size = sizeof(mlg_module_instance_t),
509  .data_add = mlg_data_add,
510  .data_del = mlg_data_del,
511 
512  .thread = {
513  .init = mlg_thread_init,
514  .data_add = mlg_thread_data_add,
515  .data_get = mlg_thread_data_get,
516  .data_del = mlg_thread_data_del
517  }
518 };
519 
520 /** A slightly larger module_instance structure to hold the module instance and thread instance
521  */
522 typedef struct {
523  module_instance_t mi; //!< Common module instance fields. Must come first.
524  module_thread_instance_t *ti; //!< Thread-specific data. Still in its own structure
525  ///< for talloc reasons.
527 
529 {
530  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
531 
532  /*
533  * Only free thread instance data we allocated...
534  */
535  if (mltl_mi->ti) module_thread_detach(mltl_mi->ti);
536 }
537 
539 {
540  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
541  return mltl_mi->ti;
542 }
543 
545 {
546  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(ti->mi, module_instance_t);
547  mltl_mi->ti = ti;
548  return 0;
549 }
550 
552 {
553  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(ti->mi, module_instance_t);
554  mltl_mi->ti = NULL;
555 }
556 
557 /** Callbacks for a thread local list
558  */
561  .data_del = mltl_mlg_data_del,
562 
563  .thread = {
564  .data_add = mltl_thread_data_add,
565  .data_get = mltl_thread_data_get,
566  .data_del = mltl_thread_data_del
567  }
568 };
569 
570 /** Print debugging information for a module
571  *
572  * @param[in] mi Module instance to print.
573  */
575 {
576  FR_FAULT_LOG("%s (%p) {", mi->name, mi);
577  FR_FAULT_LOG(" type : %s", fr_table_str_by_value(dl_module_type_prefix, mi->module->type, "<invalid>"));
578  if (mi->parent) {
579  FR_FAULT_LOG(" parent : \"%s\" (%p)", mi->parent->name, mi->parent);
580  }
581  FR_FAULT_LOG(" bootstrapped : %s", mi->state & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no");
582  FR_FAULT_LOG(" instantiated : %s", mi->state & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
583  FR_FAULT_LOG(" boot : %p", mi->boot);
584  FR_FAULT_LOG(" data : %p", mi->data);
585  FR_FAULT_LOG(" conf : %p", mi->conf);
586  FR_FAULT_LOG("}");
587 }
588 
589 /** Print the contents of a module list
590  *
591  */
593 {
594  module_instance_t const *inst;
596 
597  FR_FAULT_LOG("Module list \"%s\" (%p) {", ml->name, ml);
598  FR_FAULT_LOG(" phase masked:");
599  FR_FAULT_LOG(" bootstrap : %s", ml->mask & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no");
600  FR_FAULT_LOG(" instantiate : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
601  FR_FAULT_LOG(" thread : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
602  FR_FAULT_LOG("}");
603  /*
604  * Modules are printed in the same order
605  * they would be bootstrapped or inserted
606  * into the tree.
607  */
608  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
609  inst;
610  inst = fr_rb_iter_next_inorder(&iter)) {
612  }
613 }
614 
615 /** Protect module data
616  *
617  * @param[in] pool to protect
618  * @return
619  * - 0 on success.
620  * - -1 on failure.
621  */
622 static inline CC_HINT(always_inline)
624 {
625  if ((pool->start == NULL) || !mi->ml->write_protect) return 0; /* noop */
626 
627  DEBUG3("Protecting data for module \"%s\" %p-%p",
628  mi->name, pool->start, ((uint8_t *)pool->start + pool->len - 1));
629 
630  if (unlikely(mprotect(pool->start, pool->len, PROT_READ) < 0)) {
631  fr_strerror_printf("Protecting \"%s\" module data failed: %s", mi->name, fr_syserror(errno));
632  return -1;
633  }
634 
635  return 0;
636 }
637 
638 /** Unprotect module data
639  *
640  * @param[in] pool to protect
641  * @return
642  * - 0 on success.
643  * - -1 on failure.
644  */
645 static inline CC_HINT(always_inline)
647 {
648  if ((pool->start == NULL) || !mi->ml->write_protect) return 0; /* noop */
649 
650  DEBUG3("Unprotecting data for module \"%s\" %p-%p",
651  mi->name, pool->start, ((uint8_t *)pool->start + pool->len - 1));
652 
653  if (unlikely(mprotect(pool->start, pool->len, PROT_READ | PROT_WRITE) < 0)) {
654  fr_strerror_printf("Unprotecting \"%s\" data failed: %s", mi->name, fr_syserror(errno));
655  return -1;
656  }
657 
658  return 0;
659 }
660 
661 /** Mark module data as read only
662  *
663  * @param[in] mi Instance data to protect (mark as read only).
664  * @return
665  * - 0 on success.
666  * - -1 on failure.
667  */
669 {
670  return module_data_unprotect(mi, &mi->inst_pool);
671 }
672 
673 /** Mark module data as read/write
674  *
675  * @param[in] mi Instance data to unprotect (mark as read/write).
676  * @return
677  * - 0 on success.
678  * - -1 on failure.
679  */
681 {
682  return module_data_unprotect(mi, &mi->inst_pool);
683 }
684 
685 /** Return the prefix string for the deepest module
686  *
687  * This is useful for submodules which don't have a prefix of their own.
688  * In this case we need to use the prefix of the shallowest module, which
689  * will be a proto or rlm module.
690  *
691  * @param[in] mi Instance to get the prefix for.
692  * @return The prefix string for the shallowest module.
693  */
695 {
696  module_instance_t const *root = module_instance_root(mi);
697 
698  return fr_table_str_by_value(dl_module_type_prefix, root->module->type, "<INVALID>");
699 }
700 
701 /** Avoid boilerplate when setting the module instance name
702  *
703  */
705 {
706  char const *name2;
707 
708  name2 = cf_section_name2(conf);
709  if (name2) return name2;
710 
711  return cf_section_name1(conf);
712 }
713 
714 /** Covert a CONF_SECTION into parsed module instance data
715  *
716  */
718 {
719  /*
720  * Associate the module instance with the conf section
721  * *before* executing any parse rules that might need it.
722  */
723  cf_data_add(conf, mi, mi->module->dl->name, false);
724  mi->conf = conf;
725 
726  if (mi->exported->config && mi->conf) {
727  if ((cf_section_rules_push(mi->conf, mi->exported->config)) < 0 ||
728  (cf_section_parse(mi->data, mi->data, mi->conf) < 0)) {
729  cf_log_err(mi->conf, "Failed evaluating configuration for module \"%s\"",
730  mi->module->dl->name);
731  return -1;
732  }
733  }
734 
735  return 0;
736 }
737 
738 /** Compare module instances by parent and name
739  *
740  * The reason why we need parent, is because we could have submodules with names
741  * that conflict with their parent.
742  */
743 static int8_t module_instance_name_cmp(void const *one, void const *two)
744 {
745  module_instance_t const *a = one;
746  module_instance_t const *b = two;
747  module_instance_t const *mi;
748  int a_depth = 0, b_depth = 0;
749  int ret;
750 
751 #ifdef STATIC_ANALYZER
752  if (!fr_cond_assert(a)) return +1;
753  if (!fr_cond_assert(b)) return -1;
754 #endif
755 
756  /*
757  * Sort by depth, so for tree walking we start
758  * at the shallowest node, and finish with
759  * the deepest child.
760  */
761  for (mi = a; mi; mi = mi->parent) a_depth++;
762  for (mi = b; mi; mi = mi->parent) b_depth++;
763 
764  ret = CMP(a_depth, b_depth);
765  if (ret != 0) return ret;
766 
767  ret = CMP(a->parent, b->parent);
768  if (ret != 0) return ret;
769 
770  ret = strcmp(a->name, b->name);
771  return CMP(ret, 0);
772 }
773 
774 /** Compare module's by their private instance data
775  *
776  */
777 static int8_t module_instance_data_cmp(void const *one, void const *two)
778 {
779  void const *a = ((module_instance_t const *)one)->data;
780  void const *b = ((module_instance_t const *)two)->data;
781 
782  return CMP(a, b);
783 }
784 
785 /** Generic callback for conf_parser_t to load a submodule
786  *
787  * conf_parser_t entry should point to a module_instance_t field in the instance data
788  *
789  * @param[in] ctx unused.
790  * @param[out] out A pointer to a pointer to a module_instance_t.
791  * @param[in] parent This _must_ point to the instance data of the parent
792  * module.
793  * @param[in] ci The CONF_PAIR containing the name of the submodule to load.
794  * @param[in] rule uctx pointer must be a pointer to a module_list_t **
795  * containing the list to search in.
796  * @return
797  * - 0 on success.
798  * - -1 if we failed to load the submodule.
799  */
800 int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent,
801  CONF_ITEM *ci, conf_parser_t const *rule)
802 {
803  char const *name = cf_pair_value(cf_item_to_pair(ci));
805  CONF_SECTION *submodule_cs;
806  module_instance_t *mi;
807  module_list_t *ml = talloc_get_type_abort(*((void * const *)rule->uctx), module_list_t);
808 
809  /*
810  * We assume the submodule's config is the
811  * in a section with the same name as
812  * the submodule.
813  */
814  submodule_cs = cf_section_find(cs, name, NULL);
815 
816  /*
817  * Allocate an empty section if one doesn't exist
818  * this is so defaults get parsed.
819  */
820  if (!submodule_cs) submodule_cs = cf_section_alloc(cs, cs, name, NULL);
821 
822  /*
823  * The submodule name dictates the module loaded
824  * the instance name is always the submodule name
825  * and will be appended to the parent's instance
826  * name.
827  */
829  if (unlikely(mi == NULL)) {
830  cf_log_err(submodule_cs, "Failed loading submodule");
831  return -1;
832  }
833 
834  if (unlikely(module_instance_conf_parse(mi, submodule_cs) < 0)) {
835  cf_log_err(submodule_cs, "Failed parsing submodule config");
836  talloc_free(mi);
837  return -1;
838  }
839 
840  *((module_instance_t **)out) = mi;
841 
842  return 0;
843 }
844 
845 /** Find an existing module instance by its name and parent
846  *
847  * @param[in] ml to search in.
848  * @param[in] parent to qualify search with.
849  * @param[in] asked_name The name of the module we're attempting to find.
850  * May include '-' which indicates that it's ok for
851  * the module not to be loaded.
852  * @return
853  * - Module instance matching name.
854  * - NULL if no such module exists.
855  */
857 {
858  char const *inst_name;
859  void *inst;
860 
861  if (!ml->name_tree) return NULL;
862 
863  /*
864  * Look for the real name. Ignore the first character,
865  * which tells the server "it's OK for this module to not
866  * exist."
867  */
868  inst_name = asked_name;
869  if (inst_name[0] == '-') inst_name++;
870 
871  inst = fr_rb_find(ml->name_tree,
873  .parent = UNCONST(module_instance_t *, parent),
874  .name = inst_name
875  });
876  if (!inst) return NULL;
877 
878  return talloc_get_type_abort(inst, module_instance_t);
879 }
880 
881 /** Find the module's shallowest parent
882  *
883  * @param[in] child to locate the root for.
884  * @return
885  * - The module's shallowest parent.
886  * - NULL on error.
887  */
889 {
890  module_instance_t const *next;
891 
892  for (;;) {
893  next = child->parent;
894  if (!next) break;
895 
896  child = next;
897  }
898 
899  return UNCONST(module_instance_t *, child);
900 }
901 
902 /** Find an existing module instance by its private instance data
903  *
904  * @param[in] ml to search in.
905  * @param[in] data to resolve to module_instance_t.
906  * @return
907  * - Module instance matching data.
908  * - NULL if no such module exists.
909  */
911 {
912  module_instance_t *mi;
913 
914  mi = fr_rb_find(ml->data_tree,
916  .data = UNCONST(void *, data)
917  });
918  if (!mi) return NULL;
919 
920  return talloc_get_type_abort(mi, module_instance_t);
921 }
922 
923 /** Retrieve module/thread specific instance data for a module
924  *
925  * @param[in] ml Module list module belongs to.
926  * @param[in] data Private instance data of the module.
927  * Same as what would be provided by
928  * #module_instance_by_data.
929  * @return
930  * - Thread specific instance data on success.
931  * - NULL if module has no thread instance data.
932  */
934 {
936 
937  if (!mi) return NULL;
938 
939  return module_thread(mi);
940 }
941 
943 {
944  module_list_t *ml = ti->mi->ml;
945  ml->type->thread.data_del(ti);
946  talloc_free(ti);
947 }
948 
949 /** Remove thread-specific data for a given module list
950  *
951  * Removes all module thread data for the
952  */
954 {
956  void *inst;
957 
958  /*
959  * Loop over all the modules in the module list
960  * finding and extracting their thread specific
961  * data, and calling their detach methods.
962  */
963  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
964  inst;
965  inst = fr_rb_iter_next_inorder(&iter)) {
966  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t);
968 
970  }
971 
972  /*
973  * Cleanup any lists the module list added to this thread
974  */
975  if (ml->type->thread.free) ml->type->thread.free(ml);
976 }
977 
978 /** Callback to free thread local data
979  *
980  * ti->data is allocated in the context of ti, so will be freed too.
981  *
982  * Calls the detach function for thread local data, and removes the data from the
983  * thread local list.
984  *
985  * @param[in] ti to free.
986  */
988 {
989  module_instance_t const *mi = ti->mi;
990 
991  /*
992  * Never allocated a thread instance, so we don't need
993  * to clean it up...
994  */
995  if (mi->state & MODULE_INSTANCE_NO_THREAD_INSTANTIATE) return 0;
996 
997  DEBUG4("Cleaning up %s thread instance data (%p/%p)",
998  mi->exported->name, ti, ti->data);
999 
1000  if (mi->exported->thread_detach) {
1002  .mi = ti->mi,
1003  .thread = ti->data,
1004  .el = ti->el
1005  });
1006  }
1007 
1008  ti->mi->ml->type->thread.data_del(ti);
1009 
1010  return 0;
1011 }
1012 
1013 /** Allocate thread-local instance data for a module
1014  *
1015  * The majority of modules will have a single set of thread-specific instance data.
1016  *
1017  * An exception is dynamic modules, which may have multiple sets of thread-specific instance data tied to
1018  * a specific dynamic use of that module.
1019  *
1020  * @param[in] ctx Talloc ctx to bind thread specific data to.
1021  * @param[in] mi Module instance to perform thread instantiation for.
1022  * @param[in] el Event list serviced by this thread.
1023  * @return
1024  * - 0 on success.
1025  * - -1 on failure.
1026  */
1028 {
1029  module_list_t *ml = mi->ml;
1031 
1032  /*
1033  * Allows the caller of module_instance_alloc to
1034  * skip thread instantiation for certain modules instances
1035  * whilst allowing modules to still register thread
1036  * instantiation callbacks.
1037  *
1038  * This is mainly there for the single global instance of
1039  * a module, which will only have run-time thread-specific
1040  * instances, like dynamic/keyed modules.
1041  */
1042  if (module_instance_skip_thread_instantiate(mi)) return 0;
1043 
1044  /*
1045  * Check the list pointers are ok
1046  */
1047  (void)talloc_get_type_abort(mi->ml, module_list_t);
1048 
1049  MEM(ti = talloc_zero(ctx, module_thread_instance_t));
1050  talloc_set_destructor(ti, _module_thread_inst_free);
1051  ti->el = el;
1052  ti->mi = mi;
1053 
1054  if (mi->exported->thread_inst_size) {
1055  MEM(ti->data = talloc_zero_array(ti, uint8_t, mi->exported->thread_inst_size));
1056 
1057  /*
1058  * Fixup the type name, in case something calls
1059  * talloc_get_type_abort() on it...
1060  */
1061  if (!mi->exported->thread_inst_type) {
1062  talloc_set_name(ti->data, "%s_%s_thread_t",
1064  mi->exported->name);
1065  } else {
1066  talloc_set_name_const(ti->data, mi->exported->thread_inst_type);
1067  }
1068  }
1069 
1070  if (ml->type->thread.data_add(ti) < 0) {
1071  PERROR("Failed adding thread data for module \"%s\"", mi->name);
1072  error:
1073  ml->type->thread.data_del(ti);
1074  talloc_free(ti);
1075  return -1;
1076  }
1077 
1078  /*
1079  * So we don't get spurious errors
1080  */
1082 
1083  DEBUG4("Alloced %s thread instance data (%p/%p)", ti->mi->exported->name, ti, ti->data);
1084  if (mi->exported->thread_instantiate &&
1086  PERROR("Thread instantiation failed for module \"%s\"", mi->name);
1087  goto error;
1088  }
1089 
1090  return 0;
1091 }
1092 
1093 /** Creates per-thread instance data for modules which need it
1094  *
1095  * Must be called by any new threads before attempting to execute unlang sections.
1096  *
1097  * @param[in] ctx Talloc ctx to bind thread specific data to.
1098  * @param[in] ml Module list to perform thread instantiation for.
1099  * @param[in] el Event list serviced by this thread.
1100  * @return
1101  * - 0 on success.
1102  * - -1 on failure.
1103  */
1105 {
1106  void *inst;
1107  fr_rb_iter_inorder_t iter;
1108  int ret;
1109 
1110  /*
1111  * Do any thread-local instantiation necessary
1112  */
1113  if (ml->type->thread.init) {
1114  ret = ml->type->thread.init(&ctx, ml);
1115  if (unlikely(ret < 0)) return ret;
1116  }
1117 
1118  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1119  inst;
1120  inst = fr_rb_iter_next_inorder(&iter)) {
1121  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t); /* Sanity check*/
1122 
1123  if (module_thread_instantiate(ctx, mi, el) < 0) {
1125  return -1;
1126  }
1127  }
1128 
1129  return 0;
1130 }
1131 
1132 /** Manually complete module setup by calling its instantiate function
1133  *
1134  * @param[in] instance of module to complete instantiation for.
1135  * @return
1136  * - 0 on success.
1137  * - -1 on failure.
1138  */
1140 {
1141  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
1142  CONF_SECTION *cs = mi->conf;
1143 
1144  /*
1145  * If we're instantiating, then nothing should be able to
1146  * modify the boot data for this module.
1147  *
1148  * mprotect is thread-safe, so we don't need to worry about
1149  * synchronisation. There is the overhead of a system call
1150  * but dynamic module instantiation is relatively rare.
1151  *
1152  * We need to wait until all modules have registered things
1153  * like xlat functions, as the xlat functions themselves may
1154  * end up being allocated in boot pool data, and have inline
1155  * rbtree node structures, which may be modified as additional
1156  * xlat functions are registered.
1157  */
1158  if (unlikely(module_data_protect(mi, &mi->boot_pool) < 0)) {
1159  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1160  return -1;
1161  }
1162 
1163  /*
1164  * We only instantiate modules in the bootstrapped state
1165  */
1166  if (module_instance_skip_instantiate(mi)) return 0;
1167 
1168  if (mi->module->type == DL_MODULE_TYPE_MODULE) {
1169  if (fr_command_register_hook(NULL, mi->name, mi, module_cmd_table) < 0) {
1170  PERROR("Failed registering radmin commands for module %s", mi->name);
1171  return -1;
1172  }
1173  }
1174 
1175  /*
1176  * Now that ALL modules are instantiated, and ALL xlats
1177  * are defined, go compile the config items marked as XLAT.
1178  */
1179  if (mi->exported->config && (cf_section_parse_pass2(mi->data,
1180  mi->conf) < 0)) return -1;
1181 
1182  /*
1183  * Call the instantiate method, if any.
1184  */
1185  if (mi->exported->instantiate) {
1186  cf_log_debug(cs, "Instantiating %s_%s \"%s\"",
1188  mi->module->exported->name,
1189  mi->name);
1190 
1191  /*
1192  * Call the module's instantiation routine.
1193  */
1194  if (mi->exported->instantiate(MODULE_INST_CTX(mi)) < 0) {
1195  cf_log_err(mi->conf, "Instantiation failed for module \"%s\"", mi->name);
1196 
1197  return -1;
1198  }
1199  }
1200 
1201  /*
1202  * Instantiate shouldn't modify any global resources
1203  * so we can protect the data now without the side
1204  * effects we might see with boot data.
1205  */
1206  if (unlikely(module_data_protect(mi, &mi->inst_pool) < 0)) {
1207  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1208  return -1;
1209  }
1211 
1212  return 0;
1213 }
1214 
1215 /** Completes instantiation of modules
1216  *
1217  * Allows the module to initialise connection pools, and complete any registrations that depend on
1218  * attributes created during the bootstrap phase.
1219  *
1220  * @param[in] ml containing modules to instantiate.
1221  * @return
1222  * - 0 on success.
1223  * - -1 on failure.
1224  */
1226 {
1227  void *inst;
1228  fr_rb_iter_inorder_t iter;
1229 
1230  DEBUG2("#### Instantiating %s modules ####", ml->name);
1231 
1232  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1233  inst;
1234  inst = fr_rb_iter_next_inorder(&iter)) {
1235  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t);
1236  if (module_instantiate(mi) < 0) return -1;
1237  }
1238 
1239  return 0;
1240 }
1241 
1242 /** Manually complete module bootstrap by calling its instantiate function
1243  *
1244  * - Parse the module configuration.
1245  * - Call the modules "bootstrap" method.
1246  *
1247  * @param[in] mi Module instance to bootstrap.
1248  * @return
1249  * - 0 on success.
1250  * - -1 on failure.
1251  */
1253 {
1254  /*
1255  * We only bootstrap modules in the init state
1256  */
1257  if (module_instance_skip_bootstrap(mi)) return 0;
1258 
1259  /*
1260  * Bootstrap the module.
1261  * This must be done last so that the
1262  * module can find its module_instance_t
1263  * in the trees if it needs to bootstrap
1264  * submodules.
1265  */
1266  if (mi->exported->bootstrap) {
1267  CONF_SECTION *cs = mi->conf;
1268 
1269  cf_log_debug(cs, "Bootstrapping %s_%s \"%s\"",
1271  mi->module->exported->name,
1272  mi->name);
1273 
1274  /*
1275  * Modules MUST NOT modify their instance data during
1276  * bootstrap. This is because dynamic (runtime) modules
1277  * don't run their boostrap callbacks, and MUST re-resolve
1278  * any resources added during bootstrap in the
1279  * instantiate callback.
1280  *
1281  * Bootstrap is ONLY there for adding global,
1282  * module-specific resources.
1283  *
1284  * If the module has MODULE_TYPE_DYNAMIC_UNSAFE is set,
1285  * then we don't need the restriction.
1286  */
1287  if ((!(mi->exported->flags & MODULE_TYPE_DYNAMIC_UNSAFE)) &&
1288  unlikely(module_data_protect(mi, &mi->inst_pool) < 0)) {
1289  cf_log_perr(cs, "\"%s\"", mi->name);
1290  return -1;
1291  }
1292  if (mi->exported->bootstrap(MODULE_INST_CTX(mi)) < 0) {
1293  cf_log_err(cs, "Bootstrap failed for module \"%s\"", mi->name);
1294  return -1;
1295  }
1296  if (unlikely(module_data_unprotect(mi, &mi->inst_pool) < 0)) {
1297  cf_log_perr(cs, "\"%s\"", mi->name);
1298  return -1;
1299  }
1300  }
1302 
1303  return 0;
1304 }
1305 
1306 /** Bootstrap any modules which have not been bootstrapped already
1307  *
1308  * Allows the module to initialise connection pools, and complete any registrations that depend on
1309  * attributes created during the bootstrap phase.
1310  *
1311  * @param[in] ml containing modules to bootstrap.
1312  * @return
1313  * - 0 on success.
1314  * - -1 on failure.
1315  */
1317 {
1318  void *instance;
1319  fr_rb_iter_inorder_t iter;
1320 
1321  DEBUG2("#### Bootstrapping %s modules ####", ml->name);
1322 
1323  for (instance = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1324  instance;
1325  instance = fr_rb_iter_next_inorder(&iter)) {
1326  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
1327  if (module_bootstrap(mi) < 0) return -1;
1328  }
1329 
1330  return 0;
1331 }
1332 
1333 /** Generate a module name from the module's name and its parents
1334  *
1335  * @param[in] ctx Where to allocate the module name.
1336  * @param[out] out Where to write a pointer to the instance name.
1337  * @param[in] parent of the module.
1338  * @param[in] inst_name module's instance name.
1339  */
1340 static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out,
1341  module_instance_t const *parent, char const *inst_name)
1342 {
1343  fr_sbuff_t *agg;
1344 
1345  FR_SBUFF_TALLOC_THREAD_LOCAL(&agg, 64, 256);
1346 
1347  /*
1348  * Parent has all of the qualifiers of its ancestors
1349  * already in the name, so we just need to concatenate.
1350  */
1351  if (parent) {
1352  FR_SBUFF_IN_STRCPY_RETURN(agg, parent->name);
1353  FR_SBUFF_IN_CHAR_RETURN(agg, '.');
1354  }
1355  FR_SBUFF_IN_STRCPY_RETURN(agg, inst_name);
1356 
1357  MEM(*out = talloc_bstrndup(ctx, fr_sbuff_start(agg), fr_sbuff_used(agg)));
1358 
1359  return fr_sbuff_used(agg);
1360 }
1361 
1362 /** Detach the shallowest parent first
1363  *
1364  * This ensures that the module's parent is detached before it is.
1365  *
1366  * Generally parents reach into their children and not the other way
1367  * around. Calling the parent's detach method first ensures that
1368  * there's no code that access the child module's instance data or
1369  * reach into its symbol space if it's being unloaded.
1370  *
1371  * @note If you don't want to detach the parent, maybe because its children
1372  * are ephemeral, consider using a seaprate thread-local module list
1373  * to hold the children instead.
1374  *
1375  * @param[in] mi to detach.
1376  */
1378 {
1380 
1382 
1383  if (mi->state & MODULE_INSTANCE_INSTANTIATED) {
1384  if (mi->exported && mi->exported->detach) {
1385  mi->exported->detach(MODULE_DETACH_CTX(mi));
1386  }
1388  }
1389 
1390  if (mi->state & MODULE_INSTANCE_BOOTSTRAPPED) {
1391  if (mi->exported && mi->exported->unstrap) {
1393  }
1395  }
1396 }
1397 
1398 /** Free module's instance data, and any xlats or paircmps
1399  *
1400  * @param[in] mi to free.
1401  * @return 0
1402  */
1404 {
1405  module_list_t *ml = mi->ml;
1406 
1407  DEBUG3("Freeing %s (%p)", mi->name, mi);
1408 
1409  /*
1410  * Allow writing to instance and bootstrap data again
1411  * so we can clean up without segving.
1412  */
1413  if (unlikely(module_data_unprotect(mi, &mi->inst_pool) < 0)) {
1414  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1415  return -1;
1416  }
1417  if (unlikely(module_data_unprotect(mi, &mi->boot_pool) < 0)) {
1418  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1419  return -1;
1420  }
1421 
1422  if (fr_rb_node_inline_in_tree(&mi->name_node) && !fr_cond_assert(fr_rb_delete(ml->name_tree, mi))) return 1;
1423  if (fr_rb_node_inline_in_tree(&mi->data_node) && !fr_cond_assert(fr_rb_delete(ml->data_tree, mi))) return 1;
1424  if (ml->type->data_del) ml->type->data_del(mi);
1425 
1426  /*
1427  * mi->exported may be NULL if we failed loading the module
1428  */
1429  if (mi->exported && ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0)) {
1430 #ifndef NDEBUG
1431  int ret;
1432 
1433  /*
1434  * If the mutex is locked that means
1435  * the server exited without cleaning
1436  * up requests.
1437  *
1438  * Assert that the mutex is not held.
1439  */
1440  ret = pthread_mutex_trylock(&mi->mutex);
1441  fr_assert_msg(ret == 0, "Failed locking module mutex during exit: %s", fr_syserror(ret));
1442  pthread_mutex_unlock(&mi->mutex);
1443 #endif
1444  pthread_mutex_destroy(&mi->mutex);
1445  }
1446 
1447  /*
1448  * Remove all xlat's registered to module instance.
1449  */
1450  if (mi->data) {
1453  }
1454 
1456 
1457  /*
1458  * We need to explicitly free all children, so the module instance
1459  * destructors get executed before we unload the bytecode for the
1460  * module.
1461  *
1462  * If we don't do this, we get a SEGV deep inside the talloc code
1463  * when it tries to call a destructor that no longer exists.
1464  */
1465  talloc_free_children(mi);
1466 
1467  /*
1468  * This frees any instance and boot data associated with the
1469  * module_instance_t.
1470  */
1471  talloc_free(mi->boot_pool.ctx);
1472  talloc_free(mi->inst_pool.ctx);
1473 
1474  dl_module_free(mi->module);
1475 
1476  return 0;
1477 }
1478 
1479 /** Duplicate a module instance, placing it in a new module list
1480  *
1481  * @param[in] dst list to place the new module instance in.
1482  * @param[in] src to duplicate.
1483  * @param[in] inst_name new instance name. If null, src->name will be used.
1484  */
1486 {
1487  module_instance_t *mi = module_instance_alloc(dst, src->parent, src->module->type,
1488  src->module->name,
1489  inst_name ? inst_name : src->name, 0);
1490  if (!mi) return NULL;
1491 
1492  return mi;
1493 }
1494 
1495 /** Allocate module instance data
1496  *
1497  * @param[out] pool_out where to write pool details.
1498  * @param[out] out where to write data pointer.
1499  * @param[in] mi module instance.
1500  * @param[in] size of data to allocate.
1501  * @param[in] type talloc type to assign.
1502  */
1503 static inline CC_HINT(always_inline)
1505  module_instance_t *mi, size_t size, char const *type)
1506 {
1507  dl_module_t const *module = mi->module;
1508  void *data;
1509 
1510  /*
1511  * If there is supposed to be instance data, allocate it now.
1512  *
1513  * If the structure is zero length then allocation will still
1514  * succeed, and will create a talloc chunk header.
1515  *
1516  * This is needed so we can resolve instance data back to
1517  * module_instance_t/dl_module_t/dl_t.
1518  *
1519  * Note: On Linux allocating the pools from the module_instance_t
1520  * resulted in the protections being triggered, possibly because
1521  * the pools are siblings, and talloc was modifying the chunk header
1522  * of a protected pool.
1523  *
1524  * To correct this, we need to allocate the pools in the NULL
1525  * ctx, and free them manually. This means the chunk headers
1526  * are not linked in any way.
1527  */
1528  pool_out->ctx = talloc_page_aligned_pool(NULL,
1529  &pool_out->start, &pool_out->len,
1530  1, size);
1531  MEM(data = talloc_zero_array(pool_out->ctx, uint8_t, size));
1532  if (!type) {
1533  talloc_set_name(data, "%s_t", module->dl->name ? module->dl->name : "config");
1534  } else {
1535  talloc_set_name_const(data, type);
1536  }
1537  *out = data;
1538 }
1539 
1540 /** Allocate a new module and add it to a module list for later bootstrap/instantiation
1541  *
1542  * - Load the module shared library.
1543  * - Allocate instance data for it.
1544  *
1545  * @param[in] ml To add module to.
1546  * @param[in] parent of the module being bootstrapped, if this is a submodule.
1547  * If this is not a submodule parent must be NULL.
1548  * @param[in] type What type of module we're loading. Determines the prefix
1549  * added to the library name. Should be one of:
1550  * - DL_MODULE_TYPE_MODULE - Standard backend module.
1551  * - DL_MODULE_TYPE_SUBMODULE - Usually a driver for a backend module.
1552  * - DL_MODULE_TYPE_PROTO - A module associated with a listen section.
1553  * - DL_MODULE_TYPE_PROCESS - Protocol state machine bound to a virtual server.
1554  * @param[in] mod_name The name of this module, i.e. 'redis' for 'rlm_redis'.
1555  * @param[in] inst_name Instance name for this module, i.e. "aws_redis_01".
1556  * The notable exception is if this is a submodule, in which case
1557  * inst_name is usually the mod_name.
1558  * @param[in] init_state The state the module "starts" in. Can be used to prevent
1559  * bootstrapping, instantiation, or thread instantiation of the module,
1560  * by passing one or more of the MODULE_INSTANCE_* flags.
1561  * Should usually be 0, unless special behaviour is required.
1562  * @return
1563  * - A new module instance handle, containing the module's public interface,
1564  * and private instance data.
1565  * - NULL on error.
1566  */
1568  module_instance_t const *parent,
1569  dl_module_type_t type, char const *mod_name, char const *inst_name,
1570  module_instance_state_t init_state)
1571 {
1572  char *qual_inst_name = NULL;
1573  module_instance_t *mi;
1574 
1576  (parent && (type == DL_MODULE_TYPE_SUBMODULE)) ||
1577  (type == DL_MODULE_TYPE_PROTO) ||
1579 
1580  /*
1581  * Takes the inst_name and adds qualifiers
1582  * if this is a submodule.
1583  */
1584  if (module_instance_name(NULL, &qual_inst_name, parent, inst_name) < 0) {
1585  ERROR("Module name too long");
1586  return NULL;
1587  }
1588 
1589  /*
1590  * See if the module already exists.
1591  */
1592  mi = module_instance_by_name(ml, parent, qual_inst_name);
1593  if (mi) {
1594  /*
1595  * We may not have configuration data yet
1596  * for the duplicate module.
1597  */
1598  if (mi->conf) {
1599  ERROR("Duplicate %s_%s instance \"%s\", previous instance defined at %s[%d]",
1601  mi->module->exported->name,
1602  qual_inst_name,
1603  cf_filename(mi->conf),
1604  cf_lineno(mi->conf));
1605 
1606  } else {
1607  ERROR("Duplicate %s_%s instance \"%s\"",
1609  mi->module->exported->name,
1610  qual_inst_name);
1611  }
1612  talloc_free(qual_inst_name);
1613  return NULL;
1614  }
1615 
1616  /*
1617  * Overallocate the module instance, so we can add
1618  * some module list type specific data to it.
1619  */
1620  MEM(mi = (module_instance_t *)talloc_zero_array(parent ? (void const *)parent : (void const *)ml, uint8_t, ml->type->inst_size));
1621  talloc_set_name_const(mi, "module_instance_t");
1622  mi->name = talloc_typed_strdup(mi, qual_inst_name);
1623  talloc_free(qual_inst_name); /* Avoid stealing */
1624 
1625  mi->ml = ml;
1626  mi->parent = parent;
1627  mi->state = init_state;
1628 
1629  /*
1630  * Increment the reference count on an already loaded module,
1631  * or load the .so or .dylib, and run all the global callbacks.
1632  */
1633  mi->module = dl_module_alloc(parent ? parent->module : NULL, mod_name, type);
1634  if (!mi->module) {
1635  error:
1636  talloc_free(mi);
1637  return NULL;
1638  }
1639 
1640  /*
1641  * We have no way of checking if this is correct... so we hope...
1642  */
1643  mi->exported = (module_t const *)mi->module->exported;
1644  if (unlikely(mi->exported == NULL)) {
1645  ERROR("Missing public structure for \"%s\"", qual_inst_name);
1646  goto error;
1647  }
1648 
1649  /*
1650  * Allocate bootstrap data.
1651  */
1652  if (mi->exported->bootstrap) {
1654  mi, mi->exported->boot_size, mi->exported->boot_type);
1655  }
1656  /*
1657  * Allocate the module instance data. We always allocate
1658  * this so the module can use it for lookup.
1659  */
1661  mi, mi->exported->inst_size, mi->exported->inst_type);
1662  /*
1663  * If we're threaded, check if the module is thread-safe.
1664  *
1665  * If it isn't, we init the mutex.
1666  *
1667  * Do this here so the destructor can trylock the mutex
1668  * correctly even if bootstrap/instantiation fails.
1669  */
1670  if ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL);
1671  talloc_set_destructor(mi, _module_instance_free); /* Set late intentionally */
1672  mi->number = ml->last_number++;
1673 
1674  /*
1675  * Remember the module for later.
1676  */
1677  if (!fr_cond_assert(fr_rb_insert(ml->name_tree, mi))) goto error;
1678  if (!fr_cond_assert(fr_rb_insert(ml->data_tree, mi))) goto error;
1679  if (ml->type->data_add && unlikely(ml->type->data_add(mi) < 0)) goto error;
1680 
1681  return mi;
1682 }
1683 
1684 /** Free all modules loaded by the server
1685  *
1686  * @param[in] ml Module list being freed.
1687  * @return 0
1688  */
1690 {
1691  fr_rb_iter_inorder_t iter;
1692  module_instance_t *mi;
1693 
1694  /*
1695  * Re-initialize the iterator after freeing each module.
1696  * The module may have children which are also in the
1697  * tree. It can cause problems when we delete children
1698  * without the iterator knowing about it.
1699  */
1700  while ((mi = fr_rb_iter_init_inorder(&iter, ml->name_tree)) != NULL) {
1701  fr_rb_iter_delete_inorder(&iter); /* Keeps the iterator sane */
1702  talloc_free(mi);
1703  }
1704 
1705  if (ml->type->free) ml->type->free(ml);
1706 
1707  return 0;
1708 }
1709 
1710 /** Should we bootstrap this module instance?
1711  *
1712  * @param[in] mi to check.
1713  * @return
1714  * - true if the module instance should be bootstrapped.
1715  * - false if the module instance has already been bootstrapped.
1716  */
1718 {
1719  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_BOOTSTRAPPED);
1720 }
1721 
1722 /** Should we instantiate this module instance?
1723  *
1724  * @param[in] mi to check.
1725  * @return
1726  * - true if the module instance should be instantiated.
1727  * - false if the module instance has already been instantiated.
1728  */
1730 {
1731  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_INSTANTIATED);
1732 }
1733 
1734 /** Should we instantiate this module instance in a new thread?
1735  *
1736  * @param[in] mi to check.
1737  * @return
1738  * - true if the module instance should be instantiated in a new thread.
1739  * - false if the module instance has already been instantiated in a new thread.
1740  */
1742 {
1743  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_NO_THREAD_INSTANTIATE);
1744 }
1745 
1746 /** Set a new bootstrap/instantiate state for a list
1747  *
1748  * @param[in] ml To set the state for.
1749  * @param[in] mask New state.
1750  */
1752 {
1753  ml->mask = mask;
1754 }
1755 
1756 /** Allocate a new module list
1757  *
1758  * This is used to instantiate and destroy modules in distinct phases
1759  * for example, we may need to load all proto modules before rlm modules.
1760  *
1761  * If the list is freed all module instance data will be freed.
1762  * If no more instances of the module exist the module be unloaded.
1763  *
1764  * @param[in] ctx To allocate the list in.
1765  * @param[in] type of the list. Controls whether this is a global
1766  * module list, or a per-thread list containing
1767  * variants of an existing module.
1768  * @param[in] name of the list. Used for debugging.
1769  * @param[in] write_protect Whether to write protect the module data
1770  * after instantiation and bootstrapping.
1771  * @return A new module list.
1772  */
1774  char const *name, bool write_protect)
1775 {
1776  module_list_t *ml;
1777 
1778  /*
1779  * These callbacks are NOT optional, the rest are.
1780  */
1781  fr_assert(type->thread.data_add);
1782  fr_assert(type->thread.data_get);
1783  fr_assert(type->thread.data_del);
1784 
1785  MEM(ml = talloc_zero(ctx, module_list_t));
1786  ml->type = type;
1787 
1788  ml->thread_data_get = type->thread.data_get; /* Cache for access outside of the compilation unit */
1789  MEM(ml->name = talloc_typed_strdup(ml, name));
1792  talloc_set_destructor(ml, _module_list_free);
1793 
1794  if (ml->type->init && (ml->type->init(ml) < 0)) {
1795  talloc_free(ml);
1796  return NULL;
1797  }
1798  ml->write_protect = write_protect;
1799 
1800  return ml;
1801 }
1802 
1803 static int _module_dl_loader_init(void *uctx)
1804 {
1806 
1807  /*
1808  * Ensure the common library tracking
1809  * tree is in place...
1810  */
1811  global_lib_init();
1812 
1813  return 0;
1814 }
1815 
1816 static int _module_dl_loader_free(UNUSED void *uctx)
1817 {
1818  if (talloc_free(dl_modules) < 0) return -1;
1819  dl_modules = NULL;
1820  return 0;
1821 }
1822 
1823 /** Perform global initialisation for modules
1824  *
1825  */
1826 void modules_init(char const *lib_dir)
1827 {
1828  /*
1829  * Create the global module heap we use for
1830  * common indexes in the thread-specific
1831  * heaps.
1832  */
1834 }
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define fr_atexit_global_once(_init, _free, _uctx)
Definition: atexit.h:211
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define RCSID(id)
Definition: build.h:444
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition: build.h:110
#define unlikely(_x)
Definition: build.h:378
#define UNUSED
Definition: build.h:313
int cf_section_write(FILE *fp, CONF_SECTION *cs, int depth)
Definition: cf_file.c:3141
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition: cf_parse.c:985
int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
Fixup xlat expansions and attributes.
Definition: cf_parse.c:1163
void const * uctx
User data accessible by the cf_parse_t func.
Definition: cf_parse.h:586
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:658
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition: cf_util.c:1030
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1186
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1595
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1172
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:283
#define cf_lineno(_cf)
Definition: cf_util.h:104
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:249
#define cf_parent(_cf)
Definition: cf_util.h:101
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:290
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
Definition: cf_util.h:140
#define cf_filename(_cf)
Definition: cf_util.h:107
#define cf_log_debug(_cf, _fmt,...)
Definition: cf_util.h:286
fr_command_register_hook_t fr_command_register_hook
Definition: command.c:42
bool fr_command_strncmp(const char *word, const char *name)
Definition: command.c:2906
int argc
current argument count
Definition: command.h:39
char const * parent
e.g. "show module"
Definition: command.h:52
#define CMD_TABLE_END
Definition: command.h:62
char const ** argv
text version of commands
Definition: command.h:42
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition: debug.h:210
#define FR_FAULT_LOG(_fmt,...)
Definition: debug.h:49
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:156
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
char const * name
Name of the module e.g. sql.
Definition: dl.h:61
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
Definition: dl_module.c:57
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Definition: dl_module.c:532
dl_module_t * dl_module_alloc(dl_module_t const *parent, char const *name, dl_module_type_t type)
Load a module library using dlopen() or return a previously loaded module from the cache.
Definition: dl_module.c:318
int dl_module_free(dl_module_t *dl_module)
Free a dl_module (when there are no more references to it)
Definition: dl_module.c:284
Wrapper struct around dl_loader_t.
Definition: dl_module.c:47
dl_t *_CONST dl
Dynamic loader handle.
Definition: dl_module.h:122
dl_module_type_t _CONST type
of this module.
Definition: dl_module.h:126
dl_module_type_t
Definition: dl_module.h:65
@ DL_MODULE_TYPE_PROTO
Protocol module.
Definition: dl_module.h:67
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition: dl_module.h:69
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition: dl_module.h:66
@ DL_MODULE_TYPE_PROCESS
protocol processor.
Definition: dl_module.h:68
char const *_CONST name
Name of the module. The name passed to dl_module_alloc.
Definition: dl_module.h:118
dl_module_common_t const *_CONST exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition: dl_module.h:128
if(rcode > 0)
Definition: fd_read.h:9
int global_lib_init(void)
Initialise the global list of external libraries.
Definition: global_lib.c:204
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
Definition: heap.c:146
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
Definition: heap.c:239
unsigned int fr_heap_index_t
Definition: heap.h:80
#define fr_heap_alloc(_ctx, _cmp, _type, _field, _init)
Creates a heap that can be used with non-talloced elements.
Definition: heap.h:100
static bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
Definition: heap.h:124
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
Definition: heap.h:179
#define fr_heap_foreach(_heap, _type, _data)
Iterate over the contents of a heap.
Definition: heap.h:205
The main heap structure.
Definition: heap.h:66
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG3(_fmt,...)
Definition: log.h:266
#define DEBUG4(_fmt,...)
Definition: log.h:267
talloc_free(reap)
Stores all information relating to an event list.
Definition: event.c:411
static char const * mod_name(fr_listen_t *li)
Definition: master.c:2715
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
#define MODULE_DETACH_CTX(_mi)
Wrapper to create a module_detach_ctx_t as a compound literal.
Definition: module_ctx.h:174
#define MODULE_THREAD_INST_CTX(_mi, _thread, _el)
Wrapper to create a module_thread_inst_ctx_t as a compound literal.
Definition: module_ctx.h:186
#define MODULE_INST_CTX(_mi)
Wrapper to create a module_inst_ctx_t as a compound literal.
Definition: module_ctx.h:168
Temporary structure to hold arguments for thread_instantiation calls.
Definition: module_ctx.h:63
#define DEBUG2(fmt,...)
Definition: radclient.h:43
static rs_t * conf
Definition: radsniff.c:53
void fr_rb_iter_delete_inorder(fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
Definition: rb.c:892
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition: rb.c:844
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition: rb.c:624
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition: rb.c:736
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
Definition: rb.c:818
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition: rb.c:576
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Definition: rb.h:271
static bool fr_rb_node_inline_in_tree(fr_rb_node_t const *node)
Check to see if an item is in a tree by examining its inline fr_rb_node_t.
Definition: rb.h:314
Iterator structure for in-order traversal of an rbtree.
Definition: rb.h:321
static uint32_t mask
Definition: rbmonkey.c:39
fr_table_num_sorted_t const rcode_table[]
Definition: rcode.c:35
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
Definition: rcode.h:51
static char const * name
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
module_instance_t * mi
As opposed to the thread local inst.
Definition: module.h:317
char const * name
Instance name e.g. user_database.
Definition: module.h:298
@ MODULE_TYPE_DYNAMIC_UNSAFE
Instances of this module cannot be created at runtime.
Definition: module.h:54
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
Definition: module.h:50
module_flags_t flags
Flags that control how a module starts up and how a module is called.
Definition: module.h:190
fr_rb_node_t name_node
Entry in the name tree.
Definition: module.h:273
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:292
size_t inst_size
Size of the module's instance data.
Definition: module.h:166
module_detach_t detach
Clean up module resources from the instantiation pahses.
Definition: module.h:186
bool force
Force the module to return a specific code.
Definition: module.h:260
void * data
Module's instance data.
Definition: module.h:234
module_thread_instance_t *(* module_list_thread_data_get_t)(module_instance_t *mi)
Callback to retrieve thread-local data for a module.
Definition: module.h:330
module_instance_state_t state
What's been done with this module so far.
Definition: module.h:291
module_instance_t const * parent
Parent module's instance (if any).
Definition: module.h:300
module_thread_instantiate_t thread_instantiate
Callback to populate a new module thread instance data.
Definition: module.h:193
module_instantiate_t instantiate
Callback to allow the module to register any per-instance resources like sockets and file handles.
Definition: module.h:181
void * boot
Data allocated during the boostrap phase.
Definition: module.h:237
TALLOC_CTX * ctx
ctx data is allocated in.
Definition: module.h:217
module_instance_state_t mask
Prevent phases from being executed.
Definition: module.h:345
dl_module_t * module
dynamic loader handle.
Definition: module.h:249
void * data
Thread specific instance data.
Definition: module.h:313
module_data_pool_t inst_pool
Data to allow mprotect state toggling for instance data.
Definition: module.h:282
bool write_protect
If true, pages containing module boot or instance data will be write protected after bootstrapping an...
Definition: module.h:352
rlm_rcode_t code
Code module will return when 'force' has has been set to true.
Definition: module.h:263
char const * boot_type
talloc type to assign to bootstrap data.
Definition: module.h:164
module_t const * exported
Public module structure.
Definition: module.h:239
char const * inst_type
talloc type to assign to instance data.
Definition: module.h:167
module_data_pool_t boot_pool
Data to allow mprotect state toggling for bootstrap data.
Definition: module.h:284
module_detach_t unstrap
Clean up module resources from both the bootstrap phase.
Definition: module.h:188
module_instance_state_t
What state the module instance is currently in.
Definition: module.h:206
@ MODULE_INSTANCE_INSTANTIATED
Module instance has been bootstrapped and instantiated.
Definition: module.h:209
@ MODULE_INSTANCE_NO_THREAD_INSTANTIATE
Not set internally, but can be used to prevent thread instantiation for certain modules.
Definition: module.h:211
@ MODULE_INSTANCE_BOOTSTRAPPED
Module instance has been bootstrapped, but not yet instantiated.
Definition: module.h:207
fr_rb_tree_t * data_tree
Modules indexed by data.
Definition: module.h:349
uint32_t number
Unique module number.
Definition: module.h:275
module_list_thread_data_get_t thread_data_get
Callback to get thread-specific data.
Definition: module.h:371
char const * thread_inst_type
talloc type to assign to thread instance data.
Definition: module.h:199
module_instantiate_t bootstrap
Callback to allow the module to register any global resources like xlat functions and attributes.
Definition: module.h:169
fr_rb_node_t data_node
Entry in the data tree.
Definition: module.h:274
module_thread_detach_t thread_detach
Callback to free thread-specific resources associated < with a module.
Definition: module.h:195
size_t boot_size
Size of the module's bootstrap data.
Definition: module.h:163
module_list_t * ml
Module list this instance belongs to.
Definition: module.h:272
size_t thread_inst_size
Size of the module's thread-specific instance data.
Definition: module.h:198
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition: module.h:161
char const * name
Friendly list identifier.
Definition: module.h:344
fr_event_list_t * el
Event list associated with this thread.
Definition: module.h:315
static module_thread_instance_t * module_thread(module_instance_t *mi)
Retrieve module/thread specific instance for a module.
Definition: module.h:439
module_list_type_t const * type
Type of module list.
Definition: module.h:370
uint32_t last_number
Last identifier assigned to a module instance.
Definition: module.h:347
fr_rb_tree_t * name_tree
Modules indexed by name.
Definition: module.h:348
pthread_mutex_t mutex
Used prevent multiple threads entering a thread unsafe module simultaneously.
Definition: module.h:246
Per instance data.
Definition: module.h:228
A list of modules.
Definition: module.h:343
Struct exported by a rlm_* module.
Definition: module.h:158
Per thread per instance data.
Definition: module.h:308
module_instance_t * module_instance_copy(module_list_t *dst, module_instance_t const *src, char const *inst_name)
Duplicate a module instance, placing it in a new module list.
Definition: module.c:1485
static int mltl_thread_data_add(module_thread_instance_t *ti)
Definition: module.c:544
int module_instance_data_protect(module_instance_t const *mi)
Mark module data as read only.
Definition: module.c:668
static void module_thread_detach(module_thread_instance_t *ti)
Definition: module.c:942
void module_list_debug(module_list_t const *ml)
Print the contents of a module list.
Definition: module.c:592
module_list_type_t const module_list_type_thread_local
Callbacks for a thread local list.
Definition: module.c:559
void modules_init(char const *lib_dir)
Perform global initialisation for modules.
Definition: module.c:1826
bool module_instance_skip_thread_instantiate(module_instance_t *mi)
Should we instantiate this module instance in a new thread?
Definition: module.c:1741
module_instance_t * module_instance_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name)
Find an existing module instance by its name and parent.
Definition: module.c:856
static int module_data_unprotect(module_instance_t const *mi, module_data_pool_t const *pool)
Unprotect module data.
Definition: module.c:646
static int mlg_init(UNUSED module_list_t *ml)
Global initialisation for index heap and module array.
Definition: module.c:378
static int _module_dl_loader_free(UNUSED void *uctx)
Definition: module.c:1816
module_list_free_t free
Free any global structures required for thread-local lookups.
Definition: module.c:309
static int _module_list_free(module_list_t *ml)
Free all modules loaded by the server.
Definition: module.c:1689
module_thread_instance_t * ti
Thread-specific data.
Definition: module.c:524
char const * module_instance_root_prefix_str(module_instance_t const *mi)
Return the prefix string for the deepest module.
Definition: module.c:694
static int _module_instance_free(module_instance_t *mi)
Free module's instance data, and any xlats or paircmps.
Definition: module.c:1403
module_instance_t * module_instance_root(module_instance_t const *child)
Find the module's shallowest parent.
Definition: module.c:888
static int module_data_protect(module_instance_t *mi, module_data_pool_t *pool)
Protect module data.
Definition: module.c:623
static void module_detach_parent(module_instance_t *mi)
Detach the shallowest parent first.
Definition: module.c:1377
static int _module_thread_inst_list_free(void *tilp)
Free the thread local heap on exit.
Definition: module.c:422
void(* module_list_free_t)(module_list_t *ml)
Callback to free any global structures associated with the module list.
Definition: module.c:231
void module_list_mask_set(module_list_t *ml, module_instance_state_t mask)
Set a new bootstrap/instantiate state for a list.
Definition: module.c:1751
static void module_instance_data_alloc(module_data_pool_t *pool_out, void **out, module_instance_t *mi, size_t size, char const *type)
Allocate module instance data.
Definition: module.c:1504
static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:176
static int8_t module_instance_data_cmp(void const *one, void const *two)
Compare module's by their private instance data.
Definition: module.c:777
static int8_t module_instance_name_cmp(void const *one, void const *two)
Compare module instances by parent and name.
Definition: module.c:743
void modules_thread_detach(module_list_t *ml)
Remove thread-specific data for a given module list.
Definition: module.c:953
static int mlg_data_add(module_instance_t *mi)
Add the unique index value so we can do thread local lookups.
Definition: module.c:393
module_list_data_add_t data_add
Record that module data has been added.
Definition: module.c:313
module_list_init_t init
Initialise any global structures required for thread-local lookups.
Definition: module.c:308
static module_thread_instance_t * mlg_thread_data_get(module_instance_t *mi)
Retrieve the thread-specific data for a module from the thread-local array of instance data.
Definition: module.c:470
int modules_thread_instantiate(TALLOC_CTX *ctx, module_list_t const *ml, fr_event_list_t *el)
Creates per-thread instance data for modules which need it.
Definition: module.c:1104
bool module_instance_skip_instantiate(module_instance_t *mi)
Should we instantiate this module instance?
Definition: module.c:1729
static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:165
static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions)
Definition: module.c:139
void(* module_list_data_del_t)(module_instance_t *mi)
Callback to del data for a module.
Definition: module.c:249
size_t inst_size
Size of talloc chunk to allocate for the module_instance_t.
Definition: module.c:311
int(* module_list_thread_data_add_t)(module_thread_instance_t *ti)
Callback to add thread-local data for a module.
Definition: module.c:280
int modules_instantiate(module_list_t const *ml)
Completes instantiation of modules.
Definition: module.c:1225
module_instance_t * module_instance_by_data(module_list_t const *ml, void const *data)
Find an existing module instance by its private instance data.
Definition: module.c:910
struct module_list_type_s::@64 thread
Callbacks to manage thread-local data.
int(* module_list_init_t)(module_list_t *ml)
Callback to initialise any global structures required for the module list.
Definition: module.c:225
static void mlg_thread_data_del(module_thread_instance_t *ti)
Definition: module.c:497
static int mlg_thread_data_add(module_thread_instance_t *ti)
Definition: module.c:490
static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
Definition: module.c:190
static int _module_dl_loader_init(void *uctx)
Definition: module.c:1803
void(* module_list_thread_free_t)(module_list_t *ml)
Callback to free thread-local structures, called once per thread as the thread is being destroyed.
Definition: module.c:268
static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out, module_instance_t const *parent, char const *inst_name)
Generate a module name from the module's name and its parents.
Definition: module.c:1340
module_thread_instance_t * module_thread_by_data(module_list_t const *ml, void const *data)
Retrieve module/thread specific instance data for a module.
Definition: module.c:933
static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:128
void(* module_list_thread_data_del_t)(module_thread_instance_t *ti)
Callback to remove thread-local data for a module.
Definition: module.c:289
return count
Definition: module.c:162
int module_instance_data_unprotect(module_instance_t const *mi)
Mark module data as read/write.
Definition: module.c:680
static int _module_thread_inst_free(module_thread_instance_t *ti)
Callback to free thread local data.
Definition: module.c:987
static int _mlg_global_free(UNUSED void *uctx)
Free the global module index.
Definition: module.c:361
int module_thread_instantiate(TALLOC_CTX *ctx, module_instance_t *mi, fr_event_list_t *el)
Allocate thread-local instance data for a module.
Definition: module.c:1027
module_list_data_del_t data_del
Record that module data has been removed.
Definition: module.c:314
module_list_type_t const module_list_type_global
Callbacks for a global module list.
Definition: module.c:505
static dl_module_loader_t * dl_modules
dl module tracking
Definition: module.c:216
fr_cmd_table_t module_cmd_list_table[]
Definition: module.c:98
fr_heap_index_t inst_idx
Entry in the bootstrap/instantiation heap.
Definition: module.c:333
int(* module_list_thread_init_t)(TALLOC_CTX **ctx, module_list_t const *ml)
Callback to initialise a list for thread-local data, called once per thread.
Definition: module.c:262
int modules_bootstrap(module_list_t const *ml)
Bootstrap any modules which have not been bootstrapped already.
Definition: module.c:1316
fr_cmd_table_t module_cmd_table[]
Definition: module.c:65
static module_thread_instance_t * mltl_thread_data_get(module_instance_t *mi)
Definition: module.c:538
module_instance_t mi
Common module instance fields. Must come first.
Definition: module.c:331
static _Thread_local module_thread_instance_t ** mlg_thread_inst_list
An array of thread-local module lists.
Definition: module.c:57
int module_instantiate(module_instance_t *instance)
Manually complete module setup by calling its instantiate function.
Definition: module.c:1139
static int mlg_thread_init(UNUSED TALLOC_CTX **ctx, UNUSED module_list_t const *ml)
Allocate a thread-local array to hold thread data for each module thats been instantiated.
Definition: module.c:446
bool module_instance_skip_bootstrap(module_instance_t *mi)
Should we bootstrap this module instance?
Definition: module.c:1717
module_instance_t mi
Common module instance fields. Must come first.
Definition: module.c:523
static int _mlg_global_init(UNUSED void *uctx)
Initialise the global module index.
Definition: module.c:369
int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic callback for conf_parser_t to load a submodule.
Definition: module.c:800
int(* module_list_data_add_t)(module_instance_t *mi)
Callback to add data for a module.
Definition: module.c:242
size_t list_size
Size of talloc_chunk to allocate for the module_list_t.
Definition: module.c:306
static void mlg_data_del(module_instance_t *mi)
Definition: module.c:407
static void mltl_thread_data_del(module_thread_instance_t *ti)
Definition: module.c:551
static void mltl_mlg_data_del(module_instance_t *mi)
Definition: module.c:528
int module_instance_conf_parse(module_instance_t *mi, CONF_SECTION *conf)
Covert a CONF_SECTION into parsed module instance data.
Definition: module.c:717
static fr_heap_t * mlg_index
Heap of all lists/modules used to get a common index with mlg_thread->inst_list.
Definition: module.c:49
module_instance_t * module_instance_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name, module_instance_state_t init_state)
Allocate a new module and add it to a module list for later bootstrap/instantiation.
Definition: module.c:1567
module_list_t * module_list_alloc(TALLOC_CTX *ctx, module_list_type_t const *type, char const *name, bool write_protect)
Allocate a new module list.
Definition: module.c:1773
static int8_t _mlg_module_instance_cmp(void const *one, void const *two)
Sort module instance data first by list then by number.
Definition: module.c:344
char const * module_instance_name_from_conf(CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: module.c:704
int module_bootstrap(module_instance_t *mi)
Manually complete module bootstrap by calling its instantiate function.
Definition: module.c:1252
void module_instance_debug(module_instance_t const *mi)
Print debugging information for a module.
Definition: module.c:574
A slightly larger module_instance structure to hold the module instance and thread instance.
Definition: module.c:522
Structure to hold callbacks for a module list type.
Definition: module.c:305
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition: table.h:134
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:445
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition: talloc.c:564
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size)
Return a page aligned talloc memory pool.
Definition: talloc.c:312
Functions which we wish were included in the standard talloc distribution.
#define talloc_get_type_abort_const
Definition: talloc.h:271
static fr_event_list_t * el
static fr_slen_t parent
Definition: pair.h:844
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984
void xlat_func_unregister_module(module_instance_t const *inst)
Definition: xlat_func.c:553
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition: xlat_func.c:539