The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dl_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: 11671f5e962fdb53289587721defa3607be2b2a9 $
19  *
20  * @file src/lib/server/dl_module.c
21  * @brief Wrappers around dlopen to manage loading modules at runtime.
22  *
23  * @copyright 2016-2019 The FreeRADIUS server project
24  * @copyright 2016-2019 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25  */
26 RCSID("$Id: 11671f5e962fdb53289587721defa3607be2b2a9 $")
27 #define _DL_MODULE_PRIVATE 1
28 #include <freeradius-devel/server/dl_module.h>
29 
30 #include <freeradius-devel/server/log.h>
31 #include <freeradius-devel/server/global_lib.h>
32 #include <freeradius-devel/util/debug.h>
33 
34 #include <freeradius-devel/util/dl.h>
35 #include <freeradius-devel/util/syserror.h>
36 
37 #include <ctype.h>
38 #include <unistd.h>
39 
40 #define DL_INIT_CHECK fr_assert(dl_module_loader)
41 
42 /** Wrapper struct around dl_loader_t
43  *
44  * Provides space to store instance data.
45  */
50 };
51 
53 
54 /** Make data to instance name resolution more efficient
55  *
56  */
57 typedef struct {
58  void *data; //!< Module's data.
59  dl_module_inst_t *inst; //!< Instance wrapper struct.
61 
63 
64 /** Name prefixes matching the types of loadable module
65  */
67  { L(""), DL_MODULE_TYPE_SUBMODULE },
68  { L("process"), DL_MODULE_TYPE_PROCESS },
69  { L("proto"), DL_MODULE_TYPE_PROTO },
70  { L("rlm"), DL_MODULE_TYPE_MODULE }
71 };
73 
74 static int8_t dl_module_inst_data_cmp(void const *one, void const *two)
75 {
76  dl_module_inst_t const *a = one, *b = two;
77 
78  fr_assert(a->data);
79  fr_assert(b->data);
80 
81  return CMP(a->data, b->data);
82 }
83 
84 static int8_t dl_module_cmp(void const *one, void const *two)
85 {
86  dl_module_t const *a = one, *b = two;
87  int ret;
88 
89  fr_assert(a->dl);
90  fr_assert(b->dl);
91 
92  ret = strcmp(a->dl->name, b->dl->name);
93  return CMP(ret, 0);
94 }
95 
96 /** Call the load() function in a module's exported structure
97  *
98  * @param[in] dl to call the load function for.
99  * @param[in] symbol UNUSED.
100  * @param[in] ctx UNUSED.
101  * @return
102  * - 0 on success.
103  * - -1 on failure.
104  */
105 static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
106 {
107  dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
108 
109  /*
110  * Clear pre-existing errors.
111  */
113 
114  if (dl_module->common->onload) {
115  int ret;
116 
117  ret = dl_module->common->onload();
118  if (ret < 0) {
119 #ifndef NDEBUG
120  PERROR("Initialisation failed for module \"%s\" - onload() returned %i",
121  dl_module->common->name, ret);
122 #else
123  PERROR("Initialisation failed for module \"%s\"", dl_module->common->name);
124 #endif
125  return -1;
126  }
127  }
128 
129  return 0;
130 }
131 
132 /** Call the unload() function in a module's exported structure
133  *
134  * @param[in] dl to call the unload function for.
135  * @param[in] symbol UNUSED.
136  * @param[in] ctx UNUSED.
137  */
138 static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
139 {
140  dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
141 
142  /*
143  * common is NULL if we couldn't find the
144  * symbol and are erroring out.
145  */
146  if (dl_module->common && dl_module->common->unload) dl_module->common->unload();
147 }
148 
149 /** Check if the magic number in the module matches the one in the library
150  *
151  * This is used to detect potential ABI issues caused by running with modules which
152  * were built for a different version of the server.
153  *
154  * @param[in] module Common fields from module's exported interface struct.
155  * @returns
156  * - 0 on success.
157  * - -1 if prefix mismatch.
158  * - -2 if version mismatch.
159  * - -3 if commit mismatch.
160  */
162 {
163 #ifdef HAVE_DLADDR
164  Dl_info dl_info;
165  dladdr(module, &dl_info);
166 #endif
167 
168  if (MAGIC_PREFIX(module->magic) != MAGIC_PREFIX(RADIUSD_MAGIC_NUMBER)) {
169 #ifdef HAVE_DLADDR
170  ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
171 #endif
172  ERROR("Application and rlm_%s magic number (prefix) mismatch."
173  " application: %x module: %x", module->name,
175  MAGIC_PREFIX(module->magic));
176  return -1;
177  }
178 
179  if (MAGIC_VERSION(module->magic) != MAGIC_VERSION(RADIUSD_MAGIC_NUMBER)) {
180 #ifdef HAVE_DLADDR
181  ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
182 #endif
183  ERROR("Application and rlm_%s magic number (version) mismatch."
184  " application: %lx module: %lx", module->name,
185  (unsigned long) MAGIC_VERSION(RADIUSD_MAGIC_NUMBER),
186  (unsigned long) MAGIC_VERSION(module->magic));
187  return -2;
188  }
189 
190  if (MAGIC_COMMIT(module->magic) != MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER)) {
191 #ifdef HAVE_DLADDR
192  ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
193 #endif
194  ERROR("Application and rlm_%s magic number (commit) mismatch."
195  " application: %lx module: %lx", module->name,
196  (unsigned long) MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER),
197  (unsigned long) MAGIC_COMMIT(module->magic));
198  return -3;
199  }
200 
201  return 0;
202 }
203 
204 /** Lookup a module's parent
205  *
206  */
208 {
209  return child->parent;
210 }
211 
212 /** Lookup a dl_module_inst_t via instance data
213  *
214  */
216 {
218 
219  if (dl_inst_cache.data == data) return dl_inst_cache.inst;
220 
221  return fr_rb_find(dl_module_loader->inst_data_tree, &(dl_module_inst_t){ .data = UNCONST(void *, data) });
222 }
223 
224 /** Lookup a dl_module_inst_t via a config section
225  *
226  */
228 {
230 }
231 
232 /** Lookup instance name via instance data
233  *
234  */
235 char const *dl_module_instance_name_by_data(void const *data)
236 {
237  dl_module_inst_t const *inst;
238 
240  if (!inst) return NULL;
241 
242  return inst->name;
243 }
244 
245 /** A convenience function for returning a parent's private data
246  *
247  * @param[in] data Private instance data for child.
248  * @return
249  * - Parent's private instance data.
250  * - NULL if no parent
251  */
253 {
254  dl_module_inst_t const *dl_inst;
255 
257 
258  dl_inst = dl_module_instance_by_data(data);
259  if (!dl_inst) return NULL;
260 
261  if (!dl_inst->parent) return NULL;
262 
263  return dl_inst->parent->data;
264 }
265 
266 /** Detach the shallowest parent first
267  *
268  */
270 {
271  if (dl_inst->detached) return;
272 
273  if (dl_inst->parent) dl_module_detach_parent(UNCONST(dl_module_inst_t *, dl_inst->parent));
274 
275  if (dl_inst->module->common->detach) {
276  dl_inst->module->common->detach(&(module_detach_ctx_t){ .inst = dl_inst });
277  dl_inst->detached = true;
278  }
279 }
280 
282 {
284 
285  if (!dl_inst) {
286  ERROR("Failed resolving data %p, to dl_module_inst_t, refusing to free", data);
287  return -1;
288  }
289 
290  /*
291  * Ensure the shallowest parent module
292  * gets detached first so that it can
293  * still reach its children.
294  */
295  dl_module_detach_parent(dl_inst);
296 
297  return 0;
298 }
299 
300 /** Allocate module instance data, and parse the module's configuration
301  *
302  * @param[in] dl_inst to allocate this instance data in.
303  * @param[in] module to alloc instance data for.
304  */
305 static void dl_module_instance_data_alloc(dl_module_inst_t *dl_inst, dl_module_t const *module)
306 {
307  void *data;
308 
309  /*
310  * If there is supposed to be instance data, allocate it now.
311  *
312  * If the structure is zero length then allocation will still
313  * succeed, and will create a talloc chunk header.
314  *
315  * This is needed so we can resolve instance data back to
316  * dl_module_inst_t/dl_module_t/dl_t.
317  */
318  MEM(data = talloc_zero_array(dl_inst, uint8_t, module->common->inst_size));
319 
320  if (!module->common->inst_type) {
321  talloc_set_name(data, "%s_t", module->dl->name ? module->dl->name : "config");
322  } else {
323  talloc_set_name_const(data, module->common->inst_type);
324  }
325  dl_inst->data = data;
326 
327  /*
328  * Must be done before setting the destructor to ensure the
329  * destructor can find the dl_module_inst_t associated
330  * with the data.
331  */
332  fr_assert(dl_module_loader != NULL);
333  fr_rb_insert(dl_module_loader->inst_data_tree, dl_inst); /* Duplicates not possible */
334 
335  talloc_set_destructor(data, _dl_module_instance_data_free);
336 }
337 
338 /** Decrement the reference count of the dl, eventually freeing it
339  *
340  */
342 {
343  /*
344  * dl is empty if we tried to load it and failed.
345  */
346  if (dl_module->dl) {
347  if (DEBUG_ENABLED4) {
348  DEBUG4("%s unloaded. Handle address %p, symbol address %p", dl_module->dl->name,
350  } else {
351  DEBUG3("%s unloaded", dl_module->dl->name);
352  }
353  }
354 
355  if (dl_module->in_tree) {
357  dl_module->in_tree = false;
358  }
359 
360  dl_free(dl_module->dl);
361 
362  return 0;
363 }
364 
365 /** Load a module library using dlopen() or return a previously loaded module from the cache
366  *
367  * When the dl_module_t is no longer used, talloc_free() may be used to free it.
368  *
369  * When all references to the original dlhandle are freed, dlclose() will be called on the
370  * dlhandle to unload the module.
371  *
372  * @param[in] parent The dl_module_t of the parent module, e.g. rlm_sql for rlm_sql_postgresql.
373  * @param[in] name of the module e.g. sql for rlm_sql.
374  * @param[in] type Used to determine module name prefixes. Must be one of:
375  * - DL_MODULE_TYPE_MODULE
376  * - DL_MODULE_TYPE_PROTO
377  * - DL_MODULE_TYPE_SUBMODULE
378  * @return
379  * - Module handle holding dlhandle, and module's public interface structure.
380  * - NULL if module couldn't be loaded, or some other error occurred.
381  */
383 {
384  dl_module_t *dl_module = NULL;
385  dl_t *dl = NULL;
386  char *module_name = NULL;
387  char *p, *q;
388  dl_module_common_t const *common;
389 
391 
392  if (parent) {
393  module_name = talloc_typed_asprintf(NULL, "%s_%s_%s",
395  parent->type, "<INVALID>"),
396  parent->common->name, name);
397  } else {
398  module_name = talloc_typed_asprintf(NULL, "%s_%s",
400  name);
401  }
402 
403  if (!module_name) return NULL;
404 
405  for (p = module_name, q = p + talloc_array_length(p) - 1; p < q; p++) *p = tolower((uint8_t) *p);
406 
407  /*
408  * If the module's already been loaded, increment the reference count.
409  */
411  &(dl_module_t){ .dl = &(dl_t){ .name = module_name }});
412  if (dl_module) {
413  talloc_free(module_name);
414  talloc_increase_ref_count(dl_module);
415  return dl_module;
416  }
417 
418  dl_module = talloc_zero(dl_module_loader, dl_module_t);
420  dl_module->type = type;
421  talloc_set_destructor(dl_module, _dl_module_free); /* Do this late */
422 
423  /*
424  * Pass in dl_module as the uctx so that
425  * we can get at it in any callbacks.
426  */
427  dl = dl_by_name(dl_module_loader->dl_loader, module_name, dl_module, false);
428  if (!dl) {
429  PERROR("Failed to link to module \"%s\"", module_name);
430  ERROR("Make sure it (and all its dependent libraries!) are in the search path"
431  " of your system's ld");
432  error:
433  talloc_free(module_name);
434  talloc_free(dl_module); /* Do not free dl explicitly, it's handled by the destructor */
435  return NULL;
436  }
437  dl_module->dl = dl;
438 
439  DEBUG3("%s loaded, checking if it's valid", module_name);
440 
441  common = dlsym(dl->handle, module_name);
442  if (!common) {
443  ERROR("Could not find \"%s\" symbol in module: %s", module_name, dlerror());
444  goto error;
445  }
446  dl_module->common = common;
447 
448  /*
449  * Before doing anything else, check if it's sane.
450  */
451  if (dl_module_magic_verify(common) < 0) goto error;
452 
453  DEBUG3("%s validated. Handle address %p, symbol address %p", module_name, dl, common);
454 
456  PERROR("Failed calling initializers for module \"%s\"", module_name);
457  goto error;
458  }
459 
460  DEBUG2("Loaded module %s", module_name);
461 
462  /*
463  * Add the module to the dl cache
464  */
466  if (!dl_module->in_tree) {
467  ERROR("Failed caching module \"%s\"", module_name);
468  goto error;
469  }
470 
471  talloc_free(module_name);
472 
473  return dl_module;
474 }
475 
476 /** Free a module instance, removing it from the instance tree
477  *
478  * Also decrements the reference count of the module potentially unloading it.
479  *
480  * @param[in] dl_inst to free.
481  * @return 0.
482  */
484 {
485  /*
486  * Ensure sane free order, and that all destructors
487  * run before the .so/.dylib is unloaded.
488  *
489  * This *MUST* be done *BEFORE* decrementing the
490  * reference count on the module.
491  *
492  * It also *MUST* be done before removing this struct
493  * from the inst_data_tree, so the detach destructor
494  * can find the dl_module_inst_t associated with
495  * the opaque data.
496  */
497  talloc_free_children(dl_inst);
498 
499  /*
500  * Remove this instance from the tracking tree.
501  */
502  fr_assert(dl_module_loader != NULL);
504 
505  /*
506  * Decrements the reference count. The module object
507  * won't be unloaded until all instances of that module
508  * have been destroyed.
509  */
511 
512  return 0;
513 }
514 
515 /** Retrieve a public symbol from a module using dlsym
516  *
517  * Convenience function to lookup/return public symbols from modules loaded
518  * with #dl_module_instance.
519  *
520  * @param[in] dl_inst Instance who's module we're looking for the symbol in.
521  * @param[in] sym_name to lookup.
522  * @return
523  * - Pointer to the public data structure.
524  * - NULL if no matching symbol was found.
525  */
526 void *dl_module_instance_symbol(dl_module_inst_t const *dl_inst, char const *sym_name)
527 {
528  if (!sym_name) return NULL;
529 
530  return dlsym(dl_inst->module->dl->handle, sym_name);
531 }
532 
533 /** Load a module and parse its #CONF_SECTION in one operation
534  *
535  * When this instance is no longer needed, it should be freed with talloc_free().
536  * When all instances of a particular module are unloaded, the dl handle will be closed,
537  * unloading the module.
538  *
539  * @param[in] ctx to allocate structures in.
540  * @param[out] out where to write our #dl_module_inst_t containing the module
541  * handle and instance.
542  * @param[in] parent of module instance.
543  * @param[in] type of module to load.
544  * @param[in] mod_name of the module to load .e.g. 'udp' for 'proto_radius_udp'
545  * if the parent were 'proto_radius'.
546  * @param[in] inst_name The name of the instance .e.g. 'sql_aws_dc01'
547  *
548  * @return
549  * - 0 on success.
550  * - -1 on failure.
551  */
552 int dl_module_instance(TALLOC_CTX *ctx, dl_module_inst_t **out,
553  dl_module_inst_t const *parent,
554  dl_module_type_t type, char const *mod_name, char const *inst_name)
555 {
556  dl_module_inst_t *dl_inst;
557 
559 
560  MEM(dl_inst = talloc_zero(ctx, dl_module_inst_t));
561 
562  dl_inst->module = dl_module(parent ? parent->module : NULL, mod_name, type);
563  if (!dl_inst->module) {
564  talloc_free(dl_inst);
565  return -1;
566  }
567  dl_inst->name = talloc_typed_strdup(dl_inst, inst_name);
568 
569  /*
570  * ctx here is the main module's instance data
571  */
572  dl_module_instance_data_alloc(dl_inst, dl_inst->module);
573  talloc_set_destructor(dl_inst, _dl_module_instance_free);
574 
575  dl_inst->parent = parent;
576  *out = dl_inst;
577 
578  return 0;
579 }
580 
581 /** Avoid boilerplate when setting the module instance name
582  *
583  */
585 {
586  char const *name2;
587 
588  name2 = cf_section_name2(conf);
589  if (name2) return name2;
590 
591  return cf_section_name1(conf);
592 }
593 
595 {
596  /*
597  * Associate the module instance with the conf section
598  * *before* executing any parse rules that might need it.
599  */
600  cf_data_add(conf, dl_inst, dl_inst->module->dl->name, false);
601  dl_inst->conf = conf;
602 
603  if (dl_inst->module->common->config && dl_inst->conf) {
604  if ((cf_section_rules_push(dl_inst->conf, dl_inst->module->common->config)) < 0 ||
605  (cf_section_parse(dl_inst->data, dl_inst->data, dl_inst->conf) < 0)) {
606  cf_log_err(dl_inst->conf, "Failed evaluating configuration for module \"%s\"",
607  dl_inst->module->dl->name);
608  return -1;
609  }
610  }
611 
612  return 0;
613 }
614 
616 {
617  int ret = 0;
618 
619  if (fr_rb_num_elements(dl_module_l->inst_data_tree) > 0) {
620 #ifndef NDEBUG
622  void *data;
623 
624  WARN("Refusing to cleanup dl loader, the following module instances are still in use:");
625  for (data = fr_rb_iter_init_inorder(&iter, dl_module_l->inst_data_tree);
626  data;
627  data = fr_rb_iter_next_inorder(&iter)) {
628  dl_module_inst_t *dl_inst = talloc_get_type_abort(data, dl_module_inst_t);
629 
630  WARN(" %s (%s)", dl_inst->module->dl->name, dl_inst->name);
631  }
632 #endif
633  ret = -1;
634  goto finish;
635  }
636 
637  /*
638  * Do this as an explicit step, as this free can fail
639  */
640  ret = talloc_free(dl_module_l->dl_loader);
641  if (ret != 0) {
642  PWARN("dl loader not freed");
643  }
644 
645 finish:
646  if (ret != 0) {
647 #ifndef NDEBUG
648  WARN("This may appear as a leak in talloc memory reports");
649 #endif
650  } else {
651  dl_module_loader = NULL;
652  }
653 
654  return ret;
655 }
656 
657 char const *dl_module_search_path(void)
658 {
660 }
661 
663 {
664  return dl_module_l->dl_loader;
665 }
666 
667 /** Wrapper to log errors
668  */
669 static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
670 {
671  int ret;
672 
673  ret = fr_dl_dict_enum_autoload(module, symbol, user_ctx);
674  if (ret < 0) PERROR("Failed autoloading enum value for \"%s\"", module->name);
675 
676  return ret;
677 }
678 
679 /** Wrapper to log errors
680  */
681 static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
682 {
683  int ret;
684 
685  ret = fr_dl_dict_attr_autoload(module, symbol, user_ctx);
686  if (ret < 0) PERROR("Failed autoloading attribute for \"%s\"", module->name);
687 
688  return ret;
689 }
690 
691 /** Wrapper to log errors
692  */
693 static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
694 {
695  int ret;
696 
697  ret = fr_dl_dict_autoload(module, symbol, user_ctx);
698  if (ret < 0) PERROR("Failed autoloading dictionary for \"%s\"", module->name);
699 
700  return ret;
701 }
702 
703 /** Initialise structures needed by the dynamic linker
704  *
705  */
707 {
708  if (dl_module_loader) {
709  /*
710  * Allow it to update the search path.
711  */
712  if (dl_search_path_set(dl_module_loader->dl_loader, lib_dir) < 0) {
713  return NULL;
714  }
715 
716  return dl_module_loader;
717  }
718 
719  dl_module_loader = talloc_zero(NULL, dl_module_loader_t);
720  if (!dl_module_loader) {
721  ERROR("Failed initialising uctx for dl_loader");
722  return NULL;
723  }
724 
726  if (!dl_module_loader) {
727  PERROR("Failed initialising dl_loader");
728  error:
729  TALLOC_FREE(dl_module_loader);
730  return NULL;
731  }
732  if (lib_dir) dl_search_path_prepend(dl_module_loader->dl_loader, lib_dir);
733 
737  ERROR("Failed initialising dl->inst_data_tree");
738  goto error;
739  }
740 
742  dl_module_cmp, NULL);
744  ERROR("Failed initialising dl->module_tree");
745  goto error;
746  }
747 
749  DL_PRIORITY_BOOTSTRAP, NULL, dl_module_onload_func, NULL) < 0) {
750  ERROR("Failed registering load() callback");
751  goto error;
752  }
753 
755  DL_PRIORITY_BOOTSTRAP, NULL, dl_module_unload_func, NULL) < 0) {
756  ERROR("Failed registering unload() callback");
757  goto error;
758  }
759 
760  /*
761  * Register dictionary autoload callbacks
762  */
764  DL_PRIORITY_DICT_ENUM, "dict_enum", dl_dict_enum_autoload, NULL);
766  DL_PRIORITY_DICT_ATTR, "dict_attr", dl_dict_attr_autoload, NULL);
768  DL_PRIORITY_DICT, "dict", dl_dict_autoload, NULL);
770  DL_PRIORITY_DICT, "dict", fr_dl_dict_autofree, NULL);
771 
772  /*
773  * Register library autoload callbacks
774  */
778  DL_PRIORITY_LIB, "lib", global_lib_autofree, NULL);
779 
780  talloc_set_destructor(dl_module_loader, _dl_module_loader_free);
781 
782  DEBUG4("Module linker search path(s)");
783  if (DEBUG_ENABLED4) {
784  char const *env;
785 
786 #ifdef __APPLE__
787  char buffer[PATH_MAX];
788 
789  env = getenv("LD_LIBRARY_PATH");
790  if (env) {
791  DEBUG4("LD_LIBRARY_PATH : %s", env);
792  }
793  env = getenv("DYLD_LIBRARY_PATH");
794  if (env) {
795  DEBUG4("DYLB_LIBRARY_PATH : %s", env);
796  }
797  env = getenv("DYLD_FALLBACK_LIBRARY_PATH");
798  if (env) {
799  DEBUG4("DYLD_FALLBACK_LIBRARY_PATH : %s", env);
800  }
801  env = getcwd(buffer, sizeof(buffer));
802  if (env) {
803  DEBUG4("Current directory : %s", env);
804  }
805 #else
806  env = getenv("LD_LIBRARY_PATH");
807  if (env) {
808  DEBUG4("LD_LIBRARY_PATH : %s", env);
809  }
810  DEBUG4("Defaults : /lib:/usr/lib");
811 #endif
812  }
813 
814  return dl_module_loader;
815 }
static int const char char buffer[256]
Definition: acutest.h:574
static dl_t * dl
Definition: fuzzer.c:42
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define RCSID(id)
Definition: build.h:444
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#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 UNUSED
Definition: build.h:313
#define NUM_ELEMENTS(_t)
Definition: build.h:335
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
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:658
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1126
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1680
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1112
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:231
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:220
#define CF_IDENT_ANY
Definition: cf_util.h:78
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
int fr_dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
void fr_dl_dict_autofree(dl_t const *module, void *symbol, void *user_ctx)
int fr_dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
int fr_dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
dl_loader_t * dl_loader_init(TALLOC_CTX *ctx, void *uctx, bool uctx_free, bool defer_symbol_init)
Initialise structures needed by the dynamic linker.
Definition: dl.c:885
dl_t * dl_by_name(dl_loader_t *dl_loader, char const *name, void *uctx, bool uctx_free)
Search for a dl's shared object in various locations.
Definition: dl.c:470
int dl_symbol_free_cb_register(dl_loader_t *dl_loader, unsigned int priority, char const *symbol, dl_unload_t func, void *uctx)
Register a callback to execute when a dl with a particular symbol is unloaded.
Definition: dl.c:384
int dl_search_path_prepend(dl_loader_t *dl_loader, char const *lib_dir)
Append a new search path component to the library search path.
Definition: dl.c:813
char const * dl_search_path(dl_loader_t *dl_loader)
Return current library path.
Definition: dl.c:729
int dl_symbol_init_cb_register(dl_loader_t *dl_loader, unsigned int priority, char const *symbol, dl_onload_t func, void *uctx)
Register a callback to execute when a dl with a particular symbol is first loaded.
Definition: dl.c:321
int dl_search_path_set(dl_loader_t *dl_loader, char const *lib_dir)
Set the current library path.
Definition: dl.c:788
int dl_free(dl_t const *dl)
"free" a dl handle, possibly actually freeing it, and unloading the library
Definition: dl.c:678
int dl_symbol_init(dl_loader_t *dl_loader, dl_t const *dl)
Walk over the registered init callbacks, searching for the symbols they depend on.
Definition: dl.c:233
A dynamic loader.
Definition: dl.c:81
void * handle
Handle returned by dlopen.
Definition: dl.h:62
void * uctx
API client's opaque data.
Definition: dl.h:65
char const * name
Name of the module e.g. sql.
Definition: dl.h:61
Module handle.
Definition: dl.h:58
char const * dl_module_search_path(void)
Definition: dl_module.c:657
#define DL_INIT_CHECK
Definition: dl_module.c:40
dl_module_inst_t * inst
Instance wrapper struct.
Definition: dl_module.c:59
int dl_module_instance(TALLOC_CTX *ctx, dl_module_inst_t **out, dl_module_inst_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name)
Load a module and parse its CONF_SECTION in one operation.
Definition: dl_module.c:552
char const * dl_module_inst_name_from_conf(CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: dl_module.c:584
dl_loader_t * dl_loader
Definition: dl_module.c:49
static int _dl_module_loader_free(dl_module_loader_t *dl_module_l)
Definition: dl_module.c:615
static int _dl_module_free(dl_module_t *dl_module)
Decrement the reference count of the dl, eventually freeing it.
Definition: dl_module.c:341
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
Definition: dl_module.c:66
static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
Call the unload() function in a module's exported structure.
Definition: dl_module.c:138
char const * dl_module_instance_name_by_data(void const *data)
Lookup instance name via instance data.
Definition: dl_module.c:235
static int8_t dl_module_cmp(void const *one, void const *two)
Definition: dl_module.c:84
static _Thread_local dl_module_inst_cache_t dl_inst_cache
Definition: dl_module.c:62
dl_loader_t * dl_loader_from_module_loader(dl_module_loader_t *dl_module_l)
Definition: dl_module.c:662
static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition: dl_module.c:693
static int _dl_module_instance_free(dl_module_inst_t *dl_inst)
Free a module instance, removing it from the instance tree.
Definition: dl_module.c:483
static void dl_module_instance_data_alloc(dl_module_inst_t *dl_inst, dl_module_t const *module)
Allocate module instance data, and parse the module's configuration.
Definition: dl_module.c:305
dl_module_inst_t const * dl_module_parent_instance(dl_module_inst_t const *child)
Lookup a module's parent.
Definition: dl_module.c:207
void * dl_module_parent_data_by_child_data(void const *data)
A convenience function for returning a parent's private data.
Definition: dl_module.c:252
dl_module_inst_t const * dl_module_instance_by_data(void const *data)
Lookup a dl_module_inst_t via instance data.
Definition: dl_module.c:215
static int _dl_module_instance_data_free(void *data)
Definition: dl_module.c:281
fr_rb_tree_t * module_tree
Definition: dl_module.c:47
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Definition: dl_module.c:706
static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
Call the load() function in a module's exported structure.
Definition: dl_module.c:105
fr_rb_tree_t * inst_data_tree
Definition: dl_module.c:48
static int dl_module_magic_verify(dl_module_common_t const *module)
Check if the magic number in the module matches the one in the library.
Definition: dl_module.c:161
dl_module_t const * dl_module(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:382
void * dl_module_instance_symbol(dl_module_inst_t const *dl_inst, char const *sym_name)
Retrieve a public symbol from a module using dlsym.
Definition: dl_module.c:526
static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition: dl_module.c:681
static int8_t dl_module_inst_data_cmp(void const *one, void const *two)
Definition: dl_module.c:74
static void dl_module_detach_parent(dl_module_inst_t *dl_inst)
Detach the shallowest parent first.
Definition: dl_module.c:269
static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition: dl_module.c:669
void * data
Module's data.
Definition: dl_module.c:58
size_t dl_module_type_prefix_len
Definition: dl_module.c:72
static dl_module_loader_t * dl_module_loader
Definition: dl_module.c:52
dl_module_inst_t const * dl_module_instance_by_cs(CONF_SECTION const *cs)
Lookup a dl_module_inst_t via a config section.
Definition: dl_module.c:227
int dl_module_conf_parse(dl_module_inst_t *dl_inst, CONF_SECTION *conf)
Definition: dl_module.c:594
Make data to instance name resolution more efficient.
Definition: dl_module.c:57
Wrapper struct around dl_loader_t.
Definition: dl_module.c:46
bool _CONST in_tree
Definition: dl_module.h:155
dl_t *_CONST dl
Dynamic loader handle.
Definition: dl_module.h:143
dl_module_t const *_CONST parent
of this module.
Definition: dl_module.h:145
dl_module_type_t _CONST type
of this module.
Definition: dl_module.h:147
dl_module_type_t
Definition: dl_module.h:67
@ DL_MODULE_TYPE_PROTO
Protocol module.
Definition: dl_module.h:69
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition: dl_module.h:71
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition: dl_module.h:68
@ DL_MODULE_TYPE_PROCESS
protocol processor.
Definition: dl_module.h:70
dl_module_t const *_CONST module
Module.
Definition: dl_module.h:164
#define DL_PRIORITY_BOOTSTRAP
Callback priority for bootstrap callback.
Definition: dl_module.h:82
bool _CONST detached
Whether the detach function has been called.
Definition: dl_module.h:168
#define DL_PRIORITY_DICT_ATTR
Callback priority for attribute resolution.
Definition: dl_module.h:79
#define DL_PRIORITY_DICT
Callback priorities.
Definition: dl_module.h:78
char const *_CONST name
Instance name.
Definition: dl_module.h:163
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define DL_PRIORITY_LIB
Callback priority for library config.
Definition: dl_module.h:81
CONF_SECTION *_CONST conf
Module's instance configuration.
Definition: dl_module.h:166
dl_module_common_t const *_CONST common
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition: dl_module.h:149
#define DL_PRIORITY_DICT_ENUM
Callback priority for enum resolution.
Definition: dl_module.h:80
dl_module_inst_t const *_CONST parent
Parent module's instance (if any).
Definition: dl_module.h:167
Fields common to all types of loadable modules.
Definition: dl_module.h:133
A module/inst tuple.
Definition: dl_module.h:162
void global_lib_autofree(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for freeing of "lib" symbols.
Definition: global_lib.c:174
int global_lib_auto_instantiate(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for creation of "lib" symbols.
Definition: global_lib.c:137
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG3(_fmt,...)
Definition: log.h:266
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
Definition: log.h:260
#define PWARN(_fmt,...)
Definition: log.h:227
#define DEBUG4(_fmt,...)
Definition: log.h:267
talloc_free(reap)
static char const * mod_name(fr_listen_t *li)
Definition: master.c:2704
unsigned char uint8_t
Definition: merged_model.c:30
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define WARN(fmt,...)
Definition: radclient.h:47
static rs_t * conf
Definition: radsniff.c:53
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition: rb.c:775
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_talloc_alloc(_ctx, _type, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition: rb.h:205
Iterator structure for in-order traversal of an rbtree.
Definition: rb.h:321
The main red black tree structure.
Definition: rb.h:73
static char const * name
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
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:333
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:380
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
Definition: talloc.c:708
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 MAGIC_PREFIX(_x)
Definition: version.h:82
#define MAGIC_VERSION(_x)
Definition: version.h:83
#define MAGIC_COMMIT(_x)
Definition: version.h:84
#define RADIUSD_MAGIC_NUMBER
Definition: version.h:81
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984