From: Willem Toorop Date: Tue, 17 May 2011 14:19:00 +0000 (+0000) Subject: A new function tha X-Git-Tag: release-1.6.10rc1~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ecba4c23ff239d072f45d117a3f4279dd505673;p=thirdparty%2Fldns.git A new function tha --- diff --git a/dnssec.c b/dnssec.c index ae50996c..6550a910 100644 --- a/dnssec.c +++ b/dnssec.c @@ -764,21 +764,6 @@ ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets, return 0; } -/* returns true if the current dnssec_rrset from the given list of rrsets - * is glue */ -static int -is_glue(ldns_dnssec_rrsets *cur_rrsets, ldns_dnssec_rrsets *orig_rrsets) -{ - /* only glue if a or aaaa with names that have an NS rrset and are not the - apex (do not have a soa rrset) */ - return (cur_rrsets->type == LDNS_RR_TYPE_A || - cur_rrsets->type == LDNS_RR_TYPE_AAAA) && - (ldns_dnssec_rrsets_contains_type(orig_rrsets, - LDNS_RR_TYPE_NS) && - !ldns_dnssec_rrsets_contains_type(orig_rrsets, - LDNS_RR_TYPE_SOA)); -} - ldns_rr * ldns_dnssec_create_nsec(ldns_dnssec_name *from, ldns_dnssec_name *to, @@ -788,6 +773,7 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from, ldns_rr_type types[65536]; size_t type_count = 0; ldns_dnssec_rrsets *cur_rrsets; + int on_delegation_point; if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC && nsec_type != LDNS_RR_TYPE_NSEC3)) { @@ -799,14 +785,22 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from, ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from))); ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to))); + on_delegation_point = ldns_dnssec_rrsets_contains_type( + from->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + from->rrsets, LDNS_RR_TYPE_SOA); + cur_rrsets = from->rrsets; while (cur_rrsets) { - if (is_glue(cur_rrsets, from->rrsets)) { - cur_rrsets = cur_rrsets->next; - continue; - } - if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG && - cur_rrsets->type != LDNS_RR_TYPE_NSEC) { + /* Do not include obscured rrsets on the delegation point + * in the type bitmap */ + if ( ( on_delegation_point && ( + cur_rrsets->type == LDNS_RR_TYPE_NS + || cur_rrsets->type == LDNS_RR_TYPE_DS)) + || (!on_delegation_point && + cur_rrsets->type != LDNS_RR_TYPE_RRSIG + && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) { + types[type_count] = cur_rrsets->type; type_count++; } @@ -840,6 +834,7 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from, size_t type_count = 0; ldns_dnssec_rrsets *cur_rrsets; ldns_status status; + int on_delegation_point; flags = flags; @@ -866,13 +861,23 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from, salt_length, salt); + on_delegation_point = ldns_dnssec_rrsets_contains_type( + from->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + from->rrsets, LDNS_RR_TYPE_SOA); cur_rrsets = from->rrsets; while (cur_rrsets) { - if (is_glue(cur_rrsets, from->rrsets)) { - cur_rrsets = cur_rrsets->next; - continue; - } - if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG) { + /* Do not include obscured rrsets on the delegation point + * in the type bitmap. Potentionally not skipping insecure + * delegation should have been done earlier, in + * + */ + if ( ( on_delegation_point && ( + cur_rrsets->type == LDNS_RR_TYPE_NS + || cur_rrsets->type == LDNS_RR_TYPE_DS)) + || (!on_delegation_point && + cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) { + types[type_count] = cur_rrsets->type; type_count++; } diff --git a/dnssec_sign.c b/dnssec_sign.c index d28f87a4..126f8e70 100644 --- a/dnssec_sign.c +++ b/dnssec_sign.c @@ -522,72 +522,149 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key) } #endif /* HAVE_SSL */ -static int -ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name) +/** + * Pushes all rrs from the rrsets of type A and AAAA on gluelist. + */ +static ldns_status +ldns_dnssec_addresses_on_glue_list( + ldns_dnssec_rrsets *cur_rrset, + ldns_rr_list *glue_list) { - ldns_dnssec_rrsets *cur_rrset; - cur_rrset = cur_name->rrsets; + ldns_dnssec_rrs *cur_rrs; while (cur_rrset) { - if (cur_rrset->type != LDNS_RR_TYPE_A && - cur_rrset->type != LDNS_RR_TYPE_AAAA) { - return 0; - } else { - cur_rrset = cur_rrset->next; + if (cur_rrset->type == LDNS_RR_TYPE_A + || cur_rrset->type == LDNS_RR_TYPE_AAAA) { + for (cur_rrs = cur_rrset->rrs; + cur_rrs; + cur_rrs = cur_rrs->next) { + if (cur_rrs->rr) { + if (!ldns_rr_list_push_rr(glue_list, + cur_rrs->rr)) { + return LDNS_STATUS_MEM_ERR; + /* ldns_rr_list_push_rr() + * returns false when unable + * to increase the capacity + * of the ldsn_rr_list + */ + } + } + } } + cur_rrset = cur_rrset->next; } - return 1; + return LDNS_STATUS_OK; } -/* - * Regardless of its name, this function does not mark the glue rrsets as glue, - * but only names that have ONLY glue rrsets. +/** + * Marks the names in the zone that are occluded. Those names will be skipped + * when walking the tree with the ldns_dnssec_name_node_next_nonglue() + * function. But watch out! Names that are partially obscured (like glue with + * the same name as the delegation) will not be marked and should specifically + * be taken into account seperatly. * - * TODO - * Names with glue on the delegation are NOT marked! They are handled seperatly - * and specially within the is_glue() function in dnssec.c to exclude them - * from the NSEC and NSEC3 bitmaps; and in ldns_dnssec_zone_create_rrsigs_flg() - * in dnssec_sign.c to make sure those rrsets are not signed. - * - * Also, names that have other obscured rrsets besides A and AAAA types will NOT - * be marked. This is probably a mistake. + * When glue_list is given (not NULL), in the process of marking the names, all + * glue resource records will be pushed to that list. Even glue in partially + * obscured names. + * + * \param[in] zone the zone in which to mark the names + * \param[in] glue_list the list to which to push the glue rrs + * \return LDNS_STATUS_OK on success, an error code otherwise */ ldns_status -ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone) +ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, + ldns_rr_list *glue_list) { - ldns_rbnode_t *cur_node; - ldns_dnssec_name *cur_name; - ldns_rdf *cur_owner, *cur_parent; + ldns_rbnode_t *node; + ldns_dnssec_name *name; + ldns_rdf *owner; + ldns_rdf *cut = NULL; /* keeps track of zone cuts */ + /* When the cut is caused by a delegation, below_delegation will be 1. + * When caused by a DNAME, below_delegation will be 0. + */ + int below_delegation = -1; /* init suppresses comiler warning */ + ldns_status s; - cur_node = ldns_rbtree_first(zone->names); - while (cur_node != LDNS_RBTREE_NULL) { - cur_name = (ldns_dnssec_name *) cur_node->data; - cur_node = ldns_rbtree_next(cur_node); - if (ldns_dnssec_name_has_only_a(cur_name)) { - /* assume glue XXX check for zone cut */ - cur_owner = ldns_rdf_clone(ldns_rr_owner( - cur_name->rrsets->rrs->rr)); - while (ldns_dname_label_count(cur_owner) > - ldns_dname_label_count(zone->soa->name)) { - if (ldns_dnssec_zone_find_rrset(zone, - cur_owner, - LDNS_RR_TYPE_NS)) { - /* - fprintf(stderr, "[XX] Marking as glue: "); - ldns_rdf_print(stderr, cur_name->name); - fprintf(stderr, "\n"); - */ - cur_name->is_glue = true; + if (!zone || !zone->names) { + return LDNS_STATUS_NULL; + } + for (node = ldns_rbtree_first(zone->names); + node != LDNS_RBTREE_NULL; + node = ldns_rbtree_next(node)) { + name = (ldns_dnssec_name *) node->data; + owner = ldns_dnssec_name_name(name); + + if (cut) { + /* The previous node was a zone cut, or a subdomain + * below a zone cut. Is this node (still) a subdomain + * below the cut? Then the name is occluded. Unless + * the name contains a SOA, after which we are + * authoritative again. + * + * FIXME! If there are labels in between the SOA and + * the cut, going from the authoritative space (below + * the SOA) up into occluded space again, will not be + * detected with the contruct below! + */ + if (ldns_dname_is_subdomain(owner, cut) && + !ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_SOA)) { + + if (below_delegation && glue_list) { + s = ldns_dnssec_addresses_on_glue_list( + name->rrsets, glue_list); + if (s != LDNS_STATUS_OK) { + return s; + } } - cur_parent = ldns_dname_left_chop(cur_owner); - ldns_rdf_deep_free(cur_owner); - cur_owner = cur_parent; + name->is_glue = true; /* Mark occluded name! */ + continue; + } else { + cut = NULL; } - ldns_rdf_deep_free(cur_owner); + } + + /* The node is not below a zone cut. Is it a zone cut itself? + * Everything below a SOA is authoritative of course; Except + * when the name also contains a DNAME :). + */ + if (ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_SOA)) { + cut = owner; + below_delegation = 1; + if (glue_list) { /* record glue on the zone cut */ + s = ldns_dnssec_addresses_on_glue_list( + name->rrsets, glue_list); + if (s != LDNS_STATUS_OK) { + return s; + } + } + } else if (ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_DNAME)) { + cut = owner; + below_delegation = 0; } } return LDNS_STATUS_OK; } +/** + * Marks the names in the zone that are occluded. Those names will be skipped + * when walking the tree with the ldns_dnssec_name_node_next_nonglue() + * function. But watch out! Names that are partially obscured (like glue with + * the same name as the delegation) will not be marked and should specifically + * be taken into account seperatly. + * + * \param[in] zone the zone in which to mark the names + * \return LDNS_STATUS_OK on success, an error code otherwise + */ +ldns_status +ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone) +{ + return ldns_dnssec_zone_mark_and_get_glue(zone, NULL); +} + ldns_rbnode_t * ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node) { @@ -928,6 +1005,8 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone, size_t i; + int on_delegation_point = 0; /* handle partially obscured names */ + ldns_rr_list *pubkey_list = ldns_rr_list_new(); zone = zone; new_rrs = new_rrs; @@ -943,6 +1022,10 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone, cur_name = (ldns_dnssec_name *) cur_node->data; if (!cur_name->is_glue) { + on_delegation_point = ldns_dnssec_rrsets_contains_type( + cur_name->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + cur_name->rrsets, LDNS_RR_TYPE_SOA); cur_rrset = cur_name->rrsets; while (cur_rrset) { /* reset keys to use */ @@ -972,20 +1055,15 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone, } /* only sign non-delegation RRsets */ - /* (glue should have been marked earlier) */ - if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS || - ldns_dname_compare(ldns_rr_list_owner(rr_list), - zone->soa->name) == 0) && - /* OK, there is also the possibility that the record - * is glue, but at the same owner name as other records that - * are not NS nor A/AAAA. Bleh, our current data structure - * doesn't really support that... */ - !((ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_A || - ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_AAAA) && - !ldns_dname_compare(ldns_rr_list_owner(rr_list), zone->soa->name) == 0 && - ldns_dnssec_zone_find_rrset(zone, ldns_rr_list_owner(rr_list), LDNS_RR_TYPE_NS) - )) { - + /* (glue should have been marked earlier, + * except on the delegation points itself) */ + if (!on_delegation_point || + ldns_rr_list_type(rr_list) + == LDNS_RR_TYPE_DS || + ldns_rr_list_type(rr_list) + == LDNS_RR_TYPE_NSEC || + ldns_rr_list_type(rr_list) + == LDNS_RR_TYPE_NSEC3) { siglist = ldns_sign_public(rr_list, key_list); for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) { if (cur_rrset->signatures) { @@ -1280,3 +1358,4 @@ ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm } #endif /* HAVE_SSL */ + diff --git a/examples/ldns-verify-zone.c b/examples/ldns-verify-zone.c index e840c89b..88e79d2c 100644 --- a/examples/ldns-verify-zone.c +++ b/examples/ldns-verify-zone.c @@ -59,26 +59,6 @@ ldns_rr_list_contains_name(const ldns_rr_list *rr_list, return false; } -/* returns 1 if the list is empty, or if there are only ns or glue rrs in the - * list, 0 otherwise */ -static int -only_ns_and_glues_in_rrsets(ldns_dnssec_name *name, - ldns_rr_list *glue_rrs -) -{ - ldns_dnssec_rrsets *cur_rrset = name->rrsets; - - while (cur_rrset) { - if (cur_rrset->type != LDNS_RR_TYPE_NS && - !ldns_rr_list_contains_name(glue_rrs, name->name) - ) { - return 0; - } - cur_rrset = cur_rrset->next; - } - return 1; -} - static void print_type(ldns_rr_type type) { @@ -149,8 +129,7 @@ static ldns_status verify_dnssec_rrset(ldns_rdf *zone_name, ldns_rdf *name, ldns_dnssec_rrsets *rrset, - ldns_rr_list *keys, - ldns_rr_list *glue_rrs) + ldns_rr_list *keys) { ldns_rr_list *rrset_rrs; ldns_dnssec_rrs *cur_rr, *cur_sig; @@ -362,29 +341,10 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes, } } -static ldns_rbnode_t * -next_nonglue_node(ldns_rbnode_t *node, ldns_rr_list *glue_rrs) -{ - ldns_rbnode_t *cur_node = ldns_rbtree_next(node); - ldns_dnssec_name *cur_name; - while (cur_node != LDNS_RBTREE_NULL) { - cur_name = (ldns_dnssec_name *) cur_node->data; - if (cur_name && cur_name->name) { - if (!ldns_rr_list_contains_name(glue_rrs, cur_name->name)) { - return cur_node; - } - } - cur_node = ldns_rbtree_next(cur_node); - } - return LDNS_RBTREE_NULL; -} - static ldns_status verify_nsec(ldns_rbtree_t *zone_nodes, ldns_rbnode_t *cur_node, - ldns_rr_list *keys, - ldns_rr_list *glue_rrs -) + ldns_rr_list *keys) { ldns_rbnode_t *next_node; ldns_dnssec_name *name, *next_name; @@ -414,10 +374,11 @@ verify_nsec(ldns_rbtree_t *zone_nodes, switch (ldns_rr_get_type(name->nsec)) { case LDNS_RR_TYPE_NSEC: /* simply try next name */ - next_node = next_nonglue_node(cur_node, glue_rrs); + next_node = ldns_rbtree_next(cur_node); if (next_node == LDNS_RBTREE_NULL) { next_node = ldns_rbtree_first(zone_nodes); } + next_node = ldns_dnssec_name_node_next_nonglue(next_node); next_name = (ldns_dnssec_name *)next_node->data; if (ldns_dname_compare(next_name->name, ldns_rr_rdf(name->nsec, 0)) @@ -425,6 +386,11 @@ verify_nsec(ldns_rbtree_t *zone_nodes, printf("Error: the NSEC record for "); ldns_rdf_print(stdout, name->name); printf(" points to the wrong next owner name\n"); + printf(" : "); + ldns_rdf_print(stdout, ldns_rr_rdf(name->nsec, 0)); + printf(" i.s.o. "); + ldns_rdf_print(stdout, next_name->name); + printf(".\n"); if (result == LDNS_STATUS_OK) { result = LDNS_STATUS_ERR; } @@ -447,7 +413,14 @@ verify_nsec(ldns_rbtree_t *zone_nodes, } else { /* todo; do this once and cache result? */ if (zone_is_nsec3_optout(zone_nodes) && - only_ns_and_glues_in_rrsets(name, glue_rrs)) { + ( ldns_dnssec_name_is_glue(name) + || ( + ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_DS) + ) + )) { /* ok, no problem, but we need to remember to check * whether the chain does not actually point to this * name later */ @@ -465,34 +438,18 @@ verify_nsec(ldns_rbtree_t *zone_nodes, return result; } -static int -ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name) -{ - ldns_dnssec_rrsets *cur_rrset; - cur_rrset = cur_name->rrsets; - while (cur_rrset) { - if (cur_rrset->type != LDNS_RR_TYPE_A && - cur_rrset->type != LDNS_RR_TYPE_AAAA) { - return 0; - } else { - cur_rrset = cur_rrset->next; - } - } - return 1; -} - static ldns_status verify_dnssec_name(ldns_rdf *zone_name, ldns_dnssec_zone *zone, ldns_rbtree_t *zone_nodes, ldns_rbnode_t *cur_node, - ldns_rr_list *keys, - ldns_rr_list *glue_rrs) + ldns_rr_list *keys) { ldns_status result = LDNS_STATUS_OK; ldns_status status; ldns_dnssec_rrsets *cur_rrset; ldns_dnssec_name *name; + int on_delegation_point; /* for NSEC chain checks */ name = (ldns_dnssec_name *) cur_node->data; @@ -502,9 +459,7 @@ verify_dnssec_name(ldns_rdf *zone_name, printf("\n"); } - if (ldns_dnssec_name_has_only_a(name) && - ldns_rr_list_contains_name(glue_rrs, name->name) - ) { + if (ldns_dnssec_name_is_glue(name)) { /* glue */ cur_rrset = name->rrsets; while (cur_rrset) { @@ -530,11 +485,26 @@ verify_dnssec_name(ldns_rdf *zone_name, } } else { /* not glue, do real verify */ + + on_delegation_point = ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_NS) + && !ldns_dnssec_rrsets_contains_type( + name->rrsets, LDNS_RR_TYPE_SOA); + cur_rrset = name->rrsets; while(cur_rrset) { - if ((cur_rrset->type != LDNS_RR_TYPE_A && cur_rrset->type != LDNS_RR_TYPE_AAAA) || - !ldns_dnssec_zone_find_rrset(zone, name->name, LDNS_RR_TYPE_NS)) { - status = verify_dnssec_rrset(zone_name, name->name, cur_rrset, keys, glue_rrs); + + /* Do not check obscured rrsets + * on the delegation point + */ + if ( ( on_delegation_point && ( + cur_rrset->type == LDNS_RR_TYPE_NS + || cur_rrset->type == LDNS_RR_TYPE_DS)) + || (!on_delegation_point && + cur_rrset->type != LDNS_RR_TYPE_RRSIG + && cur_rrset->type != LDNS_RR_TYPE_NSEC)) { + + status = verify_dnssec_rrset(zone_name, name->name, cur_rrset, keys); if (status != LDNS_STATUS_OK && result == LDNS_STATUS_OK) { result = status; } @@ -542,7 +512,7 @@ verify_dnssec_name(ldns_rdf *zone_name, cur_rrset = cur_rrset->next; } - status = verify_nsec(zone_nodes, cur_node, keys, glue_rrs); + status = verify_nsec(zone_nodes, cur_node, keys); if (result == LDNS_STATUS_OK) { result = status; } @@ -552,9 +522,7 @@ verify_dnssec_name(ldns_rdf *zone_name, static ldns_status verify_dnssec_zone(ldns_dnssec_zone *dnssec_zone, - ldns_rdf *zone_name, - ldns_rr_list *glue_rrs) -{ + ldns_rdf *zone_name) { ldns_rr_list *keys; ldns_rbnode_t *cur_node; ldns_dnssec_rrsets *cur_key_rrset; @@ -596,8 +564,7 @@ verify_dnssec_zone(ldns_dnssec_zone *dnssec_zone, dnssec_zone, dnssec_zone->names, cur_node, - keys, - glue_rrs); + keys); if (status != LDNS_STATUS_OK && result == LDNS_STATUS_OK) { result = status; } @@ -620,7 +587,6 @@ main(int argc, char **argv) ldns_status s; ldns_dnssec_zone *dnssec_zone; ldns_status result = LDNS_STATUS_ERR; - ldns_rr_list *glue_rrs; while ((c = getopt(argc, argv, "hvV:")) != -1) { switch(c) { @@ -674,16 +640,20 @@ main(int argc, char **argv) exit(1); } - glue_rrs = ldns_zone_glue_rr_list(z); dnssec_zone = create_dnssec_zone(z); + result = ldns_dnssec_zone_mark_glue(dnssec_zone); + if (result != LDNS_STATUS_OK) { + if (verbosity >= 1) { + printf("There were errors identifying the glue in the zone\n"); + } + } if (verbosity >= 5) { ldns_dnssec_zone_print(stdout, dnssec_zone); } result = verify_dnssec_zone(dnssec_zone, - ldns_rr_owner(ldns_zone_soa(z)), - glue_rrs); + ldns_rr_owner(ldns_zone_soa(z))); if (result == LDNS_STATUS_OK) { diff --git a/ldns/dnssec.h b/ldns/dnssec.h index 7bfc70b7..c68ce36e 100644 --- a/ldns/dnssec.h +++ b/ldns/dnssec.h @@ -210,6 +210,16 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[], size_t size, ldns_rr_type nsec_type); +/** + * returns whether a rrset of the given type is found in the rrsets. + * + * \param[in] *rsets the rrsets to be tested + * \param[in] type the type to test for + * \return int 1 if the type was found, 0 otherwise. + */ +int +ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type); + /** * Creates NSEC */ diff --git a/ldns/dnssec_sign.h b/ldns/dnssec_sign.h index 66856d52..bca7d511 100644 --- a/ldns/dnssec_sign.h +++ b/ldns/dnssec_sign.h @@ -83,10 +83,30 @@ ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key); #endif /* HAVE_SSL */ /** - * Marks the names in the zone that contain only glue, by setting the - * is_glue attribute of the ldns_dnssec_name structure to true. - * Names with glue on the delegation point and occluded names with other - * rrsets than only A and AAAA are not marked! + * Marks the names in the zone that are occluded. Those names will be skipped + * when walking the tree with the ldns_dnssec_name_node_next_nonglue() + * function. But watch out! Names that are partially obscured (like glue with + * the same name as the delegation) will not be marked and should specifically + * be taken into account seperatly. + * + * When glue_list is given (not NULL), in the process of marking the names, all + * glue resource records will be pushed to that list. Even glue in partially + * obscured names. + * + * \param[in] zone the zone in which to mark the names + * \param[in] glue_list the list to which to push the glue rrs + * \return LDNS_STATUS_OK on success, an error code otherwise + */ +ldns_status +ldns_dnssec_zone_mark_and_get_glue( + ldns_dnssec_zone *zone, ldns_rr_list *glue_list); + +/** + * Marks the names in the zone that are occluded. Those names will be skipped + * when walking the tree with the ldns_dnssec_name_node_next_nonglue() + * function. But watch out! Names that are partially obscured (like glue with + * the same name as the delegation) will not be marked and should specifically + * be taken into account seperatly. * * \param[in] zone the zone in which to mark the names * \return LDNS_STATUS_OK on succesful completion @@ -95,8 +115,8 @@ ldns_status ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone); /** - * Finds the first dnssec_name node in the rbtree that has not been marked - * as glue, starting at the given node + * Finds the first dnssec_name node in the rbtree that is not occluded. + * It *does* return names that are partially obscured. * * \param[in] node the first node to check * \return the first node that has not been marked as glue, or NULL diff --git a/ldns_symbols.def b/ldns_symbols.def index 9158fe5a..551f2b0c 100644 --- a/ldns_symbols.def +++ b/ldns_symbols.def @@ -136,6 +136,7 @@ ldns_dnssec_zone_deep_free ldns_dnssec_zone_find_nsec3_original ldns_dnssec_zone_find_rrset ldns_dnssec_zone_free +ldns_dnssec_zone_mark_and_get_glue ldns_dnssec_zone_mark_glue ldns_dnssec_zone_names_print ldns_dnssec_zone_new