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;
 


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to