ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) { ldns_status result = LDNS_STATUS_OK; ldns_dnssec_name *cur_name; ldns_rbnode_t *cur_node; ldns_rr_type type_covered = 0; if (!zone || !rr) { return LDNS_STATUS_ERR; } if (!zone->names) { zone->names = ldns_rbtree_create(ldns_dname_compare_v); if(!zone->names) return LDNS_STATUS_MEM_ERR; } /* we need the original of the hashed name if this is an NSEC3, or an RRSIG that covers an NSEC3 */ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) { type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(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); 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); if(!cur_name) return LDNS_STATUS_MEM_ERR; cur_node = LDNS_MALLOC(ldns_rbnode_t); if(!cur_node) { ldns_dnssec_name_free(cur_name); return LDNS_STATUS_MEM_ERR; } 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 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { zone->soa = cur_name; } return result; }
ldns_dnssec_name * ldns_dnssec_name_new_frm_rr(ldns_rr *rr) { ldns_dnssec_name *new_name = ldns_dnssec_name_new(); new_name->name = ldns_rr_owner(rr); if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) { ldns_dnssec_name_free(new_name); return NULL; } return new_name; }
ldns_status ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt) { ldns_rbnode_t *first_name_node; ldns_rbnode_t *current_name_node; ldns_dnssec_name *current_name; ldns_status result = LDNS_STATUS_OK; ldns_rr *nsec_rr; ldns_rr_list *nsec3_list; uint32_t nsec_ttl; ldns_dnssec_rrsets *soa; if (!zone || !new_rrs || !zone->names) { return LDNS_STATUS_ERR; } /* the TTL of NSEC rrs should be set to the minimum TTL of * the zone SOA (RFC4035 Section 2.3) */ soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); /* did the caller actually set it? if not, * fall back to default ttl */ if (soa && soa->rrs && soa->rrs->rr) { nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf( soa->rrs->rr, 6)); } else { nsec_ttl = LDNS_DEFAULT_TTL; } nsec3_list = ldns_rr_list_new(); first_name_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_first(zone->names)); current_name_node = first_name_node; while (current_name_node && current_name_node != LDNS_RBTREE_NULL) { current_name = (ldns_dnssec_name *) current_name_node->data; nsec_rr = ldns_dnssec_create_nsec3(current_name, NULL, zone->soa->name, algorithm, flags, iterations, salt_length, salt); /* by default, our nsec based generator adds rrsigs * remove the bitmap for empty nonterminals */ if (!current_name->rrsets) { ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr)); } ldns_rr_set_ttl(nsec_rr, nsec_ttl); ldns_dnssec_name_add_rr(current_name, nsec_rr); ldns_rr_list_push_rr(new_rrs, nsec_rr); ldns_rr_list_push_rr(nsec3_list, nsec_rr); current_name_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_next(current_name_node)); } ldns_rr_list_sort_nsec3(nsec3_list); ldns_dnssec_chain_nsec3_list(nsec3_list); if (result != LDNS_STATUS_OK) { return result; } ldns_rr_list_free(nsec3_list); return result; }
ldns_status ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs) { ldns_rbnode_t *first_node, *cur_node, *next_node; ldns_dnssec_name *cur_name, *next_name; ldns_rr *nsec_rr; uint32_t nsec_ttl; ldns_dnssec_rrsets *soa; /* the TTL of NSEC rrs should be set to the minimum TTL of * the zone SOA (RFC4035 Section 2.3) */ soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); /* did the caller actually set it? if not, * fall back to default ttl */ if (soa && soa->rrs && soa->rrs->rr) { nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf( soa->rrs->rr, 6)); } else { nsec_ttl = LDNS_DEFAULT_TTL; } first_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_first(zone->names)); cur_node = first_node; if (cur_node) { next_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_next(cur_node)); } else { next_node = NULL; } while (cur_node && next_node) { cur_name = (ldns_dnssec_name *)cur_node->data; next_name = (ldns_dnssec_name *)next_node->data; nsec_rr = ldns_dnssec_create_nsec(cur_name, next_name, LDNS_RR_TYPE_NSEC); ldns_rr_set_ttl(nsec_rr, nsec_ttl); ldns_dnssec_name_add_rr(cur_name, nsec_rr); ldns_rr_list_push_rr(new_rrs, nsec_rr); cur_node = next_node; if (cur_node) { next_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_next(cur_node)); } } if (cur_node && !next_node) { cur_name = (ldns_dnssec_name *)cur_node->data; next_name = (ldns_dnssec_name *)first_node->data; nsec_rr = ldns_dnssec_create_nsec(cur_name, next_name, LDNS_RR_TYPE_NSEC); ldns_rr_set_ttl(nsec_rr, nsec_ttl); ldns_dnssec_name_add_rr(cur_name, nsec_rr); ldns_rr_list_push_rr(new_rrs, nsec_rr); } else { printf("error\n"); } return LDNS_STATUS_OK; }
static ldns_status ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, ldns_rbtree_t **map) { ldns_rbnode_t *first_name_node; ldns_rbnode_t *current_name_node; ldns_dnssec_name *current_name; ldns_status result = LDNS_STATUS_OK; ldns_rr *nsec_rr; ldns_rr_list *nsec3_list; uint32_t nsec_ttl; ldns_dnssec_rrsets *soa; ldns_rbnode_t *hashmap_node; if (!zone || !new_rrs || !zone->names) { return LDNS_STATUS_ERR; } /* the TTL of NSEC rrs should be set to the minimum TTL of * the zone SOA (RFC4035 Section 2.3) */ soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); /* did the caller actually set it? if not, * fall back to default ttl */ if (soa && soa->rrs && soa->rrs->rr && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) { nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6)); } else { nsec_ttl = LDNS_DEFAULT_TTL; } if (zone->hashed_names) { ldns_traverse_postorder(zone->hashed_names, ldns_hashed_names_node_free, NULL); LDNS_FREE(zone->hashed_names); } zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v); if (zone->hashed_names && map) { *map = zone->hashed_names; } first_name_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_first(zone->names)); current_name_node = first_name_node; while (current_name_node && current_name_node != LDNS_RBTREE_NULL && result == LDNS_STATUS_OK) { current_name = (ldns_dnssec_name *) current_name_node->data; nsec_rr = ldns_dnssec_create_nsec3(current_name, NULL, zone->soa->name, algorithm, flags, iterations, salt_length, salt); /* by default, our nsec based generator adds rrsigs * remove the bitmap for empty nonterminals */ if (!current_name->rrsets) { ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr)); } ldns_rr_set_ttl(nsec_rr, nsec_ttl); result = ldns_dnssec_name_add_rr(current_name, nsec_rr); ldns_rr_list_push_rr(new_rrs, nsec_rr); if (ldns_rr_owner(nsec_rr)) { hashmap_node = LDNS_MALLOC(ldns_rbnode_t); if (hashmap_node == NULL) { return LDNS_STATUS_MEM_ERR; } current_name->hashed_name = ldns_dname_label(ldns_rr_owner(nsec_rr), 0); if (current_name->hashed_name == NULL) { LDNS_FREE(hashmap_node); return LDNS_STATUS_MEM_ERR; } hashmap_node->key = current_name->hashed_name; hashmap_node->data = current_name; if (! ldns_rbtree_insert(zone->hashed_names , hashmap_node)) { LDNS_FREE(hashmap_node); } } current_name_node = ldns_dnssec_name_node_next_nonglue( ldns_rbtree_next(current_name_node)); } if (result != LDNS_STATUS_OK) { return result; } /* Make sorted list of nsec3s (via zone->hashed_names) */ nsec3_list = ldns_rr_list_new(); if (nsec3_list == NULL) { return LDNS_STATUS_MEM_ERR; } for ( hashmap_node = ldns_rbtree_first(zone->hashed_names) ; hashmap_node != LDNS_RBTREE_NULL ; hashmap_node = ldns_rbtree_next(hashmap_node) ) { current_name = (ldns_dnssec_name *) hashmap_node->data; nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec; if (nsec_rr) { ldns_rr_list_push_rr(nsec3_list, nsec_rr); } } result = ldns_dnssec_chain_nsec3_list(nsec3_list); ldns_rr_list_free(nsec3_list); return result; }