1 /* $NetBSD: nsecify.c,v 1.6 2014/12/10 04:37:53 christos Exp $ */
4 * Copyright (C) 2004, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: nsecify.c,v 1.12 2011/08/29 23:46:44 tbox Exp */
27 #include <isc/print.h>
28 #include <isc/string.h>
31 #include <dns/dbiterator.h>
32 #include <dns/fixedname.h>
34 #include <dns/rdataset.h>
35 #include <dns/rdatasetiter.h>
36 #include <dns/result.h>
38 static isc_mem_t
*mctx
= NULL
;
41 fatal(const char *message
) {
42 fprintf(stderr
, "%s\n", message
);
47 check_result(isc_result_t result
, const char *message
) {
48 if (result
!= ISC_R_SUCCESS
) {
49 fprintf(stderr
, "%s: %s\n", message
,
50 isc_result_totext(result
));
55 static inline isc_boolean_t
56 active_node(dns_db_t
*db
, dns_dbversion_t
*version
, dns_dbnode_t
*node
) {
57 dns_rdatasetiter_t
*rdsiter
;
58 isc_boolean_t active
= ISC_FALSE
;
60 dns_rdataset_t rdataset
;
62 dns_rdataset_init(&rdataset
);
64 result
= dns_db_allrdatasets(db
, node
, version
, 0, &rdsiter
);
65 check_result(result
, "dns_db_allrdatasets()");
66 result
= dns_rdatasetiter_first(rdsiter
);
67 while (result
== ISC_R_SUCCESS
) {
68 dns_rdatasetiter_current(rdsiter
, &rdataset
);
69 if (rdataset
.type
!= dns_rdatatype_nsec
)
71 dns_rdataset_disassociate(&rdataset
);
73 result
= dns_rdatasetiter_next(rdsiter
);
75 result
= ISC_R_NOMORE
;
77 if (result
!= ISC_R_NOMORE
)
78 fatal("rdataset iteration failed");
79 dns_rdatasetiter_destroy(&rdsiter
);
83 * Make sure there is no NSEC record for this node.
85 result
= dns_db_deleterdataset(db
, node
, version
,
86 dns_rdatatype_nsec
, 0);
87 if (result
== DNS_R_UNCHANGED
)
88 result
= ISC_R_SUCCESS
;
89 check_result(result
, "dns_db_deleterdataset");
95 static inline isc_result_t
96 next_active(dns_db_t
*db
, dns_dbversion_t
*version
, dns_dbiterator_t
*dbiter
,
97 dns_name_t
*name
, dns_dbnode_t
**nodep
)
100 isc_boolean_t active
;
104 result
= dns_dbiterator_current(dbiter
, nodep
, name
);
105 if (result
== ISC_R_SUCCESS
) {
106 active
= active_node(db
, version
, *nodep
);
108 dns_db_detachnode(db
, nodep
);
109 result
= dns_dbiterator_next(dbiter
);
112 } while (result
== ISC_R_SUCCESS
&& !active
);
118 nsecify(char *filename
) {
121 dns_dbversion_t
*wversion
;
122 dns_dbnode_t
*node
, *nextnode
;
124 dns_fixedname_t fname
, fnextname
;
125 dns_name_t
*name
, *nextname
, *target
;
128 dns_dbiterator_t
*dbiter
;
129 char newfilename
[1024];
131 dns_fixedname_init(&fname
);
132 name
= dns_fixedname_name(&fname
);
133 dns_fixedname_init(&fnextname
);
134 nextname
= dns_fixedname_name(&fnextname
);
136 origintext
= strrchr(filename
, '/');
137 if (origintext
== NULL
)
138 origintext
= filename
;
140 origintext
++; /* Skip '/'. */
141 len
= strlen(origintext
);
142 isc_buffer_init(&b
, origintext
, len
);
143 isc_buffer_add(&b
, len
);
144 result
= dns_name_fromtext(name
, &b
, dns_rootname
, 0, NULL
);
145 check_result(result
, "dns_name_fromtext()");
148 result
= dns_db_create(mctx
, "rbt", name
, dns_dbtype_zone
,
149 dns_rdataclass_in
, 0, NULL
, &db
);
150 check_result(result
, "dns_db_create()");
151 result
= dns_db_load(db
, filename
);
152 if (result
== DNS_R_SEENINCLUDE
)
153 result
= ISC_R_SUCCESS
;
154 check_result(result
, "dns_db_load()");
156 result
= dns_db_newversion(db
, &wversion
);
157 check_result(result
, "dns_db_newversion()");
159 result
= dns_db_createiterator(db
, 0, &dbiter
);
160 check_result(result
, "dns_db_createiterator()");
161 result
= dns_dbiterator_first(dbiter
);
162 check_result(result
, "dns_dbiterator_first()");
164 result
= next_active(db
, wversion
, dbiter
, name
, &node
);
165 while (result
== ISC_R_SUCCESS
) {
167 result
= dns_dbiterator_next(dbiter
);
168 if (result
== ISC_R_SUCCESS
)
169 result
= next_active(db
, wversion
, dbiter
, nextname
,
171 if (result
== ISC_R_SUCCESS
)
173 else if (result
== ISC_R_NOMORE
)
174 target
= dns_db_origin(db
);
176 target
= NULL
; /* Make compiler happy. */
177 fatal("db iteration failed");
179 dns_nsec_build(db
, wversion
, node
, target
, 3600); /* XXX BEW */
180 dns_db_detachnode(db
, &node
);
183 if (result
!= ISC_R_NOMORE
)
184 fatal("db iteration failed");
185 dns_dbiterator_destroy(&dbiter
);
187 * XXXRTH For now, we don't increment the SOA serial.
189 dns_db_closeversion(db
, &wversion
, ISC_TRUE
);
190 len
= strlen(filename
);
191 if (len
+ 4 + 1 > sizeof(newfilename
))
192 fatal("filename too long");
193 sprintf(newfilename
, "%s.new", filename
);
194 result
= dns_db_dump(db
, NULL
, newfilename
);
195 check_result(result
, "dns_db_dump");
200 main(int argc
, char *argv
[]) {
204 dns_result_register();
206 result
= isc_mem_create(0, 0, &mctx
);
207 check_result(result
, "isc_mem_create()");
212 for (i
= 0; i
< argc
; i
++)
215 /* isc_mem_stats(mctx, stdout); */
216 isc_mem_destroy(&mctx
);