diff options
Diffstat (limited to 'bin/tests/optional/nsecify.c')
-rw-r--r-- | bin/tests/optional/nsecify.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/bin/tests/optional/nsecify.c b/bin/tests/optional/nsecify.c new file mode 100644 index 0000000..357b47f --- /dev/null +++ b/bin/tests/optional/nsecify.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include <stdbool.h> +#include <stdlib.h> + +#include <isc/mem.h> +#include <isc/print.h> +#include <isc/string.h> + +#include <dns/db.h> +#include <dns/dbiterator.h> +#include <dns/fixedname.h> +#include <dns/nsec.h> +#include <dns/rdataset.h> +#include <dns/rdatasetiter.h> +#include <dns/result.h> + +static isc_mem_t *mctx = NULL; + +ISC_PLATFORM_NORETURN_PRE static void +fatal(const char *message) ISC_PLATFORM_NORETURN_POST; + +static void +fatal(const char *message) { + fprintf(stderr, "%s\n", message); + exit(1); +} + +static void +check_result(isc_result_t result, const char *message) { + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "%s: %s\n", message, isc_result_totext(result)); + exit(1); + } +} + +static bool +active_node(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) { + dns_rdatasetiter_t *rdsiter; + bool active = false; + isc_result_t result; + dns_rdataset_t rdataset; + + dns_rdataset_init(&rdataset); + rdsiter = NULL; + result = dns_db_allrdatasets(db, node, version, 0, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &rdataset); + if (rdataset.type != dns_rdatatype_nsec) { + active = true; + } + dns_rdataset_disassociate(&rdataset); + if (!active) { + result = dns_rdatasetiter_next(rdsiter); + } else { + result = ISC_R_NOMORE; + } + } + if (result != ISC_R_NOMORE) { + fatal("rdataset iteration failed"); + } + dns_rdatasetiter_destroy(&rdsiter); + + if (!active) { + /* + * Make sure there is no NSEC record for this node. + */ + result = dns_db_deleterdataset(db, node, version, + dns_rdatatype_nsec, 0); + if (result == DNS_R_UNCHANGED) { + result = ISC_R_SUCCESS; + } + check_result(result, "dns_db_deleterdataset"); + } + + return (active); +} + +static isc_result_t +next_active(dns_db_t *db, dns_dbversion_t *version, dns_dbiterator_t *dbiter, + dns_name_t *name, dns_dbnode_t **nodep) { + isc_result_t result; + bool active; + + do { + active = false; + result = dns_dbiterator_current(dbiter, nodep, name); + if (result == ISC_R_SUCCESS) { + active = active_node(db, version, *nodep); + if (!active) { + dns_db_detachnode(db, nodep); + result = dns_dbiterator_next(dbiter); + } + } + } while (result == ISC_R_SUCCESS && !active); + + return (result); +} + +static void +nsecify(char *filename) { + isc_result_t result; + dns_db_t *db; + dns_dbversion_t *wversion; + dns_dbnode_t *node, *nextnode; + const char *origintext; + dns_fixedname_t fname, fnextname; + dns_name_t *name, *nextname, *target; + isc_buffer_t b; + size_t len; + dns_dbiterator_t *dbiter; + char newfilename[1024]; + + name = dns_fixedname_initname(&fname); + nextname = dns_fixedname_initname(&fnextname); + + origintext = strrchr(filename, '/'); + if (origintext == NULL) { + origintext = filename; + } else { + origintext++; /* Skip '/'. */ + } + len = strlen(origintext); + isc_buffer_constinit(&b, origintext, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); + check_result(result, "dns_name_fromtext()"); + + db = NULL; + result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, + dns_rdataclass_in, 0, NULL, &db); + check_result(result, "dns_db_create()"); + result = dns_db_load(db, filename, dns_masterformat_text, 0); + if (result == DNS_R_SEENINCLUDE) { + result = ISC_R_SUCCESS; + } + check_result(result, "dns_db_load()"); + wversion = NULL; + result = dns_db_newversion(db, &wversion); + check_result(result, "dns_db_newversion()"); + dbiter = NULL; + result = dns_db_createiterator(db, 0, &dbiter); + check_result(result, "dns_db_createiterator()"); + result = dns_dbiterator_first(dbiter); + check_result(result, "dns_dbiterator_first()"); + node = NULL; + result = next_active(db, wversion, dbiter, name, &node); + while (result == ISC_R_SUCCESS) { + nextnode = NULL; + result = dns_dbiterator_next(dbiter); + if (result == ISC_R_SUCCESS) { + result = next_active(db, wversion, dbiter, nextname, + &nextnode); + } + if (result == ISC_R_SUCCESS) { + target = nextname; + } else if (result == ISC_R_NOMORE) { + target = dns_db_origin(db); + } else { + target = NULL; /* Make compiler happy. */ + fatal("db iteration failed"); + } + dns_nsec_build(db, wversion, node, target, 3600); /* XXX BEW */ + dns_db_detachnode(db, &node); + node = nextnode; + } + if (result != ISC_R_NOMORE) { + fatal("db iteration failed"); + } + dns_dbiterator_destroy(&dbiter); + /* + * XXXRTH For now, we don't increment the SOA serial. + */ + dns_db_closeversion(db, &wversion, true); + len = strlen(filename); + if (len + 4 + 1 > sizeof(newfilename)) { + fatal("filename too long"); + } + snprintf(newfilename, sizeof(newfilename), "%s.new", filename); + result = dns_db_dump(db, NULL, newfilename); + check_result(result, "dns_db_dump"); + dns_db_detach(&db); +} + +int +main(int argc, char *argv[]) { + int i; + + dns_result_register(); + + isc_mem_create(&mctx); + + argc--; + argv++; + + for (i = 0; i < argc; i++) { + nsecify(argv[i]); + } + + /* isc_mem_stats(mctx, stdout); */ + isc_mem_destroy(&mctx); + + return (0); +} |