Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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.
 
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.
 
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.
 
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.
 
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.
 
static void unbound_resolver_callback (void *data, int err, struct ub_result *ub_result)
 Callback invoked when resolution completes on a query.
 
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.
 
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.
 
static void unbound_resolver_stop (struct unbound_resolver *resolver)
 Stop function for the unbound resolver.
 
static void * unbound_resolver_thread (void *data)
 Resolver thread which waits and handles results.
 
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 = ASTERISK_GPL_KEY , .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.
 
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

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:1287
#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:220
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.
A container for config related information.
struct unbound_global_config * global
int error(const char *format,...)

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

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:73
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.

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:624

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:74

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:1734

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 = ASTERISK_GPL_KEY , .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.

148 {
149 .type = ACO_GLOBAL,
150 .name = "general",
151 .item_offset = offsetof(struct unbound_config, global),
152 .category_match = ACO_WHITELIST_EXACT,
153 .category = "general",
154};
@ ACO_GLOBAL
@ ACO_WHITELIST_EXACT

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.

158 {
159 .filename = "resolver_unbound.conf",
160 .types = ACO_TYPES(&global_option),
161};

Referenced by load_module().

◆ unbound_resolver

Definition at line 358 of file res_resolver_unbound.c.

358 {
359 .name = "unbound",
360 .priority = 100,
361 .resolve = unbound_resolver_resolve,
362 .cancel = unbound_resolver_cancel,
363};
static int unbound_resolver_cancel(struct ast_dns_query *query)
static int unbound_resolver_resolve(struct ast_dns_query *query)