Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


dnsmgr.c File Reference

Background DNS update manager. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include <regex.h>
#include <signal.h>
#include "asterisk/dnsmgr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/config.h"
#include "asterisk/sched.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/acl.h"

Go to the source code of this file.

Data Structures

struct  ast_dnsmgr_entry
 
struct  entry_list
 
struct  refresh_info
 

Macros

#define REFRESH_DEFAULT   300
 

Functions

int ast_dnsmgr_changed (struct ast_dnsmgr_entry *entry)
 Check is see if a dnsmgr entry has changed. More...
 
struct ast_dnsmgr_entryast_dnsmgr_get (const char *name, struct ast_sockaddr *result, const char *service)
 Allocate a new DNS manager entry. More...
 
struct ast_dnsmgr_entryast_dnsmgr_get_family (const char *name, struct ast_sockaddr *result, const char *service, unsigned int family)
 Allocate a new DNS manager entry. More...
 
int ast_dnsmgr_lookup (const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
 Allocate and initialize a DNS manager entry. More...
 
int ast_dnsmgr_lookup_cb (const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
 Allocate and initialize a DNS manager entry, with update callback. More...
 
int ast_dnsmgr_refresh (struct ast_dnsmgr_entry *entry)
 Force a refresh of a dnsmgr entry. More...
 
void ast_dnsmgr_release (struct ast_dnsmgr_entry *entry)
 Free a DNS manager entry. More...
 
int dnsmgr_init (void)
 
static int dnsmgr_refresh (struct ast_dnsmgr_entry *entry, int verbose)
 
int dnsmgr_reload (void)
 
static void dnsmgr_shutdown (void)
 
void dnsmgr_start_refresh (void)
 
static void * do_refresh (void *data)
 
static int do_reload (int loading)
 
static char * handle_cli_refresh (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int internal_dnsmgr_lookup (const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
 
static int refresh_list (const void *data)
 

Variables

static struct ast_cli_entry cli_refresh = AST_CLI_DEFINE(handle_cli_refresh, "Performs an immediate refresh")
 
static struct ast_cli_entry cli_reload = AST_CLI_DEFINE(handle_cli_reload, "Reloads the DNS manager configuration")
 
static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the DNS manager status")
 
static int enabled
 
static struct entry_list entry_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct refresh_info master_refresh_info
 
static int refresh_interval
 
static ast_mutex_t refresh_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static int refresh_sched = -1
 
static pthread_t refresh_thread = AST_PTHREADT_NULL
 
static struct sched_contextsched
 

Detailed Description

Background DNS update manager.

Author
Kevin P. Fleming kpfle.nosp@m.ming.nosp@m.@digi.nosp@m.um.c.nosp@m.om
Bug:
There is a minor race condition. In the event that an IP address of a dnsmgr managed host changes, there is the potential for the consumer of that address to access the in_addr data at the same time that the dnsmgr thread is in the middle of updating it to the new address.

Definition in file dnsmgr.c.

Macro Definition Documentation

#define REFRESH_DEFAULT   300

Definition at line 79 of file dnsmgr.c.

Referenced by do_reload().

Function Documentation

int ast_dnsmgr_changed ( struct ast_dnsmgr_entry entry)

Check is see if a dnsmgr entry has changed.

Return values
non-zeroif the dnsmgr entry has changed since the last call to this function
zeroif the dnsmgr entry has not changed since the last call to this function

Definition at line 238 of file dnsmgr.c.

References ast_mutex_lock, ast_mutex_unlock, ast_dnsmgr_entry::changed, and ast_dnsmgr_entry::lock.

Referenced by iax2_do_register().

239 {
240  int changed;
241 
242  ast_mutex_lock(&entry->lock);
243 
244  changed = entry->changed;
245  entry->changed = 0;
246 
247  ast_mutex_unlock(&entry->lock);
248 
249  return changed;
250 }
ast_mutex_t lock
Definition: dnsmgr.c:69
#define ast_mutex_lock(a)
Definition: lock.h:155
unsigned int changed
Definition: dnsmgr.c:64
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_dnsmgr_entry* ast_dnsmgr_get ( const char *  name,
struct ast_sockaddr result,
const char *  service 
)

Allocate a new DNS manager entry.

Parameters
namethe hostname
resultwhere the DNS manager should store the IP address as it refreshes it.
service

This function allocates a new DNS manager entry object, and fills it with the provided hostname and IP address. This function does not force an initial lookup of the IP address. So, generally, this should be used when the initial address is already known.

Returns
a DNS manager entry
Version
1.6.1 result changed from struct in_addr to struct sockaddr_in to store port number
1.8.0 result changed from struct ast_sockaddr_in to ast_sockaddr for IPv6 support

Definition at line 121 of file dnsmgr.c.

References ast_dnsmgr_get_family().

122 {
123  return ast_dnsmgr_get_family(name, result, service, 0);
124 }
enum ast_cc_service_type service
Definition: chan_sip.c:821
static const char name[]
struct ast_dnsmgr_entry * ast_dnsmgr_get_family(const char *name, struct ast_sockaddr *result, const char *service, unsigned int family)
Allocate a new DNS manager entry.
Definition: dnsmgr.c:96
struct ast_dnsmgr_entry* ast_dnsmgr_get_family ( const char *  name,
struct ast_sockaddr result,
const char *  service,
unsigned int  family 
)

Allocate a new DNS manager entry.

Parameters
namethe hostname
resultwhere the DNS manager should store the IP address as it refreshes it.
service
familyAddress family to filter DNS addresses.

This function allocates a new DNS manager entry object, and fills it with the provided hostname and IP address. This function does not force an initial lookup of the IP address. So, generally, this should be used when the initial address is already known.

Returns
a DNS manager entry

Definition at line 96 of file dnsmgr.c.

References ast_calloc, ast_mutex_init, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), ast_dnsmgr_entry::family, ast_dnsmgr_entry::lock, ast_dnsmgr_entry::result, and ast_dnsmgr_entry::service.

Referenced by ast_dnsmgr_get(), and internal_dnsmgr_lookup().

97 {
98  struct ast_dnsmgr_entry *entry;
99  int total_size = sizeof(*entry) + strlen(name) + (service ? strlen(service) + 1 : 0);
100 
101  if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, total_size))) {
102  return NULL;
103  }
104 
105  entry->result = result;
106  ast_mutex_init(&entry->lock);
107  strcpy(entry->name, name);
108  if (service) {
109  entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
110  strcpy(entry->service, service);
111  }
112  entry->family = family;
113 
115  AST_RWLIST_INSERT_HEAD(&entry_list, entry, list);
117 
118  return entry;
119 }
ast_mutex_t lock
Definition: dnsmgr.c:69
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
enum ast_cc_service_type service
Definition: chan_sip.c:821
Definition: dnsmgr.c:56
unsigned int family
Definition: dnsmgr.c:62
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_sockaddr * result
Definition: dnsmgr.c:58
static const char name[]
#define ast_calloc(a, b)
Definition: astmm.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
char * service
Definition: dnsmgr.c:60
int ast_dnsmgr_lookup ( const char *  name,
struct ast_sockaddr result,
struct ast_dnsmgr_entry **  dnsmgr,
const char *  service 
)

Allocate and initialize a DNS manager entry.

Parameters
namethe hostname
resultwhere to store the IP address as the DNS manager refreshes it. The address family is used as an input parameter to filter the returned addresses. If it is 0, both IPv4 and IPv6 addresses can be returned.
dnsmgrWhere to store the allocate DNS manager entry
service
Note
This function allocates a new DNS manager entry object, and fills it with the provided hostname and IP address. This function does force an initial lookup, so it may block for some period of time.
Return values
0success
non-zerofailure
Version
1.6.1 result changed from struct in_addr to struct aockaddr_in to store port number

Definition at line 180 of file dnsmgr.c.

References internal_dnsmgr_lookup().

Referenced by build_peer(), and iax2_append_register().

181 {
182  return internal_dnsmgr_lookup(name, result, dnsmgr, service, NULL, NULL);
183 }
enum ast_cc_service_type service
Definition: chan_sip.c:821
static const char name[]
static int internal_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
Definition: dnsmgr.c:140
int ast_dnsmgr_lookup_cb ( const char *  name,
struct ast_sockaddr result,
struct ast_dnsmgr_entry **  dnsmgr,
const char *  service,
dns_update_func  func,
void *  data 
)

Allocate and initialize a DNS manager entry, with update callback.

Parameters
namethe hostname
resultThe addr which is intended to be updated in the update callback when DNS manager calls it on refresh. The address family is used as an input parameter to filter the returned addresses. If it is 0, both IPv4 and IPv6 addresses can be returned.
dnsmgrWhere to store the allocate DNS manager entry
service
funcThe update callback function The update callback will be called when DNS manager detects that an IP address has been changed. Instead of updating the addr itself, DNS manager will call this callback function with the old and new addresses. It is the responsibility of the callback to perform any updates
dataA pointer to data that will be passed through to the callback function
Note
This function allocates a new DNS manager entry object, and fills it with the provided hostname and IP address. This function does force an initial lookup, so it may block for some period of time.
Return values
0success
non-zerofailure

Definition at line 185 of file dnsmgr.c.

References internal_dnsmgr_lookup().

Referenced by __sip_subscribe_mwi_do(), build_peer(), and transmit_register().

186 {
187  return internal_dnsmgr_lookup(name, result, dnsmgr, service, func, data);
188 }
enum ast_cc_service_type service
Definition: chan_sip.c:821
void * data
Definition: dnsmgr.c:66
static const char name[]
static int internal_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
Definition: dnsmgr.c:140
int ast_dnsmgr_refresh ( struct ast_dnsmgr_entry entry)

Force a refresh of a dnsmgr entry.

Return values
non-zeroif the result is different than the previous result
zeroif the result is the same as the previous result

Definition at line 230 of file dnsmgr.c.

References dnsmgr_refresh().

Referenced by build_peer(), iax2_do_register(), and sip_reg_timeout().

231 {
232  return dnsmgr_refresh(entry, 0);
233 }
static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
Definition: dnsmgr.c:193
void ast_dnsmgr_release ( struct ast_dnsmgr_entry entry)

Free a DNS manager entry.

Parameters
entrythe DNS manager entry to free
Returns
nothing

Definition at line 126 of file dnsmgr.c.

References ast_free, ast_mutex_destroy, AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_dnsmgr_entry::lock.

Referenced by cleanup_all_regs(), delete_users(), match_and_cleanup_peer_sched(), peer_destructor(), and unload_module().

127 {
128  if (!entry)
129  return;
130 
132  AST_RWLIST_REMOVE(&entry_list, entry, list);
134  ast_verb(6, "removing dns manager for '%s'\n", entry->name);
135 
136  ast_mutex_destroy(&entry->lock);
137  ast_free(entry);
138 }
ast_mutex_t lock
Definition: dnsmgr.c:69
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
#define ast_mutex_destroy(a)
Definition: lock.h:154
int dnsmgr_init ( void  )

Provided by dnsmgr.c

Definition at line 417 of file dnsmgr.c.

References ast_cli_register(), ast_log(), ast_register_atexit(), cli_refresh, cli_reload, cli_status, dnsmgr_shutdown(), do_reload(), LOG_ERROR, and sched_context_create().

Referenced by main().

418 {
419  if (!(sched = sched_context_create())) {
420  ast_log(LOG_ERROR, "Unable to create schedule context.\n");
421  return -1;
422  }
426 
428 
429  return do_reload(1);
430 }
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static struct ast_cli_entry cli_reload
Definition: dnsmgr.c:393
Definition: sched.c:57
static struct ast_cli_entry cli_refresh
Definition: dnsmgr.c:394
static int do_reload(int loading)
Definition: dnsmgr.c:437
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static struct ast_cli_entry cli_status
Definition: dnsmgr.c:395
#define LOG_ERROR
Definition: logger.h:155
static void dnsmgr_shutdown(void)
Definition: dnsmgr.c:397
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
static int dnsmgr_refresh ( struct ast_dnsmgr_entry entry,
int  verbose 
)
static

Definition at line 193 of file dnsmgr.c.

References ast_get_ip_or_srv(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, ast_verb, ast_dnsmgr_entry::changed, ast_dnsmgr_entry::data, ast_dnsmgr_entry::family, ast_sockaddr::len, ast_dnsmgr_entry::lock, LOG_NOTICE, ast_dnsmgr_entry::result, ast_dnsmgr_entry::service, ast_sockaddr::ss, and ast_dnsmgr_entry::update_func.

Referenced by ast_dnsmgr_refresh(), and refresh_list().

194 {
195  struct ast_sockaddr tmp = { .len = 0, };
196  int changed = 0;
197 
198  ast_mutex_lock(&entry->lock);
199 
200  if (verbose) {
201  ast_verb(6, "refreshing '%s'\n", entry->name);
202  }
203 
204  tmp.ss.ss_family = entry->family;
205  if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service)) {
206  if (!ast_sockaddr_port(&tmp)) {
208  }
209  if (ast_sockaddr_cmp(&tmp, entry->result)) {
210  const char *old_addr = ast_strdupa(ast_sockaddr_stringify(entry->result));
211  const char *new_addr = ast_strdupa(ast_sockaddr_stringify(&tmp));
212 
213  if (entry->update_func) {
214  entry->update_func(entry->result, &tmp, entry->data);
215  } else {
216  ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s to %s\n",
217  entry->name, old_addr, new_addr);
218 
219  ast_sockaddr_copy(entry->result, &tmp);
220  changed = entry->changed = 1;
221  }
222  }
223  }
224 
225  ast_mutex_unlock(&entry->lock);
226 
227  return changed;
228 }
struct sockaddr_storage ss
Definition: netsock2.h:64
ast_mutex_t lock
Definition: dnsmgr.c:69
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
socklen_t len
Definition: netsock2.h:65
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
unsigned int family
Definition: dnsmgr.c:62
Socket address structure.
Definition: netsock2.h:63
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
dns_update_func update_func
Definition: dnsmgr.c:68
struct ast_sockaddr * result
Definition: dnsmgr.c:58
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void * data
Definition: dnsmgr.c:66
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Definition: acl.c:597
unsigned int changed
Definition: dnsmgr.c:64
#define ast_mutex_unlock(a)
Definition: lock.h:156
char * service
Definition: dnsmgr.c:60
int dnsmgr_reload ( void  )

Provided by dnsmgr.c

Definition at line 432 of file dnsmgr.c.

References do_reload().

433 {
434  return do_reload(0);
435 }
static int do_reload(int loading)
Definition: dnsmgr.c:437
static void dnsmgr_shutdown ( void  )
static

Definition at line 397 of file dnsmgr.c.

References ast_cli_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, cli_refresh, cli_reload, cli_status, and sched_context_destroy().

Referenced by dnsmgr_init().

398 {
402 
403  /* Destroy refresh thread. */
406  /* wake up the thread so it will exit */
407  pthread_cancel(refresh_thread);
408  pthread_kill(refresh_thread, SIGURG);
409  pthread_join(refresh_thread, NULL);
411  }
413 
415 }
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
static struct ast_cli_entry cli_reload
Definition: dnsmgr.c:393
Definition: sched.c:57
static pthread_t refresh_thread
Definition: dnsmgr.c:54
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct ast_cli_entry cli_refresh
Definition: dnsmgr.c:394
#define AST_PTHREADT_NULL
Definition: lock.h:65
static struct ast_cli_entry cli_status
Definition: dnsmgr.c:395
static ast_mutex_t refresh_lock
Definition: dnsmgr.c:77
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
#define ast_mutex_unlock(a)
Definition: lock.h:156
void dnsmgr_start_refresh ( void  )

Provided by dnsmgr.c

Definition at line 291 of file dnsmgr.c.

References ast_sched_add_variable(), AST_SCHED_DEL, master_refresh_info, and refresh_list().

Referenced by main().

292 {
293  if (refresh_sched > -1) {
296  }
297 }
static struct refresh_info master_refresh_info
Definition: dnsmgr.c:91
int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Schedule callback(data) to happen when ms into the future.
Definition: sched.c:406
Definition: sched.c:57
static int refresh_sched
Definition: dnsmgr.c:53
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
static int refresh_list(const void *data)
Definition: dnsmgr.c:263
static void* do_refresh ( void *  data)
static

Definition at line 252 of file dnsmgr.c.

References ast_sched_runq(), and ast_sched_wait().

Referenced by do_reload().

253 {
254  for (;;) {
255  pthread_testcancel();
256  usleep((ast_sched_wait(sched)*1000));
257  pthread_testcancel();
259  }
260  return NULL;
261 }
Definition: sched.c:57
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
static int do_reload ( int  loading)
static

Definition at line 437 of file dnsmgr.c.

References ast_config_destroy(), ast_config_load2(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, ast_sched_add_variable(), AST_SCHED_DEL, ast_true(), ast_variable_retrieve(), config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, do_refresh(), enabled, EVENT_FLAG_SYSTEM, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, master_refresh_info, REFRESH_DEFAULT, refresh_interval, and refresh_list().

Referenced by dnsmgr_init(), dnsmgr_reload(), and handle_cli_reload().

438 {
439  struct ast_config *config;
440  struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED };
441  const char *interval_value;
442  const char *enabled_value;
443  int interval;
444  int was_enabled;
445  int res = -1;
446 
447  config = ast_config_load2("dnsmgr.conf", "dnsmgr", config_flags);
448  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEUNCHANGED || config == CONFIG_STATUS_FILEINVALID) {
449  return 0;
450  }
451 
452  /* ensure that no refresh cycles run while the reload is in progress */
454 
455  /* reset defaults in preparation for reading config file */
457  was_enabled = enabled;
458  enabled = 0;
459 
461 
462  if (config) {
463  if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
464  enabled = ast_true(enabled_value);
465  }
466  if ((interval_value = ast_variable_retrieve(config, "general", "refreshinterval"))) {
467  if (sscanf(interval_value, "%30d", &interval) < 1)
468  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", interval_value);
469  else if (interval < 0)
470  ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval);
471  else
472  refresh_interval = interval;
473  }
474  ast_config_destroy(config);
475  }
476 
477  if (enabled && refresh_interval)
478  ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval);
479 
480  /* if this reload enabled the manager, create the background thread
481  if it does not exist */
482  if (enabled) {
483  if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) {
485  ast_log(LOG_ERROR, "Unable to start refresh thread.\n");
486  }
487  }
488  /* make a background refresh happen right away */
490  res = 0;
491  }
492  /* if this reload disabled the manager and there is a background thread,
493  kill it */
494  else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) {
495  /* wake up the thread so it will exit */
496  pthread_cancel(refresh_thread);
497  pthread_kill(refresh_thread, SIGURG);
498  pthread_join(refresh_thread, NULL);
500  res = 0;
501  }
502  else
503  res = 0;
504 
506  manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: DNSmgr\r\nStatus: %s\r/nMessage: DNSmgr reload Requested\r\n", enabled ? "Enabled" : "Disabled");
507 
508  return res;
509 }
static struct refresh_info master_refresh_info
Definition: dnsmgr.c:91
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static const char config[]
Definition: cdr_csv.c:57
int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Schedule callback(data) to happen when ms into the future.
Definition: sched.c:406
static int refresh_interval
Definition: dnsmgr.c:82
#define LOG_WARNING
Definition: logger.h:144
Definition: sched.c:57
#define REFRESH_DEFAULT
Definition: dnsmgr.c:79
static pthread_t refresh_thread
Definition: dnsmgr.c:54
static int refresh_sched
Definition: dnsmgr.c:53
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
#define AST_PTHREADT_NULL
Definition: lock.h:65
static ast_mutex_t refresh_lock
Definition: dnsmgr.c:77
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int refresh_list(const void *data)
Definition: dnsmgr.c:263
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
Structure used to handle boolean flags.
Definition: utils.h:200
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int enabled
Definition: cdr.c:91
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
static void * do_refresh(void *data)
Definition: dnsmgr.c:252
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_cli_refresh ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 320 of file dnsmgr.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, enabled, refresh_info::entries, entry_list, ast_cli_args::fd, refresh_info::filter, refresh_list(), refresh_info::regex_present, and ast_cli_entry::usage.

321 {
322  struct refresh_info info = {
323  .entries = &entry_list,
324  .verbose = 1,
325  };
326  switch (cmd) {
327  case CLI_INIT:
328  e->command = "dnsmgr refresh";
329  e->usage =
330  "Usage: dnsmgr refresh [pattern]\n"
331  " Peforms an immediate refresh of the managed DNS entries.\n"
332  " Optional regular expression pattern is used to filter the entries to refresh.\n";
333  return NULL;
334  case CLI_GENERATE:
335  return NULL;
336  }
337 
338  if (!enabled) {
339  ast_cli(a->fd, "DNS Manager is disabled.\n");
340  return 0;
341  }
342 
343  if (a->argc > 3) {
344  return CLI_SHOWUSAGE;
345  }
346 
347  if (a->argc == 3) {
348  if (regcomp(&info.filter, a->argv[2], REG_EXTENDED | REG_NOSUB)) {
349  return CLI_SHOWUSAGE;
350  } else {
351  info.regex_present = 1;
352  }
353  }
354 
355  refresh_list(&info);
356 
357  if (info.regex_present) {
358  regfree(&info.filter);
359  }
360 
361  return CLI_SUCCESS;
362 }
regex_t filter
Definition: dnsmgr.c:88
struct entry_list * entries
Definition: dnsmgr.c:85
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
unsigned int regex_present
Definition: dnsmgr.c:87
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int refresh_list(const void *data)
Definition: dnsmgr.c:263
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int enabled
Definition: cdr.c:91
static struct entry_list entry_list
static char* handle_cli_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 301 of file dnsmgr.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, do_reload(), and ast_cli_entry::usage.

302 {
303  switch (cmd) {
304  case CLI_INIT:
305  e->command = "dnsmgr reload";
306  e->usage =
307  "Usage: dnsmgr reload\n"
308  " Reloads the DNS manager configuration.\n";
309  return NULL;
310  case CLI_GENERATE:
311  return NULL;
312  }
313  if (a->argc > 2)
314  return CLI_SHOWUSAGE;
315 
316  do_reload(0);
317  return CLI_SUCCESS;
318 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static int do_reload(int loading)
Definition: dnsmgr.c:437
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 364 of file dnsmgr.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, enabled, ast_cli_args::fd, refresh_interval, and ast_cli_entry::usage.

365 {
366  int count = 0;
367  struct ast_dnsmgr_entry *entry;
368  switch (cmd) {
369  case CLI_INIT:
370  e->command = "dnsmgr status";
371  e->usage =
372  "Usage: dnsmgr status\n"
373  " Displays the DNS manager status.\n";
374  return NULL;
375  case CLI_GENERATE:
376  return NULL;
377  }
378 
379  if (a->argc > 2)
380  return CLI_SHOWUSAGE;
381 
382  ast_cli(a->fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled");
383  ast_cli(a->fd, "Refresh Interval: %d seconds\n", refresh_interval);
385  AST_RWLIST_TRAVERSE(&entry_list, entry, list)
386  count++;
388  ast_cli(a->fd, "Number of entries: %d\n", count);
389 
390  return CLI_SUCCESS;
391 }
static int refresh_interval
Definition: dnsmgr.c:82
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
Definition: dnsmgr.c:56
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int enabled
Definition: cdr.c:91
static int internal_dnsmgr_lookup ( const char *  name,
struct ast_sockaddr result,
struct ast_dnsmgr_entry **  dnsmgr,
const char *  service,
dns_update_func  func,
void *  data 
)
static

Definition at line 140 of file dnsmgr.c.

References ast_dnsmgr_get_family(), ast_get_ip_or_srv(), ast_sockaddr_parse(), ast_strlen_zero(), ast_verb, ast_dnsmgr_entry::data, enabled, ast_dnsmgr_entry::family, PARSE_PORT_FORBID, and ast_sockaddr::ss.

Referenced by ast_dnsmgr_lookup(), and ast_dnsmgr_lookup_cb().

141 {
142  unsigned int family;
143 
144  if (ast_strlen_zero(name) || !result || !dnsmgr) {
145  return -1;
146  }
147 
148  if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name)) {
149  return 0;
150  }
151 
152  /* Lookup address family filter. */
153  family = result->ss.ss_family;
154 
155  /*
156  * If it's actually an IP address and not a name, there's no
157  * need for a managed lookup.
158  */
159  if (ast_sockaddr_parse(result, name, PARSE_PORT_FORBID)) {
160  return 0;
161  }
162 
163  ast_verb(6, "doing dnsmgr_lookup for '%s'\n", name);
164 
165  /* do a lookup now but add a manager so it will automagically get updated in the background */
166  ast_get_ip_or_srv(result, name, service);
167 
168  /* if dnsmgr is not enable don't bother adding an entry */
169  if (!enabled) {
170  return 0;
171  }
172 
173  ast_verb(6, "adding dns manager for '%s'\n", name);
174  *dnsmgr = ast_dnsmgr_get_family(name, result, service, family);
175  (*dnsmgr)->update_func = func;
176  (*dnsmgr)->data = data;
177  return !*dnsmgr;
178 }
struct sockaddr_storage ss
Definition: netsock2.h:64
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:198
enum ast_cc_service_type service
Definition: chan_sip.c:821
unsigned int family
Definition: dnsmgr.c:62
#define ast_verb(level,...)
Definition: logger.h:243
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void * data
Definition: dnsmgr.c:66
static const char name[]
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Definition: acl.c:597
static int enabled
Definition: cdr.c:91
struct ast_dnsmgr_entry * ast_dnsmgr_get_family(const char *name, struct ast_sockaddr *result, const char *service, unsigned int family)
Allocate a new DNS manager entry.
Definition: dnsmgr.c:96
static int refresh_list ( const void *  data)
static

Definition at line 263 of file dnsmgr.c.

References ast_log(), ast_mutex_trylock, ast_mutex_unlock, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_verb, dnsmgr_refresh(), refresh_info::entries, refresh_info::filter, LOG_WARNING, refresh_interval, refresh_info::regex_present, and refresh_info::verbose.

Referenced by dnsmgr_start_refresh(), do_reload(), and handle_cli_refresh().

264 {
265  struct refresh_info *info = (struct refresh_info *)data;
266  struct ast_dnsmgr_entry *entry;
267 
268  /* if a refresh or reload is already in progress, exit now */
270  if (info->verbose)
271  ast_log(LOG_WARNING, "DNS Manager refresh already in progress.\n");
272  return -1;
273  }
274 
275  ast_verb(6, "Refreshing DNS lookups.\n");
276  AST_RWLIST_RDLOCK(info->entries);
277  AST_RWLIST_TRAVERSE(info->entries, entry, list) {
278  if (info->regex_present && regexec(&info->filter, entry->name, 0, NULL, 0))
279  continue;
280 
281  dnsmgr_refresh(entry, info->verbose);
282  }
283  AST_RWLIST_UNLOCK(info->entries);
284 
286 
287  /* automatically reschedule based on the interval */
288  return refresh_interval * 1000;
289 }
regex_t filter
Definition: dnsmgr.c:88
static int refresh_interval
Definition: dnsmgr.c:82
struct entry_list * entries
Definition: dnsmgr.c:85
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: dnsmgr.c:56
#define ast_verb(level,...)
Definition: logger.h:243
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_mutex_trylock(a)
Definition: lock.h:157
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
static ast_mutex_t refresh_lock
Definition: dnsmgr.c:77
unsigned int regex_present
Definition: dnsmgr.c:87
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
Definition: dnsmgr.c:193
int verbose
Definition: dnsmgr.c:86
#define ast_mutex_unlock(a)
Definition: lock.h:156

Variable Documentation

struct ast_cli_entry cli_refresh = AST_CLI_DEFINE(handle_cli_refresh, "Performs an immediate refresh")
static

Definition at line 394 of file dnsmgr.c.

Referenced by dnsmgr_init(), and dnsmgr_shutdown().

struct ast_cli_entry cli_reload = AST_CLI_DEFINE(handle_cli_reload, "Reloads the DNS manager configuration")
static

Definition at line 393 of file dnsmgr.c.

Referenced by dnsmgr_init(), and dnsmgr_shutdown().

struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the DNS manager status")
static

Definition at line 395 of file dnsmgr.c.

Referenced by dnsmgr_init(), and dnsmgr_shutdown().

int enabled
static

Definition at line 81 of file dnsmgr.c.

struct entry_list entry_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static

Referenced by handle_cli_refresh().

struct refresh_info master_refresh_info
static
Initial value:
= {
.entries = &entry_list,
.verbose = 0,
}
static struct entry_list entry_list

Definition at line 91 of file dnsmgr.c.

Referenced by dnsmgr_start_refresh(), and do_reload().

int refresh_interval
static

Definition at line 82 of file dnsmgr.c.

Referenced by do_reload(), handle_cli_status(), and refresh_list().

ast_mutex_t refresh_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 77 of file dnsmgr.c.

int refresh_sched = -1
static

Definition at line 53 of file dnsmgr.c.

pthread_t refresh_thread = AST_PTHREADT_NULL
static

Definition at line 54 of file dnsmgr.c.

struct sched_context* sched
static

Definition at line 52 of file dnsmgr.c.