Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 1489 of file res_resolver_unbound.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

1425{
1426 struct unbound_global_config *global = obj;
1427
1428 if (!global->nameservers) {
1430 if (!global->nameservers) {
1431 return -1;
1432 }
1433 }
1434
1435 return ast_str_container_add(global->nameservers, var->value);
1436}
#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 1438 of file res_resolver_unbound.c.

1439{
1440 struct ast_config *cfg;
1441 struct ast_flags cfg_flags = { 0, };
1442
1443 if (aco_info_init(&cfg_info)) {
1445 }
1446
1447 aco_option_register(&cfg_info, "hosts", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, hosts));
1448 aco_option_register(&cfg_info, "resolv", ACO_EXACT, global_options, "system", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, resolv));
1451 aco_option_register(&cfg_info, "ta_file", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct unbound_global_config, ta_file));
1452
1453 /* This purposely checks for a configuration file so we don't output an error message in ACO if one is not present */
1455 if (!cfg) {
1457 unload_module();
1459 }
1460 } else {
1461 ast_config_destroy(cfg);
1462 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
1463 unload_module();
1465 }
1466 }
1467
1469
1471
1472 AST_TEST_REGISTER(resolve_sync);
1473 AST_TEST_REGISTER(resolve_async);
1474 AST_TEST_REGISTER(resolve_sync_off_nominal);
1475 AST_TEST_REGISTER(resolve_async_off_nominal);
1476 AST_TEST_REGISTER(resolve_cancel_off_nominal);
1477 AST_TEST_REGISTER(resolve_naptr);
1478 AST_TEST_REGISTER(resolve_srv);
1479
1481}
@ 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:441
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 1400 of file res_resolver_unbound.c.

1401{
1402 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
1404 }
1405
1406 return 0;
1407}
@ 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 373 of file res_resolver_unbound.c.

374{
375 struct unbound_config *cfg;
376
378 if (!cfg) {
379 return NULL;
380 }
381
382 /* Allocate/initialize memory */
385 if (!cfg->global) {
386 goto error;
387 }
388
389 if (ast_string_field_init(cfg->global, 128)) {
390 goto error;
391 }
392
393 return cfg;
394error:
395 ao2_ref(cfg, -1);
396 return NULL;
397}
#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 480 of file res_resolver_unbound.c.

481{
482 struct unbound_config *cfg;
483
484 cfg = unbound_config_alloc();
485 if (!cfg) {
486 ast_log(LOG_ERROR, "Could not create default configuration for unbound resolver\n");
487 return -1;
488 }
489
490 aco_set_defaults(&global_option, "general", cfg->global);
491
492 if (unbound_config_preapply(cfg)) {
493 ao2_ref(cfg, -1);
494 return -1;
495 }
496
497 ast_verb(1, "Starting unbound resolver using default configuration\n");
498
500 ao2_ref(cfg, -1);
501
502 return 0;
503}
#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 347 of file res_resolver_unbound.c.

348{
349 struct unbound_config *cfg = obj;
350
351 ao2_cleanup(cfg->global);
352}
#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 399 of file res_resolver_unbound.c.

400{
401 int res = 0;
402
405 if (!cfg->global->state) {
406 ast_log(LOG_ERROR, "Could not allocate unbound resolver state structure\n");
407 return -1;
408 }
409
411 if (!cfg->global->state->resolver) {
412 ast_log(LOG_ERROR, "Could not create an unbound resolver\n");
413 return -1;
414 }
415
416 ub_ctx_debuglevel(cfg->global->state->resolver->context, cfg->global->debug);
417
418 if (!strcmp(cfg->global->hosts, "system")) {
419 res = ub_ctx_hosts(cfg->global->state->resolver->context, NULL);
420 } else if (!ast_strlen_zero(cfg->global->hosts)) {
421 res = ub_ctx_hosts(cfg->global->state->resolver->context, cfg->global->hosts);
422 }
423
424 if (res) {
425 ast_log(LOG_ERROR, "Failed to set hosts file to '%s' in unbound resolver: %s\n",
426 cfg->global->hosts, ub_strerror(res));
427 return -1;
428 }
429
430 if (cfg->global->nameservers) {
431 struct ao2_iterator it_nameservers;
432 char *nameserver;
433
434 it_nameservers = ao2_iterator_init(cfg->global->nameservers, 0);
435 while (!res && (nameserver = ao2_iterator_next(&it_nameservers))) {
436 res = ub_ctx_set_fwd(cfg->global->state->resolver->context, nameserver);
437
438 if (res) {
439 ast_log(LOG_ERROR, "Failed to add nameserver '%s' to unbound resolver: %s\n",
440 nameserver, ub_strerror(res));
441 }
442 ao2_ref(nameserver, -1);
443 }
444 ao2_iterator_destroy(&it_nameservers);
445 if (res) {
446 return -1;
447 }
448 }
449
450 if (!strcmp(cfg->global->resolv, "system")) {
451 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, NULL);
452 } else if (!ast_strlen_zero(cfg->global->resolv)) {
453 res = ub_ctx_resolvconf(cfg->global->state->resolver->context, cfg->global->resolv);
454 }
455
456 if (res) {
457 ast_log(LOG_ERROR, "Failed to set resolv.conf file to '%s' in unbound resolver: %s\n",
458 cfg->global->resolv, ub_strerror(res));
459 return -1;
460 }
461
462 if (!ast_strlen_zero(cfg->global->ta_file)) {
463 res = ub_ctx_add_ta_file(cfg->global->state->resolver->context, cfg->global->ta_file);
464
465 if (res) {
466 ast_log(LOG_ERROR, "Failed to set trusted anchor file to '%s' in unbound resolver: %s\n",
467 cfg->global->ta_file, ub_strerror(res));
468 return -1;
469 }
470 }
471
473 ast_log(LOG_ERROR, "Could not start unbound resolver thread\n");
474 return -1;
475 }
476
477 return 0;
478}
#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 505 of file res_resolver_unbound.c.

506{
508}
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 363 of file res_resolver_unbound.c.

364{
365 struct unbound_config_state *state = obj;
366
367 if (state->resolver) {
368 unbound_resolver_stop(state->resolver);
369 ao2_ref(state->resolver, -1);
370 }
371}
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 354 of file res_resolver_unbound.c.

355{
356 struct unbound_global_config *global = obj;
357
359 ao2_cleanup(global->nameservers);
360 ao2_cleanup(global->state);
361}
#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 (!ub_result) {
261 ast_debug(3, "Badly formatted DNS query '%s'\n", ast_dns_query_get_name(query));
262 ast_dns_resolver_set_result(query, 0, 0, ns_r_formerr, ast_dns_query_get_name(query), "", 0);
264 ao2_ref(query, -1);
265 return;
266 }
267
268 if (!ast_dns_resolver_set_result(query, ub_result->secure, ub_result->bogus, ub_result->rcode,
269 S_OR(ub_result->canonname, ast_dns_query_get_name(query)), ub_result->answer_packet, ub_result->answer_len)) {
270 int i;
271 char *result_data;
272
273 for (i = 0; (result_data = ub_result->data[i]); i++) {
274 if (ast_dns_resolver_add_record(query, ub_result->qtype, ub_result->qclass, ub_result->ttl,
275 result_data, ub_result->len[i])) {
276 break;
277 }
278 }
279 }
280
282 ao2_ref(query, -1);
283 ub_resolve_free(ub_result);
284}
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 324 of file res_resolver_unbound.c.

325{
327 int res;
328
329 res = ub_cancel(data->resolver->context, data->id);
330 if (!res) {
331 /* When this query was started we bumped the ref, now that it has been cancelled we have ownership and
332 * need to drop it
333 */
334 ao2_ref(query, -1);
335 }
336
337 return res;
338}
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 286 of file res_resolver_unbound.c.

287{
288 struct unbound_resolver_data *doomed = vdoomed;
289
290 ao2_cleanup(doomed->resolver);
291}

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

294{
296 struct unbound_resolver_data *data;
297 int res;
298
299 data = ao2_alloc_options(sizeof(*data), unbound_resolver_data_dtor,
301 if (!data) {
302 ast_log(LOG_ERROR, "Failed to allocate resolver data for resolution of '%s'\n",
304 return -1;
305 }
306 data->resolver = ao2_bump(cfg->global->state->resolver);
307 ast_dns_resolver_set_data(query, data);
308
309 res = ub_resolve_async(data->resolver->context, ast_dns_query_get_name(query),
311 ao2_bump(query), unbound_resolver_callback, &data->id);
312
313 if (res) {
314 ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n",
316 ao2_ref(query, -1);
317 }
318
319 ao2_ref(data, -1);
320 ao2_ref(cfg, -1);
321 return res;
322}
#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}
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 1409 of file res_resolver_unbound.c.

1410{
1411 aco_info_destroy(&cfg_info);
1413
1414 AST_TEST_UNREGISTER(resolve_sync);
1415 AST_TEST_UNREGISTER(resolve_async);
1416 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1417 AST_TEST_UNREGISTER(resolve_sync_off_nominal);
1418 AST_TEST_UNREGISTER(resolve_cancel_off_nominal);
1419 AST_TEST_UNREGISTER(resolve_naptr);
1420 AST_TEST_UNREGISTER(resolve_srv);
1421 return 0;
1422}
#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 1489 of file res_resolver_unbound.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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