Mon Mar 19 11:30:47 2012

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.
ast_dnsmgr_entryast_dnsmgr_get (const char *name, struct ast_sockaddr *result, const char *service)
 Allocate a new DNS manager entry.
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)
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 = { .handler = handle_cli_refresh , .summary = "Performs an immediate refresh" ,__VA_ARGS__ }
static struct ast_cli_entry cli_reload = { .handler = handle_cli_reload , .summary = "Reloads the DNS manager configuration" ,__VA_ARGS__ }
static struct ast_cli_entry cli_status = { .handler = handle_cli_status , .summary = "Display the DNS manager status" ,__VA_ARGS__ }
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 75 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 234 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().

00235 {
00236    int changed;
00237 
00238    ast_mutex_lock(&entry->lock);
00239 
00240    changed = entry->changed;
00241    entry->changed = 0;
00242 
00243    ast_mutex_unlock(&entry->lock);
00244    
00245    return changed;
00246 }

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

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 117 of file dnsmgr.c.

References ast_dnsmgr_get_family(), and ast_dnsmgr_entry::result.

00118 {
00119    return ast_dnsmgr_get_family(name, result, service, 0);
00120 }

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

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

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 176 of file dnsmgr.c.

References internal_dnsmgr_lookup(), and ast_dnsmgr_entry::result.

Referenced by build_peer(), and iax2_append_register().

00177 {
00178    return internal_dnsmgr_lookup(name, result, dnsmgr, service, NULL, NULL);
00179 }

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 181 of file dnsmgr.c.

References internal_dnsmgr_lookup(), and ast_dnsmgr_entry::result.

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

00182 {
00183    return internal_dnsmgr_lookup(name, result, dnsmgr, service, func, data);
00184 }

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 226 of file dnsmgr.c.

References dnsmgr_refresh().

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

00227 {
00228    return dnsmgr_refresh(entry, 0);
00229 }

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 122 of file dnsmgr.c.

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

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

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

int dnsmgr_init ( void   ) 

Provided by dnsmgr.c

Definition at line 393 of file dnsmgr.c.

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

Referenced by main().

00394 {
00395    if (!(sched = sched_context_create())) {
00396       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
00397       return -1;
00398    }
00399    ast_cli_register(&cli_reload);
00400    ast_cli_register(&cli_status);
00401    ast_cli_register(&cli_refresh);
00402    return do_reload(1);
00403 }

static int dnsmgr_refresh ( struct ast_dnsmgr_entry entry,
int  verbose 
) [static]

Definition at line 189 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().

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

int dnsmgr_reload ( void   ) 

Provided by dnsmgr.c

Definition at line 405 of file dnsmgr.c.

References do_reload().

00406 {
00407    return do_reload(0);
00408 }

void dnsmgr_start_refresh ( void   ) 

Provided by dnsmgr.c

Definition at line 287 of file dnsmgr.c.

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

Referenced by main().

00288 {
00289    if (refresh_sched > -1) {
00290       AST_SCHED_DEL(sched, refresh_sched);
00291       refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
00292    }
00293 }

static void* do_refresh ( void *  data  )  [static]

Definition at line 248 of file dnsmgr.c.

References ast_sched_runq(), ast_sched_wait(), and sched.

Referenced by do_reload(), and load_module().

00249 {
00250    for (;;) {
00251       pthread_testcancel();
00252       usleep((ast_sched_wait(sched)*1000));
00253       pthread_testcancel();
00254       ast_sched_runq(sched);
00255    }
00256    return NULL;
00257 }

static int do_reload ( int  loading  )  [static]

Definition at line 410 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_flags, 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, refresh_list(), and sched.

00411 {
00412    struct ast_config *config;
00413    struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED };
00414    const char *interval_value;
00415    const char *enabled_value;
00416    int interval;
00417    int was_enabled;
00418    int res = -1;
00419 
00420    config = ast_config_load2("dnsmgr.conf", "dnsmgr", config_flags);
00421    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEUNCHANGED || config == CONFIG_STATUS_FILEINVALID) {
00422       return 0;
00423    }
00424 
00425    /* ensure that no refresh cycles run while the reload is in progress */
00426    ast_mutex_lock(&refresh_lock);
00427 
00428    /* reset defaults in preparation for reading config file */
00429    refresh_interval = REFRESH_DEFAULT;
00430    was_enabled = enabled;
00431    enabled = 0;
00432 
00433    AST_SCHED_DEL(sched, refresh_sched);
00434 
00435    if (config) {
00436       if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
00437          enabled = ast_true(enabled_value);
00438       }
00439       if ((interval_value = ast_variable_retrieve(config, "general", "refreshinterval"))) {
00440          if (sscanf(interval_value, "%30d", &interval) < 1)
00441             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", interval_value);
00442          else if (interval < 0)
00443             ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval);
00444          else
00445             refresh_interval = interval;
00446       }
00447       ast_config_destroy(config);
00448    }
00449 
00450    if (enabled && refresh_interval)
00451       ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval);
00452 
00453    /* if this reload enabled the manager, create the background thread
00454       if it does not exist */
00455    if (enabled) {
00456       if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) {
00457          if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
00458             ast_log(LOG_ERROR, "Unable to start refresh thread.\n");
00459          }
00460       }
00461       /* make a background refresh happen right away */
00462       refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
00463       res = 0;
00464    }
00465    /* if this reload disabled the manager and there is a background thread,
00466       kill it */
00467    else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) {
00468       /* wake up the thread so it will exit */
00469       pthread_cancel(refresh_thread);
00470       pthread_kill(refresh_thread, SIGURG);
00471       pthread_join(refresh_thread, NULL);
00472       refresh_thread = AST_PTHREADT_NULL;
00473       res = 0;
00474    }
00475    else
00476       res = 0;
00477 
00478    ast_mutex_unlock(&refresh_lock);
00479    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: DNSmgr\r\nStatus: %s\r/nMessage: DNSmgr reload Requested\r\n", enabled ? "Enabled" : "Disabled");
00480 
00481    return res;
00482 }

static char* handle_cli_refresh ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 316 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.

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

static char* handle_cli_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 297 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.

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

static char* handle_cli_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 360 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, ast_dnsmgr_entry::list, refresh_interval, and ast_cli_entry::usage.

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

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 136 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, ast_dnsmgr_entry::result, and ast_sockaddr::ss.

Referenced by ast_dnsmgr_lookup(), and ast_dnsmgr_lookup_cb().

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

static int refresh_list ( const void *  data  )  [static]

Definition at line 259 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, ast_dnsmgr_entry::list, 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().

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


Variable Documentation

struct ast_cli_entry cli_refresh = { .handler = handle_cli_refresh , .summary = "Performs an immediate refresh" ,__VA_ARGS__ } [static]

Definition at line 390 of file dnsmgr.c.

Referenced by dnsmgr_init().

struct ast_cli_entry cli_reload = { .handler = handle_cli_reload , .summary = "Reloads the DNS manager configuration" ,__VA_ARGS__ } [static]

Definition at line 389 of file dnsmgr.c.

Referenced by dnsmgr_init(), load_module(), and unload_module().

struct ast_cli_entry cli_status = { .handler = handle_cli_status , .summary = "Display the DNS manager status" ,__VA_ARGS__ } [static]

Definition at line 391 of file dnsmgr.c.

int enabled [static]

Definition at line 77 of file dnsmgr.c.

struct refresh_info master_refresh_info [static]

Initial value:

 {
   .entries = &entry_list,
   .verbose = 0,
}

Definition at line 87 of file dnsmgr.c.

Referenced by dnsmgr_start_refresh(), and do_reload().

int refresh_interval [static]

Definition at line 78 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 73 of file dnsmgr.c.

int refresh_sched = -1 [static]

Definition at line 49 of file dnsmgr.c.

pthread_t refresh_thread = AST_PTHREADT_NULL [static]

Definition at line 50 of file dnsmgr.c.

struct sched_context* sched [static]

Definition at line 48 of file dnsmgr.c.


Generated on Mon Mar 19 11:30:47 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7