]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
makefile nicer in case flex is missing.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 13 Aug 2007 10:27:44 +0000 (10:27 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 13 Aug 2007 10:27:44 +0000 (10:27 +0000)
canonical compare.

git-svn-id: file:///svn/unbound/trunk@509 be551aaa-1e26-0410-a405-d3ace91eadb9

Makefile.in
doc/Changelog
util/data/dname.h
validator/val_sigcrypt.c

index c5efeb2a5ee72c5db6a303801b75b7f5d6617a5e..4e6348a6dfe7e433b38bb961a4075533999e398f 100644 (file)
@@ -116,9 +116,14 @@ pktview:   $(PKTVIEW_OBJ)
 util/config_file.c:    util/configparser.h
 util/configlexer.c:  $(srcdir)/util/configlexer.lex util/configparser.h
        $(INFO) Lex $<
+ifeq "$(strip $(LEX))" ":"
+       $Qecho "Need to rebuild lexer, but no lex program"
+       exit 1
+else
        @if test ! -d util; then $(INSTALL) -d util; fi
        $Qecho "#include \"util/configyyrename.h\"" > $@
        $Q$(LEX) -t $< >> $@
+endif
 
 util/configparser.c util/configparser.h:  $(srcdir)/util/configparser.y
        $(INFO) Yacc $<
index b843f44d59b6904eb1ddebe82058e78b0474a586..ca477f7d6283c4323d3df3e6494b7c2a1c57e3ae 100644 (file)
@@ -1,3 +1,8 @@
+13 August 2007: Wouter
+       - fixup makefile, if lexer is missing give nice error and do not
+         mess up the dependencies.
+       - canonical compare routine updated.
+
 10 August 2007: Wouter
        - malloc and free overrides that track total allocation and frees.
          for memory debugging.
index 57f2c2b277632464aca5bfe4b2f3bf6d466665a7..5334e6d6d793685143934fac56b7014af36b3a4c 100644 (file)
@@ -68,6 +68,16 @@ void query_dname_tolower(uint8_t* dname);
 /**
  * Compare query dnames (uncompressed storage). The Dnames passed do not
  * have to be lowercased, comparison routine does this.
+ *
+ * This routine is special, in that the comparison that it does corresponds
+ * with the canonical comparison needed when comparing dnames inside rdata
+ * for RR types that need canonicalization. That means that the first byte
+ * that is smaller (possibly after lowercasing) makes an RR smaller, or the
+ * shortest name makes an RR smaller.
+ *
+ * This routine does not compute the canonical order needed for NSEC 
+ * processing.
+ *
  * Dnames have to be valid format.
  * @param d1: dname to compare
  * @param d2: dname to compare
index d8ced8fd8fc9a6b2df0d66a51ba726105c1d638c..01d6bf914a1915388e935f9a2aa3aa621c7edff4 100644 (file)
@@ -463,97 +463,126 @@ canonical_compare_byfield(struct packed_rrset_data* d,
         *      current position in rdata, length left.
         *      are we in a dname, length left in a label.
         */
-       const ldns_rdf_type* wfi = desc->_wireformat;
-       const ldns_rdf_type* wfj = desc->_wireformat;
-       uint8_t* di = d->rr_data[i]+2;
+       int wfi = -1;   /* current wireformat rdata field (rdf) */
+       int wfj = -1;
+       uint8_t* di = d->rr_data[i]+2; /* ptr to current rdata byte */
        uint8_t* dj = d->rr_data[j]+2;
-       size_t ilen = d->rr_len[i]-2;
+       size_t ilen = d->rr_len[i]-2; /* length left in rdata */
        size_t jlen = d->rr_len[j]-2;
-       int dname_i = 0;
+       int dname_i = 0;  /* true if these bytes are part of a name */
        int dname_j = 0;
-       int lablen_i = 0;
-       int lablen_j = 0;
-       uint8_t bi, bj;
-       /* TODO keep track of number of dnames left */
-
-       /* setup initial state */
-       /* if it is a domain name, set it true, lablen is then 0 to indicate
-        * that the current byte is the label length itself.
-        * If it is a string, get the length of the wireformat
-        */
-       if(*wfi == LDNS_RDF_TYPE_DNAME)
-               dname_i = 1;
-       else if(*wfi == LDNS_RDF_TYPE_STR && ilen > 0)
-               lablen_i = (int)(*di)+1;
-       else    lablen_i = (int)get_rdf_size(*wfi);
-       if(*wfj == LDNS_RDF_TYPE_DNAME)
-               dname_j = 1;
-       else if(*wfj == LDNS_RDF_TYPE_STR && jlen > 0)
-               lablen_j = (int)(*dj)+1;
-       else    lablen_j = (int)get_rdf_size(*wfj);
-
-       while(ilen > 0 && jlen > 0) {
+       size_t lablen_i = 0; /* 0 for label length byte,for first byte of rdf*/
+       size_t lablen_j = 0; /* otherwise remaining length of rdf or label */
+       int dname_num_i = (int)desc->_dname_count; /* decreased at root label */
+       int dname_num_j = (int)desc->_dname_count;
+
+       /* loop while there are rdata bytes available for both rrs,
+        * and still some lowercasing needs to be done; either the dnames
+        * have not been reached yet, or they are currently being processed */
+       while(ilen > 0 && jlen > 0 && (dname_num_i > 0 || dname_num_j > 0)) {
                /* compare these two bytes */
-               /* note that labellengths are <=63 and A is 65 */
-               if(dname_i && lablen_i)
-                       bi = (uint8_t)tolower((int)*di++);
-               else    bi = *di++;
+               /* lowercase if in a dname and not a label length byte */
+               if( ((dname_i && lablen_i)?(uint8_t)tolower((int)*di++):*di++)
+                != ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj++):*dj++)
+                ) {
+                 if(((dname_i && lablen_i)?(uint8_t)tolower((int)*di++):*di++)
+                 < ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj++):*dj++))
+                       return -1;
+                   return 1;
+               }
                ilen--;
-               if(dname_j && lablen_j)
-                       bj = (uint8_t)tolower((int)*dj++);
-               else    bj = *dj++;
                jlen--;
-               if(bi != bj) {
-                       if(bi < bj)
-                               return -1;
-                       return 1;
-               }
                /* bytes are equal */
 
-               if(lablen_i == 0) { /* advance field i */
+               /* advance field i */
+               /* lablen 0 means that this byte is the first byte of the
+                * next rdata field; inspect this rdata field and setup
+                * to process the rest of this rdata field.
+                * The reason to first read the byte, then setup the rdf,
+                * is that we are then sure the byte is available and short
+                * rdata is handled gracefully (even if it is a formerr). */
+               if(lablen_i == 0) { 
                        if(dname_i) {
-                               lablen_i = (int)bi;
-                               if(!lablen_i)
+                               /* scan this dname label */
+                               /* capture length to lowercase */
+                               lablen_i = (size_t)di[-1];
+                               if(lablen_i == 0) {
+                                       /* end root label */
                                        dname_i = 0;
-                       }
-                       if(lablen_i == 0) {
+                                       dname_num_i--;
+                                       /* if dname num is 0, then the
+                                        * remainder is binary only */
+                                       if(dname_num_i == 0)
+                                               lablen_i = ilen;
+                               }
+                       } else {
+                               /* scan this rdata field */
                                wfi++;
-                               if(wfi-desc->_wireformat > (int)desc->_maximum)
-                                       return 0; /* its formerr */
-                               if(*wfi == LDNS_RDF_TYPE_DNAME)
-                                       dname_i = 1;
-                               else if(*wfi == LDNS_RDF_TYPE_STR)
-                                       lablen_i = (int)bi+1;
-                               else    lablen_i = (int)get_rdf_size(*wfi);
+                               if(desc->_wireformat[wfi] 
+                                       == LDNS_RDF_TYPE_DNAME) {
+                                       dname_i = 1; 
+                                       lablen_i = (size_t)di[-1];
+                                       if(lablen_i == 0) {
+                                               dname_i = 0;
+                                               dname_num_i--;
+                                               if(dname_num_i == 0)
+                                                       lablen_i = ilen;
+                                       }
+                               } else if(desc->_wireformat[wfi] 
+                                       == LDNS_RDF_TYPE_STR)
+                                       lablen_i = (size_t)di[-1];
+                               else    lablen_i = get_rdf_size(
+                                       desc->_wireformat[wfi]) - 1;
                        }
-               } else  
-                       lablen_i--;
-               if(lablen_j == 0) { /* advance field j */
+               } else  lablen_i--;
+
+               /* advance field j; same as for i */
+               if(lablen_j == 0) { 
                        if(dname_j) {
-                               lablen_j = (int)bj;
-                               if(!lablen_j)
+                               lablen_j = (size_t)dj[-1];
+                               if(lablen_j == 0) {
                                        dname_j = 0;
+                                       dname_num_j--;
+                                       if(dname_num_j == 0)
+                                               lablen_j = jlen;
+                               }
+                       } else {
+                               wfj++;
+                               if(desc->_wireformat[wfj] 
+                                       == LDNS_RDF_TYPE_DNAME) {
+                                       dname_j = 1; 
+                                       lablen_j = (size_t)dj[-1];
+                                       if(lablen_j == 0) {
+                                               dname_j = 0;
+                                               dname_num_j--;
+                                               if(dname_num_j == 0)
+                                                       lablen_j = jlen;
+                                       }
+                               } else if(desc->_wireformat[wfj] 
+                                       == LDNS_RDF_TYPE_STR)
+                                       lablen_j = (size_t)dj[-1];
+                               else    lablen_j = get_rdf_size(
+                                       desc->_wireformat[wfj]) - 1;
                        }
-                       if(lablen_j == 0) {
-                               wfi++;
-                               if(wfi-desc->_wireformat > (int)desc->_maximum)
-                                       return 0; /* its formerr */
-                               if(*wfi == LDNS_RDF_TYPE_DNAME)
-                                       dname_j = 1;
-                               else if(*wfj == LDNS_RDF_TYPE_STR)
-                                       lablen_j = (int)bj+1;
-                               else    lablen_j = (int)get_rdf_size(*wfj);
-                       }
-               } else
-                       lablen_j--;
-
+               } else  lablen_j--;
        }
+       /* end of the loop; because we advanced byte by byte; now we have
+        * that the rdata has ended, or that there is a binary remainder */
        /* shortest first */
        if(ilen == 0 && jlen == 0)
                return 0;
        if(ilen == 0)
                return -1;
-       return 1;
+       if(jlen == 0)
+               return 1;
+       /* binary remainder, capture comparison in wfi variable */
+       if((wfi = memcmp(di, dj, (ilen<jlen)?ilen:jlen)) != 0)
+               return wfi;
+       if(ilen < jlen)
+               return -1;
+       if(jlen < ilen)
+               return 1;
+       return 0;
 }
 
 /**
@@ -578,7 +607,8 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
                return 0;
 
        switch(type) {
-               /* only a name */
+               /* These RR types have only a name as RDATA. 
+                * This name has to be canonicalized.*/
                case LDNS_RR_TYPE_NS:
                case LDNS_RR_TYPE_MD:
                case LDNS_RR_TYPE_MF:
@@ -591,7 +621,11 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
                        return query_dname_compare(d->rr_data[i]+2, 
                                d->rr_data[j]+2);
 
-               /* type starts with the name */
+               /* These RR types have STR and fixed size rdata fields
+                * before one or more name fields that need canonicalizing,
+                * and after that a byte-for byte remainder can be compared.
+                */
+               /* type starts with the name; remainder is binary compared */
                case LDNS_RR_TYPE_NXT: 
                case LDNS_RR_TYPE_NSEC: 
                /* use rdata field formats */
@@ -613,10 +647,13 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
                        log_assert(desc->_minimum == desc->_maximum);
                        return canonical_compare_byfield(d, desc, i, j);
 
-               /* special (TXT is lowercased) */
+               /* This RR type is special, as the contents of text fields
+                * is lowercased. */
                case LDNS_RR_TYPE_HINFO:
 
        default:
+               /* For unknown RR types, or types not listed above,
+                * no canonicalization is needed, do binary compare */
                /* byte for byte compare, equal means shortest first*/
                minlen = d->rr_len[i]-2;
                if(minlen > d->rr_len[j]-2)
@@ -624,10 +661,12 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
                c = memcmp(d->rr_data[i]+2, d->rr_data[j]+2, minlen);
                if(c!=0)
                        return c;
+               /* rdata equal, shortest is first */
                if(d->rr_len[i] < d->rr_len[j])
                        return -1;
                if(d->rr_len[i] > d->rr_len[j])
                        return 1;
+               /* rdata equal, length equal */
                break;
        }
        return 0;