diff --git a/CHANGES b/CHANGES index 78b4b267b1..ba301734ab 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2749. [bug] ixfr-from-differences generated a non-minimal ixfr + for NSEC3 signed zones. [RT #20452] + 2748. [func] Identify bad answers from GTLD servers and treat them as referrals. [RT #18884] diff --git a/lib/dns/journal.c b/lib/dns/journal.c index 6062d5d683..479da1e98f 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: journal.c,v 1.107 2009/11/04 01:25:55 marka Exp $ */ +/* $Id: journal.c,v 1.108 2009/11/04 03:46:44 marka Exp $ */ #include @@ -1859,18 +1859,11 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { return (result); } -/* - * Compare the databases 'dba' and 'dbb' and generate a journal - * entry containing the changes to make 'dba' from 'dbb' (note - * the order). This journal entry will consist of a single, - * possibly very large transaction. - */ - -isc_result_t -dns_db_diff(isc_mem_t *mctx, - dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - const char *journal_filename) +static isc_result_t +diff_namespace(isc_mem_t *mctx, + dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, + unsigned int options, dns_diff_t *resultdiff) { dns_db_t *db[2]; dns_dbversion_t *ver[2]; @@ -1878,30 +1871,24 @@ dns_db_diff(isc_mem_t *mctx, isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE }; dns_fixedname_t fixname[2]; isc_result_t result, itresult[2]; - dns_diff_t diff[2], resultdiff; + dns_diff_t diff[2]; int i, t; - dns_journal_t *journal = NULL; db[0] = dba, db[1] = dbb; ver[0] = dbvera, ver[1] = dbverb; dns_diff_init(mctx, &diff[0]); dns_diff_init(mctx, &diff[1]); - dns_diff_init(mctx, &resultdiff); dns_fixedname_init(&fixname[0]); dns_fixedname_init(&fixname[1]); - result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal); + result = dns_db_createiterator(db[0], options, &dbit[0]); if (result != ISC_R_SUCCESS) return (result); - - result = dns_db_createiterator(db[0], 0, &dbit[0]); + result = dns_db_createiterator(db[1], options, &dbit[1]); if (result != ISC_R_SUCCESS) - goto cleanup_journal; - result = dns_db_createiterator(db[1], 0, &dbit[1]); - if (result != ISC_R_SUCCESS) - goto cleanup_interator0; + goto cleanup_interator; itresult[0] = dns_dbiterator_first(dbit[0]); itresult[1] = dns_dbiterator_first(dbit[1]); @@ -1928,7 +1915,7 @@ dns_db_diff(isc_mem_t *mctx, for (i = 0; i < 2; i++) { if (! have[!i]) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[i].tuples, link); INSIST(ISC_LIST_EMPTY(diff[i].tuples)); have[i] = ISC_FALSE; @@ -1939,21 +1926,21 @@ dns_db_diff(isc_mem_t *mctx, t = dns_name_compare(dns_fixedname_name(&fixname[0]), dns_fixedname_name(&fixname[1])); if (t < 0) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[0].tuples, link); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); have[0] = ISC_FALSE; continue; } if (t > 0) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[1].tuples, link); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[1] = ISC_FALSE; continue; } INSIST(t == 0); - CHECK(dns_diff_subtract(diff, &resultdiff)); + CHECK(dns_diff_subtract(diff, resultdiff)); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[0] = have[1] = ISC_FALSE; @@ -1964,20 +1951,49 @@ dns_db_diff(isc_mem_t *mctx, if (itresult[1] != ISC_R_NOMORE) FAIL(itresult[1]); + INSIST(ISC_LIST_EMPTY(diff[0].tuples)); + INSIST(ISC_LIST_EMPTY(diff[1].tuples)); + + failure: + dns_dbiterator_destroy(&dbit[1]); + cleanup_interator: + dns_dbiterator_destroy(&dbit[0]); + return (result); +} + +/* + * Compare the databases 'dba' and 'dbb' and generate a journal + * entry containing the changes to make 'dba' from 'dbb' (note + * the order). This journal entry will consist of a single, + * possibly very large transaction. + */ +isc_result_t +dns_db_diff(isc_mem_t *mctx, + dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, + const char *journal_filename) +{ + isc_result_t result; + dns_journal_t *journal = NULL; + dns_diff_t resultdiff; + + result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal); + if (result != ISC_R_SUCCESS) + return (result); + + dns_diff_init(mctx, &resultdiff); + + CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, + DNS_DB_NONSEC3, &resultdiff)); + CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, + DNS_DB_NSEC3ONLY, &resultdiff)); if (ISC_LIST_EMPTY(resultdiff.tuples)) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); } else { CHECK(dns_journal_write_transaction(journal, &resultdiff)); } - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - failure: dns_diff_clear(&resultdiff); - dns_dbiterator_destroy(&dbit[1]); - cleanup_interator0: - dns_dbiterator_destroy(&dbit[0]); - cleanup_journal: dns_journal_destroy(&journal); return (result); }