From 76453961bd0b2fee550557dce59ef2c7caf831d1 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 20 Jul 2021 08:46:32 +1000 Subject: [PATCH] Order the diff from dns_db_diffx so that deletes proceed adds for the same rdataset. This allows the diff when passed to dns_diff_apply to succeed. --- lib/dns/include/dns/diff.h | 7 ++++--- lib/dns/journal.c | 22 +++++++++++++--------- lib/dns/zone.c | 3 ++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/dns/include/dns/diff.h b/lib/dns/include/dns/diff.h index ea535d4426..b3ae0054bd 100644 --- a/lib/dns/include/dns/diff.h +++ b/lib/dns/include/dns/diff.h @@ -66,6 +66,7 @@ typedef enum { } dns_diffop_t; typedef struct dns_difftuple dns_difftuple_t; +typedef ISC_LIST(dns_difftuple_t) dns_difftuplelist_t; #define DNS_DIFFTUPLE_MAGIC ISC_MAGIC('D', 'I', 'F', 'T') #define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC) @@ -92,9 +93,9 @@ typedef struct dns_diff dns_diff_t; #define DNS_DIFF_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFF_MAGIC) struct dns_diff { - unsigned int magic; - isc_mem_t * mctx; - ISC_LIST(dns_difftuple_t) tuples; + unsigned int magic; + isc_mem_t * mctx; + dns_difftuplelist_t tuples; }; /* Type of comparison function for sorting diffs. */ diff --git a/lib/dns/journal.c b/lib/dns/journal.c index 48fbb433aa..6639ddc3f3 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -2194,9 +2194,12 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { dns_difftuple_t *p[2]; int i, t; bool append; + dns_difftuplelist_t add, del; CHECK(dns_diff_sort(&diff[0], rdata_order)); CHECK(dns_diff_sort(&diff[1], rdata_order)); + ISC_LIST_INIT(add); + ISC_LIST_INIT(del); for (;;) { p[0] = ISC_LIST_HEAD(diff[0].tuples); @@ -2207,23 +2210,21 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { for (i = 0; i < 2; i++) { if (p[!i] == NULL) { - { - ISC_LIST_UNLINK(diff[i].tuples, p[i], - link); - ISC_LIST_APPEND(r->tuples, p[i], link); - goto next; - } + dns_difftuplelist_t *l = (i == 0) ? &add : &del; + ISC_LIST_UNLINK(diff[i].tuples, p[i], link); + 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); - ISC_LIST_APPEND(r->tuples, p[0], link); + ISC_LIST_APPEND(add, p[0], link); goto next; } if (t > 0) { ISC_LIST_UNLINK(diff[1].tuples, p[1], link); - ISC_LIST_APPEND(r->tuples, p[1], link); + ISC_LIST_APPEND(del, p[1], link); goto next; } INSIST(t == 0); @@ -2235,13 +2236,16 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { for (i = 0; i < 2; i++) { ISC_LIST_UNLINK(diff[i].tuples, p[i], link); if (append) { - ISC_LIST_APPEND(r->tuples, p[i], link); + dns_difftuplelist_t *l = (i == 0) ? &add : &del; + ISC_LIST_APPEND(*l, p[i], link); } else { dns_difftuple_free(&p[i]); } } next:; } + ISC_LIST_APPENDLIST(r->tuples, del, link); + ISC_LIST_APPENDLIST(r->tuples, add, link); result = ISC_R_SUCCESS; failure: return (result); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 98ff8facf1..e97202b30b 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -16424,7 +16424,8 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, * If the SOA records are the same except for the serial * remove them from the diff. */ - if (oldsoa.refresh == newsoa.refresh && + if (oldtuple->ttl == newtuple->ttl && + oldsoa.refresh == newsoa.refresh && oldsoa.retry == newsoa.retry && oldsoa.minimum == newsoa.minimum && oldsoa.expire == newsoa.expire &&