diff options
Diffstat (limited to 'usr.sbin/unbound/ldns/dnssec_zone.c')
-rw-r--r-- | usr.sbin/unbound/ldns/dnssec_zone.c | 205 |
1 files changed, 110 insertions, 95 deletions
diff --git a/usr.sbin/unbound/ldns/dnssec_zone.c b/usr.sbin/unbound/ldns/dnssec_zone.c index df71a23c7ed..60d62eae09f 100644 --- a/usr.sbin/unbound/ldns/dnssec_zone.c +++ b/usr.sbin/unbound/ldns/dnssec_zone.c @@ -7,7 +7,7 @@ #include <ldns/ldns.h> ldns_dnssec_rrs * -ldns_dnssec_rrs_new() +ldns_dnssec_rrs_new(void) { ldns_dnssec_rrs *new_rrs; new_rrs = LDNS_MALLOC(ldns_dnssec_rrs); @@ -54,10 +54,8 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) /* this could be done more efficiently; name and type should already be equal */ - cmp = ldns_rr_compare(rrs->rr, - rr); - /* should we error on equal? */ - if (cmp <= 0) { + cmp = ldns_rr_compare(rrs->rr, rr); + if (cmp < 0) { if (rrs->next) { return ldns_dnssec_rrs_add_rr(rrs->next, rr); } else { @@ -74,6 +72,7 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) rrs->rr = rr; rrs->next = new_rrs; } + /* Silently ignore equal rr's */ return LDNS_STATUS_OK; } @@ -102,7 +101,7 @@ ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs) ldns_dnssec_rrsets * -ldns_dnssec_rrsets_new() +ldns_dnssec_rrsets_new(void) { ldns_dnssec_rrsets *new_rrsets; new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets); @@ -164,7 +163,7 @@ ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, return LDNS_STATUS_ERR; } -ldns_dnssec_rrsets * +static ldns_dnssec_rrsets * ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr) { ldns_dnssec_rrsets *new_rrsets; @@ -270,7 +269,7 @@ ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr) return result; } -void +static void ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_rrsets *rrsets, bool follow, @@ -298,16 +297,6 @@ ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, } } -void -ldns_dnssec_rrsets_print_soa(FILE *out, - ldns_dnssec_rrsets *rrsets, - bool follow, - bool show_soa) -{ - ldns_dnssec_rrsets_print_soa_fmt(out, ldns_output_format_default, - rrsets, follow, show_soa); -} - void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, @@ -325,7 +314,7 @@ ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow) } ldns_dnssec_name * -ldns_dnssec_name_new() +ldns_dnssec_name_new(void) { ldns_dnssec_name *new_name; @@ -428,14 +417,6 @@ ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, } } -ldns_rr * -ldns_dnssec_name_nsec(ldns_dnssec_name *rrset) -{ - if (rrset) { - return rrset->nsec; - } - return NULL; -} void ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec) @@ -468,8 +449,6 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name, ldns_rr *rr) { ldns_status result = LDNS_STATUS_OK; - ldns_rdf *name_name; - bool hashed_name = false; ldns_rr_type rr_type; ldns_rr_type typecovered = 0; @@ -485,19 +464,6 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name, typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); } -#ifdef HAVE_SSL - if (rr_type == LDNS_RR_TYPE_NSEC3 || - typecovered == LDNS_RR_TYPE_NSEC3) { - name_name = ldns_nsec3_hash_name_frm_nsec3(rr, - ldns_dnssec_name_name(name)); - hashed_name = true; - } else { - name_name = ldns_dnssec_name_name(name); - } -#else - name_name = ldns_dnssec_name_name(name); -#endif /* HAVE_SSL */ - if (rr_type == LDNS_RR_TYPE_NSEC || rr_type == LDNS_RR_TYPE_NSEC3) { /* XX check if is already set (and error?) */ @@ -519,11 +485,6 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name, result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); } } - - if (hashed_name) { - ldns_rdf_deep_free(name_name); - } - return result; } @@ -563,7 +524,7 @@ ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone, } } -void +static void ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_name *name, bool show_soa) @@ -589,12 +550,6 @@ ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, } } -void -ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa) -{ - ldns_dnssec_name_print_soa_fmt(out, ldns_output_format_default, - name, show_soa); -} void ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, @@ -611,12 +566,14 @@ ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name) ldns_dnssec_zone * -ldns_dnssec_zone_new() +ldns_dnssec_zone_new(void) { ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone); if(!zone) return NULL; zone->soa = NULL; zone->names = NULL; + zone->hashed_names = NULL; + zone->_nsec3params = NULL; return zone; } @@ -699,6 +656,8 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, ldns_rr_list_push_rr(todo_nsec3s, cur_rr); } + status = LDNS_STATUS_OK; + } else if (status != LDNS_STATUS_OK) goto error; @@ -722,18 +681,13 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, if (ldns_rr_list_rr_count(todo_nsec3s) > 0) { (void) ldns_dnssec_zone_add_empty_nonterminals(newzone); - for (i = 0; status == LDNS_STATUS_OK && + for (i = 0; status == LDNS_STATUS_OK && i < ldns_rr_list_rr_count(todo_nsec3s); i++) { cur_rr = ldns_rr_list_rr(todo_nsec3s, i); status = ldns_dnssec_zone_add_rr(newzone, cur_rr); } - for (i = 0; status == LDNS_STATUS_OK && - i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); - i++){ - cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); - status = ldns_dnssec_zone_add_rr(newzone, cur_rr); - } - } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) { + } + if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) { for (i = 0; status == LDNS_STATUS_OK && i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){ @@ -777,14 +731,14 @@ ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); } -void +static void ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) { (void) arg; ldns_dnssec_name_free((ldns_dnssec_name *)node->data); LDNS_FREE(node); } -void +static void ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) { (void) arg; ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data); @@ -827,31 +781,99 @@ ldns_dname_compare_v(const void *a, const void *b) { return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); } -ldns_rbnode_t * -ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, - ldns_rr *rr) { - ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names); - ldns_dnssec_name *current_name; - ldns_rdf *hashed_name; +static void +ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, + ldns_dnssec_name* name, ldns_rr* nsec3rr); - hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); +static void +ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) { + (void) arg; + LDNS_FREE(node); +} + +static void +ldns_dnssec_zone_hashed_names_from_nsec3( + ldns_dnssec_zone* zone, ldns_rr* nsec3rr) +{ + ldns_rbnode_t* current_node; + ldns_dnssec_name* current_name; - while (current_node != LDNS_RBTREE_NULL) { + assert(zone != NULL); + assert(nsec3rr != NULL); + + if (zone->hashed_names) { + ldns_traverse_postorder(zone->hashed_names, + ldns_hashed_names_node_free, NULL); + LDNS_FREE(zone->hashed_names); + } + zone->_nsec3params = nsec3rr; + + /* So this is a NSEC3 zone. + * Calculate hashes for all names already in the zone + */ + zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v); + if (zone->hashed_names == NULL) { + return; + } + for ( current_node = ldns_rbtree_first(zone->names) + ; current_node != LDNS_RBTREE_NULL + ; current_node = ldns_rbtree_next(current_node) + ) { current_name = (ldns_dnssec_name *) current_node->data; - if (!current_name->hashed_name) { - current_name->hashed_name = - ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name); + ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr); + + } +} + +static void +ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, + ldns_dnssec_name* name, ldns_rr* nsec3rr) +{ + ldns_rbnode_t* new_node; + + assert(name != NULL); + if (! zone->_nsec3params) { + if (! nsec3rr) { + return; } - if (ldns_dname_compare(hashed_name, - current_name->hashed_name) - == 0) { - ldns_rdf_deep_free(hashed_name); - return current_node; + ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr); + + } else if (! nsec3rr) { + nsec3rr = zone->_nsec3params; + } + name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name); + + /* Also store in zone->hashed_names */ + if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) { + + new_node->key = name->hashed_name; + new_node->data = name; + + if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) { + + LDNS_FREE(new_node); } - current_node = ldns_rbtree_next(current_node); } - ldns_rdf_deep_free(hashed_name); - return NULL; +} + + +static ldns_rbnode_t * +ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) { + ldns_rdf *hashed_name; + + hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); + if (hashed_name == NULL) { + return NULL; + } + if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){ + + ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr); + } + if (zone->hashed_names == NULL) { + ldns_rdf_deep_free(hashed_name); + return NULL; + } + return ldns_rbtree_search(zone->hashed_names, hashed_name); } ldns_status @@ -878,15 +900,13 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) } if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 || type_covered == LDNS_RR_TYPE_NSEC3) { - cur_node = ldns_dnssec_zone_find_nsec3_original(zone, - rr); + cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr); if (!cur_node) { return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND; } } else { cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr)); } - if (!cur_node) { /* add */ cur_name = ldns_dnssec_name_new_frm_rr(rr); @@ -899,21 +919,14 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) cur_node->key = ldns_rr_owner(rr); cur_node->data = cur_name; (void)ldns_rbtree_insert(zone->names, cur_node); + ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL); } else { cur_name = (ldns_dnssec_name *) cur_node->data; result = ldns_dnssec_name_add_rr(cur_name, rr); } - - if (result != LDNS_STATUS_OK) { - fprintf(stderr, "error adding rr: "); - ldns_rr_print(stderr, rr); - } - - /*TODO ldns_dnssec_name_print_names(stdout, zone->names, 0);*/ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { zone->soa = cur_name; } - return result; } @@ -1059,6 +1072,8 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone) new_node->key = new_name->name; new_node->data = new_name; (void)ldns_rbtree_insert(zone->names, new_node); + ldns_dnssec_name_make_hashed_name( + zone, new_name, NULL); } ldns_rdf_deep_free(l1); ldns_rdf_deep_free(l2); |