]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Mutate diff.tuples only through methods
authorAlessio Podda <alessio@isc.org>
Fri, 8 May 2026 12:45:07 +0000 (14:45 +0200)
committerAlessio Podda <alessio@isc.org>
Tue, 2 Jun 2026 11:44:32 +0000 (13:44 +0200)
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
lib/dns/include/dns/diff.h
lib/dns/journal.c
lib/dns/nsec3.c
lib/dns/update.c
lib/dns/xfrin.c
lib/dns/zone.c
lib/ns/update.c

index e8dcae9fbccc7115d3ee7e1d441f8c83d957aeae..495bc53d8e9689eab818cb401413538d9488aec9 100644 (file)
@@ -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);
        }
 }
 
index eb9ad1e8c1dda2641f7ac6957a648c139400f5b8..1b76a6509d07462a14e395ac4c35134016949e73 100644 (file)
@@ -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.
index 3af3efa4e6c7e3573419703ffa4e1119c78c32bc..603d6fffa6fc15fd9109634516a6f68bcb74ad19 100644 (file)
@@ -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;
                }
index 64e49ad3f0fe30699d6592034ff53a1f374c6cb8..6b4c45954c683c1104ed136de13b140ff7cb8078 100644 (file)
@@ -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;
index e1cb886713ca4951d04425ea2905669349c6788e..b0088d864ff71eba754a70630c822c68691d5f6b 100644 (file)
@@ -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);
                }
 
index 4cd74212bceb6e5aa4ac02afe27eac0d9bbc845f..2c55369d5b164fb75ad484c92a72f0dce18f1437 100644 (file)
@@ -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);
index 3638e06c85529ffde4950552bd2da198b8e495b0..d993cf2a693b1e1aa8fe5c8ff58d7894a47cdb72 100644 (file)
@@ -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));
index 735d81de9bce5b01bfd94cb358e35f4c3c7fbdea..536fdc04505ebbea206524a4f669c35aaa63c343 100644 (file)
@@ -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);
        }
 
        /*