The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
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: 742541762963c4cfc46f723070b93ccf301f9c36 $
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 */
26RCSID("$Id: 742541762963c4cfc46f723070b93ccf301f9c36 $")
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 <pthread.h>
38#include <ctype.h>
39#include <unistd.h>
40
41#define DL_INIT_CHECK fr_assert(dl_module_loader)
42
43/** Wrapper struct around dl_loader_t
44 *
45 * Provides space to store instance data.
46 */
48 pthread_mutex_t lock; //!< Protects the module tree when multiple threads are loading modules simultaneously.
49 fr_rb_tree_t *module_tree; //!< Module's dl handles.
50 dl_loader_t *dl_loader; //!< A list of loaded libraries, and symbol to callback mappings.
51};
52
54
55/** Name prefixes matching the types of loadable module
56 */
59 { L("process"), DL_MODULE_TYPE_PROCESS },
60 { L("proto"), DL_MODULE_TYPE_PROTO },
61 { L("rlm"), DL_MODULE_TYPE_MODULE }
62};
64
65static int8_t dl_module_cmp(void const *one, void const *two)
66{
67 dl_module_t const *a = one, *b = two;
68 int ret;
69
70 fr_assert(a->dl);
71 fr_assert(b->dl);
72
73 ret = strcmp(a->dl->name, b->dl->name);
74 return CMP(ret, 0);
75}
76
77/** Find the module's shallowest parent, or the child if no parents are found
78 *
79 * @param[in] child to locate the root for.
80 * @return
81 * - The module's shallowest parent.
82 * - NULL on error.
83 */
84static dl_module_t const *dl_module_root(dl_module_t const *child)
85{
86 dl_module_t const *next;
87
88 for (;;) {
89 next = child->parent;
90 if (!next) break;
91
92 child = next;
93 }
94
95 return child;
96}
97
98/** Return the prefix string for the deepest module
99 *
100 * This is useful for submodules which don't have a prefix of their own.
101 * In this case we need to use the prefix of the shallowest module, which
102 * will be a proto or rlm module.
103 *
104 * @param[in] module to get the prefix for.
105 * @return The prefix string for the shallowest module.
106 */
107static inline CC_HINT(always_inline)
108char const *dl_module_root_prefix_str(dl_module_t const *module)
109{
110 dl_module_t const *root = dl_module_root(module);
111
112 return fr_table_str_by_value(dl_module_type_prefix, root->type, "<INVALID>");
113}
114
115/** Call the load() function in a module's exported structure
116 *
117 * @param[in] dl to call the load function for.
118 * @param[in] symbol UNUSED.
119 * @param[in] ctx UNUSED.
120 * @return
121 * - 0 on success.
122 * - -1 on failure.
123 */
124static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
125{
126 dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
127
128 /*
129 * Clear pre-existing errors.
130 */
132
133 if (dl_module->exported->onload) {
134 int ret;
135
136 ret = dl_module->exported->onload();
137 if (ret < 0) {
138#ifndef NDEBUG
139 PERROR("Initialisation failed for module \"%s\" - onload() returned %i",
140 dl_module->exported->name, ret);
141#else
142 PERROR("Initialisation failed for module \"%s\"", dl_module->exported->name);
143#endif
144 return -1;
145 }
146 }
147
148 return 0;
149}
150
151/** Call the unload() function in a module's exported structure
152 *
153 * @param[in] dl to call the unload function for.
154 * @param[in] symbol UNUSED.
155 * @param[in] ctx UNUSED.
156 */
157static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
158{
159 dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
160
161 /*
162 * common is NULL if we couldn't find the
163 * symbol and are erroring out.
164 */
165 if (dl_module->exported && dl_module->exported->unload) dl_module->exported->unload();
166}
167
168/** Check if the magic number in the module matches the one in the library
169 *
170 * This is used to detect potential ABI issues caused by running with modules which
171 * were built for a different version of the server.
172 *
173 * @param[in] module Common fields from module's exported interface struct.
174 * @returns
175 * - 0 on success.
176 * - -1 if prefix mismatch.
177 * - -2 if version mismatch.
178 * - -3 if commit mismatch.
179 */
181{
182#ifdef HAVE_DLADDR
183 Dl_info dl_info;
184 dladdr(module, &dl_info);
185#endif
186
187 if (MAGIC_PREFIX(module->magic) != MAGIC_PREFIX(RADIUSD_MAGIC_NUMBER)) {
188#ifdef HAVE_DLADDR
189 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
190#endif
191 ERROR("Application and rlm_%s magic number (prefix) mismatch."
192 " application: %x module: %x", module->name,
194 MAGIC_PREFIX(module->magic));
195 return -1;
196 }
197
198 if (MAGIC_VERSION(module->magic) != MAGIC_VERSION(RADIUSD_MAGIC_NUMBER)) {
199#ifdef HAVE_DLADDR
200 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
201#endif
202 ERROR("Application and rlm_%s magic number (version) mismatch."
203 " application: %lx module: %lx", module->name,
204 (unsigned long) MAGIC_VERSION(RADIUSD_MAGIC_NUMBER),
205 (unsigned long) MAGIC_VERSION(module->magic));
206 return -2;
207 }
208
209 if (MAGIC_COMMIT(module->magic) != MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER)) {
210#ifdef HAVE_DLADDR
211 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
212#endif
213 ERROR("Application and rlm_%s magic number (commit) mismatch."
214 " application: %lx module: %lx", module->name,
215 (unsigned long) MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER),
216 (unsigned long) MAGIC_COMMIT(module->magic));
217 return -3;
218 }
219
220 return 0;
221}
222
223/** Decrement the reference count of the dl, eventually freeing it
224 *
225 */
226static int _dl_module_free(dl_module_t *dl_module)
227{
228 /*
229 * Talloc destructors access the talloc chunk after
230 * calling the destructor, which could lead to a race
231 * if the mutex is acquired within the destructor
232 * itself. This unfortunately means that we have to
233 * free modules using a dedicated free function which
234 * locks the dl_module_loader mutex.
235 *
236 * Ensure this module is not being freed using the
237 * normal talloc hierarchy, or with talloc_free().
238 */
239 fr_assert_msg(pthread_mutex_trylock(&dl_module->loader->lock) != 0,
240 "dl_module_loader->lock not held when freeing module, "
241 "use dl_module_free() to free modules, not talloc_free");
242
243 /*
244 * Decrement refcounts, freeing at zero
245 */
246 if (--dl_module->refs > 0) return -1;
247
248 /*
249 * dl is empty if we tried to load it and failed.
250 */
251 if (dl_module->dl) {
252 if (DEBUG_ENABLED4) {
253 DEBUG4("%s unloaded. Handle address %p, symbol address %p", dl_module->dl->name,
254 dl_module->dl->handle, dl_module->exported);
255 } else {
256 DEBUG3("%s unloaded", dl_module->dl->name);
257 }
258 }
259
260 if (dl_module->in_tree) {
262 dl_module->in_tree = false;
263 }
264
265 dl_free(dl_module->dl);
266
267 return 0;
268}
269
270/** Free a dl_module (when there are no more references to it)
271 *
272 * Decrement the reference count for a module, freeing it and unloading the module if there are no
273 * more references.
274 *
275 * @note This must be used to free modules, not talloc_free().
276 *
277 * @return
278 * - 0 on success.
279 * - -1 if the module wasn't freed. This likely means there are more ferences held to it.
280 */
282{
283 int ret;
284 dl_module_loader_t *dl_module_l = dl_module->loader; /* Save this, as dl_module will be free'd */
285
286 pthread_mutex_lock(&dl_module_l->lock);
287 ret = talloc_free(dl_module);
288 pthread_mutex_unlock(&dl_module_l->lock);
289
290 return ret;
291}
292
293/** Load a module library using dlopen() or return a previously loaded module from the cache
294 *
295 * When the dl_module_t is no longer used, talloc_free() may be used to free it.
296 *
297 * When all references to the original dlhandle are freed, dlclose() will be called on the
298 * dlhandle to unload the module.
299 *
300 * @note This function is threadsafe. Multiple callers may attempt to load the same module
301 * at the same time, and the module will only be loaded once, and will not be freed
302 * until all callers have released their references to it. This is useful for dynamic/runtime
303 * loading of modules.
304 *
305 * @param[in] parent The dl_module_t of the parent module, e.g. rlm_sql for rlm_sql_postgresql.
306 * @param[in] name of the module e.g. sql for rlm_sql.
307 * @param[in] type Used to determine module name prefixes. Must be one of:
308 * - DL_MODULE_TYPE_MODULE
309 * - DL_MODULE_TYPE_PROTO
310 * - DL_MODULE_TYPE_SUBMODULE
311 * @return
312 * - Module handle holding dlhandle, and module's public interface structure.
313 * - NULL if module couldn't be loaded, or some other error occurred.
314 */
316{
317 dl_module_t *dl_module = NULL;
318 dl_t *dl = NULL;
319 char *module_name = NULL;
320 dl_module_common_t *common;
321
323
324 if (parent) {
325 module_name = talloc_typed_asprintf(NULL, "%s_%s_%s",
327 parent->exported->name, name);
328 } else {
329 module_name = talloc_typed_asprintf(NULL, "%s_%s",
331 name);
332 }
333
334 if (!module_name) {
335 fr_strerror_const("Out of memory");
336 return NULL;
337 }
338
339 talloc_bstr_tolower(module_name);
340
341 pthread_mutex_lock(&dl_module_loader->lock);
342 /*
343 * If the module's already been loaded, increment the reference count.
344 */
346 &(dl_module_t){ .dl = &(dl_t){ .name = module_name }});
347 if (dl_module) {
348 dl_module->refs++;
349
350 /*
351 * Release the lock, the caller is guaranteed to have a completely
352 * loaded module, which won't be freed out from underneath them until
353 * the reference count drops to zero.
354 */
355 pthread_mutex_unlock(&dl_module_loader->lock);
356 talloc_free(module_name);
357
358 return dl_module;
359 }
360
361 MEM(dl_module = talloc_zero(dl_module_loader, dl_module_t));
362 dl_module->name = talloc_strdup(dl_module, name);
363 dl_module->loader = dl_module_loader;
364 dl_module->parent = parent;
365 dl_module->type = type;
366 dl_module->refs = 1;
367 talloc_set_destructor(dl_module, _dl_module_free); /* Do this late */
368
369 /*
370 * Pass in dl_module as the uctx so that
371 * we can get at it in any callbacks.
372 */
373 dl = dl_by_name(dl_module_loader->dl_loader, module_name, dl_module, false);
374 if (!dl) {
375 PERROR("Failed to link to module \"%s\"", module_name);
376 ERROR("Make sure it (and all its dependent libraries!) are in the search path"
377 " of your system's ld");
378 error:
379 talloc_free(module_name);
380 talloc_free(dl_module); /* Do not free dl explicitly, it's handled by the destructor */
381 pthread_mutex_unlock(&dl_module_loader->lock);
382 return NULL;
383 }
384 dl_module->dl = dl;
385
386 DEBUG3("%s loaded, checking if it's valid", module_name);
387
388 common = dlsym(dl->handle, module_name);
389 if (!common) {
390 ERROR("Could not find \"%s\" symbol in module: %s", module_name, dlerror());
391 goto error;
392 }
393 dl_module->exported = common;
394
395 /*
396 * Before doing anything else, check if it's sane.
397 */
398 if (dl_module_magic_verify(common) < 0) goto error;
399
400 DEBUG3("%s validated. Handle address %p, symbol address %p", module_name, dl, common);
401
403 PERROR("Failed calling initializers for module \"%s\"", module_name);
404 goto error;
405 }
406
407 DEBUG2("Loaded module %s", module_name);
408
409 /*
410 * Add the module to the dl cache
411 */
412 dl_module->in_tree = fr_rb_insert(dl_module_loader->module_tree, dl_module);
413 if (!dl_module->in_tree) {
414 ERROR("Failed caching module \"%s\"", module_name);
415 goto error;
416 }
417
418 /*
419 * Hold the lock for the entire module loading process.
420 *
421 * This ensures that all the global resources the module has symbol callbacks
422 * registered for, are fully populated, before something else attempts to use
423 * it.
424 */
425 pthread_mutex_unlock(&dl_module_loader->lock);
426
427 talloc_free(module_name);
428
429 return dl_module;
430}
431
433{
434 int ret = 0;
435
436 /*
437 * Lock must not be held when freeing the loader list.
438 */
439 fr_assert_msg(pthread_mutex_trylock(&dl_module_l->lock) == 0,
440 "dl_module_loader->lock held when attempting to free dL_module_loader_t");
441
442 if (fr_rb_num_elements(dl_module_l->module_tree) > 0) {
443#ifndef NDEBUG
445 void *data;
446
447 WARN("Refusing to cleanup dl loader, the following modules are still in use:");
448 for (data = fr_rb_iter_init_inorder(&iter, dl_module_l->module_tree);
449 data;
450 data = fr_rb_iter_next_inorder(&iter)) {
451 dl_module_t *module = talloc_get_type_abort(data, dl_module_t);
452
453 WARN(" %s", module->exported->name);
454 }
455#endif
456 ret = -1;
457 goto finish;
458 }
459
460 /*
461 * Do this as an explicit step, as this free can fail
462 */
463 ret = talloc_free(dl_module_l->dl_loader);
464 if (ret != 0) {
465 PWARN("dl loader not freed");
466 }
467
468finish:
469 if (ret != 0) {
470#ifndef NDEBUG
471 WARN("This may appear as a leak in talloc memory reports");
472#endif
473 } else {
474 dl_module_loader = NULL;
475 }
476
477 pthread_mutex_unlock(&dl_module_l->lock);
478 pthread_mutex_destroy(&dl_module_l->lock);
479
480 return ret;
481}
482
483char const *dl_module_search_path(void)
484{
486}
487
489{
490 return dl_module_l->dl_loader;
491}
492
493/** Wrapper to log errors
494 */
495static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
496{
497 int ret;
498
499 ret = fr_dl_dict_enum_autoload(module, symbol, user_ctx);
500 if (ret < 0) PERROR("Failed autoloading enum value for \"%s\"", module->name);
501
502 return ret;
503}
504
505/** Wrapper to log errors
506 */
507static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
508{
509 int ret;
510
511 ret = fr_dl_dict_attr_autoload(module, symbol, user_ctx);
512 if (ret < 0) PERROR("Failed autoloading attribute for \"%s\"", module->name);
513
514 return ret;
515}
516
517/** Wrapper to log errors
518 */
519static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
520{
521 int ret;
522
523 ret = fr_dl_dict_autoload(module, symbol, user_ctx);
524 if (ret < 0) PERROR("Failed autoloading dictionary for \"%s\"", module->name);
525
526 return ret;
527}
528
529/** Initialise structures needed by the dynamic linker
530 *
531 */
533{
534 if (dl_module_loader) {
535 /*
536 * Allow it to update the search path.
537 */
538 if (dl_search_path_set(dl_module_loader->dl_loader, lib_dir) < 0) {
539 return NULL;
540 }
541
542 return dl_module_loader;
543 }
544
545 dl_module_loader = talloc_zero(NULL, dl_module_loader_t);
546 if (!dl_module_loader) {
547 ERROR("Failed initialising uctx for dl_loader");
548 return NULL;
549 }
550 pthread_mutex_init(&dl_module_loader->lock, NULL);
551
553 if (!dl_module_loader) {
554 PERROR("Failed initialising dl_loader");
555 error:
556 TALLOC_FREE(dl_module_loader);
557 return NULL;
558 }
559 if (lib_dir) dl_search_path_prepend(dl_module_loader->dl_loader, lib_dir);
560
562 dl_module_cmp, NULL);
564 ERROR("Failed initialising dl->module_tree");
565 goto error;
566 }
567
570 ERROR("Failed registering load() callback");
571 goto error;
572 }
573
576 ERROR("Failed registering unload() callback");
577 goto error;
578 }
579
580 /*
581 * Register dictionary autoload callbacks
582 */
584 DL_PRIORITY_DICT_ENUM, "dict_enum", dl_dict_enum_autoload, NULL);
586 DL_PRIORITY_DICT_ATTR, "dict_attr", dl_dict_attr_autoload, NULL);
588 DL_PRIORITY_DICT, "dict", dl_dict_autoload, NULL);
591
592 /*
593 * Register library autoload callbacks for registering
594 * global configuration sections.
595 */
600
601 talloc_set_destructor(dl_module_loader, _dl_module_loader_free);
602
603 DEBUG4("Module linker search path(s)");
604 if (DEBUG_ENABLED4) {
605 char const *env;
606
607#ifdef __APPLE__
608 char buffer[PATH_MAX];
609
610 env = getenv("LD_LIBRARY_PATH");
611 if (env) {
612 DEBUG4("LD_LIBRARY_PATH : %s", env);
613 }
614 env = getenv("DYLD_LIBRARY_PATH");
615 if (env) {
616 DEBUG4("DYLB_LIBRARY_PATH : %s", env);
617 }
618 env = getenv("DYLD_FALLBACK_LIBRARY_PATH");
619 if (env) {
620 DEBUG4("DYLD_FALLBACK_LIBRARY_PATH : %s", env);
621 }
622 env = getcwd(buffer, sizeof(buffer));
623 if (env) {
624 DEBUG4("Current directory : %s", env);
625 }
626#else
627 env = getenv("LD_LIBRARY_PATH");
628 if (env) {
629 DEBUG4("LD_LIBRARY_PATH : %s", env);
630 }
631 DEBUG4("Defaults : /lib:/usr/lib");
632#endif
633 }
634
635 return dl_module_loader;
636}
static int const char char buffer[256]
Definition acutest.h:576
static dl_t * dl
Definition fuzzer.c:42
#define RCSID(id)
Definition build.h:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#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:112
#define UNUSED
Definition build.h:315
#define NUM_ELEMENTS(_t)
Definition build.h:337
#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 MEM(x)
Definition debug.h:36
#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
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
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
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
#define DL_INIT_CHECK
Definition dl_module.c:41
static dl_module_t const * dl_module_root(dl_module_t const *child)
Find the module's shallowest parent, or the child if no parents are found.
Definition dl_module.c:84
dl_loader_t * dl_loader
A list of loaded libraries, and symbol to callback mappings.
Definition dl_module.c:50
static int _dl_module_loader_free(dl_module_loader_t *dl_module_l)
Definition dl_module.c:432
static int _dl_module_free(dl_module_t *dl_module)
Decrement the reference count of the dl, eventually freeing it.
Definition dl_module.c:226
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
Definition dl_module.c:57
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:157
static int8_t dl_module_cmp(void const *one, void const *two)
Definition dl_module.c:65
static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:519
dl_loader_t * dl_loader_from_module_loader(dl_module_loader_t *dl_module_l)
Definition dl_module.c:488
fr_rb_tree_t * module_tree
Module's dl handles.
Definition dl_module.c:49
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:124
pthread_mutex_t lock
Protects the module tree when multiple threads are loading modules simultaneously.
Definition dl_module.c:48
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:315
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:180
static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:507
static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:495
static char const * dl_module_root_prefix_str(dl_module_t const *module)
Return the prefix string for the deepest module.
Definition dl_module.c:108
size_t dl_module_type_prefix_len
Definition dl_module.c:63
static dl_module_loader_t * dl_module_loader
Definition dl_module.c:53
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:281
char const * dl_module_search_path(void)
Definition dl_module.c:483
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Definition dl_module.c:532
Wrapper struct around dl_loader_t.
Definition dl_module.c:47
bool _CONST in_tree
Definition dl_module.h:143
dl_t *_CONST dl
Dynamic loader handle.
Definition dl_module.h:122
dl_module_common_t * exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition dl_module.h:128
dl_module_t const *_CONST parent
of this module.
Definition dl_module.h:124
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
#define DL_PRIORITY_BOOTSTRAP
Callback priority for bootstrap callback.
Definition dl_module.h:80
#define DL_PRIORITY_DICT_ATTR
Callback priority for attribute resolution.
Definition dl_module.h:77
#define DL_PRIORITY_DICT
Callback priorities.
Definition dl_module.h:76
dl_module_loader_t *_CONST loader
Loader that owns this dl.
Definition dl_module.h:120
#define DL_PRIORITY_LIB
Callback priority for library config.
Definition dl_module.h:79
#define DL_PRIORITY_DICT_ENUM
Callback priority for enum resolution.
Definition dl_module.h:78
unsigned int refs
Number of references to this module.
Definition dl_module.h:135
Fields common to all types of loadable modules.
Definition dl_module.h:108
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)
#define fr_assert(_expr)
Definition rad_assert.h:38
#define DEBUG2(fmt,...)
Definition radclient.h:43
#define WARN(fmt,...)
Definition radclient.h:47
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition rb.c:781
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:824
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:850
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:577
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition rb.c:626
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:741
#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_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:492
static void talloc_bstr_tolower(char *str)
Convert a talloced string to lowercase.
Definition talloc.h:128
static fr_slen_t parent
Definition pair.h:851
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition strerror.c:577
#define fr_strerror_const(_msg)
Definition strerror.h:223
#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:1265