[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