dname compare lower case version. Preserves case.

git-svn-id: file:///svn/unbound/trunk@238 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-04-12 14:02:02 +00:00
parent 6763650624
commit eb51f48214
5 changed files with 95 additions and 4 deletions

View file

@ -1,6 +1,10 @@
12 April 2007: Wouter
- dname compare routine that preserves case, with unit tests.
11 April 2007: Wouter 11 April 2007: Wouter
- parse work - dname packet parse, msgparse, querysection parse, - parse work - dname packet parse, msgparse, querysection parse,
start of sectionparse. start of sectionparse.
10 April 2007: Wouter 10 April 2007: Wouter
- Improved alignment of reply_info packet, nice for 32 and 64 bit. - 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 - Put RRset counts in reply_info, because the number of RRs can change

View file

@ -167,6 +167,31 @@ msgreply_test()
query_dname_tolower(ldns_buffer_begin(buff), 4); query_dname_tolower(ldns_buffer_begin(buff), 4);
unit_assert( memcmp(ldns_buffer_begin(buff), "\002nl\000", 4) == 0); 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); ldns_buffer_free(buff);
} }

View 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 void
query_dname_tolower(uint8_t* dname, size_t len) query_dname_tolower(uint8_t* dname, size_t len)
{ {

View file

@ -56,6 +56,17 @@ size_t query_dname_len(ldns_buffer* query);
/** lowercase query dname */ /** lowercase query dname */
void query_dname_tolower(uint8_t* dname, size_t len); 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. * Determine correct, compressed, dname present in packet.
* Checks for parse errors. * Checks for parse errors.

View file

@ -385,9 +385,9 @@ query_info_compare(void* m1, void* m2)
int mc; int mc;
/* from most different to least different for speed */ /* from most different to least different for speed */
COMPARE_IT(msg1->qtype, msg2->qtype); COMPARE_IT(msg1->qtype, msg2->qtype);
COMPARE_IT(msg1->qnamesize, msg2->qnamesize); if((mc = query_dname_compare(msg1->qname, msg2->qname)) != 0)
if((mc = memcmp(msg1->qname, msg2->qname, msg1->qnamesize)) != 0)
return mc; return mc;
log_assert(msg1->qnamesize == msg2->qnamesize);
COMPARE_IT(msg1->has_cd, msg2->has_cd); COMPARE_IT(msg1->has_cd, msg2->has_cd);
COMPARE_IT(msg1->qclass, msg2->qclass); COMPARE_IT(msg1->qclass, msg2->qclass);
return 0; return 0;
@ -437,12 +437,30 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg))
hashvalue_t hashvalue_t
query_info_hash(struct query_info *q) 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; hashvalue_t h = 0xab;
h = hashlittle(&q->qtype, sizeof(q->qtype), h); h = hashlittle(&q->qtype, sizeof(q->qtype), h);
h = hashlittle(&q->qclass, sizeof(q->qclass), h); h = hashlittle(&q->qclass, sizeof(q->qclass), h);
h = hashlittle(&q->has_cd, sizeof(q->has_cd), 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; return h;
} }