ya_result nsec3_load_add_rrsig(nsec3_load_context *context, const u8 *digest_label, s32 ttl, const u8 *rdata, u16 rdata_size) { u8 digest_len = BASE32HEX_DECODED_LEN(digest_label[0]); u8 digest[digest_len + 1]; digest[0] = digest_len; if(ISOK(base32hex_decode((const char*)&digest_label[1], digest_label[0], &digest[1]))) { zdb_packed_ttlrdata *rrsig; ZDB_RECORD_ZALLOC(rrsig,ttl,rdata_size,rdata); if(context->last_inserted_nsec3 != NULL) { nsec3_context_record* nsec3_r = (nsec3_context_record*)context->last_inserted_nsec3; if(memcmp(nsec3_r->digest_then_rdata, digest, 1 + digest[0]) == 0) { rrsig->next = nsec3_r->rrsig; nsec3_r->rrsig = rrsig; return SUCCESS; } } // the records are not nicely ordered : need to postpone the insertion of this record. ptr_node *node = ptr_set_avl_insert(&context->postponed_rrsig, digest); if(node->value == NULL) { u8 *key; ZALLOC_ARRAY_OR_DIE(u8*, key, digest_len + 1, N3LKEYDG_TAG); memcpy(key, digest, digest_len + 1); node->key = key; }
ya_result nsec3_icmtl_replay_execute(nsec3_icmtl_replay *replay) { bool nsec3param_added = FALSE; if(!treeset_avl_isempty(&replay->nsec3param_add)) { treeset_avl_iterator n3p_avl_iter; treeset_avl_iterator_init(&replay->nsec3param_add, &n3p_avl_iter); while(treeset_avl_iterator_hasnext(&n3p_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&n3p_avl_iter); zdb_ttlrdata* nsec3param = (zdb_ttlrdata*)node->data; nsec3_zone* n3 = nsec3_zone_get_from_rdata(replay->zone, nsec3param->rdata_size, nsec3param->rdata_pointer); if(n3 == NULL) { /* * add the record */ zdb_packed_ttlrdata *packed_ttlrdata; ZDB_RECORD_ZALLOC(packed_ttlrdata, 0, nsec3param->rdata_size ,nsec3param->rdata_pointer); zdb_record_insert(&replay->zone->apex->resource_record_set, TYPE_NSEC3PARAM, packed_ttlrdata); nsec3_zone_add_from_rdata(replay->zone, nsec3param->rdata_size, nsec3param->rdata_pointer); //nsec3_load_chain_init(nsec3param->rdata_pointer, nsec3param->rdata_size); nsec3param_added = TRUE; } zdb_ttlrdata_delete(nsec3param); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3param_add); } if(!treeset_avl_isempty(&replay->nsec3_del)) { /* stuff to delete */ treeset_avl_iterator ts_avl_iter; treeset_avl_iterator_init(&replay->nsec3_del, &ts_avl_iter); while(treeset_avl_iterator_hasnext(&ts_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&ts_avl_iter); u8 *fqdn = (u8*)node->key; zdb_ttlrdata *ttlrdata = (zdb_ttlrdata*)node->data; #ifndef NDEBUG log_debug("journal: NSEC3: post/del %{dnsname}", fqdn); #endif treeset_node *add_node; if((add_node = treeset_avl_find(&replay->nsec3_add, fqdn)) != NULL) { /* replace */ #ifndef NDEBUG log_debug("journal: NSEC3: upd %{dnsname}", fqdn); rdata_desc type_len_rdata = {TYPE_NSEC3, ttlrdata->rdata_size, ttlrdata->rdata_pointer }; log_debug("journal: NSEC3: - %{typerdatadesc}", &type_len_rdata); #endif zdb_ttlrdata *add_ttlrdata = (zdb_ttlrdata *)add_node->data; #ifndef NDEBUG rdata_desc add_type_len_rdata = {TYPE_NSEC3, add_ttlrdata->rdata_size, add_ttlrdata->rdata_pointer }; log_debug("journal: NSEC3: + %{typerdatadesc}", &add_type_len_rdata); #endif /* * The node may need an update of the type bitmap * After all changes (del/upd/add) all the added records should be matched again (check) * * nsec3_zone_item_get_by_name(); * nsec3_zone_item_update_bitmap(item, rdata, rdata_len) */ nsec3_zone_item *add_item = nsec3_zone_item_find_by_record(replay->zone, fqdn, ttlrdata->rdata_size, ttlrdata->rdata_pointer); if(add_item != NULL) { nsec3_zone_item_update_bitmap(add_item, add_ttlrdata->rdata_pointer, add_ttlrdata->rdata_size); u8* add_key = add_node->key; treeset_avl_delete(&replay->nsec3_add, fqdn); zdb_ttlrdata_delete(add_ttlrdata); free(add_key); } else { log_err("journal: NSEC3: %{dnsname} has not been found in the NSEC3 database (del/add)", fqdn); return ERROR; } } else { #ifndef NDEBUG log_debug("journal: NSEC3: del %{dnsname}", fqdn); rdata_desc type_len_rdata = {TYPE_NSEC3, ttlrdata->rdata_size, ttlrdata->rdata_pointer }; log_debug("journal: NSEC3: - %{typerdatadesc}", &type_len_rdata); #endif /* delete */ nsec3_zone_item *add_item = nsec3_zone_item_find_by_record(replay->zone, fqdn, ttlrdata->rdata_size, ttlrdata->rdata_pointer); if(add_item != NULL) { nsec3_remove_nsec3_by_name(replay->zone, fqdn, ttlrdata->rdata_pointer); } else { log_err("journal: NSEC3: %{dnsname} has not been found in the NSEC3 database (del)", fqdn); } /* * The node has to be deleted */ } zdb_ttlrdata_delete(ttlrdata); free(fqdn); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3_del); } if(!treeset_avl_isempty(&replay->nsec3_add)) { /* stuff to add */ treeset_avl_iterator ts_avl_iter; treeset_avl_iterator_init(&replay->nsec3_add, &ts_avl_iter); while(treeset_avl_iterator_hasnext(&ts_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&ts_avl_iter); u8 *fqdn = (u8*)node->key; #ifndef NDEBUG log_debug("journal: NSEC3: post/add %{dnsname}", fqdn); #endif zdb_ttlrdata *ttlrdata = (zdb_ttlrdata*)node->data; #ifndef NDEBUG log_debug("journal: NSEC3: add %{dnsname}", fqdn); rdata_desc type_len_rdata = {TYPE_NSEC3, ttlrdata->rdata_size, ttlrdata->rdata_pointer }; log_debug("journal: NSEC3: + %{typerdatadesc}", &type_len_rdata); #endif /* * The node must be added. It should not exist already. * After all changes (del/upd/add) all the added records should be matched again (check) */ nsec3_zone_item *add_item = nsec3_zone_item_find_by_record(replay->zone, fqdn, ttlrdata->rdata_size, ttlrdata->rdata_pointer); if(add_item != NULL) { log_err("journal: NSEC3: already exists"); nsec3_zone *n3 = replay->zone->nsec.nsec3; if(n3 != NULL ) { zdb_packed_ttlrdata *nsec3; zdb_packed_ttlrdata *nsec3_rrsig; u8 owner[256]; nsec3_zone_item_to_zdb_packed_ttlrdata(n3, add_item, replay->zone->origin, owner, 600, &nsec3, &nsec3_rrsig); #ifndef NDEBUG rdata_desc type_len_rdata = {TYPE_NSEC3, nsec3->rdata_size, nsec3->rdata_start }; log_debug("journal: NSEC3: ? %{typerdatadesc}", &type_len_rdata); #endif free(nsec3); nsec3_remove_nsec3_by_digest(replay->zone, add_item->digest, ttlrdata->rdata_pointer); } } nsec3_add_nsec3_by_name(replay->zone, fqdn, ttlrdata->rdata_pointer, ttlrdata->rdata_size); zdb_ttlrdata_delete(ttlrdata); free(fqdn); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3_add); } if(!treeset_avl_isempty(&replay->nsec3rrsig_del)) { /* stuff to add */ treeset_avl_iterator ts_avl_iter; treeset_avl_iterator_init(&replay->nsec3rrsig_del, &ts_avl_iter); while(treeset_avl_iterator_hasnext(&ts_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&ts_avl_iter); u8 *fqdn = (u8*)node->key; #ifndef NDEBUG log_debug("journal: NSEC3: post/add %{dnsname}", fqdn); #endif zdb_ttlrdata *nsec3_rrsig = (zdb_ttlrdata*)node->data; #ifndef NDEBUG log_debug("journal: NSEC3: add %{dnsname}", fqdn); rdata_desc type_len_rdata = {TYPE_RRSIG, ZDB_RECORD_PTR_RDATASIZE(nsec3_rrsig), ZDB_RECORD_PTR_RDATAPTR(nsec3_rrsig) }; log_debug("journal: NSEC3: + %{typerdatadesc}", &type_len_rdata); #endif /* * The node must be added. It should not exist already. * After all changes (del/upd/add) all the added records should be matched again (check) */ nsec3_zone_item *item = nsec3_zone_item_find_by_name_ext(replay->zone, fqdn, NULL); if(item != NULL) { nsec3_zone_item_rrsig_del(item, nsec3_rrsig); } zdb_ttlrdata_delete(nsec3_rrsig); free(fqdn); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3rrsig_del); } if(!treeset_avl_isempty(&replay->nsec3rrsig_add)) { /* stuff to add */ treeset_avl_iterator ts_avl_iter; treeset_avl_iterator_init(&replay->nsec3rrsig_add, &ts_avl_iter); while(treeset_avl_iterator_hasnext(&ts_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&ts_avl_iter); u8 *fqdn = (u8*)node->key; #ifndef NDEBUG log_debug("journal: NSEC3: post/add %{dnsname}", fqdn); #endif zdb_packed_ttlrdata *nsec3_rrsig = (zdb_packed_ttlrdata*)node->data; #ifndef NDEBUG log_debug("journal: NSEC3: add %{dnsname}", fqdn); rdata_desc type_len_rdata = {TYPE_RRSIG, ZDB_PACKEDRECORD_PTR_RDATASIZE(nsec3_rrsig), ZDB_PACKEDRECORD_PTR_RDATAPTR(nsec3_rrsig) }; log_debug("journal: NSEC3: + %{typerdatadesc}", &type_len_rdata); #endif /* * The node must be added. It should not exist already. * After all changes (del/upd/add) all the added records should be matched again (check) */ nsec3_zone_item *item = nsec3_zone_item_find_by_name_ext(replay->zone, fqdn, NULL); if(item != NULL) { nsec3_zone_item_rrsig_add(item, nsec3_rrsig); } else { ZDB_RECORD_ZFREE(nsec3_rrsig); } free(fqdn); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3rrsig_add); } if(!treeset_avl_isempty(&replay->nsec3_labels)) { /* labels to update */ treeset_avl_iterator ts_avl_iter; treeset_avl_iterator_init(&replay->nsec3_labels, &ts_avl_iter); while(treeset_avl_iterator_hasnext(&ts_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&ts_avl_iter); u8 *fqdn = (u8*)node->key; zdb_rr_label *rr_label = (zdb_rr_label*)node->data; #ifndef NDEBUG log_debug("journal: NSEC3: lbl %{dnsname} (%{dnslabel})", fqdn, rr_label->name); #endif /* * The fqdn/label should be updated for self & star match. */ if(rr_label->nsec.nsec3 == NULL) { nsec3_label_link(replay->zone, rr_label, fqdn); } free(fqdn); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3_labels); } /**/ if(nsec3param_added) { /* * ALL the labels of the zone have to be linked again. */ zdb_zone_label_iterator label_iterator; u8 fqdn[MAX_DOMAIN_LENGTH]; zdb_zone_label_iterator_init(replay->zone, &label_iterator); while(zdb_zone_label_iterator_hasnext(&label_iterator)) { zdb_zone_label_iterator_nextname(&label_iterator, fqdn); zdb_rr_label* label = zdb_zone_label_iterator_next(&label_iterator); nsec3_label_link(replay->zone, label, fqdn); } } if(!treeset_avl_isempty(&replay->nsec3param_del)) { treeset_avl_iterator n3p_avl_iter; treeset_avl_iterator_init(&replay->nsec3param_del, &n3p_avl_iter); while(treeset_avl_iterator_hasnext(&n3p_avl_iter)) { treeset_node *node = treeset_avl_iterator_next_node(&n3p_avl_iter); zdb_ttlrdata* nsec3param = (zdb_ttlrdata*)node->data; nsec3_zone* n3 = nsec3_zone_get_from_rdata(replay->zone, nsec3param->rdata_size, nsec3param->rdata_pointer); if(n3 == NULL) { nsec3_zone_destroy(replay->zone, n3); zdb_record_delete_exact(&replay->zone->apex->resource_record_set, TYPE_NSEC3PARAM, nsec3param); } zdb_ttlrdata_delete(nsec3param); node->key = NULL; node->data = NULL; } treeset_avl_destroy(&replay->nsec3param_del); } return SUCCESS; }
ya_result zdb_zone_update_ixfr(zdb* db, input_stream* is) { u8 rname[MAX_DOMAIN_LENGTH]; u16 rtype; u16 rclass; u32 rttl; u16 rdata_size; u8* rdata; zdb_packed_ttlrdata* soa_ttlrdata; zdb_packed_ttlrdata* tmp_ttlrdata; zdb_packed_ttlrdata* ttlrdata; dnsname_vector name; dnsname_vector entry_name; ya_result err; /* Get the first SOA */ if(FAIL(err = input_stream_read_rr_header(is, rname, sizeof (rname), &rtype, &rclass, &rttl, &rdata_size))) { return err; } if(rtype != TYPE_SOA) { return ZDB_ERROR_GENERAL; } DEBUG_RESET_dnsname(name); dnsname_to_dnsname_vector(rname, &name); ZDB_RECORD_ZALLOC_EMPTY(soa_ttlrdata, rttl, rdata_size); if(FAIL(err = input_stream_read_fully(is, ZDB_PACKEDRECORD_PTR_RDATAPTR(soa_ttlrdata), rdata_size))) { return err; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr H: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, ZDB_PACKEDRECORD_PTR_RDATAPTR(soa_ttlrdata), rdata_size); println(""); } #endif #endif u32 serial_first; if(FAIL(err = rr_soa_get_serial(soa_ttlrdata->rdata_start, soa_ttlrdata->rdata_size, &serial_first))) { return err; } zdb_zone_label* zone_label = zdb_zone_label_find(db, &name, rclass); if((zone_label == NULL) || (zone_label->zone == NULL)) { /* Not loaded */ return ZDB_ERROR_GENERAL; } zdb_zone* zone = zone_label->zone; u32 serial_current; if(FAIL(err = zdb_zone_getserial(zone, &serial_current))) { return err; } #if ZDB_NSEC3_SUPPORT != 0 nsec3_load_context nsec3_context; nsec3_load_init(&nsec3_context, zone); #endif MALLOC_OR_DIE(zdb_packed_ttlrdata*, tmp_ttlrdata, sizeof (zdb_ttlrdata) + RDATA_MAX_LENGTH, ZDB_RDATABUF_TAG); /* We do not need tmp_ttlrdata and rdata at the same time, let's spare memory */ rdata = ZDB_PACKEDRECORD_PTR_RDATAPTR(tmp_ttlrdata); /* Read the next SOA (sub or end) */ if(FAIL(err = input_stream_read_rr_header(is, rname, sizeof (rname), &rtype, &rclass, &rttl, &rdata_size))) { return err; } if(rtype != TYPE_SOA) { return ZDB_ERROR_GENERAL; } for(;;) { if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr F: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif #endif /* The SOA serial is supposed to match our current one or the first one * * If it's the first one, then the task is done * * If it's the current one, we are moving forward * * If it's something else, there is an error * */ u32 serial_from; if(FAIL(err = rr_soa_get_serial(rdata, rdata_size, &serial_from))) { break; } /* Check the serial */ if(serial_from != serial_current) { if(serial_from == serial_first) { /* IXFR done */ err = SUCCESS; break; } /* Serial sequence is not right */ err = ZDB_ERROR_GENERAL; break; } tmp_ttlrdata->ttl = rttl; tmp_ttlrdata->rdata_size = rdata_size; zdb_zone_record_delete(zone, NULL, -1, TYPE_SOA, tmp_ttlrdata); for(;;) { /* Load the next record without the data (sub) */ if(FAIL(err = input_stream_read_rr_header(is, rname, sizeof (rname), &rtype, &rclass, &rttl, &rdata_size))) { break; } /* If we got an SOA, it's the one that starts the "add" sequence */ if(rtype == TYPE_SOA) { break; } /* Load the data */ if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr R: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif #endif tmp_ttlrdata->ttl = rttl; tmp_ttlrdata->rdata_size = rdata_size; /* The vector is not always required, but it's so much easier to * read putting it here */ DEBUG_RESET_dnsname(entry_name); dnsname_to_dnsname_vector(rname, &entry_name); #if ZDB_NSEC3_SUPPORT != 0 if(rtype == TYPE_NSEC3PARAM) { /* Remove it from the zone */ zdb_zone_record_delete(zone, name.labels, (entry_name.size - name.size) - 1, rtype, tmp_ttlrdata); /* Destroy the whole NSEC3 collection associated to the NSEC3PARAM */ nsec3_remove_nsec3param_by_record(zone, tmp_ttlrdata); continue; } if(rtype == TYPE_NSEC3) { /* Remove the NSEC3 label (and its signature) * * The previous record will have its signature changed, no doubt. * But I cannot edit the previous one about this. * Since we are in an IXFR, the previous NSEC3 is supposed to be * removed too, until one of the previous is also added in the * next section (soa add) * * zdb_zone_record_delete is not the right call, it's * * nsec3_... * */ nsec3_remove_nsec3(zone, tmp_ttlrdata); continue; } if(rtype == TYPE_RRSIG) { if((GET_U16_AT(*rdata)) == TYPE_NSEC3) /** @note : NATIVETYPE */ { /* Remove the RRSIG from the NSEC3 label * * zdb_zone_record_delete is not the right call, it's * * nsec3_... * */ nsec3_remove_rrsig(zone, tmp_ttlrdata); continue; } } #endif /* Remove from the zone */ zdb_zone_record_delete(zone, name.labels, (entry_name.size - name.size) - 1, rtype, tmp_ttlrdata); } /* Remove records */ /* The current header is the "ADD" SOA */ if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr T: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif #endif /* The SOA serial is supposed to be bigger than the previous one */ u32 serial_to; if(FAIL(err = rr_soa_get_serial(rdata, rdata_size, &serial_to))) { break; } /* * After the "add" sequence is done, serial_current will be serial_to */ do { /* Load the record without the data (add) */ if(FAIL(err = input_stream_read_rr_header(is, rname, sizeof (rname), &rtype, &rclass, &rttl, &rdata_size))) { break; } #if ZDB_NSEC3_SUPPORT != 0 if(rtype == TYPE_NSEC3PARAM) { /* Load the data */ if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr A: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif #endif /* Add it to the nsec3 context */ nsec3_load_add_nsec3param(&nsec3_context, rdata, rdata_size); /* Add it to the zone */ DEBUG_RESET_dnsname(entry_name); dnsname_to_dnsname_vector(rname, &entry_name); ZDB_RECORD_ZALLOC(ttlrdata, rttl, rdata_size, rdata); zdb_zone_record_add(zone, entry_name.labels, (entry_name.size - name.size) - 1, rtype, ttlrdata); } else if(rtype == TYPE_NSEC3) { /* Load the data */ if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr A: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif #endif /* Add it to the nsec3 context */ if(FAIL(err = nsec3_load_add_nsec3(&nsec3_context, rname, rttl, rdata, rdata_size))) { break; } } else if(rtype == TYPE_RRSIG) { /* Load the data */ if(FAIL(err = input_stream_read_fully(is, rdata, rdata_size))) { break; } #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr A: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, rdata, rdata_size); println(""); } #endif if((GET_U16_AT(*rdata)) == TYPE_NSEC3) /** @note : NATIVETYPE */ { /* Add it to the nsec3 context */ if(FAIL(err = nsec3_load_add_rrsig(&nsec3_context, rname, rttl, rdata, rdata_size))) { break; } } else { /* Add it to the zone */ DEBUG_RESET_dnsname(entry_name); dnsname_to_dnsname_vector(rname, &entry_name); ZDB_RECORD_ZALLOC(ttlrdata, rttl, rdata_size, rdata); zdb_zone_record_add(zone, entry_name.labels, (entry_name.size - name.size) - 1, rtype, ttlrdata); } } else { #endif /* Add it to the zone */ ZDB_RECORD_ZALLOC_EMPTY(ttlrdata, rttl, rdata_size); if(FAIL(err = input_stream_read_fully(is, ZDB_PACKEDRECORD_PTR_RDATAPTR(ttlrdata), rdata_size))) { break; } #ifndef NDEBUG #if DUMP_ICMTL_UPDATE != 0 if(err != 0) { format("zdb_zone_update_ixfr A: %{dnsname} %d %{dnsclass} %{dnstype} ", rname, rttl, &rclass, &rtype); print_rdata(rtype, ttlrdata->rdata_start, rdata_size); println(termout, ""); } #endif #endif DEBUG_RESET_dnsname(entry_name); dnsname_to_dnsname_vector(rname, &entry_name); zdb_zone_record_add(zone, entry_name.labels, (entry_name.size - name.size) - 1, rtype, ttlrdata); /* class is implicit */ #if ZDB_NSEC3_SUPPORT != 0 } #endif } while(rtype != TYPE_SOA); /* * The record is either the first of another SOA pair (sub, add) * Either the final one. */ /* Update the current serial */ serial_current = serial_to; break; } free(tmp_ttlrdata); if(ISOK(err)) { /* * soa_ttlrdata is the new SOA */ zdb_zone_record_add(zone, NULL, -1, TYPE_SOA, soa_ttlrdata); #if ZDB_NSEC3_SUPPORT != 0 /** * Check if there is both NSEC & NSEC3. Reject if yes. * compile NSEC if any * compile NSEC3 if any * * @todo: I'm only doing NSEC3 here. Do NSEC as well */ err = nsec3_load_compile(&nsec3_context); if((nsec3_context.nsec3_rejected > 0)||(nsec3_context.nsec3_discarded > 0)) { err = DNSSEC_ERROR_NSEC3_INVALIDZONESTATE; } if(ISOK(err)) { nsec3_load_destroy(&nsec3_context); #endif zone_label->zone = zone; return err; #if ZDB_NSEC3_SUPPORT != 0 } #endif } #if ZDB_NSEC3_SUPPORT != 0 nsec3_load_destroy(&nsec3_context); #endif /** * @note : do NOT use these to unload a zone. * zdb_zone_label_delete(db, &name, zone->zclass); * zdb_zone_destroy(zone); */ zdb_zone_unload(db, &name, zdb_zone_getclass(zone)); return err; }