]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
dname compare lower case version. Preserves case.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 12 Apr 2007 14:02:02 +0000 (14:02 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 12 Apr 2007 14:02:02 +0000 (14:02 +0000)
git-svn-id: file:///svn/unbound/trunk@238 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
testcode/unitmain.c
util/data/dname.c
util/data/dname.h
util/data/msgreply.c

index 065a0b6d4492704ae3c2cd5fcbf3314fa2c544ae..8f7c0bb2f524ca309b61635ce959a372460744aa 100644 (file)
@@ -1,6 +1,10 @@
+12 April 2007: Wouter
+       - dname compare routine that preserves case, with unit tests.
+       
 11 April 2007: Wouter
        - parse work - dname packet parse, msgparse, querysection parse,
          start of sectionparse.
+
 10 April 2007: Wouter
        - Improved alignment of reply_info packet, nice for 32 and 64 bit.
        - Put RRset counts in reply_info, because the number of RRs can change
index 5f16d8970fd1e4d130eed3ecfaa44f0e278efc18..0dd883cebe76a5ee5ff379da653914b9073ac9ef 100644 (file)
@@ -167,6 +167,31 @@ msgreply_test()
        query_dname_tolower(ldns_buffer_begin(buff), 4);
        unit_assert( memcmp(ldns_buffer_begin(buff), "\002nl\000", 4) == 0);
 
+       /* test query_dname_compare */
+       unit_assert(query_dname_compare((uint8_t*)"", (uint8_t*)"") == 0);
+       unit_assert(query_dname_compare((uint8_t*)"\001a", 
+                                       (uint8_t*)"\001a") == 0);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001a", 
+                                       (uint8_t*)"\003abc\001a") == 0);
+       unit_assert(query_dname_compare((uint8_t*)"\003aBc\001a", 
+                                       (uint8_t*)"\003AbC\001A") == 0);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc", 
+                                       (uint8_t*)"\003abc\001a") == -1);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001a", 
+                                       (uint8_t*)"\003abc") == +1);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001a", 
+                                       (uint8_t*)"") == +1);
+       unit_assert(query_dname_compare((uint8_t*)"", 
+                                       (uint8_t*)"\003abc\001a") == -1);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001a", 
+                                       (uint8_t*)"\003xxx\001a") == -1);
+       unit_assert(query_dname_compare((uint8_t*)"\003axx\001a", 
+                                       (uint8_t*)"\003abc\001a") == 1);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001a", 
+                                       (uint8_t*)"\003abc\001Z") == -1);
+       unit_assert(query_dname_compare((uint8_t*)"\003abc\001Z", 
+                                       (uint8_t*)"\003abc\001a") == 1);
+
        ldns_buffer_free(buff);
 }
 
index 8c8c0e80daee7009aab683fbd1fbdf2d5edcac1b..b9d0bdfc8e07e3c85411b2afbddc43875407d7b9 100644 (file)
@@ -66,6 +66,39 @@ query_dname_len(ldns_buffer* query)
        }
 }
 
+int 
+query_dname_compare(uint8_t* d1, uint8_t* d2)
+{
+       uint8_t lab1, lab2;
+       log_assert(d1 && d2);
+       lab1 = *d1++;
+       lab2 = *d2++;
+       while( lab1 != 0 || lab2 != 0 ) {
+               /* compare label length */
+               /* if one dname ends, it has labellength 0 */
+               if(lab1 != lab2) {
+                       if(lab1 < lab2)
+                               return -1;
+                       return 1;
+               }
+               log_assert(lab1 == lab2 && lab1 != 0);
+               /* compare lowercased labels. */
+               while(lab1--) {
+                       if(tolower((int)*d1) != tolower((int)*d2)) {
+                               if(tolower((int)*d1) < tolower((int)*d2))
+                                       return -1;
+                               return 1;
+                       }
+                       d1++;
+                       d2++;
+               }
+               /* next pair of labels. */
+               lab1 = *d1++;
+               lab2 = *d2++;
+       }
+       return 0;
+}
+
 void 
 query_dname_tolower(uint8_t* dname, size_t len)
 {
index 4a10bdce6d1325274db8775476f99329d8732368..ce4eaecf3ea6ed6344436a00676c456dc00dae13 100644 (file)
@@ -56,6 +56,17 @@ size_t query_dname_len(ldns_buffer* query);
 /** lowercase query dname */
 void query_dname_tolower(uint8_t* dname, size_t len);
 
+/**
+ * Compare query dnames (uncompressed storage). The Dnames passed do not
+ * have to be lowercased, comparison routine does this.
+ * Dnames have to be valid format.
+ * @param d1: dname to compare
+ * @param d2: dname to compare
+ * @return: -1, 0, or +1 depending on comparison results.
+ *     Sort order is first difference found. not the canonical ordering.
+ */
+int query_dname_compare(uint8_t* d1, uint8_t* d2);
+
 /**
  * Determine correct, compressed, dname present in packet.
  * Checks for parse errors.
index d7f5ff1918242c9603332afd760436fb2d0c44fa..b69e984d1acbeeb30b64a5ffd9518697e11e7359 100644 (file)
@@ -385,9 +385,9 @@ query_info_compare(void* m1, void* m2)
        int mc;
        /* from most different to least different for speed */
        COMPARE_IT(msg1->qtype, msg2->qtype);
-       COMPARE_IT(msg1->qnamesize, msg2->qnamesize);
-       if((mc = memcmp(msg1->qname, msg2->qname, msg1->qnamesize)) != 0)
+       if((mc = query_dname_compare(msg1->qname, msg2->qname)) != 0)
                return mc;
+       log_assert(msg1->qnamesize == msg2->qnamesize);
        COMPARE_IT(msg1->has_cd, msg2->has_cd);
        COMPARE_IT(msg1->qclass, msg2->qclass);
        return 0;
@@ -437,12 +437,30 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg))
 hashvalue_t 
 query_info_hash(struct query_info *q)
 {
+       uint8_t labuf[LDNS_MAX_LABELLEN+1];
+       uint8_t lablen;
+       uint8_t* d;
+       int i;
+
        hashvalue_t h = 0xab;
        h = hashlittle(&q->qtype, sizeof(q->qtype), h);
        h = hashlittle(&q->qclass, sizeof(q->qclass), h);
        h = hashlittle(&q->has_cd, sizeof(q->has_cd), h);
-       query_dname_tolower(q->qname, q->qnamesize);
-       h = hashlittle(q->qname, q->qnamesize, h);
+
+       /* preserve case of query, make hash label by label */
+       d = q->qname;
+       lablen = *d;
+       while(lablen) {
+               log_assert(lablen <= LDNS_MAX_LABELLEN);
+               labuf[0] = lablen;
+               d++;
+               i=0;
+               while(lablen--)
+                       labuf[++i] = (uint8_t)tolower((int)*d++);
+               h = hashlittle(labuf, labuf[0] + 1, h);
+               lablen = *d;
+       }
+
        return h;
 }