[asterisk-commits] file: branch file/pjsip-dns r410486 - in /team/file/pjsip-dns/res: ./ res_pjs...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 12 11:14:08 CDT 2014


Author: file
Date: Wed Mar 12 11:14:01 2014
New Revision: 410486

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410486
Log:
Add an initial implementation for configurable DNS support.

Nameservers can be specified explicitly, discovered via resolv.conf,
or the feature can be disabled entirely.

Modified:
    team/file/pjsip-dns/res/res_pjsip.c
    team/file/pjsip-dns/res/res_pjsip/config_system.c
    team/file/pjsip-dns/res/res_pjsip/include/res_pjsip_private.h

Modified: team/file/pjsip-dns/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pjsip-dns/res/res_pjsip.c?view=diff&rev=410486&r1=410485&r2=410486
==============================================================================
--- team/file/pjsip-dns/res/res_pjsip.c (original)
+++ team/file/pjsip-dns/res/res_pjsip.c Wed Mar 12 11:14:01 2014
@@ -1066,6 +1066,15 @@
 				<configOption name="threadpool_max_size" default="0">
 					<synopsis>Maximum number of threads in the res_pjsip threadpool.
 					A value of 0 indicates no maximum.</synopsis>
+				</configOption>
+				<configOption name="nameservers" default="auto">
+					<synopsis>Set nameservers to use for DNS resolution.</synopsis>
+					<description><para>
+						The nameservers can be specified by order of preference using ',' as a separator.
+						To have the nameservers configured on the system automatically used you can specify
+						the special value of "auto". To disable DNS support and resort to using the system
+						for resolution you can specify the special value of "disabled".
+					</para></description>
 				</configOption>
 				<configOption name="type">
 					<synopsis>Must be of type 'system'.</synopsis>
@@ -2305,6 +2314,17 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
+	if (ast_sip_initialize_dns()) {
+		ast_log(LOG_ERROR, "Failed to initialize DNS. Aborting load\n");
+		ast_sip_destroy_system();
+		pj_pool_release(memory_pool);
+		memory_pool = NULL;
+		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
+		pj_caching_pool_destroy(&caching_pool);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
 	pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
 	pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
 

Modified: team/file/pjsip-dns/res/res_pjsip/config_system.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pjsip-dns/res/res_pjsip/config_system.c?view=diff&rev=410486&r1=410485&r2=410486
==============================================================================
--- team/file/pjsip-dns/res/res_pjsip/config_system.c (original)
+++ team/file/pjsip-dns/res/res_pjsip/config_system.c Wed Mar 12 11:14:01 2014
@@ -29,6 +29,8 @@
 #define TIMER_T1_MIN 100
 #define DEFAULT_TIMER_T1 500
 #define DEFAULT_TIMER_B 32000
+
+#define NAMESERVERS_SIZE 512
 
 struct system_config {
 	SORCERY_OBJECT(details);
@@ -48,11 +50,15 @@
 		/*! Maxumum number of threads in the threadpool */
 		int max_size;
 	} threadpool;
+	/*! Configured nameservers */
+	char nameservers[NAMESERVERS_SIZE];
 };
 
 static struct ast_threadpool_options sip_threadpool_options = {
 	.version = AST_THREADPOOL_OPTIONS_VERSION,
 };
+
+static char sip_nameservers[NAMESERVERS_SIZE];
 
 void sip_get_threadpool_options(struct ast_threadpool_options *threadpool_options)
 {
@@ -101,6 +107,8 @@
 	sip_threadpool_options.auto_increment = system->threadpool.auto_increment;
 	sip_threadpool_options.idle_timeout = system->threadpool.idle_timeout;
 	sip_threadpool_options.max_size = system->threadpool.max_size;
+
+	ast_copy_string(sip_nameservers, system->nameservers, sizeof(sip_nameservers));
 
 	return 0;
 }
@@ -142,6 +150,8 @@
 			OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.idle_timeout));
 	ast_sorcery_object_field_register(system_sorcery, "system", "threadpool_max_size", "0",
 			OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.max_size));
+	ast_sorcery_object_field_register(system_sorcery, "system", "nameservers", "auto",
+			OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct system_config, nameservers));
 
 	ast_sorcery_load(system_sorcery);
 
@@ -174,3 +184,123 @@
 	ast_sorcery_unref(system_sorcery);
 }
 
+/*! \brief Helper function which parses resolv.conf and automatically adds nameservers if found */
+static int system_add_resolv_conf_nameservers(pj_pool_t *pool, pj_str_t *nameservers, unsigned int *count)
+{
+	FILE *f;
+	char buf[256], *nameserver = buf + 10;
+
+	f = fopen("/etc/resolv.conf", "r");
+	if (!f) {
+		ast_log(LOG_ERROR, "Could not open '/etc/resolv.conf' for automatic nameserver discovery\n");
+		return -1;
+	}
+
+	while (!feof(f)) {
+		if (!fgets(buf, sizeof(buf), f)) {
+			if (ferror(f)) {
+				ast_log(LOG_ERROR, "Error reading from file /etc/resolv.conf: %s\n", strerror(errno));
+			}
+			continue;
+		} else if (strncmp(buf, "nameserver", 10)) {
+			continue;
+		}
+
+		nameserver = ast_strip((buf + 10));
+		if (ast_strlen_zero(nameserver)) {
+			continue;
+		}
+
+		/* Since the memory where the nameserver is held will be overwritten we duplicate it from a pool passed in*/
+		pj_strdup2(pool, &nameservers[(*count)++], nameserver);
+
+		if (*count == (PJ_DNS_RESOLVER_MAX_NS - 1)) {
+			break;
+		}
+	}
+
+	fclose(f);
+
+	return 0;
+}
+
+static int system_create_resolver_and_set_nameservers(void *data)
+{
+	pj_status_t status;
+	pj_pool_t *pool = NULL;
+	pj_dns_resolver *resolver;
+	pj_str_t nameservers[PJ_DNS_RESOLVER_MAX_NS];
+	unsigned int count = 0;
+	char *nameserver, *remaining = sip_nameservers;
+
+	status = pjsip_endpt_create_resolver(ast_sip_get_pjsip_endpoint(), &resolver);
+	if (status != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Could not create DNS resolver(%d)\n", status);
+		return -1;
+	}
+
+	while ((nameserver = strsep(&remaining, ","))) {
+		nameserver = ast_strip(nameserver);
+
+		if (!strcmp(nameserver, "auto")) {
+			if (!pool) {
+				pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Automatic Nameserver Discovery", 256, 256);
+			}
+			if (!pool) {
+				ast_log(LOG_ERROR, "Could not create memory pool for automatic nameserver discovery\n");
+				return -1;
+			} else if (system_add_resolv_conf_nameservers(pool, nameservers, &count)) {
+				/* A log message will have already been output by system_add_resolv_conf_nameservers */
+				pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+				return -1;
+			}
+		} else {
+			pj_strset2(&nameservers[count++], nameserver);
+		}
+
+		/* If we have reached the max number of nameservers we can specify bail early */
+		if (count == (PJ_DNS_RESOLVER_MAX_NS - 1)) {
+			break;
+		}
+	}
+
+	if (!count) {
+		ast_log(LOG_ERROR, "No nameservers specified for DNS resolver, resorting to system resolution\n");
+		if (pool) {
+			pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		}
+		return 0;
+	}
+
+	status = pj_dns_resolver_set_ns(resolver, count, nameservers, NULL);
+
+	/* Since we no longer need the nameservers we can drop the memory pool they may be allocated from */
+	if (pool) {
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+	}
+
+	if (status != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Could not set nameservers on DNS resolver in PJSIP(%d)\n", status);
+		return -1;
+	}
+
+	status = pjsip_endpt_set_resolver(ast_sip_get_pjsip_endpoint(), resolver);
+	if (status != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Could not set DNS resolver in PJSIP(%d)\n", status);
+		return -1;
+	}
+
+	return 0;
+}
+
+int ast_sip_initialize_dns(void)
+{
+	/* If DNS support has been disabled don't even bother doing anything, just resort to the
+	 * system way of doing lookups
+	 */
+	if (!strcmp(sip_nameservers, "disabled")) {
+		return 0;
+	}
+
+	return ast_sip_push_task_synchronous(NULL, system_create_resolver_and_set_nameservers, NULL);
+}

Modified: team/file/pjsip-dns/res/res_pjsip/include/res_pjsip_private.h
URL: http://svnview.digium.com/svn/asterisk/team/file/pjsip-dns/res/res_pjsip/include/res_pjsip_private.h?view=diff&rev=410486&r1=410485&r2=410486
==============================================================================
--- team/file/pjsip-dns/res/res_pjsip/include/res_pjsip_private.h (original)
+++ team/file/pjsip-dns/res/res_pjsip/include/res_pjsip_private.h Wed Mar 12 11:14:01 2014
@@ -73,6 +73,14 @@
 void ast_sip_destroy_system(void);
 
 /*!
+ * \brief Initialize nameserver configuration
+ *
+ * \retval 0 Success
+ * \retval non-zero Failure
+ */
+int ast_sip_initialize_dns(void);
+
+/*!
  * \brief Initialize global configuration
  *
  * \retval 0 Success




More information about the asterisk-commits mailing list