[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