| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-02-10 20:40:00 +00:00
										 |  |  |  * Copyright (C) 2005-2006, Kevin P. Fleming | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Kevin P. Fleming <kpfleming@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief Background DNS update manager | 
					
						
							| 
									
										
										
										
											2005-12-30 21:18:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-03-22 19:51:16 +00:00
										 |  |  |  * \author Kevin P. Fleming <kpfleming@digium.com> | 
					
						
							| 
									
										
										
										
											2008-03-28 22:45:43 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \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. | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-18 14:17:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*! \li \ref dnsmgr.c uses the configuration file \ref dnsmgr.conf
 | 
					
						
							|  |  |  |  * \addtogroup configuration_file Configuration Files | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |  * \page dnsmgr.conf dnsmgr.conf | 
					
						
							|  |  |  |  * \verbinclude dnsmgr.conf.sample | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-15 16:20:16 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<support_level>core</support_level> | 
					
						
							|  |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-20 22:18:21 +00:00
										 |  |  | #include "asterisk/_private.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | #include <regex.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | #include "asterisk/module.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/dnsmgr.h"
 | 
					
						
							|  |  |  | #include "asterisk/linkedlists.h"
 | 
					
						
							|  |  |  | #include "asterisk/utils.h"
 | 
					
						
							|  |  |  | #include "asterisk/config.h"
 | 
					
						
							|  |  |  | #include "asterisk/sched.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-27 21:10:50 +00:00
										 |  |  | #include "asterisk/manager.h"
 | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | #include "asterisk/acl.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-20 17:15:54 +00:00
										 |  |  | static struct ast_sched_context *sched; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | static int refresh_sched = -1; | 
					
						
							|  |  |  | static pthread_t refresh_thread = AST_PTHREADT_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_dnsmgr_entry { | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 	/*! where we will store the resulting IP address and port number */ | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	struct ast_sockaddr *result; | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 	/*! SRV record to lookup, if provided. Composed of service, protocol, and domain name: _Service._Proto.Name */ | 
					
						
							|  |  |  | 	char *service; | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	/*! Address family to filter DNS responses. */ | 
					
						
							|  |  |  | 	unsigned int family; | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	/*! Set to 1 if the entry changes */ | 
					
						
							| 
									
										
										
										
											2008-10-30 16:49:02 +00:00
										 |  |  | 	unsigned int changed:1; | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | 	/*! Data to pass back to update_func */ | 
					
						
							|  |  |  | 	void *data; | 
					
						
							|  |  |  | 	/*! The callback function to execute on address update */ | 
					
						
							|  |  |  | 	dns_update_func update_func; | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	ast_mutex_t lock; | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | 	AST_RWLIST_ENTRY(ast_dnsmgr_entry) list; | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	/*! just 1 here, but we use calloc to allocate the correct size */ | 
					
						
							| 
									
										
										
										
											2006-06-05 16:17:31 +00:00
										 |  |  | 	char name[1]; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | static AST_RWLIST_HEAD_STATIC(entry_list, ast_dnsmgr_entry); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(refresh_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define REFRESH_DEFAULT 300
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-27 22:14:33 +00:00
										 |  |  | static int enabled; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | static int refresh_interval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct refresh_info { | 
					
						
							|  |  |  | 	struct entry_list *entries; | 
					
						
							|  |  |  | 	int verbose; | 
					
						
							| 
									
										
										
										
											2005-04-12 14:11:59 +00:00
										 |  |  | 	unsigned int regex_present:1; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	regex_t filter; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct refresh_info master_refresh_info = { | 
					
						
							|  |  |  | 	.entries = &entry_list, | 
					
						
							|  |  |  | 	.verbose = 0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | struct ast_dnsmgr_entry *ast_dnsmgr_get_family(const char *name, struct ast_sockaddr *result, const char *service, unsigned int family) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ast_dnsmgr_entry *entry; | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 	int total_size = sizeof(*entry) + strlen(name) + (service ? strlen(service) + 1 : 0); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, total_size))) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	entry->result = result; | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	ast_mutex_init(&entry->lock); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	strcpy(entry->name, name); | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 	if (service) { | 
					
						
							|  |  |  | 		entry->service = ((char *) entry) + sizeof(*entry) + strlen(name); | 
					
						
							|  |  |  | 		strcpy(entry->service, service); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	entry->family = family; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | 	AST_RWLIST_WRLOCK(&entry_list); | 
					
						
							|  |  |  | 	AST_RWLIST_INSERT_HEAD(&entry_list, entry, list); | 
					
						
							|  |  |  | 	AST_RWLIST_UNLOCK(&entry_list); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return entry; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct ast_sockaddr *result, const char *service) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ast_dnsmgr_get_family(name, result, service, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	if (!entry) { | 
					
						
							| 
									
										
										
										
											2005-04-07 07:41:06 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-07 07:41:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | 	AST_RWLIST_WRLOCK(&entry_list); | 
					
						
							|  |  |  | 	AST_RWLIST_REMOVE(&entry_list, entry, list); | 
					
						
							|  |  |  | 	AST_RWLIST_UNLOCK(&entry_list); | 
					
						
							| 
									
										
										
										
											2012-03-26 21:22:23 +00:00
										 |  |  | 	ast_debug(6, "removing dns manager for '%s'\n", entry->name); | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_destroy(&entry->lock); | 
					
						
							| 
									
										
										
										
											2007-06-06 21:20:11 +00:00
										 |  |  | 	ast_free(entry); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | 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) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	unsigned int family; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	if (ast_strlen_zero(name) || !result || !dnsmgr) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name)) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	/* Lookup address family filter. */ | 
					
						
							|  |  |  | 	family = result->ss.ss_family; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-08 18:48:16 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If it's actually an IP address and not a name, there's no | 
					
						
							|  |  |  | 	 * need for a managed lookup. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2011-06-14 17:22:26 +00:00
										 |  |  | 	if (ast_sockaddr_parse(result, name, PARSE_PORT_FORBID)) { | 
					
						
							| 
									
										
										
										
											2011-06-08 18:48:16 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 21:22:23 +00:00
										 |  |  | 	ast_debug(6, "doing dnsmgr_lookup for '%s'\n", name); | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-08 00:03:49 +00:00
										 |  |  | 	/* do a lookup now but add a manager so it will automagically get updated in the background */ | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 	ast_get_ip_or_srv(result, name, service); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-08 00:03:49 +00:00
										 |  |  | 	/* if dnsmgr is not enable don't bother adding an entry */ | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	if (!enabled) { | 
					
						
							| 
									
										
										
										
											2005-04-07 07:41:06 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2010-07-16 13:32:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 21:22:23 +00:00
										 |  |  | 	ast_debug(6, "adding dns manager for '%s'\n", name); | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	*dnsmgr = ast_dnsmgr_get_family(name, result, service, family); | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | 	(*dnsmgr)->update_func = func; | 
					
						
							|  |  |  | 	(*dnsmgr)->data = data; | 
					
						
							| 
									
										
										
										
											2007-06-08 00:03:49 +00:00
										 |  |  | 	return !*dnsmgr; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return internal_dnsmgr_lookup(name, result, dnsmgr, service, NULL, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return internal_dnsmgr_lookup(name, result, dnsmgr, service, func, data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Refresh a dnsmgr entry | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-21 15:45:46 +00:00
										 |  |  | 	struct ast_sockaddr tmp = { .len = 0, }; | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	int changed = 0; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	ast_mutex_lock(&entry->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 21:22:23 +00:00
										 |  |  | 	ast_debug(6, "refreshing '%s'\n", entry->name); | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 23:06:11 +00:00
										 |  |  | 	tmp.ss.ss_family = entry->family; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service)) { | 
					
						
							| 
									
										
										
										
											2010-09-21 15:45:46 +00:00
										 |  |  | 		if (!ast_sockaddr_port(&tmp)) { | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 			ast_sockaddr_set_port(&tmp, ast_sockaddr_port(entry->result)); | 
					
						
							| 
									
										
										
										
											2010-09-21 15:45:46 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 		if (ast_sockaddr_cmp(&tmp, entry->result)) { | 
					
						
							| 
									
										
										
										
											2010-09-21 15:45:46 +00:00
										 |  |  | 			const char *old_addr = ast_strdupa(ast_sockaddr_stringify(entry->result)); | 
					
						
							|  |  |  | 			const char *new_addr = ast_strdupa(ast_sockaddr_stringify(&tmp)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | 			if (entry->update_func) { | 
					
						
							|  |  |  | 				entry->update_func(entry->result, &tmp, entry->data); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s to %s\n", | 
					
						
							|  |  |  | 						entry->name, old_addr, new_addr); | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-30 23:58:51 +00:00
										 |  |  | 				ast_sockaddr_copy(entry->result, &tmp); | 
					
						
							|  |  |  | 				changed = entry->changed = 1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-04-01 17:53:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	ast_mutex_unlock(&entry->lock); | 
					
						
							| 
									
										
										
										
											2010-09-21 15:45:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	return changed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return dnsmgr_refresh(entry, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Check if dnsmgr entry has changed from since last call to this function | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry) | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int changed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&entry->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	changed = entry->changed; | 
					
						
							|  |  |  | 	entry->changed = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&entry->lock); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 	return changed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | static void *do_refresh(void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		pthread_testcancel(); | 
					
						
							| 
									
										
										
										
											2006-10-13 15:56:17 +00:00
										 |  |  | 		usleep((ast_sched_wait(sched)*1000)); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		pthread_testcancel(); | 
					
						
							|  |  |  | 		ast_sched_runq(sched); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-21 14:40:10 +00:00
										 |  |  | static int refresh_list(const void *data) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-21 14:40:10 +00:00
										 |  |  | 	struct refresh_info *info = (struct refresh_info *)data; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	struct ast_dnsmgr_entry *entry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if a refresh or reload is already in progress, exit now */ | 
					
						
							|  |  |  | 	if (ast_mutex_trylock(&refresh_lock)) { | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		if (info->verbose) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "DNS Manager refresh already in progress.\n"); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 21:22:23 +00:00
										 |  |  | 	ast_debug(6, "Refreshing DNS lookups.\n"); | 
					
						
							| 
									
										
										
										
											2007-06-18 16:56:06 +00:00
										 |  |  | 	AST_RWLIST_RDLOCK(info->entries); | 
					
						
							|  |  |  | 	AST_RWLIST_TRAVERSE(info->entries, entry, list) { | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		if (info->regex_present && regexec(&info->filter, entry->name, 0, NULL, 0)) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 17:44:36 +00:00
										 |  |  | 		dnsmgr_refresh(entry, info->verbose); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-06-18 16:56:06 +00:00
										 |  |  | 	AST_RWLIST_UNLOCK(info->entries); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&refresh_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-08 01:29:14 +00:00
										 |  |  | 	/* automatically reschedule based on the interval */ | 
					
						
							|  |  |  | 	return refresh_interval * 1000; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dnsmgr_start_refresh(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (refresh_sched > -1) { | 
					
						
							| 
									
										
										
										
											2008-01-27 22:35:29 +00:00
										 |  |  | 		AST_SCHED_DEL(sched, refresh_sched); | 
					
						
							| 
									
										
										
										
											2005-11-08 01:32:40 +00:00
										 |  |  | 		refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1); | 
					
						
							| 
									
										
										
										
											2005-11-08 01:29:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int do_reload(int loading); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | static char *handle_cli_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "dnsmgr reload"; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		e->usage = | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 			"Usage: dnsmgr reload\n" | 
					
						
							|  |  |  | 			"       Reloads the DNS manager configuration.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	if (a->argc > 2) { | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	do_reload(0); | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | static char *handle_cli_refresh(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct refresh_info info = { | 
					
						
							|  |  |  | 		.entries = &entry_list, | 
					
						
							|  |  |  | 		.verbose = 1, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "dnsmgr refresh"; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		e->usage = | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 			"Usage: dnsmgr refresh [pattern]\n" | 
					
						
							| 
									
										
										
										
											2021-10-30 21:04:30 -04:00
										 |  |  | 			"       Performs an immediate refresh of the managed DNS entries.\n" | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 			"       Optional regular expression pattern is used to filter the entries to refresh.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!enabled) { | 
					
						
							|  |  |  | 		ast_cli(a->fd, "DNS Manager is disabled.\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc > 3) { | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	if (a->argc == 3) { | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 		if (regcomp(&info.filter, a->argv[2], REG_EXTENDED | REG_NOSUB)) { | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 			return CLI_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2005-04-12 14:11:59 +00:00
										 |  |  | 			info.regex_present = 1; | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	refresh_list(&info); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 	if (info.regex_present) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		regfree(&info.filter); | 
					
						
							| 
									
										
										
										
											2008-07-14 17:21:18 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int count = 0; | 
					
						
							|  |  |  | 	struct ast_dnsmgr_entry *entry; | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "dnsmgr status"; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		e->usage = | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 			"Usage: dnsmgr status\n" | 
					
						
							|  |  |  | 			"       Displays the DNS manager status.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	if (a->argc > 2) { | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	ast_cli(a->fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled"); | 
					
						
							|  |  |  | 	ast_cli(a->fd, "Refresh Interval: %d seconds\n", refresh_interval); | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | 	AST_RWLIST_RDLOCK(&entry_list); | 
					
						
							|  |  |  | 	AST_RWLIST_TRAVERSE(&entry_list, entry, list) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		count++; | 
					
						
							| 
									
										
										
										
											2007-06-18 16:37:14 +00:00
										 |  |  | 	AST_RWLIST_UNLOCK(&entry_list); | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	ast_cli(a->fd, "Number of entries: %d\n", count); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-22 20:05:18 +00:00
										 |  |  | static struct ast_cli_entry cli_reload = AST_CLI_DEFINE(handle_cli_reload, "Reloads the DNS manager configuration"); | 
					
						
							|  |  |  | static struct ast_cli_entry cli_refresh = AST_CLI_DEFINE(handle_cli_refresh, "Performs an immediate refresh"); | 
					
						
							|  |  |  | static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the DNS manager status"); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2012-12-11 00:37:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	ast_cli_unregister(&cli_reload); | 
					
						
							|  |  |  | 	ast_cli_unregister(&cli_status); | 
					
						
							|  |  |  | 	ast_cli_unregister(&cli_refresh); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Destroy refresh thread. */ | 
					
						
							|  |  |  | 	ast_mutex_lock(&refresh_lock); | 
					
						
							|  |  |  | 	if (refresh_thread != AST_PTHREADT_NULL) { | 
					
						
							|  |  |  | 		/* wake up the thread so it will exit */ | 
					
						
							|  |  |  | 		pthread_cancel(refresh_thread); | 
					
						
							|  |  |  | 		pthread_kill(refresh_thread, SIGURG); | 
					
						
							|  |  |  | 		pthread_join(refresh_thread, NULL); | 
					
						
							|  |  |  | 		refresh_thread = AST_PTHREADT_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&refresh_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_sched_context_destroy(sched); | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2012-12-11 00:37:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-20 17:15:54 +00:00
										 |  |  | 	if (!(sched = ast_sched_context_create())) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Unable to create schedule context.\n"); | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | 		return AST_MODULE_LOAD_FAILURE; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_cli_register(&cli_reload); | 
					
						
							|  |  |  | 	ast_cli_register(&cli_status); | 
					
						
							| 
									
										
										
										
											2007-09-18 22:43:45 +00:00
										 |  |  | 	ast_cli_register(&cli_refresh); | 
					
						
							| 
									
										
										
										
											2012-12-11 00:37:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | 	return do_reload(1) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | static int reload_module(void) | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-14 23:08:06 +00:00
										 |  |  | 	return do_reload(0); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int do_reload(int loading) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ast_config *config; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	struct ast_variable *v; | 
					
						
							| 
									
										
										
										
											2007-08-16 21:09:46 +00:00
										 |  |  | 	struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED }; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	int interval; | 
					
						
							|  |  |  | 	int was_enabled; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 21:52:59 +00:00
										 |  |  | 	if ((config = ast_config_load2("dnsmgr.conf", "dnsmgr", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-09-12 23:30:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-08-16 21:09:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 	/* ensure that no refresh cycles run while the reload is in progress */ | 
					
						
							|  |  |  | 	ast_mutex_lock(&refresh_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* reset defaults in preparation for reading config file */ | 
					
						
							|  |  |  | 	refresh_interval = REFRESH_DEFAULT; | 
					
						
							|  |  |  | 	was_enabled = enabled; | 
					
						
							|  |  |  | 	enabled = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 21:52:59 +00:00
										 |  |  | 	if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&refresh_lock); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-27 22:35:29 +00:00
										 |  |  | 	AST_SCHED_DEL(sched, refresh_sched); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	for (v = ast_variable_browse(config, "general"); v; v = v->next) { | 
					
						
							|  |  |  | 		if (!strcasecmp(v->name, "enable")) { | 
					
						
							|  |  |  | 			enabled = ast_true(v->value); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "refreshinterval")) { | 
					
						
							|  |  |  | 			if (sscanf(v->value, "%30d", &interval) < 1) { | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value); | 
					
						
							|  |  |  | 			} else if (interval < 0) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 				refresh_interval = interval; | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	ast_config_destroy(config); | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	if (enabled && refresh_interval) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* if this reload enabled the manager, create the background thread
 | 
					
						
							|  |  |  | 	   if it does not exist */ | 
					
						
							| 
									
										
										
										
											2006-10-13 15:56:17 +00:00
										 |  |  | 	if (enabled) { | 
					
						
							|  |  |  | 		if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) { | 
					
						
							|  |  |  | 			if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "Unable to start refresh thread.\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-10-13 15:56:17 +00:00
										 |  |  | 		/* make a background refresh happen right away */ | 
					
						
							|  |  |  | 		refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1); | 
					
						
							| 
									
										
										
										
											2011-09-13 14:22:58 +00:00
										 |  |  | 	/* if this reload disabled the manager and there is a background thread, kill it */ | 
					
						
							|  |  |  | 	} else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) { | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | 		/* wake up the thread so it will exit */ | 
					
						
							|  |  |  | 		pthread_cancel(refresh_thread); | 
					
						
							|  |  |  | 		pthread_kill(refresh_thread, SIGURG); | 
					
						
							|  |  |  | 		pthread_join(refresh_thread, NULL); | 
					
						
							|  |  |  | 		refresh_thread = AST_PTHREADT_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&refresh_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-13 21:52:59 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-04-06 21:13:51 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "DNS Manager", | 
					
						
							|  |  |  | 	.support_level = AST_MODULE_SUPPORT_CORE, | 
					
						
							|  |  |  | 	.load = load_module, | 
					
						
							|  |  |  | 	.unload = unload_module, | 
					
						
							|  |  |  | 	.reload = reload_module, | 
					
						
							|  |  |  | 	.load_pri = AST_MODPRI_CORE, | 
					
						
							| 
									
										
										
										
											2018-07-26 13:52:46 -04:00
										 |  |  | 	.requires = "extconfig", | 
					
						
							| 
									
										
										
										
											2018-02-16 22:11:42 -05:00
										 |  |  | ); |