Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 1507 of file res_resolver_unbound.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1507 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 1507 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 1442 of file res_resolver_unbound.c.

1443{
1444 struct unbound_global_config *global = obj;
1445
1446 if (!global->nameservers) {
1448 if (!global->nameservers) {
1449 return -1;
1450 }
1451 }
1452
1453 return ast_str_container_add(global->nameservers, var->value);
1454}
#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 1456 of file res_resolver_unbound.c.

1457{
1458 struct ast_config *cfg;
1459 struct ast_flags cfg_flags = { 0, };
1460
1461 if (aco_info_init(&cfg_info)) {
1463 }
1464
1465 aco_option_register(&cfg_info, "hosts", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, hosts));
1466 aco_option_register(&cfg_info, "resolv", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, resolv));
1469 aco_option_register(&cfg_info, "ta_file", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, ta_file));
1470
1471 /* This purposely checks for a configuration file so we don't output an error message in ACO if one is not present */
1473 if (!cfg) {
1475 unload_module();
1477 }
1478 } else {
1479 ast_config_destroy(cfg);
1480 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
1481 unload_module();
1483 }
1484 }
1485
1487
1489
1490 AST_TEST_REGISTER(resolve_sync);
1491 AST_TEST_REGISTER(resolve_async);
1492 AST_TEST_REGISTER(resolve_sync_off_nominal);
1493 AST_TEST_REGISTER(resolve_async_off_nominal);
1494 AST_TEST_REGISTER(resolve_cancel_off_nominal);
1495 AST_TEST_REGISTER(resolve_naptr);
1496 AST_TEST_REGISTER(resolve_srv);
1497
1499}
@ 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:632
#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:478
@ 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:570
const char * filename
Structure used to handle boolean flags.
Definition: utils.h:199
struct ast_module * self
Definition: module.h:356
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 1418 of file res_resolver_unbound.c.

1419{
1420 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
1422 }
1423
1424 return 0;
1425}
@ 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 391 of file res_resolver_unbound.c.

392{
393 struct unbound_config *cfg;
394
396 if (!cfg) {
397 return NULL;
398 }
399
400 /* Allocate/initialize memory */
403 if (!cfg->global) {
404 goto error;
405 }
406
407 if (ast_string_field_init(cfg->global, 128)) {
408 goto error;
409 }
410
411 return cfg;
412error:
413 ao2_ref(cfg, -1);
414 return NULL;
415}
#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 498 of file res_resolver_unbound.c.

499{
500 struct unbound_config *cfg;
501
502 cfg = unbound_config_alloc();
503 if (!cfg) {
504 ast_log(LOG_ERROR, "Could not create default configuration for unbound resolver\n");
505 return -1;
506 }
507
508 aco_set_defaults(&global_option, "general", cfg->global);
509
510 if (unbound_config_preapply(cfg)) {
511 ao2_ref(cfg, -1);
512 return -1;
513 }
514
515 ast_verb(1, "Starting unbound resolver using default configuration\n");
516
518 ao2_ref(cfg, -1);
519
520 return 0;
521}
#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 365 of file res_resolver_unbound.c.

366{
367 struct unbound_config *cfg = obj;
368
369 ao2_cleanup(cfg->global);
370}
#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 417 of file res_resolver_unbound.c.

418{
419 int res = 0;
420
423 if (!cfg->global->state) {
424 ast_log(LOG_ERROR, "Could not allocate unbound resolver state structure\n");
425 return -1;
426 }
427
429 if (!cfg->global->state->resolver) {
430 ast_log(LOG_ERROR, "Could not create an unbound resolver\n");
431 return -1;
432 }
433
434 ub_ctx_debuglevel(cfg->global->state->resolver->context, cfg->global->debug);
435
436 if (!strcmp(cfg->global->hosts, "system")) {
437 res = ub_ctx_hosts(cfg->global->state->resolver->context, NULL);
438 } else if (!ast_strlen_zero(cfg->global->hosts)) {
439 res = ub_ctx_hosts(cfg->global->state->resolver->context, cfg->global->hosts);
440 }
441
442 if (res) {
443 ast_log(LOG_ERROR, "Failed to set hosts file to '%s' in unbound resolver: %s\n",
444 cfg->global->hosts, ub_strerror(res));
445 return -1;
446 }
447
448 if (cfg->global->nameservers) {
449 struct ao2_iterator it_nameservers;
450 char *nameserver;
451
452 it_nameservers = ao2_iterator_init(cfg->global->nameservers, 0);
453 while (!res && (nameserver = ao2_iterator_next(&it_nameservers))) {
454 res = ub_ctx_set_fwd(cfg->global->state->resolver->context, nameserver);
455
456 if (res) {
457 ast_log(LOG_ERROR, "Failed to add nameserver '%s' to unbound resolver: %s\n",
458 nameserver, ub_strerror(res));
459 }
460 ao2_ref(nameserver, -1);
461 }
462 ao2_iterator_destroy(&it_nameservers);
463 if (res) {
464 return -1;
465 }
466 }
467
468 if (!strcmp(cfg->global->resolv, "system")) {
469 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, NULL);
470 } else if (!ast_strlen_zero(cfg->global->resolv)) {
471 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, cfg->global->resolv);
472 }
473
474 if (res) {
475 ast_log(LOG_ERROR, "Failed to set resolv.conf file to '%s' in unbound resolver: %s\n",
476 cfg->global->resolv, ub_strerror(res));
477 return -1;
478 }
479
480 if (!ast_strlen_zero(cfg->global->ta_file)) {
481 res = ub_ctx_add_ta_file(cfg->global->state->resolver->context, cfg->global->ta_file);
482
483 if (res) {
484 ast_log(LOG_ERROR, "Failed to set trusted anchor file to '%s' in unbound resolver: %s\n",
485 cfg->global->ta_file, ub_strerror(res));
486 return -1;
487 }
488 }
489
491 ast_log(LOG_ERROR, "Could not start unbound resolver thread\n");
492 return -1;
493 }
494
495 return 0;
496}
#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 523 of file res_resolver_unbound.c.

524{
526}
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 381 of file res_resolver_unbound.c.

382{
383 struct unbound_config_state *state = obj;
384
385 if (state->resolver) {
386 unbound_resolver_stop(state->resolver);
387 ao2_ref(state->resolver, -1);
388 }
389}
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 372 of file res_resolver_unbound.c.

373{
374 struct unbound_global_config *global = obj;
375
377 ao2_cleanup(global->nameservers);
378 ao2_cleanup(global->state);
379}
#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 189 of file res_resolver_unbound.c.

190{
191 struct unbound_resolver *resolver;
192
194 if (!resolver) {
195 return NULL;
196 }
197
198 resolver->thread = AST_PTHREADT_NULL;
199
200 resolver->context = ub_ctx_create();
201 if (!resolver->context) {
202 ao2_ref(resolver, -1);
203 return NULL;
204 }
205
206 /* Each async result should be invoked in a separate thread so others are not blocked */
207 ub_ctx_async(resolver->context, 1);
208
209 return resolver;
210}
#define AST_PTHREADT_NULL
Definition: lock.h:70
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 274 of file res_resolver_unbound.c.

275{
276 struct ast_dns_query *query = data;
277
278 if (!ub_result) {
279 ast_debug(3, "Badly formatted DNS query '%s'\n", ast_dns_query_get_name(query));
280 ast_dns_resolver_set_result(query, 0, 0, ns_r_formerr, ast_dns_query_get_name(query), "", 0);
282 ao2_ref(query, -1);
283 return;
284 }
285
286 if (!ast_dns_resolver_set_result(query, ub_result->secure, ub_result->bogus, ub_result->rcode,
287 S_OR(ub_result->canonname, ast_dns_query_get_name(query)), ub_result->answer_packet, ub_result->answer_len)) {
288 int i;
289 char *result_data;
290
291 for (i = 0; (result_data = ub_result->data[i]); i++) {
292 if (ast_dns_resolver_add_record(query, ub_result->qtype, ub_result->qclass, ub_result->ttl,
293 result_data, ub_result->len[i])) {
294 break;
295 }
296 }
297 }
298
300 ao2_ref(query, -1);
301 ub_resolve_free(ub_result);
302}
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 ast_debug(level,...)
Log a DEBUG message.
#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_debug, 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 342 of file res_resolver_unbound.c.

343{
345 int res;
346
347 res = ub_cancel(data->resolver->context, data->id);
348 if (!res) {
349 /* When this query was started we bumped the ref, now that it has been cancelled we have ownership and
350 * need to drop it
351 */
352 ao2_ref(query, -1);
353 }
354
355 return res;
356}
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 304 of file res_resolver_unbound.c.

305{
306 struct unbound_resolver_data *doomed = vdoomed;
307
308 ao2_cleanup(doomed->resolver);
309}

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 179 of file res_resolver_unbound.c.

180{
181 struct unbound_resolver *resolver = obj;
182
183 if (resolver->context) {
184 ub_ctx_delete(resolver->context);
185 }
186}

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 311 of file res_resolver_unbound.c.

312{
314 struct unbound_resolver_data *data;
315 int res;
316
317 data = ao2_alloc_options(sizeof(*data), unbound_resolver_data_dtor,
319 if (!data) {
320 ast_log(LOG_ERROR, "Failed to allocate resolver data for resolution of '%s'\n",
322 return -1;
323 }
324 data->resolver = ao2_bump(cfg->global->state->resolver);
325 ast_dns_resolver_set_data(query, data);
326
327 res = ub_resolve_async(data->resolver->context, ast_dns_query_get_name(query),
329 ao2_bump(query), unbound_resolver_callback, &data->id);
330
331 if (res) {
332 ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n",
334 ao2_ref(query, -1);
335 }
336
337 ao2_ref(data, -1);
338 ao2_ref(cfg, -1);
339 return res;
340}
#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 235 of file res_resolver_unbound.c.

236{
237 int res;
238
239 if (resolver->thread != AST_PTHREADT_NULL) {
240 return 0;
241 }
242
243 ast_debug(1, "Starting thread for unbound resolver\n");
244
245 res = ast_pthread_create(&resolver->thread, NULL, unbound_resolver_thread, ao2_bump(resolver));
246 if (res) {
247 ast_debug(1, "Could not start thread for unbound resolver\n");
248 ao2_ref(resolver, -1);
249 }
250
251 return res;
252}
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 255 of file res_resolver_unbound.c.

256{
257 pthread_t thread;
258
259 if (resolver->thread == AST_PTHREADT_NULL) {
260 return;
261 }
262
263 ast_debug(1, "Stopping processing thread for unbound resolver\n");
264
265 thread = resolver->thread;
266 resolver->thread = AST_PTHREADT_STOP;
267 pthread_kill(thread, SIGURG);
268 pthread_join(thread, NULL);
269
270 ast_debug(1, "Stopped processing thread for unbound resolver\n");
271}
pthread_t thread
Definition: app_sla.c:335
#define AST_PTHREADT_STOP
Definition: lock.h:71

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 213 of file res_resolver_unbound.c.

214{
215 struct unbound_resolver *resolver = data;
216
217 ast_debug(1, "Starting processing for unbound resolver\n");
218
219 while (resolver->thread != AST_PTHREADT_STOP) {
220 /* Wait for any results to come in */
221 ast_wait_for_input(ub_fd(resolver->context), -1);
222
223 /* Finally process any results */
224 ub_process(resolver->context);
225 }
226
227 ast_debug(1, "Terminating processing for unbound resolver\n");
228
229 ao2_ref(resolver, -1);
230
231 return NULL;
232}
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 1427 of file res_resolver_unbound.c.

1428{
1429 aco_info_destroy(&cfg_info);
1431
1432 AST_TEST_UNREGISTER(resolve_sync);
1433 AST_TEST_UNREGISTER(resolve_async);
1434 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1435 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1436 AST_TEST_UNREGISTER(resolve_cancel_off_nominal);
1437 AST_TEST_UNREGISTER(resolve_naptr);
1438 AST_TEST_UNREGISTER(resolve_srv);
1439 return 0;
1440}
#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 1507 of file res_resolver_unbound.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1507 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 148 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 156 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 158 of file res_resolver_unbound.c.

Referenced by load_module().

◆ unbound_resolver

Definition at line 358 of file res_resolver_unbound.c.