From: Alessio Podda Date: Fri, 8 May 2026 12:45:07 +0000 (+0200) Subject: Mutate diff.tuples only through methods X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1ed82fc609f0f44b29a05b12850c12d96749663;p=thirdparty%2Fbind9.git Mutate diff.tuples only through methods Mutating the underlying list in diff.tuples directly would not update the size parameter of the tuples. With this commit we ensure that the underlying list is updated only through methods that update the size. --- diff --git a/lib/dns/diff.c b/lib/dns/diff.c index e8dcae9fbcc..495bc53d8e9 100644 --- a/lib/dns/diff.c +++ b/lib/dns/diff.c @@ -93,11 +93,11 @@ dns_difftuple_create(isc_mem_t *mctx, dns_diffop_t op, const dns_name_t *name, void dns_difftuple_free(dns_difftuple_t **tp) { - dns_difftuple_t *t = *tp; - *tp = NULL; isc_mem_t *mctx; - REQUIRE(DNS_DIFFTUPLE_VALID(t)); + REQUIRE(tp != NULL && DNS_DIFFTUPLE_VALID(*tp)); + + dns_difftuple_t *t = MOVE_OWNERSHIP(*tp); dns_name_invalidate(&t->name); t->magic = 0; @@ -108,6 +108,9 @@ dns_difftuple_free(dns_difftuple_t **tp) { void dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp) { + REQUIRE(DNS_DIFFTUPLE_VALID(orig)); + REQUIRE(copyp != NULL && *copyp == NULL); + dns_difftuple_create(orig->mctx, orig->op, &orig->name, orig->ttl, &orig->rdata, copyp); } @@ -134,9 +137,44 @@ dns_diff_clear(dns_diff_t *diff) { void dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep) { REQUIRE(DNS_DIFF_VALID(diff)); - ISC_LIST_APPEND(diff->tuples, *tuplep, link); + REQUIRE(tuplep != NULL && DNS_DIFFTUPLE_VALID(*tuplep)); + + dns_difftuple_t *tuple = MOVE_OWNERSHIP(*tuplep); + ISC_LIST_APPEND(diff->tuples, tuple, link); diff->size += 1; - *tuplep = NULL; +} + +void +dns_diff_prepend(dns_diff_t *diff, dns_difftuple_t **tuplep) { + REQUIRE(DNS_DIFF_VALID(diff)); + REQUIRE(tuplep != NULL && DNS_DIFFTUPLE_VALID(*tuplep)); + + dns_difftuple_t *tuple = MOVE_OWNERSHIP(*tuplep); + ISC_LIST_PREPEND(diff->tuples, tuple, link); + diff->size += 1; +} + +void +dns_diff_unlink(dns_diff_t *diff, dns_difftuple_t *tuple) { + REQUIRE(DNS_DIFF_VALID(diff)); + REQUIRE(DNS_DIFFTUPLE_VALID(tuple)); + REQUIRE(diff->size > 0); + + ISC_LIST_UNLINK(diff->tuples, tuple, link); + diff->size -= 1; +} + +bool +dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *new_name) { + REQUIRE(DNS_DIFF_VALID(diff)); + REQUIRE(DNS_NAME_VALID(new_name)); + + if (ISC_LIST_EMPTY(diff->tuples)) { + return false; + } + + dns_difftuple_t *tail = ISC_LIST_TAIL(diff->tuples); + return !dns_name_caseequal(&tail->name, new_name); } size_t @@ -150,7 +188,7 @@ dns_diff_size(const dns_diff_t *diff) { void dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) { REQUIRE(DNS_DIFF_VALID(diff)); - REQUIRE(DNS_DIFFTUPLE_VALID(*tuplep)); + REQUIRE(tuplep != NULL && DNS_DIFFTUPLE_VALID(*tuplep)); /* * Look for an existing tuple with the same owner name, @@ -184,9 +222,7 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) { } if (*tuplep != NULL) { - ISC_LIST_APPEND(diff->tuples, *tuplep, link); - diff->size += 1; - *tuplep = NULL; + dns_diff_append(diff, tuplep); } } diff --git a/lib/dns/include/dns/diff.h b/lib/dns/include/dns/diff.h index eb9ad1e8c1d..1b76a6509d0 100644 --- a/lib/dns/include/dns/diff.h +++ b/lib/dns/include/dns/diff.h @@ -187,6 +187,43 @@ dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple); * \li The tuple has been freed, or will be freed when the diff is cleared. */ +void +dns_diff_prepend(dns_diff_t *diff, dns_difftuple_t **tuple); +/*%< + * Prepend a single tuple to a diff. + * + * Requires: + * \li 'diff' is a valid diff. + * \li '*tuple' is a valid tuple. + * + * Ensures: + * \li *tuple is NULL. + * \li The tuple has been freed, or will be freed when the diff is cleared. + */ + +void +dns_diff_unlink(dns_diff_t *diff, dns_difftuple_t *tuple); +/*%< + * Unlink a single tuple from a diff without freeing it. + * + * Requires: + * \li 'diff' is a valid diff. + * \li 'tuple' is a valid tuple in 'diff'. + * + * Ensures: + * \li The caller owns 'tuple'. + */ + +bool +dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *name); +/*%< + * Checks if 'name' is equal, up to case, to the last name of the diff. + * + * Requires: + * \li 'diff' is a valid diff. + * \li 'name' is a valid dns name. + */ + size_t dns_diff_size(const dns_diff_t *diff); /*%< @@ -204,6 +241,7 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple); * * Requires: *\li 'diff' is a minimal diff. + *\li '*tuple' is a valid tuple. * * Ensures: *\li 'diff' is still a minimal diff. diff --git a/lib/dns/journal.c b/lib/dns/journal.c index 3af3efa4e6c..603d6fffa6f 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -2163,19 +2163,19 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { for (i = 0; i < 2; i++) { if (p[!i] == NULL) { dns_difftuplelist_t *l = (i == 0) ? &add : &del; - ISC_LIST_UNLINK(diff[i].tuples, p[i], link); + dns_diff_unlink(&diff[i], p[i]); ISC_LIST_APPEND(*l, p[i], link); goto next; } } t = rdata_order(&p[0], &p[1]); if (t < 0) { - ISC_LIST_UNLINK(diff[0].tuples, p[0], link); + dns_diff_unlink(&diff[0], p[0]); ISC_LIST_APPEND(add, p[0], link); goto next; } if (t > 0) { - ISC_LIST_UNLINK(diff[1].tuples, p[1], link); + dns_diff_unlink(&diff[1], p[1]); ISC_LIST_APPEND(del, p[1], link); goto next; } @@ -2186,7 +2186,7 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { */ append = (p[0]->ttl != p[1]->ttl); for (i = 0; i < 2; i++) { - ISC_LIST_UNLINK(diff[i].tuples, p[i], link); + dns_diff_unlink(&diff[i], p[i]); if (append) { dns_difftuplelist_t *l = (i == 0) ? &add : &del; ISC_LIST_APPEND(*l, p[i], link); @@ -2196,8 +2196,14 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { } next:; } - ISC_LIST_APPENDLIST(r->tuples, del, link); - ISC_LIST_APPENDLIST(r->tuples, add, link); + ISC_LIST_FOREACH(del, deltuple, link) { + ISC_LIST_UNLINK(del, deltuple, link); + dns_diff_append(r, &deltuple); + } + ISC_LIST_FOREACH(add, addtuple, link) { + ISC_LIST_UNLINK(add, addtuple, link); + dns_diff_append(r, &addtuple); + } result = ISC_R_SUCCESS; cleanup: return result; @@ -2256,9 +2262,10 @@ diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, for (i = 0; i < 2; i++) { if (!have[!i]) { - ISC_LIST_APPENDLIST(resultdiff->tuples, - diff[i].tuples, link); - INSIST(ISC_LIST_EMPTY(diff[i].tuples)); + ISC_LIST_FOREACH(diff[i].tuples, tuple, link) { + dns_diff_unlink(&diff[i], tuple); + dns_diff_append(resultdiff, &tuple); + } have[i] = false; goto next; } @@ -2267,16 +2274,18 @@ diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, t = dns_name_compare(dns_fixedname_name(&fixname[0]), dns_fixedname_name(&fixname[1])); if (t < 0) { - ISC_LIST_APPENDLIST(resultdiff->tuples, diff[0].tuples, - link); - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); + ISC_LIST_FOREACH(diff[0].tuples, tuple, link) { + dns_diff_unlink(&diff[0], tuple); + dns_diff_append(resultdiff, &tuple); + } have[0] = false; continue; } if (t > 0) { - ISC_LIST_APPENDLIST(resultdiff->tuples, diff[1].tuples, - link); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); + ISC_LIST_FOREACH(diff[1].tuples, tuple, link) { + dns_diff_unlink(&diff[1], tuple); + dns_diff_append(resultdiff, &tuple); + } have[1] = false; continue; } diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c index 64e49ad3f0f..6b4c45954c6 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -297,19 +297,21 @@ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; + dns_difftuple_t *temp_tuple = *tuple; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); + dns_diff_append(&temp_diff, tuple); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); + dns_diff_unlink(&temp_diff, temp_tuple); + *tuple = MOVE_OWNERSHIP(temp_tuple); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return result; diff --git a/lib/dns/update.c b/lib/dns/update.c index e1cb886713c..b0088d864ff 100644 --- a/lib/dns/update.c +++ b/lib/dns/update.c @@ -122,19 +122,21 @@ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; + dns_difftuple_t *temp_tuple = *tuple; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); + dns_diff_append(&temp_diff, tuple); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); + dns_diff_unlink(&temp_diff, temp_tuple); + *tuple = MOVE_OWNERSHIP(temp_tuple); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return result; @@ -685,7 +687,7 @@ uniqify_name_list(dns_diff_t *list) { if (curr_name == NULL || !dns_name_equal(curr_name, &p->name)) { curr_name = &(p->name); } else { - ISC_LIST_UNLINK(list->tuples, p, link); + dns_diff_unlink(list, p); dns_difftuple_free(&p); } } @@ -1532,10 +1534,8 @@ next_state: tuple->rdata.type == type) { next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(diff->tuples, tuple, - link); - ISC_LIST_APPEND(state->work.tuples, - tuple, link); + dns_diff_unlink(diff, tuple); + dns_diff_append(&state->work, &tuple); tuple = next; } } @@ -1543,7 +1543,10 @@ next_state: return DNS_R_CONTINUE; } } - ISC_LIST_APPENDLIST(diff->tuples, state->work.tuples, link); + ISC_LIST_FOREACH(state->work.tuples, t, link) { + dns_diff_unlink(&state->work, t); + dns_diff_append(diff, &t); + } update_log(log, zone, ISC_LOG_DEBUG(3), "updated data signatures"); @@ -1658,9 +1661,10 @@ next_state: CHECK(namelist_append_subdomain(db, &t->name, &state->affected)); } - ISC_LIST_APPENDLIST(state->affected.tuples, - state->diffnames.tuples, link); - INSIST(ISC_LIST_EMPTY(state->diffnames.tuples)); + ISC_LIST_FOREACH(state->diffnames.tuples, t, link) { + dns_diff_unlink(&state->diffnames, t); + dns_diff_append(&state->affected, &t); + } CHECK(uniqify_name_list(&state->affected)); @@ -1723,14 +1727,16 @@ next_state: &sigs)); } unlink: - ISC_LIST_UNLINK(state->affected.tuples, t, link); - ISC_LIST_APPEND(state->work.tuples, t, link); + dns_diff_unlink(&state->affected, t); + dns_diff_append(&state->work, &t); if (state != &mystate && sigs > maxsigs) { return DNS_R_CONTINUE; } } - ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, - link); + ISC_LIST_FOREACH(state->work.tuples, t, link) { + dns_diff_unlink(&state->work, t); + dns_diff_append(&state->affected, &t); + } /* * Now we know which names are part of the NSEC chain. @@ -1771,7 +1777,7 @@ next_state: * replaced with identical ones. */ ISC_LIST_FOREACH(state->nsec_diff.tuples, t, link) { - ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); + dns_diff_unlink(&state->nsec_diff, t); dns_diff_appendminimal(&state->nsec_mindiff, &t); } @@ -1799,25 +1805,27 @@ next_state: } else { UNREACHABLE(); } - ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); - ISC_LIST_APPEND(state->work.tuples, t, link); + dns_diff_unlink(&state->nsec_mindiff, t); + dns_diff_append(&state->work, &t); if (state != &mystate && sigs > maxsigs) { return DNS_R_CONTINUE; } } - ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, - state->work.tuples, link); + ISC_LIST_FOREACH(state->work.tuples, t, link) { + dns_diff_unlink(&state->work, t); + dns_diff_append(&state->nsec_mindiff, &t); + } FALLTHROUGH; case update_nsec3: state->state = update_nsec3; /* Record our changes for the journal. */ ISC_LIST_FOREACH(state->sig_diff.tuples, t, link) { - ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); + dns_diff_unlink(&state->sig_diff, t); dns_diff_appendminimal(diff, &t); } ISC_LIST_FOREACH(state->nsec_mindiff.tuples, t, link) { - ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); + dns_diff_unlink(&state->nsec_mindiff, t); dns_diff_appendminimal(diff, &t); } @@ -1930,14 +1938,16 @@ next_state: unsecure, privatetype, &state->nsec_diff)); } - ISC_LIST_UNLINK(state->affected.tuples, t, link); - ISC_LIST_APPEND(state->work.tuples, t, link); + dns_diff_unlink(&state->affected, t); + dns_diff_append(&state->work, &t); if (state != &mystate && sigs > maxsigs) { return DNS_R_CONTINUE; } } - ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, - link); + ISC_LIST_FOREACH(state->work.tuples, t, link) { + dns_diff_unlink(&state->work, t); + dns_diff_append(&state->affected, &t); + } /* * Minimize the set of NSEC3 updates so that we don't @@ -1945,7 +1955,7 @@ next_state: * replaced with identical ones. */ ISC_LIST_FOREACH(state->nsec_diff.tuples, t, link) { - ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); + dns_diff_unlink(&state->nsec_diff, t); dns_diff_appendminimal(&state->nsec_mindiff, &t); } @@ -1973,22 +1983,24 @@ next_state: } else { UNREACHABLE(); } - ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); - ISC_LIST_APPEND(state->work.tuples, t, link); + dns_diff_unlink(&state->nsec_mindiff, t); + dns_diff_append(&state->work, &t); if (state != &mystate && sigs > maxsigs) { return DNS_R_CONTINUE; } } - ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, - state->work.tuples, link); + ISC_LIST_FOREACH(state->work.tuples, t, link) { + dns_diff_unlink(&state->work, t); + dns_diff_append(&state->nsec_mindiff, &t); + } /* Record our changes for the journal. */ ISC_LIST_FOREACH(state->sig_diff.tuples, t, link) { - ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); + dns_diff_unlink(&state->sig_diff, t); dns_diff_appendminimal(diff, &t); } ISC_LIST_FOREACH(state->nsec_mindiff.tuples, t, link) { - ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); + dns_diff_unlink(&state->nsec_mindiff, t); dns_diff_appendminimal(diff, &t); } diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 4cd74212bce..2c55369d5b1 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -698,8 +698,10 @@ ixfr_commit(dns_xfrin_t *xfr) { } dns_diff_init(xfr->mctx, &data->diff); - /* FIXME: Should we add dns_diff_move() */ - ISC_LIST_MOVE(data->diff.tuples, xfr->diff.tuples); + ISC_LIST_FOREACH(xfr->diff.tuples, tuple, link) { + dns_diff_unlink(&xfr->diff, tuple); + dns_diff_append(&data->diff, &tuple); + } (void)cds_wfcq_enqueue(&xfr->diff_head, &xfr->diff_tail, &data->wfcq_node); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 3638e06c855..d993cf2a693 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -3569,19 +3569,21 @@ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; + dns_difftuple_t *temp_tuple = *tuple; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); + dns_diff_append(&temp_diff, tuple); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); + dns_diff_unlink(&temp_diff, temp_tuple); + *tuple = MOVE_OWNERSHIP(temp_tuple); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return result; @@ -7102,7 +7104,7 @@ static void move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) { do { dns_difftuple_t *next = find_next_matching_tuple(cur); - ISC_LIST_UNLINK(src->tuples, cur, link); + dns_diff_unlink(src, cur); dns_diff_appendminimal(dst, &cur); cur = next; } while (cur != NULL); @@ -14214,7 +14216,7 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, if (seczone->privatetype != 0 && tuple->rdata.type == seczone->privatetype) { - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); dns_difftuple_free(&tuple); continue; } @@ -14227,7 +14229,7 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, tuple->rdata.type == dns_rdatatype_nsec3 || tuple->rdata.type == dns_rdatatype_nsec3param) { - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); dns_difftuple_free(&tuple); continue; } @@ -14271,7 +14273,7 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, /* * Split into deletions and additions. */ - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); switch (tuple->op) { case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: @@ -14322,14 +14324,38 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, /* * Rebuild the diff now that we have filtered it */ - ISC_LIST_APPENDLIST(diff->tuples, del, link); - ISC_LIST_APPENDLIST(diff->tuples, keydel, link); - ISC_LIST_APPENDLIST(diff->tuples, ckeydel, link); - ISC_LIST_APPENDLIST(diff->tuples, cdsdel, link); - ISC_LIST_APPENDLIST(diff->tuples, add, link); - ISC_LIST_APPENDLIST(diff->tuples, keyadd, link); - ISC_LIST_APPENDLIST(diff->tuples, ckeyadd, link); - ISC_LIST_APPENDLIST(diff->tuples, cdsadd, link); + ISC_LIST_FOREACH(del, tuple, link) { + ISC_LIST_UNLINK(del, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(keydel, tuple, link) { + ISC_LIST_UNLINK(keydel, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(ckeydel, tuple, link) { + ISC_LIST_UNLINK(ckeydel, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(cdsdel, tuple, link) { + ISC_LIST_UNLINK(cdsdel, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(add, tuple, link) { + ISC_LIST_UNLINK(add, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(keyadd, tuple, link) { + ISC_LIST_UNLINK(keyadd, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(ckeyadd, tuple, link) { + ISC_LIST_UNLINK(ckeyadd, tuple, link); + dns_diff_append(diff, &tuple); + } + ISC_LIST_FOREACH(cdsadd, tuple, link) { + ISC_LIST_UNLINK(cdsadd, tuple, link); + dns_diff_append(diff, &tuple); + } if (ISC_LIST_EMPTY(diff->tuples)) { return DNS_R_UNCHANGED; @@ -14340,12 +14366,12 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, * saving the new SOA record. */ if (oldtuple != NULL) { - ISC_LIST_UNLINK(diff->tuples, oldtuple, link); + dns_diff_unlink(diff, oldtuple); dns_difftuple_free(&oldtuple); } if (newtuple != NULL) { - ISC_LIST_UNLINK(diff->tuples, newtuple, link); + dns_diff_unlink(diff, newtuple); *soatuple = newtuple; } @@ -16489,7 +16515,7 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, */ ISC_LIST_FOREACH(diff->tuples, tuple, link) { if (tuple->rdata.type != dns_rdatatype_dnskey) { - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); ISC_LIST_APPEND(tuples, tuple, link); continue; } @@ -16497,12 +16523,12 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0) { - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); ISC_LIST_APPEND(tuples, tuple, link); continue; } - ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_diff_unlink(diff, tuple); switch (tuple->op) { case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: @@ -16521,7 +16547,10 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, * Put the tuples that don't need more processing back onto * diff->tuples. */ - ISC_LIST_APPENDLIST(diff->tuples, tuples, link); + ISC_LIST_FOREACH(tuples, tuple, link) { + ISC_LIST_UNLINK(tuples, tuple, link); + dns_diff_append(diff, &tuple); + } /* * Filter out DNSKEY TTL changes and put them back onto diff->tuples. @@ -16532,9 +16561,9 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, &addtuple->rdata); if (n == 0) { ISC_LIST_UNLINK(del, deltuple, link); - ISC_LIST_APPEND(diff->tuples, deltuple, link); + dns_diff_append(diff, &deltuple); ISC_LIST_UNLINK(add, addtuple, link); - ISC_LIST_APPEND(diff->tuples, addtuple, link); + dns_diff_append(diff, &addtuple); break; } } @@ -16601,7 +16630,10 @@ cleanup: /* * Put the DNSKEY changes we cared about back on diff->tuples. */ - ISC_LIST_APPENDLIST(diff->tuples, tuples, link); + ISC_LIST_FOREACH(tuples, tuple, link) { + ISC_LIST_UNLINK(tuples, tuple, link); + dns_diff_append(diff, &tuple); + } INSIST(ISC_LIST_EMPTY(add)); INSIST(ISC_LIST_EMPTY(del)); INSIST(ISC_LIST_EMPTY(tuples)); diff --git a/lib/ns/update.c b/lib/ns/update.c index 735d81de9bc..536fdc04505 100644 --- a/lib/ns/update.c +++ b/lib/ns/update.c @@ -419,19 +419,21 @@ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; + dns_difftuple_t *temp_tuple = *tuple; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); + dns_diff_append(&temp_diff, tuple); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); + dns_diff_unlink(&temp_diff, temp_tuple); + *tuple = MOVE_OWNERSHIP(temp_tuple); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return result; @@ -459,8 +461,9 @@ static isc_result_t do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { isc_result_t result; + ISC_LIST_FOREACH(updates->tuples, t, link) { - ISC_LIST_UNLINK(updates->tuples, t, link); + dns_diff_unlink(updates, t); CHECK(do_one_tuple(&t, db, ver, diff)); } return ISC_R_SUCCESS; @@ -1003,7 +1006,7 @@ temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { REQUIRE(DNS_DIFF_VALID(diff)); dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, name, 0, rdata, &tuple); - ISC_LIST_APPEND(diff->tuples, tuple, link); + dns_diff_append(diff, &tuple); } /*% @@ -1156,8 +1159,8 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, t->rdata.type == type) { dns_difftuple_t *next = ISC_LIST_NEXT(t, link); - ISC_LIST_UNLINK(temp->tuples, t, link); - ISC_LIST_APPEND(u_rrs.tuples, t, link); + dns_diff_unlink(temp, t); + dns_diff_append(&u_rrs, &t); t = next; } @@ -1170,8 +1173,14 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, * them yet because "name" still points into one * of them. Move them on a temporary list. */ - ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); - ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); + ISC_LIST_FOREACH(u_rrs.tuples, trash_tuple, link) { + dns_diff_unlink(&u_rrs, trash_tuple); + dns_diff_append(&trash, &trash_tuple); + } + ISC_LIST_FOREACH(d_rrs.tuples, trash_tuple, link) { + dns_diff_unlink(&d_rrs, trash_tuple); + dns_diff_append(&trash, &trash_tuple); + } dns_rdataset_disassociate(&rdataset); continue; @@ -1995,7 +2004,7 @@ remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { cleanup: ISC_LIST_FOREACH(temp_diff.tuples, tuple, link) { - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); + dns_diff_unlink(&temp_diff, tuple); dns_diff_appendminimal(diff, &tuple); } return result; @@ -2296,8 +2305,8 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, { continue; } - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_APPEND(temp_diff.tuples, tuple, link); + dns_diff_unlink(diff, tuple); + dns_diff_append(&temp_diff, &tuple); } /* @@ -2309,6 +2318,8 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, tuple != NULL; tuple = next) { if (tuple->op == DNS_DIFFOP_ADD) { + bool found = false; + if (!ttl_good) { /* * Any adds here will contain the final @@ -2330,10 +2341,11 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, !memcmp(next_data, tuple_data, next->rdata.length)) { - ISC_LIST_UNLINK(temp_diff.tuples, next, - link); - ISC_LIST_APPEND(diff->tuples, next, - link); + dns_difftuple_t *match = next; + + found = true; + dns_diff_unlink(&temp_diff, next); + dns_diff_append(diff, &match); break; } next = ISC_LIST_NEXT(next, link); @@ -2342,7 +2354,7 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, * If we have not found a pair move onto the next * tuple. */ - if (next == NULL) { + if (!found) { next = ISC_LIST_NEXT(tuple, link); continue; } @@ -2351,8 +2363,8 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, * unlinking then complete moving the pair to 'diff'. */ next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); + dns_diff_unlink(&temp_diff, tuple); + dns_diff_append(diff, &tuple); } else { next = ISC_LIST_NEXT(tuple, link); } @@ -2381,7 +2393,7 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, dns_difftuple_create(diff->mctx, op, name, ttl, &tuple->rdata, &newtuple); CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); + dns_diff_unlink(&temp_diff, tuple); dns_diff_appendminimal(diff, &tuple); } } @@ -2427,8 +2439,8 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, next = ISC_LIST_NEXT(next, link); continue; } - ISC_LIST_UNLINK(temp_diff.tuples, next, link); - ISC_LIST_APPEND(diff->tuples, next, link); + dns_diff_unlink(&temp_diff, next); + dns_diff_append(diff, &next); next = ISC_LIST_HEAD(temp_diff.tuples); } @@ -2489,7 +2501,7 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, ttl, &tuple->rdata, &newtuple); CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); + dns_diff_unlink(&temp_diff, tuple); dns_diff_appendminimal(diff, &tuple); dns_rdata_reset(&rdata); } else { @@ -2526,7 +2538,7 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, ttl, &tuple->rdata, &newtuple); CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); + dns_diff_unlink(&temp_diff, tuple); dns_diff_appendminimal(diff, &tuple); dns_rdata_reset(&rdata); } @@ -2573,8 +2585,8 @@ rollback_private(dns_db_t *db, dns_rdatatype_t privatetype, continue; } - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_PREPEND(temp_diff.tuples, tuple, link); + dns_diff_unlink(diff, tuple); + dns_diff_prepend(&temp_diff, &tuple); } /*