[asterisk-commits] mmichelson: branch group/dns_naptr r433314 - in /team/group/dns_naptr: includ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 23 12:30:57 CDT 2015


Author: mmichelson
Date: Mon Mar 23 12:30:55 2015
New Revision: 433314

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=433314
Log:
Add sorting to DNS NAPTR records.

I modeled this after the method being done in the SRV branch. That is,
I have an internal function that is defined in dns_naptr.c to sort the
records. I opted to sort records after they are collected in order to
make the code more uniform: SRV and NAPTR work the same way.

In order to test this, I added some more NAPTR records to the nominal
NAPTR resolution test and gave it a shot. This pointed to an error where
I needed to cast to unsigned char when getting the order and preference
from the NAPTR record.


Modified:
    team/group/dns_naptr/include/asterisk/dns_internal.h
    team/group/dns_naptr/main/dns_core.c
    team/group/dns_naptr/main/dns_naptr.c
    team/group/dns_naptr/res/res_resolver_unbound.c

Modified: team/group/dns_naptr/include/asterisk/dns_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/include/asterisk/dns_internal.h?view=diff&rev=433314&r1=433313&r2=433314
==============================================================================
--- team/group/dns_naptr/include/asterisk/dns_internal.h (original)
+++ team/group/dns_naptr/include/asterisk/dns_internal.h Mon Mar 23 12:30:55 2015
@@ -147,3 +147,10 @@
  * \return scheduler context
  */
 struct ast_sched_context *ast_dns_get_sched(void);
+
+/*!
+ * \brief Sort the NAPTR records on a result
+ *
+ * \param result The DNS result
+ */
+void ast_dns_naptr_sort(struct ast_dns_result *result);

Modified: team/group/dns_naptr/main/dns_core.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/main/dns_core.c?view=diff&rev=433314&r1=433313&r2=433314
==============================================================================
--- team/group/dns_naptr/main/dns_core.c (original)
+++ team/group/dns_naptr/main/dns_core.c Mon Mar 23 12:30:55 2015
@@ -485,7 +485,7 @@
 	end_of_record = ptr + size;
 
 	/* ORDER */
-	order = (ptr[1] << 0) | (ptr[0] << 8);
+	order = ((unsigned char)(ptr[1]) << 0) | ((unsigned char)(ptr[0]) << 8);
 	ptr += 2;
 
 	if (ptr >= end_of_record) {
@@ -493,7 +493,7 @@
 	}
 
 	/* PREFERENCE */
-	preference = (ptr[1] << 0) | (ptr[0] << 8);
+	preference = ((unsigned char) (ptr[1]) << 0) | ((unsigned char)(ptr[0]) << 8);
 	ptr += 2;
 
 	if (ptr >= end_of_record) {
@@ -633,6 +633,9 @@
 
 void ast_dns_resolver_completed(struct ast_dns_query *query)
 {
+	if (ast_dns_query_get_rr_type(query) == ns_t_naptr) {
+		ast_dns_naptr_sort(query->result);
+	}
 	query->callback(query);
 }
 

Modified: team/group/dns_naptr/main/dns_naptr.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/main/dns_naptr.c?view=diff&rev=433314&r1=433313&r2=433314
==============================================================================
--- team/group/dns_naptr/main/dns_naptr.c (original)
+++ team/group/dns_naptr/main/dns_naptr.c Mon Mar 23 12:30:55 2015
@@ -38,6 +38,78 @@
 #include "asterisk/linkedlists.h"
 #include "asterisk/dns_internal.h"
 #include "asterisk/utils.h"
+
+static int compare_order(const void *record1, const void *record2)
+{
+	const struct ast_dns_naptr_record **left = (const struct ast_dns_naptr_record **)record1;
+	const struct ast_dns_naptr_record **right = (const struct ast_dns_naptr_record **)record2;
+
+	if ((*left)->order < (*right)->order) {
+		return -1;
+	} else if ((*left)->order > (*right)->order) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+static int compare_preference(const void *record1, const void *record2)
+{
+	const struct ast_dns_naptr_record **left = (const struct ast_dns_naptr_record **)record1;
+	const struct ast_dns_naptr_record **right = (const struct ast_dns_naptr_record **)record2;
+
+	if ((*left)->preference < (*right)->preference) {
+		return -1;
+	} else if ((*left)->preference > (*right)->preference) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+void ast_dns_naptr_sort(struct ast_dns_result *result)
+{
+	struct ast_dns_record *current;
+	size_t num_records = 0;
+	struct ast_dns_naptr_record **records;
+	int i = 0;
+	int j = 0;
+	int cur_order;
+
+	/* Determine the number of records */
+	AST_LIST_TRAVERSE(&result->records, current, list) {
+		++num_records;
+	}
+
+	/* Allocate an array with that number of records */
+	records = ast_alloca(num_records * sizeof(*records));
+
+	/* Move records from the list to the array */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&result->records, current, list) {
+		records[i++] = (struct ast_dns_naptr_record *) current;
+		AST_LIST_REMOVE_CURRENT(list);
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
+	/* Sort the array by order */
+	qsort(records, num_records, sizeof(*records), compare_order);
+
+	/* Sort subarrays by preference */
+	for (i = 0; i < num_records; i = j) {
+		cur_order = records[i]->order;
+		for (j = i + 1; j < num_records; ++j) {
+			if (records[j]->order != cur_order) {
+				break;
+			}
+		}
+		qsort(&records[i], j - i, sizeof(*records), compare_preference);
+	}
+
+	/* Place sorted records back into the original list */
+	for (i = 0; i < num_records; ++i) {
+		AST_LIST_INSERT_TAIL(&result->records, (struct ast_dns_record *)(records[i]), list);
+	}
+}
 
 const char *ast_dns_naptr_get_flags(const struct ast_dns_record *record)
 {

Modified: team/group/dns_naptr/res/res_resolver_unbound.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/res/res_resolver_unbound.c?view=diff&rev=433314&r1=433313&r2=433314
==============================================================================
--- team/group/dns_naptr/res/res_resolver_unbound.c (original)
+++ team/group/dns_naptr/res/res_resolver_unbound.c Mon Mar 23 12:30:55 2015
@@ -1210,7 +1210,10 @@
 
 	ub_ctx_zone_add(resolver->context, DOMAIN1, "static");
 
-	ub_ctx_data_add(resolver->context, "goose.feathers 12345 IN NAPTR 100 100 A \"Fake service\" \"\" goose.down");
+	ub_ctx_data_add(resolver->context, "goose.feathers 12345 IN NAPTR 200 200 A \"Fake service\" \"\" goose.down");
+	ub_ctx_data_add(resolver->context, "goose.feathers 12345 IN NAPTR 200 100 A \"Fake service\" \"\" duck.down");
+	ub_ctx_data_add(resolver->context, "goose.feathers 12345 IN NAPTR 100 200 A \"Fake service\" \"\" pheasant.down");
+	ub_ctx_data_add(resolver->context, "goose.feathers 12345 IN NAPTR 100 100 A \"Fake service\" \"\" platypus.fur");
 
 	if (ast_dns_resolve(DOMAIN1, ns_t_naptr, ns_c_in, &result)) {
 		ast_test_status_update(test, "Failed to resolve domain\n");
@@ -1228,16 +1231,18 @@
 		return AST_TEST_FAIL;
 	}
 
-	/* XXX This just prints data for my own inspection right now. It will need to actually
-	 * perform a check in order to really pass. This will be done once more NAPTR records
-	 * are added so I can check ordering as well as individual data
-	 */
-	ast_log(LOG_NOTICE, "order is %hu\n", ast_dns_naptr_get_order(record));
-	ast_log(LOG_NOTICE, "preference is %hu\n", ast_dns_naptr_get_preference(record));
-	ast_log(LOG_NOTICE, "flags is %s\n", ast_dns_naptr_get_flags(record));
-	ast_log(LOG_NOTICE, "service is %s\n", ast_dns_naptr_get_service(record));
-	ast_log(LOG_NOTICE, "regexp is %s\n", ast_dns_naptr_get_regexp(record));
-	ast_log(LOG_NOTICE, "replacement is %s\n", ast_dns_naptr_get_replacement(record));
+	for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
+		/* XXX This just prints data for my own inspection right now. It will need to actually
+		 * perform a check in order to really pass. This will be done once more NAPTR records
+		 * are added so I can check ordering as well as individual data
+		 */
+		ast_log(LOG_NOTICE, "order is %hu\n", ast_dns_naptr_get_order(record));
+		ast_log(LOG_NOTICE, "preference is %hu\n", ast_dns_naptr_get_preference(record));
+		ast_log(LOG_NOTICE, "flags is %s\n", ast_dns_naptr_get_flags(record));
+		ast_log(LOG_NOTICE, "service is %s\n", ast_dns_naptr_get_service(record));
+		ast_log(LOG_NOTICE, "regexp is %s\n", ast_dns_naptr_get_regexp(record));
+		ast_log(LOG_NOTICE, "replacement is %s\n", ast_dns_naptr_get_replacement(record));
+	}
 
 	return AST_TEST_PASS;
 




More information about the asterisk-commits mailing list