Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Functions | Variables
res_resolver_unbound.c File Reference
#include "asterisk.h"
#include <signal.h>
#include <unbound.h>
#include <arpa/nameser.h>
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dns_core.h"
#include "asterisk/dns_resolver.h"
#include "asterisk/config.h"
#include "asterisk/config_options.h"
#include "asterisk/test.h"
Include dependency graph for res_resolver_unbound.c:

Go to the source code of this file.

Data Structures

struct  unbound_config
 A container for config related information. More...
 
struct  unbound_config_state
 Unbound configuration state information. More...
 
struct  unbound_global_config
 A structure to hold global configuration-related options. More...
 
struct  unbound_resolver
 Structure for an unbound resolver. More...
 
struct  unbound_resolver_data
 Structure for query resolver data. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (globals)
 A global object container that will contain the global_config that gets swapped out on reloads. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 CONFIG_INFO_STANDARD (cfg_info, globals, unbound_config_alloc,.files=ACO_FILES(&resolver_unbound_conf),.pre_apply_config=unbound_config_preapply_callback,)
 Register information about the configs being processed by this module. More...
 
static int custom_nameserver_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int load_module (void)
 
static int reload_module (void)
 
static void * unbound_config_alloc (void)
 Allocate a unbound_config to hold a snapshot of the complete results of parsing a config. More...
 
static int unbound_config_apply_default (void)
 
static void unbound_config_destructor (void *obj)
 
static int unbound_config_preapply (struct unbound_config *cfg)
 
static int unbound_config_preapply_callback (void)
 Finish initializing new configuration. More...
 
static void unbound_config_state_destructor (void *obj)
 
static void unbound_global_config_destructor (void *obj)
 
static struct unbound_resolverunbound_resolver_alloc (void)
 Allocator for unbound resolver. More...
 
static void unbound_resolver_callback (void *data, int err, struct ub_result *ub_result)
 Callback invoked when resolution completes on a query. More...
 
static int unbound_resolver_cancel (struct ast_dns_query *query)
 
static void unbound_resolver_data_dtor (void *vdoomed)
 
static void unbound_resolver_destroy (void *obj)
 Destructor for unbound resolver. More...
 
static int unbound_resolver_resolve (struct ast_dns_query *query)
 
static int unbound_resolver_start (struct unbound_resolver *resolver)
 Start function for the unbound resolver. More...
 
static void unbound_resolver_stop (struct unbound_resolver *resolver)
 Stop function for the unbound resolver. More...
 
static void * unbound_resolver_thread (void *data)
 Resolver thread which waits and handles results. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Unbound DNS Resolver Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct aco_type global_option
 An aco_type structure to link the "general" category to the unbound_global_config type. More...
 
static struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
static struct aco_file resolver_unbound_conf
 
struct ast_dns_resolver unbound_resolver
 

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1474 of file res_resolver_unbound.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1474 of file res_resolver_unbound.c.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( globals  )
static

A global object container that will contain the global_config that gets swapped out on reloads.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1474 of file res_resolver_unbound.c.

◆ CONFIG_INFO_STANDARD()

CONFIG_INFO_STANDARD ( cfg_info  ,
globals  ,
unbound_config_alloc  ,
files = ACO_FILES(&resolver_unbound_conf),
pre_apply_config = unbound_config_preapply_callback 
)

Register information about the configs being processed by this module.

◆ custom_nameserver_handler()

static int custom_nameserver_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 1409 of file res_resolver_unbound.c.

1410{
1411 struct unbound_global_config *global = obj;
1412
1413 if (!global->nameservers) {
1415 if (!global->nameservers) {
1416 return -1;
1417 }
1418 }
1419
1420 return ast_str_container_add(global->nameservers, var->value);
1421}
#define var
Definition: ast_expr2f.c:605
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition: strings.c:200
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition: strings.c:205
A structure to hold global configuration-related options.
static struct aco_type global
Definition: test_config.c:1445

References AO2_ALLOC_OPT_LOCK_NOLOCK, ast_str_container_add(), ast_str_container_alloc_options(), global, and var.

Referenced by load_module().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1423 of file res_resolver_unbound.c.

1424{
1425 struct ast_config *cfg;
1426 struct ast_flags cfg_flags = { 0, };
1427
1428 if (aco_info_init(&cfg_info)) {
1430 }
1431
1432 aco_option_register(&cfg_info, "hosts", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, hosts));
1433 aco_option_register(&cfg_info, "resolv", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, resolv));
1436 aco_option_register(&cfg_info, "ta_file", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, ta_file));
1437
1438 /* This purposely checks for a configuration file so we don't output an error message in ACO if one is not present */
1440 if (!cfg) {
1442 unload_module();
1444 }
1445 } else {
1446 ast_config_destroy(cfg);
1447 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
1448 unload_module();
1450 }
1451 }
1452
1454
1456
1457 AST_TEST_REGISTER(resolve_sync);
1458 AST_TEST_REGISTER(resolve_async);
1459 AST_TEST_REGISTER(resolve_sync_off_nominal);
1460 AST_TEST_REGISTER(resolve_async_off_nominal);
1461 AST_TEST_REGISTER(resolve_cancel_off_nominal);
1462 AST_TEST_REGISTER(resolve_naptr);
1463 AST_TEST_REGISTER(resolve_srv);
1464
1466}
@ ACO_EXACT
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Definition: module.h:464
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct aco_type * global_options[]
static struct aco_file resolver_unbound_conf
static int unbound_config_apply_default(void)
static int custom_nameserver_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static int unload_module(void)
static int debug
Global debug status.
Definition: res_xmpp.c:441
const char * filename
Structure used to handle boolean flags.
Definition: utils.h:199
struct ast_module * self
Definition: module.h:342
Structure for an unbound resolver.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

References ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, ast_config_destroy(), ast_config_load, ast_dns_resolver_register(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_module_shutdown_ref, AST_TEST_REGISTER, custom_nameserver_handler(), debug, aco_file::filename, FLDSET, global_options, OPT_STRINGFIELD_T, OPT_UINT_T, resolver_unbound_conf, ast_module_info::self, STRFLDSET, unbound_config_apply_default(), and unload_module().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1385 of file res_resolver_unbound.c.

1386{
1387 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
1389 }
1390
1391 return 0;
1392}
@ AST_MODULE_RELOAD_ERROR
Definition: module.h:113

References aco_process_config(), ACO_PROCESS_ERROR, and AST_MODULE_RELOAD_ERROR.

◆ unbound_config_alloc()

static void * unbound_config_alloc ( void  )
static

Allocate a unbound_config to hold a snapshot of the complete results of parsing a config.

Definition at line 365 of file res_resolver_unbound.c.

366{
367 struct unbound_config *cfg;
368
370 if (!cfg) {
371 return NULL;
372 }
373
374 /* Allocate/initialize memory */
377 if (!cfg->global) {
378 goto error;
379 }
380
381 if (ast_string_field_init(cfg->global, 128)) {
382 goto error;
383 }
384
385 return cfg;
386error:
387 ao2_ref(cfg, -1);
388 return NULL;
389}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void unbound_config_destructor(void *obj)
static void unbound_global_config_destructor(void *obj)
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
A container for config related information.
struct unbound_global_config * global
int error(const char *format,...)
Definition: utils/frame.c:999

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_string_field_init, error(), unbound_config::global, NULL, unbound_config_destructor(), and unbound_global_config_destructor().

Referenced by unbound_config_apply_default().

◆ unbound_config_apply_default()

static int unbound_config_apply_default ( void  )
static

Definition at line 472 of file res_resolver_unbound.c.

473{
474 struct unbound_config *cfg;
475
476 cfg = unbound_config_alloc();
477 if (!cfg) {
478 ast_log(LOG_ERROR, "Could not create default configuration for unbound resolver\n");
479 return -1;
480 }
481
482 aco_set_defaults(&global_option, "general", cfg->global);
483
484 if (unbound_config_preapply(cfg)) {
485 ao2_ref(cfg, -1);
486 return -1;
487 }
488
489 ast_verb(1, "Starting unbound resolver using default configuration\n");
490
492 ao2_ref(cfg, -1);
493
494 return 0;
495}
#define ast_log
Definition: astobj2.c:42
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
static struct console_pvt globals
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
#define LOG_ERROR
#define ast_verb(level,...)
static void * unbound_config_alloc(void)
Allocate a unbound_config to hold a snapshot of the complete results of parsing a config.
static int unbound_config_preapply(struct unbound_config *cfg)
static struct aco_type global_option
An aco_type structure to link the "general" category to the unbound_global_config type.

References aco_set_defaults(), ao2_global_obj_replace_unref, ao2_ref, ast_log, ast_verb, unbound_config::global, global_option, globals, LOG_ERROR, unbound_config_alloc(), and unbound_config_preapply().

Referenced by load_module().

◆ unbound_config_destructor()

static void unbound_config_destructor ( void *  obj)
static

Definition at line 339 of file res_resolver_unbound.c.

340{
341 struct unbound_config *cfg = obj;
342
343 ao2_cleanup(cfg->global);
344}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934

References ao2_cleanup, and unbound_config::global.

Referenced by unbound_config_alloc().

◆ unbound_config_preapply()

static int unbound_config_preapply ( struct unbound_config cfg)
static

Definition at line 391 of file res_resolver_unbound.c.

392{
393 int res = 0;
394
397 if (!cfg->global->state) {
398 ast_log(LOG_ERROR, "Could not allocate unbound resolver state structure\n");
399 return -1;
400 }
401
403 if (!cfg->global->state->resolver) {
404 ast_log(LOG_ERROR, "Could not create an unbound resolver\n");
405 return -1;
406 }
407
408 ub_ctx_debuglevel(cfg->global->state->resolver->context, cfg->global->debug);
409
410 if (!strcmp(cfg->global->hosts, "system")) {
411 res = ub_ctx_hosts(cfg->global->state->resolver->context, NULL);
412 } else if (!ast_strlen_zero(cfg->global->hosts)) {
413 res = ub_ctx_hosts(cfg->global->state->resolver->context, cfg->global->hosts);
414 }
415
416 if (res) {
417 ast_log(LOG_ERROR, "Failed to set hosts file to '%s' in unbound resolver: %s\n",
418 cfg->global->hosts, ub_strerror(res));
419 return -1;
420 }
421
422 if (cfg->global->nameservers) {
423 struct ao2_iterator it_nameservers;
424 char *nameserver;
425
426 it_nameservers = ao2_iterator_init(cfg->global->nameservers, 0);
427 while (!res && (nameserver = ao2_iterator_next(&it_nameservers))) {
428 res = ub_ctx_set_fwd(cfg->global->state->resolver->context, nameserver);
429
430 if (res) {
431 ast_log(LOG_ERROR, "Failed to add nameserver '%s' to unbound resolver: %s\n",
432 nameserver, ub_strerror(res));
433 }
434 ao2_ref(nameserver, -1);
435 }
436 ao2_iterator_destroy(&it_nameservers);
437 if (res) {
438 return -1;
439 }
440 }
441
442 if (!strcmp(cfg->global->resolv, "system")) {
443 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, NULL);
444 } else if (!ast_strlen_zero(cfg->global->resolv)) {
445 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, cfg->global->resolv);
446 }
447
448 if (res) {
449 ast_log(LOG_ERROR, "Failed to set resolv.conf file to '%s' in unbound resolver: %s\n",
450 cfg->global->resolv, ub_strerror(res));
451 return -1;
452 }
453
454 if (!ast_strlen_zero(cfg->global->ta_file)) {
455 res = ub_ctx_add_ta_file(cfg->global->state->resolver->context, cfg->global->ta_file);
456
457 if (res) {
458 ast_log(LOG_ERROR, "Failed to set trusted anchor file to '%s' in unbound resolver: %s\n",
459 cfg->global->ta_file, ub_strerror(res));
460 return -1;
461 }
462 }
463
465 ast_log(LOG_ERROR, "Could not start unbound resolver thread\n");
466 return -1;
467 }
468
469 return 0;
470}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static struct unbound_resolver * unbound_resolver_alloc(void)
Allocator for unbound resolver.
static int unbound_resolver_start(struct unbound_resolver *resolver)
Start function for the unbound resolver.
static void unbound_config_state_destructor(void *obj)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct unbound_resolver * resolver
The configured resolver.
struct unbound_config_state * state
State information.
const ast_string_field resolv
unsigned int debug
Debug level for the resolver.
struct ao2_container * nameservers
List of nameservers (in order) to use for queries.
const ast_string_field hosts
const ast_string_field ta_file
struct ub_ctx * context
Resolver context itself.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, ast_strlen_zero(), unbound_resolver::context, unbound_global_config::debug, unbound_config::global, unbound_global_config::hosts, LOG_ERROR, unbound_global_config::nameservers, NULL, unbound_global_config::resolv, unbound_config_state::resolver, unbound_global_config::state, unbound_global_config::ta_file, unbound_config_state_destructor(), unbound_resolver_alloc(), and unbound_resolver_start().

Referenced by unbound_config_apply_default(), and unbound_config_preapply_callback().

◆ unbound_config_preapply_callback()

static int unbound_config_preapply_callback ( void  )
static

Finish initializing new configuration.

Definition at line 497 of file res_resolver_unbound.c.

498{
500}
void * aco_pending_config(struct aco_info *info)
Get pending config changes.

References aco_pending_config(), and unbound_config_preapply().

◆ unbound_config_state_destructor()

static void unbound_config_state_destructor ( void *  obj)
static

Definition at line 355 of file res_resolver_unbound.c.

356{
357 struct unbound_config_state *state = obj;
358
359 if (state->resolver) {
360 unbound_resolver_stop(state->resolver);
361 ao2_ref(state->resolver, -1);
362 }
363}
static void unbound_resolver_stop(struct unbound_resolver *resolver)
Stop function for the unbound resolver.
Unbound configuration state information.

References ao2_ref, and unbound_resolver_stop().

Referenced by unbound_config_preapply().

◆ unbound_global_config_destructor()

static void unbound_global_config_destructor ( void *  obj)
static

Definition at line 346 of file res_resolver_unbound.c.

347{
348 struct unbound_global_config *global = obj;
349
351 ao2_cleanup(global->nameservers);
352 ao2_cleanup(global->state);
353}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ao2_cleanup, ast_string_field_free_memory, and global.

Referenced by unbound_config_alloc().

◆ unbound_resolver_alloc()

static struct unbound_resolver * unbound_resolver_alloc ( void  )
static

Allocator for unbound resolver.

Definition at line 171 of file res_resolver_unbound.c.

172{
173 struct unbound_resolver *resolver;
174
176 if (!resolver) {
177 return NULL;
178 }
179
180 resolver->thread = AST_PTHREADT_NULL;
181
182 resolver->context = ub_ctx_create();
183 if (!resolver->context) {
184 ao2_ref(resolver, -1);
185 return NULL;
186 }
187
188 /* Each async result should be invoked in a separate thread so others are not blocked */
189 ub_ctx_async(resolver->context, 1);
190
191 return resolver;
192}
#define AST_PTHREADT_NULL
Definition: lock.h:66
static void unbound_resolver_destroy(void *obj)
Destructor for unbound resolver.
pthread_t thread
Thread handling the resolver.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, AST_PTHREADT_NULL, unbound_resolver::context, NULL, unbound_resolver::thread, and unbound_resolver_destroy().

Referenced by unbound_config_preapply().

◆ unbound_resolver_callback()

static void unbound_resolver_callback ( void *  data,
int  err,
struct ub_result *  ub_result 
)
static

Callback invoked when resolution completes on a query.

Definition at line 256 of file res_resolver_unbound.c.

257{
258 struct ast_dns_query *query = data;
259
260 if (!ast_dns_resolver_set_result(query, ub_result->secure, ub_result->bogus, ub_result->rcode,
261 S_OR(ub_result->canonname, ast_dns_query_get_name(query)), ub_result->answer_packet, ub_result->answer_len)) {
262 int i;
263 char *result_data;
264
265 for (i = 0; (result_data = ub_result->data[i]); i++) {
266 if (ast_dns_resolver_add_record(query, ub_result->qtype, ub_result->qclass, ub_result->ttl,
267 result_data, ub_result->len[i])) {
268 break;
269 }
270 }
271 }
272
274 ao2_ref(query, -1);
275 ub_resolve_free(ub_result);
276}
const char * ast_dns_query_get_name(const struct ast_dns_query *query)
Get the name queried in a DNS query.
Definition: dns_core.c:57
int ast_dns_resolver_set_result(struct ast_dns_query *query, unsigned int secure, unsigned int bogus, unsigned int rcode, const char *canonical, const char *answer, size_t answer_size)
Set result information for a DNS query.
Definition: dns_core.c:456
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
Definition: dns_core.c:599
int ast_dns_resolver_add_record(struct ast_dns_query *query, int rr_type, int rr_class, int ttl, const char *data, const size_t size)
Add a DNS record to the result of a DNS query.
Definition: dns_core.c:535
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
A DNS query.
Definition: dns_internal.h:137

References ao2_ref, ast_dns_query_get_name(), ast_dns_resolver_add_record(), ast_dns_resolver_completed(), ast_dns_resolver_set_result(), and S_OR.

Referenced by unbound_resolver_resolve().

◆ unbound_resolver_cancel()

static int unbound_resolver_cancel ( struct ast_dns_query query)
static

Definition at line 316 of file res_resolver_unbound.c.

317{
319 int res;
320
321 res = ub_cancel(data->resolver->context, data->id);
322 if (!res) {
323 /* When this query was started we bumped the ref, now that it has been cancelled we have ownership and
324 * need to drop it
325 */
326 ao2_ref(query, -1);
327 }
328
329 return res;
330}
void * ast_dns_resolver_get_data(const struct ast_dns_query *query)
Retrieve resolver specific data.
Definition: dns_core.c:451
Structure for query resolver data.
int id
ID for the specific query.
struct unbound_resolver * resolver
The resolver in use for the query.

References ao2_ref, ast_dns_resolver_get_data(), unbound_resolver::context, unbound_resolver_data::id, and unbound_resolver_data::resolver.

◆ unbound_resolver_data_dtor()

static void unbound_resolver_data_dtor ( void *  vdoomed)
static

Definition at line 278 of file res_resolver_unbound.c.

279{
280 struct unbound_resolver_data *doomed = vdoomed;
281
282 ao2_cleanup(doomed->resolver);
283}

References ao2_cleanup, and unbound_resolver_data::resolver.

Referenced by unbound_resolver_resolve().

◆ unbound_resolver_destroy()

static void unbound_resolver_destroy ( void *  obj)
static

Destructor for unbound resolver.

Definition at line 161 of file res_resolver_unbound.c.

162{
163 struct unbound_resolver *resolver = obj;
164
165 if (resolver->context) {
166 ub_ctx_delete(resolver->context);
167 }
168}

References unbound_resolver::context.

Referenced by unbound_resolver_alloc().

◆ unbound_resolver_resolve()

static int unbound_resolver_resolve ( struct ast_dns_query query)
static

Definition at line 285 of file res_resolver_unbound.c.

286{
288 struct unbound_resolver_data *data;
289 int res;
290
291 data = ao2_alloc_options(sizeof(*data), unbound_resolver_data_dtor,
293 if (!data) {
294 ast_log(LOG_ERROR, "Failed to allocate resolver data for resolution of '%s'\n",
296 return -1;
297 }
298 data->resolver = ao2_bump(cfg->global->state->resolver);
299 ast_dns_resolver_set_data(query, data);
300
301 res = ub_resolve_async(data->resolver->context, ast_dns_query_get_name(query),
303 ao2_bump(query), unbound_resolver_callback, &data->id);
304
305 if (res) {
306 ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n",
308 ao2_ref(query, -1);
309 }
310
311 ao2_ref(data, -1);
312 ao2_ref(cfg, -1);
313 return res;
314}
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
int ast_dns_query_get_rr_type(const struct ast_dns_query *query)
Get the record resource type of a DNS query.
Definition: dns_core.c:62
int ast_dns_query_get_rr_class(const struct ast_dns_query *query)
Get the record resource class of a DNS query.
Definition: dns_core.c:67
int ast_dns_resolver_set_data(struct ast_dns_query *query, void *data)
Set resolver specific data on a query.
Definition: dns_core.c:440
static void unbound_resolver_callback(void *data, int err, struct ub_result *ub_result)
Callback invoked when resolution completes on a query.
static void unbound_resolver_data_dtor(void *vdoomed)

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_global_obj_ref, ao2_ref, ast_dns_query_get_name(), ast_dns_query_get_rr_class(), ast_dns_query_get_rr_type(), ast_dns_resolver_set_data(), ast_log, unbound_resolver::context, unbound_config::global, globals, unbound_resolver_data::id, LOG_ERROR, unbound_resolver_data::resolver, unbound_config_state::resolver, unbound_global_config::state, unbound_resolver_callback(), and unbound_resolver_data_dtor().

◆ unbound_resolver_start()

static int unbound_resolver_start ( struct unbound_resolver resolver)
static

Start function for the unbound resolver.

Definition at line 217 of file res_resolver_unbound.c.

218{
219 int res;
220
221 if (resolver->thread != AST_PTHREADT_NULL) {
222 return 0;
223 }
224
225 ast_debug(1, "Starting thread for unbound resolver\n");
226
227 res = ast_pthread_create(&resolver->thread, NULL, unbound_resolver_thread, ao2_bump(resolver));
228 if (res) {
229 ast_debug(1, "Could not start thread for unbound resolver\n");
230 ao2_ref(resolver, -1);
231 }
232
233 return res;
234}
#define ast_debug(level,...)
Log a DEBUG message.
static void * unbound_resolver_thread(void *data)
Resolver thread which waits and handles results.
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584

References ao2_bump, ao2_ref, ast_debug, ast_pthread_create, AST_PTHREADT_NULL, NULL, unbound_resolver::thread, and unbound_resolver_thread().

Referenced by unbound_config_preapply().

◆ unbound_resolver_stop()

static void unbound_resolver_stop ( struct unbound_resolver resolver)
static

Stop function for the unbound resolver.

Definition at line 237 of file res_resolver_unbound.c.

238{
239 pthread_t thread;
240
241 if (resolver->thread == AST_PTHREADT_NULL) {
242 return;
243 }
244
245 ast_debug(1, "Stopping processing thread for unbound resolver\n");
246
247 thread = resolver->thread;
248 resolver->thread = AST_PTHREADT_STOP;
249 pthread_kill(thread, SIGURG);
250 pthread_join(thread, NULL);
251
252 ast_debug(1, "Stopped processing thread for unbound resolver\n");
253}
pthread_t thread
Definition: app_sla.c:329
#define AST_PTHREADT_STOP
Definition: lock.h:67

References ast_debug, AST_PTHREADT_NULL, AST_PTHREADT_STOP, NULL, thread, and unbound_resolver::thread.

Referenced by unbound_config_state_destructor().

◆ unbound_resolver_thread()

static void * unbound_resolver_thread ( void *  data)
static

Resolver thread which waits and handles results.

Definition at line 195 of file res_resolver_unbound.c.

196{
197 struct unbound_resolver *resolver = data;
198
199 ast_debug(1, "Starting processing for unbound resolver\n");
200
201 while (resolver->thread != AST_PTHREADT_STOP) {
202 /* Wait for any results to come in */
203 ast_wait_for_input(ub_fd(resolver->context), -1);
204
205 /* Finally process any results */
206 ub_process(resolver->context);
207 }
208
209 ast_debug(1, "Terminating processing for unbound resolver\n");
210
211 ao2_ref(resolver, -1);
212
213 return NULL;
214}
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1698

References ao2_ref, ast_debug, AST_PTHREADT_STOP, ast_wait_for_input(), unbound_resolver::context, NULL, and unbound_resolver::thread.

Referenced by unbound_resolver_start().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1394 of file res_resolver_unbound.c.

1395{
1396 aco_info_destroy(&cfg_info);
1398
1399 AST_TEST_UNREGISTER(resolve_sync);
1400 AST_TEST_UNREGISTER(resolve_async);
1401 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1402 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1403 AST_TEST_UNREGISTER(resolve_cancel_off_nominal);
1404 AST_TEST_UNREGISTER(resolve_naptr);
1405 AST_TEST_UNREGISTER(resolve_srv);
1406 return 0;
1407}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

References aco_info_destroy(), ao2_global_obj_release, AST_TEST_UNREGISTER, and globals.

Referenced by load_module().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Unbound DNS Resolver Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, }
static

Definition at line 1474 of file res_resolver_unbound.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1474 of file res_resolver_unbound.c.

◆ global_option

struct aco_type global_option
static

An aco_type structure to link the "general" category to the unbound_global_config type.

Definition at line 130 of file res_resolver_unbound.c.

Referenced by unbound_config_apply_default().

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)
static

Definition at line 138 of file res_resolver_unbound.c.

Referenced by load_module().

◆ resolver_unbound_conf

struct aco_file resolver_unbound_conf
static
Initial value:
= {
.filename = "resolver_unbound.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.

Definition at line 140 of file res_resolver_unbound.c.

Referenced by load_module().

◆ unbound_resolver

Definition at line 332 of file res_resolver_unbound.c.