Compare commits
5 Commits
ondrej/bum
...
alessio/ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97460c9929 | ||
|
|
44c18b62fb | ||
|
|
5d0d537b31 | ||
|
|
5d00cd48a8 | ||
|
|
ccb7e3ecd5 |
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
@@ -124,6 +125,7 @@ dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff) {
|
||||
diff->mctx = mctx;
|
||||
ISC_LIST_INIT(diff->tuples);
|
||||
diff->magic = DNS_DIFF_MAGIC;
|
||||
diff->size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -134,15 +136,32 @@ dns_diff_clear(dns_diff_t *diff) {
|
||||
ISC_LIST_UNLINK(diff->tuples, t, link);
|
||||
dns_difftuple_free(&t);
|
||||
}
|
||||
diff->size = 0;
|
||||
ENSURE(ISC_LIST_EMPTY(diff->tuples));
|
||||
}
|
||||
|
||||
void
|
||||
dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep) {
|
||||
ISC_LIST_APPEND(diff->tuples, *tuplep, link);
|
||||
diff->size += 1;
|
||||
*tuplep = NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *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
|
||||
dns_diff_size(const dns_diff_t *diff) {
|
||||
return diff->size;
|
||||
}
|
||||
|
||||
/* XXX this is O(N) */
|
||||
|
||||
void
|
||||
@@ -171,6 +190,9 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) {
|
||||
ot->ttl == (*tuplep)->ttl)
|
||||
{
|
||||
ISC_LIST_UNLINK(diff->tuples, ot, link);
|
||||
INSIST(diff->size > 0);
|
||||
diff->size -= 1;
|
||||
|
||||
if ((*tuplep)->op == ot->op) {
|
||||
UNEXPECTED_ERROR("unexpected non-minimal diff");
|
||||
} else {
|
||||
@@ -183,6 +205,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;
|
||||
}
|
||||
}
|
||||
@@ -254,7 +277,8 @@ optotext(dns_diffop_t op) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, bool warn) {
|
||||
diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
bool warn) {
|
||||
dns_difftuple_t *t;
|
||||
dns_dbnode_t *node = NULL;
|
||||
isc_result_t result;
|
||||
@@ -494,19 +518,20 @@ failure:
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
|
||||
dns_diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
|
||||
return (diff_apply(diff, db, ver, true));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
|
||||
dns_diff_applysilently(const dns_diff_t *diff, dns_db_t *db,
|
||||
dns_dbversion_t *ver) {
|
||||
return (diff_apply(diff, db, ver, false));
|
||||
}
|
||||
|
||||
/* XXX this duplicates lots of code in diff_apply(). */
|
||||
|
||||
isc_result_t
|
||||
dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks) {
|
||||
dns_diff_load(const dns_diff_t *diff, dns_rdatacallbacks_t *callbacks) {
|
||||
dns_difftuple_t *t;
|
||||
isc_result_t result;
|
||||
|
||||
@@ -642,7 +667,7 @@ diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata,
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_diff_print(dns_diff_t *diff, FILE *file) {
|
||||
dns_diff_print(const dns_diff_t *diff, FILE *file) {
|
||||
isc_result_t result;
|
||||
dns_difftuple_t *t;
|
||||
char *mem = NULL;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
*** Imports
|
||||
***/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/magic.h>
|
||||
|
||||
@@ -97,6 +99,7 @@ struct dns_diff {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
dns_difftuplelist_t tuples;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* Type of comparison function for sorting diffs. */
|
||||
@@ -194,6 +197,12 @@ 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.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *new_name);
|
||||
|
||||
size_t
|
||||
dns_diff_size(const dns_diff_t *diff);
|
||||
|
||||
void
|
||||
dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple);
|
||||
/*%<
|
||||
@@ -218,9 +227,10 @@ dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
|
||||
dns_diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
|
||||
isc_result_t
|
||||
dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
|
||||
dns_diff_applysilently(const dns_diff_t *diff, dns_db_t *db,
|
||||
dns_dbversion_t *ver);
|
||||
/*%<
|
||||
* Apply 'diff' to the database 'db'.
|
||||
*
|
||||
@@ -239,7 +249,7 @@ dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
|
||||
dns_diff_load(const dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
|
||||
/*%<
|
||||
* Like dns_diff_apply, but for use when loading a new database
|
||||
* instead of modifying an existing one. This bypasses the
|
||||
@@ -251,7 +261,7 @@ dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_diff_print(dns_diff_t *diff, FILE *file);
|
||||
dns_diff_print(const dns_diff_t *diff, FILE *file);
|
||||
|
||||
/*%<
|
||||
* Print the differences to 'file' or if 'file' is NULL via the
|
||||
|
||||
@@ -300,6 +300,9 @@ failure:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
axfr_apply(void *arg);
|
||||
|
||||
static isc_result_t
|
||||
axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
|
||||
dns_rdata_t *rdata) {
|
||||
@@ -312,8 +315,20 @@ axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
|
||||
}
|
||||
|
||||
CHECK(dns_zone_checknames(xfr->zone, name, rdata));
|
||||
if (dns_diff_size(&xfr->diff) > 128 &&
|
||||
dns_diff_is_boundary(&xfr->diff, name))
|
||||
{
|
||||
xfrin_work_t work = (xfrin_work_t){
|
||||
.xfr = xfr,
|
||||
.result = ISC_R_UNSET,
|
||||
};
|
||||
axfr_apply((void *)&work);
|
||||
CHECK(work.result);
|
||||
}
|
||||
|
||||
dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple);
|
||||
dns_diff_append(&xfr->diff, &tuple);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
failure:
|
||||
return (result);
|
||||
@@ -1095,7 +1110,6 @@ xfrin_reset(dns_xfrin_t *xfr) {
|
||||
}
|
||||
|
||||
dns_diff_clear(&xfr->diff);
|
||||
|
||||
xfr->ixfr.diffs = 0;
|
||||
|
||||
if (xfr->ixfr.journal != NULL) {
|
||||
|
||||
@@ -24,6 +24,7 @@ check_PROGRAMS = \
|
||||
dbdiff_test \
|
||||
dbiterator_test \
|
||||
dbversion_test \
|
||||
diff_test \
|
||||
dispatch_test \
|
||||
dns64_test \
|
||||
dst_test \
|
||||
|
||||
108
tests/dns/diff_test.c
Normal file
108
tests/dns/diff_test.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <unistd.h>
|
||||
#include "isc/list.h"
|
||||
|
||||
#define UNIT_TESTING
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <dns/diff.h>
|
||||
|
||||
#include <tests/dns.h>
|
||||
|
||||
unsigned char data_1[] = "\006name_1";
|
||||
unsigned char offsets_1[] = { 0, 7 };
|
||||
dns_name_t name_1 = DNS_NAME_INITABSOLUTE(data_1, offsets_1);
|
||||
|
||||
unsigned char data_2[] = "\006name_2";
|
||||
unsigned char offsets_2[] = { 0, 7 };
|
||||
dns_name_t name_2 = DNS_NAME_INITABSOLUTE(data_2, offsets_2);
|
||||
|
||||
unsigned char data_3[] = "\006name_3";
|
||||
unsigned char offsets_3[] = { 0, 7 };
|
||||
dns_name_t name_3 = DNS_NAME_INITABSOLUTE(data_3, offsets_3);
|
||||
|
||||
unsigned char data_dup[] = "\006name_1";
|
||||
unsigned char offsets_dup[] = {0, 7};
|
||||
dns_name_t name_dup = DNS_NAME_INITABSOLUTE(data_dup, offsets_dup);
|
||||
|
||||
unsigned char data_nodup[] = "\006name_1";
|
||||
unsigned char offsets_nodup[] = {0, 7};
|
||||
dns_name_t name_nodup = DNS_NAME_INITABSOLUTE(data_nodup, offsets_nodup);
|
||||
|
||||
dns_rdata_t rdata_1 = DNS_RDATA_INIT;
|
||||
dns_rdata_t rdata_2 = DNS_RDATA_INIT;
|
||||
dns_rdata_t rdata_3 = DNS_RDATA_INIT;
|
||||
dns_rdata_t rdata_dup = DNS_RDATA_INIT;
|
||||
dns_rdata_t rdata_nodup = DNS_RDATA_INIT;
|
||||
|
||||
static size_t count_elements(const dns_diff_t *diff) {
|
||||
dns_difftuple_t *ot = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
for (ot = ISC_LIST_HEAD(diff->tuples); ot != NULL; ot = ISC_LIST_NEXT(ot, link)) {
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(dns_diff_size) {
|
||||
dns_diff_t diff;
|
||||
dns_diff_init(mctx, &diff);
|
||||
|
||||
assert_true(dns_diff_size(&diff) == 0);
|
||||
|
||||
dns_difftuple_t *tup_1 = NULL, *tup_2 = NULL, *tup_3 = NULL;
|
||||
dns_difftuple_create(mctx, DNS_DIFFOP_ADD, &name_1, 1, &rdata_1, &tup_1);
|
||||
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_2, 1, &rdata_2, &tup_2);
|
||||
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_3, 1, &rdata_3, &tup_3);
|
||||
|
||||
dns_difftuple_t *tup_dup = NULL, *tup_nodup = NULL;
|
||||
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_dup, 1, &rdata_dup, &tup_dup);
|
||||
dns_difftuple_create(mctx, DNS_DIFFOP_ADD, &name_nodup, 1, &rdata_nodup, &tup_nodup);
|
||||
(void)tup_dup;
|
||||
(void)tup_nodup;
|
||||
|
||||
dns_diff_append(&diff, &tup_1);
|
||||
assert_true(dns_diff_size(&diff) == 1);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_diff_append(&diff, &tup_2);
|
||||
assert_true(dns_diff_size(&diff) == 2);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_diff_appendminimal(&diff, &tup_dup);
|
||||
assert_true(dns_diff_size(&diff) == 1);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_diff_append(&diff, &tup_3);
|
||||
assert_true(dns_diff_size(&diff) == 2);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_diff_appendminimal(&diff, &tup_nodup);
|
||||
assert_true(dns_diff_size(&diff) == 3);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_diff_clear(&diff);
|
||||
assert_true(dns_diff_size(&diff) == 0);
|
||||
assert_true(dns_diff_size(&diff) == count_elements(&diff));
|
||||
|
||||
dns_difftuple_t* to_clear[] = {tup_1, tup_2, tup_3, tup_dup, tup_nodup};
|
||||
size_t to_clear_size = sizeof(to_clear) / sizeof(*to_clear);
|
||||
|
||||
for (size_t idx = 0; idx < to_clear_size; ++idx) {
|
||||
if (to_clear[idx] != NULL) {
|
||||
printf("Tuple %zu is not null\n", idx);
|
||||
dns_difftuple_free(&to_clear[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ISC_TEST_LIST_START
|
||||
ISC_TEST_ENTRY(dns_diff_size)
|
||||
ISC_TEST_LIST_END
|
||||
|
||||
ISC_TEST_MAIN
|
||||
Reference in New Issue
Block a user