]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
sorting algorithm was incorrect for dnssec canonical sorting.
authorJelte Jansen <jeltejan@NLnetLabs.nl>
Mon, 14 Nov 2005 13:53:58 +0000 (13:53 +0000)
committerJelte Jansen <jeltejan@NLnetLabs.nl>
Mon, 14 Nov 2005 13:53:58 +0000 (13:53 +0000)
dname.c
dnssec.c
ldns/dname.h
rr.c
str2host.c

diff --git a/dname.c b/dname.c
index 93530c859f7c03c6d4f87ad34d07ead44a465923..15adba842ed3c5ac119b88a0f6c49d739ab5301a 100644 (file)
--- a/dname.c
+++ b/dname.c
@@ -212,6 +212,46 @@ ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
        return true; 
 }
 
+int
+ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
+{
+       size_t lc1, lc2;
+       ldns_rdf *label1, *label2;
+       size_t i;
+       /* see RFC4034 for this algorithm */
+       /* this algorithm assumes the names are normalized to case */
+       
+       lc1 = ldns_dname_label_count(dname1) - 1;
+       lc2 = ldns_dname_label_count(dname2) - 1;
+       
+       while (true) {
+               label1 = ldns_dname_label(dname1, lc1);
+               label2 = ldns_dname_label(dname2, lc2);
+               if (ldns_rdf_size(label1) < ldns_rdf_size(label2)) {
+                       return -1;
+               } else if (ldns_rdf_size(label1) > ldns_rdf_size(label2)) {
+                       return 1;
+               } else {
+                       for (i = 0; i < ldns_rdf_size(label1); i++) {
+                               if (ldns_rdf_data(label1)[i] < ldns_rdf_data(label2)[i]) {
+                                       return -1;
+                               } else if (ldns_rdf_data(label1)[i] > ldns_rdf_data(label2)[i]) {
+                                       return 1;
+                               }
+                       }
+               }
+               if (lc1 == 0 && lc2 > 0) {
+                       return -1;
+               } else if (lc1 > 0 && lc2 == 0) {
+                       return 1;
+               } else if (lc1 == 0 && lc2 == 0) {
+                       return 0;
+               }
+               lc1--;
+               lc2--;
+       }
+}
+
 bool
 ldns_dname_str_absolute(const char *dname_str)
 {
index 50c67954ddbd8544d937f42719724caeaf1e7c22..4ce4da50be9d7880e96931a62c80d553577a0553 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -1188,10 +1188,11 @@ ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list)
        }
        signed_zone_rrs = ldns_rr_list_new();
 
-       ldns_rr_list_sort_oct(orig_zone_rrs);
+       ldns_rr_list_sort(orig_zone_rrs);
        
        /* add nsecs */
        for (i = 0; i < ldns_rr_list_rr_count(orig_zone_rrs); i++) {
+               ldns_rr_list_push_rr(signed_zone_rrs, ldns_rr_list_rr(orig_zone_rrs, i));
                if (!start_dname) {
                        /*start_dname = ldns_rr_owner(ldns_zone_soa(zone));*/
                        start_dname = ldns_rr_owner(ldns_rr_list_rr(orig_zone_rrs, i));
@@ -1199,7 +1200,6 @@ ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list)
                } else {
                        next_rr = ldns_rr_list_rr(orig_zone_rrs, i);
                        next_dname = ldns_rr_owner(next_rr);
-                       ldns_rr_list_push_rr(signed_zone_rrs, ldns_rr_list_rr(orig_zone_rrs, i));
                        if (ldns_rdf_compare(cur_dname, next_dname) != 0) {
                                /* skip glue */
                                if (ldns_rr_list_contains_rr(glue_rrs, next_rr)) {
index e7d54e6b98c84efca49ee6ac35d9aed7b902fd2c..6098ba6075f632244d9d0631c60a5352927515ed 100644 (file)
@@ -85,6 +85,15 @@ void ldns_dname2canonical(const ldns_rdf *rdf);
  */
 bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent);
 
+/**
+ * Compares the two dname rdf's according to the algorithm for ordering
+ * in RFC4034 Section 6.
+ * \param[in] dname1 First dname rdf to compare
+ * \param[in] dname1 Second dname rdf to compare
+ * \return -1 if dname1 comes before dname2, 1 if dname1 comes after dname2, and 0 if they are equal.
+ */
+int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2);
+
 /**
  * Checks whether the given dname string is absolute (i.e. ends with a '.')
  * \param[in] *dname_str a string representing the dname
diff --git a/rr.c b/rr.c
index 732d4cb113317190eabe2f0f1ba99f33fd777905..9867d428d8f85eb09b9626720a78205b437bbac4 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -1107,8 +1107,7 @@ ldns_rr_compare_oct(const ldns_rr *rr1, const ldns_rr *rr2)
        c1 = ldns_rr_get_class(rr1);
        c2 = ldns_rr_get_class(rr2);
        t1 = ldns_rr_get_type(rr1);
-       t2 = ldns_rr_get_type(rr2);
-       
+       t2 = ldns_rr_get_type(rr2);     
        
        result = strcmp(n1, n2);
        if (result == 0) {
@@ -1145,6 +1144,11 @@ ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
        rr1_len = ldns_rr_uncompressed_size(rr1);
        rr2_len = ldns_rr_uncompressed_size(rr2);
 
+       if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) < 0) {
+               return -1;
+       } else if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) > 0) {
+               return 1;
+       }
        if (rr1_len < rr2_len) {
                return -1;
        } else if (rr1_len > rr2_len) {
index f2b7926caa59b4916b2a45d4767e0f232dfd806a..8ea7cc144d51a5af7bb9f2dc4cdcfe661dce066a 100644 (file)
@@ -159,7 +159,8 @@ ldns_str2rdf_dname(ldns_rdf **d, const char *str)
        *d = NULL;
        
        len = strlen((char*)str);
-       if (len > LDNS_MAX_DOMAINLEN) {
+       /* octet representation can make strings a lot longer than actual length */
+       if (len > LDNS_MAX_DOMAINLEN * 3) {
                return LDNS_STATUS_DOMAINNAME_OVERFLOW;
        }
        if (0 == len) {