mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 23:40:00 -04:00
Implement dns_dbiterator_seek3
This is a new seek function for dbiterator that is meant to find an NSEC3 node in a zone database. The difference with dns_dbiterator_seek is that if the node does not exist, this seek function will point the iterator to the next NSEC3 name.
This commit is contained in:
parent
5e704bbb59
commit
41159e9062
6 changed files with 137 additions and 18 deletions
|
|
@ -58,6 +58,14 @@ dns__dbiterator_seek(dns_dbiterator_t *iterator,
|
|||
return iterator->methods->seek(iterator, name DNS__DB_FLARG_PASS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns__dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG) {
|
||||
REQUIRE(DNS_DBITERATOR_VALID(iterator));
|
||||
|
||||
return iterator->methods->seek3(iterator, name DNS__DB_FLARG_PASS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns__dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
|
||||
REQUIRE(DNS_DBITERATOR_VALID(iterator));
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ typedef struct dns_dbiteratormethods {
|
|||
isc_result_t (*last)(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
isc_result_t (*seek)(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
isc_result_t (*seek3)(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
isc_result_t (*prev)(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
isc_result_t (*next)(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
isc_result_t (*current)(dns_dbiterator_t *iterator,
|
||||
|
|
@ -189,6 +191,30 @@ dns__dbiterator_seek(dns_dbiterator_t *iterator,
|
|||
*\li Other results are possible, depending on the DB implementation.
|
||||
*/
|
||||
|
||||
#define dns_dbiterator_seek3(iterator, name) \
|
||||
dns__dbiterator_seek3(iterator, name DNS__DB_FILELINE)
|
||||
isc_result_t
|
||||
dns__dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
/*%<
|
||||
* Move the node cursor to the node with NSEC3 name 'name'.
|
||||
* If not found, the iterator is set to the next name.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'iterator' is a valid iterator.
|
||||
*
|
||||
*\li 'name' is a valid name.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOTFOUND
|
||||
*\li #ISC_R_NOMORE There are no NSEC3 nodes in the database.
|
||||
*\li #ISC_R_NOTIMPLEMENTED
|
||||
* (this function is only implemented for NSEC3 only iterators)
|
||||
*
|
||||
*\li Other results are possible, depending on the DB implementation.
|
||||
*/
|
||||
|
||||
#define dns_dbiterator_prev(iterator) \
|
||||
dns__dbiterator_prev(iterator DNS__DB_FILELINE)
|
||||
isc_result_t
|
||||
|
|
|
|||
|
|
@ -374,6 +374,9 @@ static isc_result_t
|
|||
dbiterator_seek(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
|
|
@ -386,9 +389,10 @@ static isc_result_t
|
|||
dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name);
|
||||
|
||||
static dns_dbiteratormethods_t dbiterator_methods = {
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_prev, dbiterator_next,
|
||||
dbiterator_current, dbiterator_pause, dbiterator_origin
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_seek3, dbiterator_prev,
|
||||
dbiterator_next, dbiterator_current, dbiterator_pause,
|
||||
dbiterator_origin
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -3634,6 +3638,12 @@ dbiterator_seek(dns_dbiterator_t *iterator,
|
|||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator ISC_ATTR_UNUSED,
|
||||
const dns_name_t *name ISC_ATTR_UNUSED DNS__DB_FLARG) {
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator ISC_ATTR_UNUSED DNS__DB_FLARG) {
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
|
|
|
|||
|
|
@ -345,6 +345,9 @@ static isc_result_t
|
|||
dbiterator_seek(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
|
|
@ -357,9 +360,10 @@ static isc_result_t
|
|||
dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name);
|
||||
|
||||
static dns_dbiteratormethods_t dbiterator_methods = {
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_prev, dbiterator_next,
|
||||
dbiterator_current, dbiterator_pause, dbiterator_origin
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_seek3, dbiterator_prev,
|
||||
dbiterator_next, dbiterator_current, dbiterator_pause,
|
||||
dbiterator_origin
|
||||
};
|
||||
|
||||
typedef struct qpdb_dbiterator {
|
||||
|
|
@ -4357,6 +4361,53 @@ dbiterator_seek(dns_dbiterator_t *iterator,
|
|||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG) {
|
||||
isc_result_t result;
|
||||
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
|
||||
|
||||
if (qpdbiter->result != ISC_R_SUCCESS &&
|
||||
qpdbiter->result != ISC_R_NOTFOUND &&
|
||||
qpdbiter->result != DNS_R_PARTIALMATCH &&
|
||||
qpdbiter->result != ISC_R_NOMORE)
|
||||
{
|
||||
return qpdbiter->result;
|
||||
}
|
||||
|
||||
if (qpdbiter->nsec3mode != nsec3only) {
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
|
||||
|
||||
result = dns_qp_lookup(qpdbiter->snap, name, DNS_DBNAMESPACE_NSEC3,
|
||||
&qpdbiter->iter, NULL, (void **)&qpdbiter->node,
|
||||
NULL);
|
||||
|
||||
switch (result) {
|
||||
case ISC_R_SUCCESS:
|
||||
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
|
||||
break;
|
||||
case DNS_R_PARTIALMATCH:
|
||||
/* dbiterator_next() will dereference the node */
|
||||
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
|
||||
|
||||
result = dbiterator_next(iterator);
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = dbiterator_first(iterator);
|
||||
}
|
||||
break;
|
||||
case ISC_R_NOTFOUND:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qpdbiter->result = result;
|
||||
|
||||
return qpdbiter->result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
|
||||
isc_result_t result;
|
||||
|
|
|
|||
|
|
@ -210,6 +210,9 @@ static isc_result_t
|
|||
dbiterator_seek(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator,
|
||||
const dns_name_t *name DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
static isc_result_t
|
||||
dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG);
|
||||
|
|
@ -222,9 +225,10 @@ static isc_result_t
|
|||
dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name);
|
||||
|
||||
static dns_dbiteratormethods_t dbiterator_methods = {
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_prev, dbiterator_next,
|
||||
dbiterator_current, dbiterator_pause, dbiterator_origin
|
||||
dbiterator_destroy, dbiterator_first, dbiterator_last,
|
||||
dbiterator_seek, dbiterator_seek3, dbiterator_prev,
|
||||
dbiterator_next, dbiterator_current, dbiterator_pause,
|
||||
dbiterator_origin
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1149,6 +1153,12 @@ dbiterator_seek(dns_dbiterator_t *iterator,
|
|||
return ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_seek3(dns_dbiterator_t *iterator ISC_ATTR_UNUSED,
|
||||
const dns_name_t *name ISC_ATTR_UNUSED DNS__DB_FLARG) {
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
|
||||
sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
|
||||
|
|
|
|||
|
|
@ -182,10 +182,10 @@ ISC_RUN_TEST_IMPL(reverse_nsec3) {
|
|||
|
||||
/* seek: walk database starting at a particular node */
|
||||
static void
|
||||
test_seek_node(const char *filename, int flags, int nodes) {
|
||||
isc_result_t result;
|
||||
test_seek_node(const char *filename, bool nsec3, int flags, int nodes) {
|
||||
isc_result_t result, result3;
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbiterator_t *iter = NULL;
|
||||
dns_dbiterator_t *iter = NULL, *iter3 = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_name_t *name, *seekname;
|
||||
dns_fixedname_t f1, f2;
|
||||
|
|
@ -200,6 +200,9 @@ test_seek_node(const char *filename, int flags, int nodes) {
|
|||
result = dns_db_createiterator(db, flags, &iter);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result3 = dns_db_createiterator(db, flags, &iter3);
|
||||
assert_int_equal(result3, ISC_R_SUCCESS);
|
||||
|
||||
result = make_name("c." TEST_ORIGIN, seekname);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -207,6 +210,14 @@ test_seek_node(const char *filename, int flags, int nodes) {
|
|||
if (flags == DNS_DB_NSEC3ONLY) {
|
||||
/* "c" isn't in the NSEC3 tree but the origin node is */
|
||||
assert_int_equal(result, DNS_R_PARTIALMATCH);
|
||||
|
||||
/* NSEC3 iterator */
|
||||
result3 = dns_dbiterator_seek3(iter3, seekname);
|
||||
if (nsec3) {
|
||||
assert_int_equal(result3, ISC_R_SUCCESS);
|
||||
} else {
|
||||
assert_int_equal(result3, ISC_R_NOMORE);
|
||||
}
|
||||
} else {
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -244,26 +255,29 @@ test_seek_node(const char *filename, int flags, int nodes) {
|
|||
assert_int_equal(i, nodes);
|
||||
|
||||
dns_dbiterator_destroy(&iter);
|
||||
dns_dbiterator_destroy(&iter3);
|
||||
dns_db_detach(&db);
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(seek_node) {
|
||||
UNUSED(state);
|
||||
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data", 0, 9);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data",
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data", false, 0,
|
||||
9);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data", false,
|
||||
DNS_DB_NONSEC3, 9);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data",
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone1.data", false,
|
||||
DNS_DB_NSEC3ONLY, 0);
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(seek_node_nsec3) {
|
||||
UNUSED(state);
|
||||
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data", 0, 29);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data",
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data", true, 0,
|
||||
29);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data", true,
|
||||
DNS_DB_NONSEC3, 9);
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data",
|
||||
test_seek_node(TESTS_DIR "/testdata/dbiterator/zone2.data", true,
|
||||
DNS_DB_NSEC3ONLY, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue