From b3752b59115dad7fca00086eeb041043400a1572 Mon Sep 17 00:00:00 2001 From: Alessio Podda Date: Fri, 8 May 2026 14:45:07 +0200 Subject: [PATCH] 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. --- lib/dns/diff.c | 54 +++++++++++++++++++++----- lib/dns/include/dns/diff.h | 38 +++++++++++++++++++ lib/dns/journal.c | 39 +++++++++++-------- lib/dns/nsec3.c | 6 ++- lib/dns/update.c | 78 ++++++++++++++++++++++---------------- lib/dns/xfrin.c | 6 ++- lib/dns/zone.c | 78 +++++++++++++++++++++++++++----------- lib/ns/update.c | 62 ++++++++++++++++++------------ 8 files changed, 252 insertions(+), 109 deletions(-) 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 6b8d3b8f522..fc5b66bf7de 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -298,19 +298,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 c8e6542d139..2491aa2e6ab 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); } } @@ -1550,10 +1552,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; } } @@ -1561,7 +1561,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"); @@ -1676,9 +1679,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)); @@ -1741,14 +1745,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. @@ -1789,7 +1795,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); } @@ -1817,25 +1823,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); } @@ -1948,14 +1956,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 @@ -1963,7 +1973,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); } @@ -1991,22 +2001,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 408dc707e9c..bcc2046aa9f 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -702,8 +702,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 2fe411c2222..7567c2c6a0d 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -3587,19 +3587,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; @@ -7082,7 +7084,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); @@ -14227,7 +14229,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; } @@ -14240,7 +14242,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; } @@ -14284,7 +14286,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: @@ -14335,14 +14337,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; @@ -14353,12 +14379,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; } @@ -16633,7 +16659,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; } @@ -16641,12 +16667,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: @@ -16665,7 +16691,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. @@ -16676,9 +16705,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; } } @@ -16745,7 +16774,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 d6517899204..25deb741ab5 100644 --- a/lib/ns/update.c +++ b/lib/ns/update.c @@ -414,19 +414,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; @@ -454,8 +456,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; @@ -991,7 +994,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); } /*% @@ -1144,8 +1147,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; } @@ -1158,8 +1161,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; @@ -2039,7 +2048,7 @@ remove_orphaned_ds(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *newver, 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; @@ -2340,8 +2349,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); } /* @@ -2353,6 +2362,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 @@ -2374,10 +2385,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); @@ -2386,7 +2398,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; } @@ -2395,8 +2407,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); } @@ -2425,7 +2437,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); } } @@ -2471,8 +2483,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); } @@ -2533,7 +2545,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 { @@ -2570,7 +2582,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); } @@ -2617,8 +2629,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); } /* -- 2.47.3