Mon Aug 31 12:30:34 2015

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

Defines

#define REFRESH_DEFAULT   300

Functions

int ast_dnsmgr_changed (struct ast_dnsmgr_entry *entry)
 Check is see if a dnsmgr entry has changed.
struct ast_dnsmgr_entryast_dnsmgr_get (const char *name, struct ast_sockaddr *result, const char *service)
 Allocate a new DNS manager entry.
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.
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.
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.
int ast_dnsmgr_refresh (struct ast_dnsmgr_entry *entry)
 Force a refresh of a dnsmgr entry.
void ast_dnsmgr_release (struct ast_dnsmgr_entry *entry)
 Free a DNS manager entry.
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 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 <kpfleming@digium.com>
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.


Define 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-zero if the dnsmgr entry has changed since the last call to this function
zero if 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().

00239 {
00240    int changed;
00241 
00242    ast_mutex_lock(&entry->lock);
00243 
00244    changed = entry->changed;
00245    entry->changed = 0;
00246 
00247    ast_mutex_unlock(&entry->lock);
00248    
00249    return changed;
00250 }

struct ast_dnsmgr_entry* ast_dnsmgr_get ( const char *  name,
struct ast_sockaddr result,
const char *  service 
) [read]

Allocate a new DNS manager entry.

Parameters:
name the hostname
result where 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().

00122 {
00123    return ast_dnsmgr_get_family(name, result, service, 0);
00124 }

struct ast_dnsmgr_entry* ast_dnsmgr_get_family ( const char *  name,
struct ast_sockaddr result,
const char *  service,
unsigned int  family 
) [read]

Allocate a new DNS manager entry.

Parameters:
name the hostname
result where the DNS manager should store the IP address as it refreshes it.
service 
family Address 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::name, ast_dnsmgr_entry::result, and ast_dnsmgr_entry::service.

Referenced by ast_dnsmgr_get(), and internal_dnsmgr_lookup().

00097 {
00098    struct ast_dnsmgr_entry *entry;
00099    int total_size = sizeof(*entry) + strlen(name) + (service ? strlen(service) + 1 : 0);
00100 
00101    if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, total_size))) {
00102       return NULL;
00103    }
00104 
00105    entry->result = result;
00106    ast_mutex_init(&entry->lock);
00107    strcpy(entry->name, name);
00108    if (service) {
00109       entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
00110       strcpy(entry->service, service);
00111    }
00112    entry->family = family;
00113 
00114    AST_RWLIST_WRLOCK(&entry_list);
00115    AST_RWLIST_INSERT_HEAD(&entry_list, entry, list);
00116    AST_RWLIST_UNLOCK(&entry_list);
00117 
00118    return entry;
00119 }

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:
name the hostname
result where 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.
dnsmgr Where 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:
0 success
non-zero failure
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().

00181 {
00182    return internal_dnsmgr_lookup(name, result, dnsmgr, service, NULL, NULL);
00183 }

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:
name the hostname
result The 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.
dnsmgr Where to store the allocate DNS manager entry
service 
func The 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
data A 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:
0 success
non-zero failure

Definition at line 185 of file dnsmgr.c.

References internal_dnsmgr_lookup().

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

00186 {
00187    return internal_dnsmgr_lookup(name, result, dnsmgr, service, func, data);
00188 }

int ast_dnsmgr_refresh ( struct ast_dnsmgr_entry entry  ) 

Force a refresh of a dnsmgr entry.

Return values:
non-zero if the result is different than the previous result
zero if 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().

00231 {
00232    return dnsmgr_refresh(entry, 0);
00233 }

void ast_dnsmgr_release ( struct ast_dnsmgr_entry entry  ) 

Free a DNS manager entry.

Parameters:
entry the 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, ast_dnsmgr_entry::lock, and ast_dnsmgr_entry::name.

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

00127 {
00128    if (!entry)
00129       return;
00130 
00131    AST_RWLIST_WRLOCK(&entry_list);
00132    AST_RWLIST_REMOVE(&entry_list, entry, list);
00133    AST_RWLIST_UNLOCK(&entry_list);
00134    ast_verb(6, "removing dns manager for '%s'\n", entry->name);
00135 
00136    ast_mutex_destroy(&entry->lock);
00137    ast_free(entry);
00138 }

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().

00418 {
00419    if (!(sched = sched_context_create())) {
00420       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
00421       return -1;
00422    }
00423    ast_cli_register(&cli_reload);
00424    ast_cli_register(&cli_status);
00425    ast_cli_register(&cli_refresh);
00426 
00427    ast_register_atexit(dnsmgr_shutdown);
00428 
00429    return do_reload(1);
00430 }

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::name, 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().

00194 {
00195    struct ast_sockaddr tmp = { .len = 0, };
00196    int changed = 0;
00197 
00198    ast_mutex_lock(&entry->lock);
00199 
00200    if (verbose) {
00201       ast_verb(6, "refreshing '%s'\n", entry->name);
00202    }
00203 
00204    tmp.ss.ss_family = entry->family;
00205    if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service)) {
00206       if (!ast_sockaddr_port(&tmp)) {
00207          ast_sockaddr_set_port(&tmp, ast_sockaddr_port(entry->result));
00208       }
00209       if (ast_sockaddr_cmp(&tmp, entry->result)) {
00210          const char *old_addr = ast_strdupa(ast_sockaddr_stringify(entry->result));
00211          const char *new_addr = ast_strdupa(ast_sockaddr_stringify(&tmp));
00212 
00213          if (entry->update_func) {
00214             entry->update_func(entry->result, &tmp, entry->data);
00215          } else {
00216             ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s to %s\n",
00217                   entry->name, old_addr, new_addr);
00218 
00219             ast_sockaddr_copy(entry->result, &tmp);
00220             changed = entry->changed = 1;
00221          }
00222       }
00223    }
00224 
00225    ast_mutex_unlock(&entry->lock);
00226 
00227    return changed;
00228 }

int dnsmgr_reload ( void   ) 

Provided by dnsmgr.c

Definition at line 432 of file dnsmgr.c.

References do_reload().

00433 {
00434    return do_reload(0);
00435 }

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().

00398 {
00399    ast_cli_unregister(&cli_reload);
00400    ast_cli_unregister(&cli_status);
00401    ast_cli_unregister(&cli_refresh);
00402 
00403    /* Destroy refresh thread. */
00404    ast_mutex_lock(&refresh_lock);
00405    if (refresh_thread != AST_PTHREADT_NULL) {
00406       /* wake up the thread so it will exit */
00407       pthread_cancel(refresh_thread);
00408       pthread_kill(refresh_thread, SIGURG);
00409       pthread_join(refresh_thread, NULL);
00410       refresh_thread = AST_PTHREADT_NULL;
00411    }
00412    ast_mutex_unlock(&refresh_lock);
00413 
00414    sched_context_destroy(sched);
00415 }

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().

00292 {
00293    if (refresh_sched > -1) {
00294       AST_SCHED_DEL(sched, refresh_sched);
00295       refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
00296    }
00297 }

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().

00253 {
00254    for (;;) {
00255       pthread_testcancel();
00256       usleep((ast_sched_wait(sched)*1000));
00257       pthread_testcancel();
00258       ast_sched_runq(sched);
00259    }
00260    return NULL;
00261 }

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().

00438 {
00439    struct ast_config *config;
00440    struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED };
00441    const char *interval_value;
00442    const char *enabled_value;
00443    int interval;
00444    int was_enabled;
00445    int res = -1;
00446 
00447    config = ast_config_load2("dnsmgr.conf", "dnsmgr", config_flags);
00448    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEUNCHANGED || config == CONFIG_STATUS_FILEINVALID) {
00449       return 0;
00450    }
00451 
00452    /* ensure that no refresh cycles run while the reload is in progress */
00453    ast_mutex_lock(&refresh_lock);
00454 
00455    /* reset defaults in preparation for reading config file */
00456    refresh_interval = REFRESH_DEFAULT;
00457    was_enabled = enabled;
00458    enabled = 0;
00459 
00460    AST_SCHED_DEL(sched, refresh_sched);
00461 
00462    if (config) {
00463       if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
00464          enabled = ast_true(enabled_value);
00465       }
00466       if ((interval_value = ast_variable_retrieve(config, "general", "refreshinterval"))) {
00467          if (sscanf(interval_value, "%30d", &interval) < 1)
00468             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", interval_value);
00469          else if (interval < 0)
00470             ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval);
00471          else
00472             refresh_interval = interval;
00473       }
00474       ast_config_destroy(config);
00475    }
00476 
00477    if (enabled && refresh_interval)
00478       ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval);
00479 
00480    /* if this reload enabled the manager, create the background thread
00481       if it does not exist */
00482    if (enabled) {
00483       if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) {
00484          if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
00485             ast_log(LOG_ERROR, "Unable to start refresh thread.\n");
00486          }
00487       }
00488       /* make a background refresh happen right away */
00489       refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
00490       res = 0;
00491    }
00492    /* if this reload disabled the manager and there is a background thread,
00493       kill it */
00494    else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) {
00495       /* wake up the thread so it will exit */
00496       pthread_cancel(refresh_thread);
00497       pthread_kill(refresh_thread, SIGURG);
00498       pthread_join(refresh_thread, NULL);
00499       refresh_thread = AST_PTHREADT_NULL;
00500       res = 0;
00501    }
00502    else
00503       res = 0;
00504 
00505    ast_mutex_unlock(&refresh_lock);
00506    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: DNSmgr\r\nStatus: %s\r/nMessage: DNSmgr reload Requested\r\n", enabled ? "Enabled" : "Disabled");
00507 
00508    return res;
00509 }

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, ast_cli_args::fd, refresh_info::filter, refresh_list(), refresh_info::regex_present, and ast_cli_entry::usage.

00321 {
00322    struct refresh_info info = {
00323       .entries = &entry_list,
00324       .verbose = 1,
00325    };
00326    switch (cmd) {
00327    case CLI_INIT:
00328       e->command = "dnsmgr refresh";
00329       e->usage = 
00330          "Usage: dnsmgr refresh [pattern]\n"
00331          "       Peforms an immediate refresh of the managed DNS entries.\n"
00332          "       Optional regular expression pattern is used to filter the entries to refresh.\n";
00333       return NULL;
00334    case CLI_GENERATE:
00335       return NULL;   
00336    }
00337 
00338    if (!enabled) {
00339       ast_cli(a->fd, "DNS Manager is disabled.\n");
00340       return 0;
00341    }
00342 
00343    if (a->argc > 3) {
00344       return CLI_SHOWUSAGE;
00345    }
00346 
00347    if (a->argc == 3) {
00348       if (regcomp(&info.filter, a->argv[2], REG_EXTENDED | REG_NOSUB)) {
00349          return CLI_SHOWUSAGE;
00350       } else {
00351          info.regex_present = 1;
00352       }
00353    }
00354 
00355    refresh_list(&info);
00356 
00357    if (info.regex_present) {
00358       regfree(&info.filter);
00359    }
00360 
00361    return CLI_SUCCESS;
00362 }

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.

00302 {
00303    switch (cmd) {
00304    case CLI_INIT:
00305       e->command = "dnsmgr reload";
00306       e->usage = 
00307          "Usage: dnsmgr reload\n"
00308          "       Reloads the DNS manager configuration.\n";
00309       return NULL;
00310    case CLI_GENERATE:
00311       return NULL;   
00312    }
00313    if (a->argc > 2)
00314       return CLI_SHOWUSAGE;
00315 
00316    do_reload(0);
00317    return CLI_SUCCESS;
00318 }

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.

00365 {
00366    int count = 0;
00367    struct ast_dnsmgr_entry *entry;
00368    switch (cmd) {
00369    case CLI_INIT:
00370       e->command = "dnsmgr status";
00371       e->usage = 
00372          "Usage: dnsmgr status\n"
00373          "       Displays the DNS manager status.\n";
00374       return NULL;
00375    case CLI_GENERATE:
00376       return NULL;   
00377    }
00378 
00379    if (a->argc > 2)
00380       return CLI_SHOWUSAGE;
00381 
00382    ast_cli(a->fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled");
00383    ast_cli(a->fd, "Refresh Interval: %d seconds\n", refresh_interval);
00384    AST_RWLIST_RDLOCK(&entry_list);
00385    AST_RWLIST_TRAVERSE(&entry_list, entry, list)
00386       count++;
00387    AST_RWLIST_UNLOCK(&entry_list);
00388    ast_cli(a->fd, "Number of entries: %d\n", count);
00389 
00390    return CLI_SUCCESS;
00391 }

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, enabled, ast_dnsmgr_entry::family, PARSE_PORT_FORBID, and ast_sockaddr::ss.

Referenced by ast_dnsmgr_lookup(), and ast_dnsmgr_lookup_cb().

00141 {
00142    unsigned int family;
00143 
00144    if (ast_strlen_zero(name) || !result || !dnsmgr) {
00145       return -1;
00146    }
00147 
00148    if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name)) {
00149       return 0;
00150    }
00151 
00152    /* Lookup address family filter. */
00153    family = result->ss.ss_family;
00154 
00155    /*
00156     * If it's actually an IP address and not a name, there's no
00157     * need for a managed lookup.
00158     */
00159    if (ast_sockaddr_parse(result, name, PARSE_PORT_FORBID)) {
00160       return 0;
00161    }
00162 
00163    ast_verb(6, "doing dnsmgr_lookup for '%s'\n", name);
00164 
00165    /* do a lookup now but add a manager so it will automagically get updated in the background */
00166    ast_get_ip_or_srv(result, name, service);
00167 
00168    /* if dnsmgr is not enable don't bother adding an entry */
00169    if (!enabled) {
00170       return 0;
00171    }
00172 
00173    ast_verb(6, "adding dns manager for '%s'\n", name);
00174    *dnsmgr = ast_dnsmgr_get_family(name, result, service, family);
00175    (*dnsmgr)->update_func = func;
00176    (*dnsmgr)->data = data;
00177    return !*dnsmgr;
00178 }

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, ast_dnsmgr_entry::name, refresh_interval, refresh_info::regex_present, and refresh_info::verbose.

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

00264 {
00265    struct refresh_info *info = (struct refresh_info *)data;
00266    struct ast_dnsmgr_entry *entry;
00267 
00268    /* if a refresh or reload is already in progress, exit now */
00269    if (ast_mutex_trylock(&refresh_lock)) {
00270       if (info->verbose)
00271          ast_log(LOG_WARNING, "DNS Manager refresh already in progress.\n");
00272       return -1;
00273    }
00274 
00275    ast_verb(6, "Refreshing DNS lookups.\n");
00276    AST_RWLIST_RDLOCK(info->entries);
00277    AST_RWLIST_TRAVERSE(info->entries, entry, list) {
00278       if (info->regex_present && regexec(&info->filter, entry->name, 0, NULL, 0))
00279           continue;
00280 
00281       dnsmgr_refresh(entry, info->verbose);
00282    }
00283    AST_RWLIST_UNLOCK(info->entries);
00284 
00285    ast_mutex_unlock(&refresh_lock);
00286 
00287    /* automatically reschedule based on the interval */
00288    return refresh_interval * 1000;
00289 }


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.

Initial value:
 {
   .entries = &entry_list,
   .verbose = 0,
}

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.


Generated on 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1