[svn-commits] file: branch group/dns_srv r433316 - in /team/group/dns_srv: ./ include/aster...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Mar 23 13:16:00 CDT 2015


Author: file
Date: Mon Mar 23 13:15:59 2015
New Revision: 433316

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=433316
Log:
Merge in conflicting changes.

Modified:
    team/group/dns_srv/   (props changed)
    team/group/dns_srv/include/asterisk/dns_internal.h
    team/group/dns_srv/main/dns_core.c
    team/group/dns_srv/main/dns_naptr.c
    team/group/dns_srv/res/res_resolver_unbound.c

Propchange: team/group/dns_srv/
------------------------------------------------------------------------------
--- srv-integrated (original)
+++ srv-integrated Mon Mar 23 13:15:59 2015
@@ -1,1 +1,1 @@
-/team/group/dns_naptr:1-433302
+/team/group/dns_naptr:1-433315

Modified: team/group/dns_srv/include/asterisk/dns_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_srv/include/asterisk/dns_internal.h?view=diff&rev=433316&r1=433315&r2=433316
==============================================================================
--- team/group/dns_srv/include/asterisk/dns_internal.h (original)
+++ team/group/dns_srv/include/asterisk/dns_internal.h Mon Mar 23 13:15:59 2015
@@ -169,4 +169,24 @@
  *
  * \param result The DNS result
  */
-void ast_dns_srv_sort(struct ast_dns_result *result);
+void ast_dns_srv_sort(struct ast_dns_result *result);
+
+/*!
+ * \brief Allocate and parse a DNS NAPTR record
+ *
+ * \param query The DNS query
+ * \param data This specific NAPTR record
+ * \param size The size of the NAPTR record
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_dns_record *ast_dns_naptr_alloc(struct ast_dns_query *query, const char *data, const size_t size);
+
+/*!
+ * \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_srv/main/dns_core.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_srv/main/dns_core.c?view=diff&rev=433316&r1=433315&r2=433316
==============================================================================
--- team/group/dns_srv/main/dns_core.c (original)
+++ team/group/dns_srv/main/dns_core.c Mon Mar 23 13:15:59 2015
@@ -45,7 +45,6 @@
 
 #include <netinet/in.h>
 #include <arpa/nameser.h>
-#include <resolv.h>
 
 AST_RWLIST_HEAD_STATIC(resolvers, ast_dns_resolver);
 
@@ -427,155 +426,6 @@
 	return record;
 }
 
-static struct ast_dns_record *naptr_record_alloc(struct ast_dns_query *query, const char *data, const size_t size)
-{
-	struct ast_dns_naptr_record *naptr;
-	char *ptr = NULL;
-	uint16_t order;
-	uint16_t preference;
-	uint8_t flags_size;
-	char *flags;
-	uint8_t services_size;
-	char *services;
-	uint8_t regexp_size;
-	char *regexp;
-	char replacement[256] = "";
-	int replacement_size;
-	char *naptr_offset;
-	char *naptr_search_base = (char *)query->result->answer;
-	size_t remaining_size = query->result->answer_size;
-	char *end_of_record;
-
-	/* 
-	 * This is bordering on the hackiest thing I've ever written.
-	 * Part of parsing a NAPTR record is to parse a potential replacement
-	 * domain name. Decoding this domain name requires the use of the
-	 * dn_expand() function. This function requires that the domain you
-	 * pass in be a pointer to within the full DNS answer. Unfortunately,
-	 * libunbound gives its RRs back as copies of data from the DNS answer
-	 * instead of pointers to within the DNS answer. This means that in order
-	 * to be able to parse the domain name correctly, I need to find the
-	 * current NAPTR record inside the DNS answer and operate on it. This
-	 * loop is designed to find the current NAPTR record within the full
-	 * DNS answer and set the "ptr" variable to the beginning of the
-	 * NAPTR RDATA
-	 */
-	while (1) {
-		naptr_offset = memchr(naptr_search_base, data[0], remaining_size);
-
-		/* Since the NAPTR record we have been given came from the DNS answer,
-		 * we should never run into a situation where we can't find ourself
-		 * in the answer
-		 */
-		ast_assert(naptr_offset != NULL);
-		ast_assert(naptr_search_base + remaining_size - naptr_offset >= size);
-		
-		if (!memcmp(naptr_offset, data, size)) {
-			/* BAM! FOUND IT! */
-			ptr = naptr_offset;
-			break;
-		}
-		/* Data didn't match us, so keep looking */
-		remaining_size -= naptr_offset - naptr_search_base;
-		naptr_search_base = naptr_offset + 1;
-	}
-
-	ast_assert(ptr != NULL);
-
-	end_of_record = ptr + size;
-
-	/* ORDER */
-	order = (ptr[1] << 0) | (ptr[0] << 8);
-	ptr += 2;
-
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-
-	/* PREFERENCE */
-	preference = (ptr[1] << 0) | (ptr[0] << 8);
-	ptr += 2;
-
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-
-	/* FLAGS */
-	flags_size = *ptr;
-	++ptr;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-	flags = ptr;
-	ptr += flags_size;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-
-	/* SERVICES */
-	services_size = *ptr;
-	++ptr;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-	services = ptr;
-	ptr += services_size;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-
-	/* REGEXP */
-	regexp_size = *ptr;
-	++ptr;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-	regexp = ptr;
-	ptr += regexp_size;
-	if (ptr >= end_of_record) {
-		return NULL;
-	}
-
-	replacement_size = dn_expand((unsigned char *)query->result->answer, (unsigned char *) end_of_record, (unsigned char *) ptr, replacement, sizeof(replacement) - 1);
-	if (replacement_size < 0) {
-		ast_log(LOG_ERROR, "Failed to expand domain name: %s\n", strerror(errno));
-		return NULL;
-	}
-
-	naptr = ast_calloc(1, sizeof(*naptr) + size + flags_size + 1 + services_size + 1 + regexp_size + 1 + replacement_size + 1);
-	if (!naptr) {
-		return NULL;
-	}
-
-	naptr->order = order;
-	naptr->preference = preference;
-
-	ptr = naptr->data;
-	ptr += size;
-
-	strncpy(ptr, flags, flags_size);
-	ptr[flags_size] = '\0';
-	naptr->flags = ptr;
-	ptr += flags_size + 1;
-
-	strncpy(ptr, services, services_size);
-	ptr[services_size] = '\0';
-	naptr->service = ptr;
-	ptr += services_size + 1;
-
-	strncpy(ptr, regexp, regexp_size);
-	ptr[regexp_size] = '\0';
-	naptr->regexp = ptr;
-	ptr += regexp_size + 1;
-
-	strcpy(ptr, replacement);
-	naptr->replacement = ptr;
-
-	naptr->generic.data_ptr = naptr->data;
-
-	return (struct ast_dns_record *)naptr;
-}
-
 int ast_dns_resolver_add_record(struct ast_dns_query *query, int rr_type, int rr_class, int ttl, const char *data, const size_t size)
 {
 	struct ast_dns_record *record;
@@ -611,7 +461,7 @@
 	}
 
 	if (rr_type == ns_t_naptr) {
-		record = naptr_record_alloc(query, data, size);
+		record = ast_dns_naptr_alloc(query, data, size);
 	} else if (rr_type == ns_t_srv) {
 		record = ast_dns_srv_alloc(query, data, size);
 	} else {
@@ -637,6 +487,8 @@
 {
 	if (ast_dns_query_get_rr_type(query) == ns_t_srv) {
 		ast_dns_srv_sort(query->result);
+	} else if (ast_dns_query_get_rr_type(query) == ns_t_naptr) {
+		ast_dns_naptr_sort(query->result);
 	}
 
 	query->callback(query);

Modified: team/group/dns_srv/main/dns_naptr.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_srv/main/dns_naptr.c?view=diff&rev=433316&r1=433315&r2=433316
==============================================================================
--- team/group/dns_srv/main/dns_naptr.c (original)
+++ team/group/dns_srv/main/dns_naptr.c Mon Mar 23 13:15:59 2015
@@ -32,6 +32,7 @@
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <arpa/nameser.h>
+#include <resolv.h>
 
 #include "asterisk/dns_core.h"
 #include "asterisk/dns_naptr.h"
@@ -39,6 +40,228 @@
 #include "asterisk/dns_internal.h"
 #include "asterisk/utils.h"
 
+struct ast_dns_record *ast_dns_naptr_alloc(struct ast_dns_query *query, const char *data, const size_t size)
+{
+	struct ast_dns_naptr_record *naptr;
+	char *ptr = NULL;
+	uint16_t order;
+	uint16_t preference;
+	uint8_t flags_size;
+	char *flags;
+	uint8_t services_size;
+	char *services;
+	uint8_t regexp_size;
+	char *regexp;
+	char replacement[256] = "";
+	int replacement_size;
+	char *naptr_offset;
+	char *naptr_search_base = (char *)query->result->answer;
+	size_t remaining_size = query->result->answer_size;
+	char *end_of_record;
+
+	/* 
+	 * This is bordering on the hackiest thing I've ever written.
+	 * Part of parsing a NAPTR record is to parse a potential replacement
+	 * domain name. Decoding this domain name requires the use of the
+	 * dn_expand() function. This function requires that the domain you
+	 * pass in be a pointer to within the full DNS answer. Unfortunately,
+	 * libunbound gives its RRs back as copies of data from the DNS answer
+	 * instead of pointers to within the DNS answer. This means that in order
+	 * to be able to parse the domain name correctly, I need to find the
+	 * current NAPTR record inside the DNS answer and operate on it. This
+	 * loop is designed to find the current NAPTR record within the full
+	 * DNS answer and set the "ptr" variable to the beginning of the
+	 * NAPTR RDATA
+	 */
+	while (1) {
+		naptr_offset = memchr(naptr_search_base, data[0], remaining_size);
+
+		/* Since the NAPTR record we have been given came from the DNS answer,
+		 * we should never run into a situation where we can't find ourself
+		 * in the answer
+		 */
+		ast_assert(naptr_offset != NULL);
+		ast_assert(naptr_search_base + remaining_size - naptr_offset >= size);
+		
+		if (!memcmp(naptr_offset, data, size)) {
+			/* BAM! FOUND IT! */
+			ptr = naptr_offset;
+			break;
+		}
+		/* Data didn't match us, so keep looking */
+		remaining_size -= naptr_offset - naptr_search_base;
+		naptr_search_base = naptr_offset + 1;
+	}
+
+	ast_assert(ptr != NULL);
+
+	end_of_record = ptr + size;
+
+	/* ORDER */
+	order = ((unsigned char)(ptr[1]) << 0) | ((unsigned char)(ptr[0]) << 8);
+	ptr += 2;
+
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+
+	/* PREFERENCE */
+	preference = ((unsigned char) (ptr[1]) << 0) | ((unsigned char)(ptr[0]) << 8);
+	ptr += 2;
+
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+
+	/* FLAGS */
+	flags_size = *ptr;
+	++ptr;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+	flags = ptr;
+	ptr += flags_size;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+
+	/* SERVICES */
+	services_size = *ptr;
+	++ptr;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+	services = ptr;
+	ptr += services_size;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+
+	/* REGEXP */
+	regexp_size = *ptr;
+	++ptr;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+	regexp = ptr;
+	ptr += regexp_size;
+	if (ptr >= end_of_record) {
+		return NULL;
+	}
+
+	replacement_size = dn_expand((unsigned char *)query->result->answer, (unsigned char *) end_of_record, (unsigned char *) ptr, replacement, sizeof(replacement) - 1);
+	if (replacement_size < 0) {
+		ast_log(LOG_ERROR, "Failed to expand domain name: %s\n", strerror(errno));
+		return NULL;
+	}
+
+	naptr = ast_calloc(1, sizeof(*naptr) + size + flags_size + 1 + services_size + 1 + regexp_size + 1 + replacement_size + 1);
+	if (!naptr) {
+		return NULL;
+	}
+
+	naptr->order = order;
+	naptr->preference = preference;
+
+	ptr = naptr->data;
+	ptr += size;
+
+	strncpy(ptr, flags, flags_size);
+	ptr[flags_size] = '\0';
+	naptr->flags = ptr;
+	ptr += flags_size + 1;
+
+	strncpy(ptr, services, services_size);
+	ptr[services_size] = '\0';
+	naptr->service = ptr;
+	ptr += services_size + 1;
+
+	strncpy(ptr, regexp, regexp_size);
+	ptr[regexp_size] = '\0';
+	naptr->regexp = ptr;
+	ptr += regexp_size + 1;
+
+	strcpy(ptr, replacement);
+	naptr->replacement = ptr;
+
+	naptr->generic.data_ptr = naptr->data;
+
+	return (struct ast_dns_record *)naptr;
+}
+
+
+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)
 {
 	struct ast_dns_naptr_record *naptr = (struct ast_dns_naptr_record *) record;

Modified: team/group/dns_srv/res/res_resolver_unbound.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_srv/res/res_resolver_unbound.c?view=diff&rev=433316&r1=433315&r2=433316
==============================================================================
--- team/group/dns_srv/res/res_resolver_unbound.c (original)
+++ team/group/dns_srv/res/res_resolver_unbound.c Mon Mar 23 13:15:59 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 svn-commits mailing list