]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Drill trace continue on non-terminals with NSEC3
authorWillem Toorop <willem@nlnetlabs.nl>
Wed, 21 Aug 2013 21:16:52 +0000 (23:16 +0200)
committerWillem Toorop <willem@nlnetlabs.nl>
Wed, 21 Aug 2013 21:16:52 +0000 (23:16 +0200)
Changelog
drill/securetrace.c

index 0c185b5e02238f44f96424671b93e74eb392758d..34add1693d7d5d5c2d4238b1e6f3afa2b04dca89 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -43,6 +43,7 @@
        * Bump version to 1.7.0
        * The version of shared library now has similar scheme as libunbound.
          ldns 1.7.0 will have shared library version (SONAME) 2.0.0
+       * bugfix #521: drill trace continue on empty non-terminals with NSEC3
 
 1.6.16 2012-11-13
        * Fix Makefile to build pyldns with BSD make
index 408ec13659e9d558343899096e89b8f1c9474249..5fc493a7275d65f44386a89c1599183d12a1d8f7 100644 (file)
@@ -156,6 +156,9 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
 
        /* empty non-terminal check */
        bool ent;
+       ldns_rr  *nsecrr;      /* The nsec that proofs the non-terminal */
+       ldns_rdf *hashed_name; /* The query hashed with nsec3 params */
+       ldns_rdf *label0;      /* The first label of an nsec3 owner name */
 
        /* glue handling */
        ldns_rr_list *new_ns_addr;
@@ -382,8 +385,27 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                /* there might be an empty non-terminal, in which case we need to continue */
                                ent = false;
                                for (j = 0; j < ldns_rr_list_rr_count(nsec_rrs); j++) {
-                                       if (ldns_dname_is_subdomain(ldns_rr_rdf(ldns_rr_list_rr(nsec_rrs, j), 0), labels[i])) {
+                                       nsecrr = ldns_rr_list_rr(nsec_rrs, j);
+                                       /* For NSEC when the next name is a subdomain of the question */
+                                       if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC &&
+                                                       ldns_dname_is_subdomain(ldns_rr_rdf(nsecrr, 0), labels[i])) {
                                                ent = true;
+
+                                       /* For NSEC3, the hash matches the name and the type bitmap is empty*/
+                                       } else if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC3) {
+                                               hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsecrr, labels[i]);
+                                               label0 = ldns_dname_label(ldns_rr_owner(nsecrr), 0);
+                                               if (hashed_name && label0 &&
+                                                               ldns_dname_compare(hashed_name, label0) == 0 &&
+                                                               ldns_nsec3_bitmap(nsecrr) == NULL) {
+                                                       ent = true;
+                                               }
+                                               if (label0) {
+                                                       LDNS_FREE(label0);
+                                               }
+                                               if (hashed_name) {
+                                                       LDNS_FREE(hashed_name);
+                                               }
                                        }
                                }
                                if (!ent) {