Commit 0a09237a authored by Bob Halley's avatar Bob Halley
Browse files

add noexact matching option

parent 48ed268b
......@@ -178,6 +178,7 @@ struct dns_db {
#define DNS_DBFIND_VALIDATEGLUE 0x02
#define DNS_DBFIND_NOWILD 0x04
#define DNS_DBFIND_PENDINGOK 0x08
#define DNS_DBFIND_NOEXACT 0x10
/*
* Options that can be specified for dns_db_addrdataset().
......@@ -753,8 +754,8 @@ dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
*
* Notes:
*
* If 'options' has DNS_DBFIND_ONLYANCESTORS set, then 'name' will
* be returned as the deepest match if it has an NS rdataset.
* If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned
* (if any) will be the deepest known ancestor of 'name'.
*
* If 'now' is zero, then the current time will be used.
*
......
......@@ -27,6 +27,13 @@
ISC_LANG_BEGINDECLS
/*
* Option values for dns_rbt_findnode() and dns_rbt_findname().
* These are used to form a bitmask.
*/
#define DNS_RBTFIND_EMPTYDATA 0x01
#define DNS_RBTFIND_NOEXACT 0x02
/*
* These should add up to 30.
*/
......@@ -288,7 +295,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep);
*/
isc_result_t
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name,
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
dns_name_t *foundname, void **data);
/*
* Get the data pointer associated with 'name'.
......@@ -296,6 +303,12 @@ dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name,
* Notes:
* A node that has no data is considered not to exist for this function.
*
* A node that has no data is considered not to exist for this function,
* unless the DNS_RBTFIND_EMPTYDATA option is set. When
* DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
* returned (also subject to DNS_RBTFIND_EMPTYDATA), even when
* there is an exact match in the tree.
*
* Requires:
* rbt is a valid rbt manager.
* dns_name_isabsolute(name) == TRUE
......@@ -324,7 +337,7 @@ dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name,
isc_result_t
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
isc_boolean_t empty_data_ok, dns_rbtfindcallback_t callback,
unsigned int options, dns_rbtfindcallback_t callback,
void *callback_arg);
/*
* Find the node for 'name'.
......@@ -332,7 +345,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* Notes:
* It is _not_ required that the node associated with 'name' has a
* non-NULL data pointer for an exact match. A partial match must
* have associated data, unless the empty_data_ok flag is true.
* have associated data, unless the DNS_RBTFIND_EMPTYDATA option is set.
*
* If the chain parameter is non-NULL, then the path through the tree
* to the DNSSEC predecessor of the searched for name is maintained.
......@@ -374,6 +387,12 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* could have been stored; the amount to be freed from the rbt->mctx
* is ancestor_maxitems * sizeof(dns_rbtnode_t *).
*
* A node that has no data is considered not to exist for this function,
* unless the DNS_RBTFIND_EMPTYDATA option is set. When
* DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
* returned (also subject to DNS_RBTFIND_EMPTYDATA), even when
* there is an exact match in the tree.
*
* Requires:
* rbt is a valid rbt manager.
* dns_name_isabsolute(name) == TRUE
......@@ -397,7 +416,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* of 'name' which has data.
*
* 'foundname' is the name of deepest superdomain (which has
* data, unless 'empty_data_ok').
* data, unless the DNS_RBTFIND_EMPTYDATA option is set).
*
* 'chain' points to the DNSSEC predecessor, if any, of 'name'.
*
......
......@@ -26,6 +26,8 @@
ISC_LANG_BEGINDECLS
#define DNS_ZTFIND_NOEXACT 0x01
isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
dns_zt_t **zt);
/*
......@@ -70,13 +72,17 @@ isc_result_t dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone);
* ISC_R_NOMEMORY
*/
isc_result_t dns_zt_find(dns_zt_t *zt, dns_name_t *name,
dns_name_t *foundname, dns_zone_t **zone);
isc_result_t dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
dns_name_t *foundname, dns_zone_t **zone);
/*
* Find the best match for 'name' in 'zt'. If foundname is non NULL
* then the name of the zone found is returned.
*
* Notes:
* If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any)
* to 'name' will be returned.
*
* Requires:
* 'zt' to be valid
* 'name' to be valid
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: rbt.c,v 1.73 2000/04/12 21:38:04 tale Exp $ */
/* $Id: rbt.c,v 1.74 2000/04/19 18:20:26 halley Exp $ */
/* Principal Authors: DCL */
......@@ -725,7 +725,7 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
isc_result_t
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
isc_boolean_t empty_data_ok, dns_rbtfindcallback_t callback,
unsigned int options, dns_rbtfindcallback_t callback,
void *callback_arg)
{
dns_rbtnode_t *current;
......@@ -820,7 +820,8 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
/*
* This might be the closest enclosing name.
*/
if (empty_data_ok || DATA(current) != NULL)
if (DATA(current) != NULL ||
(options & DNS_RBTFIND_EMPTYDATA) != 0)
*node = current;
/*
......@@ -892,7 +893,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
}
}
if (current != NULL) {
if (current != NULL && (options & DNS_RBTFIND_NOEXACT) == 0) {
/*
* Found an exact match.
*/
......@@ -909,10 +910,10 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
result = saved_result;
} else
*node = NULL;
} else {
/*
* Did not find an exact match.
* Did not find an exact match (or did, but we don't want
* one).
*/
if (*node != NULL) {
/*
......@@ -950,7 +951,25 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
} else
result = ISC_R_NOTFOUND;
if (chain != &localchain) {
/*
* XXXRTH We could add a DNS_RBTFIND_NOPREDECESSOR
* option to turn off the following code. Some clients
* may use a chain but may not care about the DNSSEC
* predecessor (e.g. cache code), so we could improve
* performance for them by letting them turn it off
*/
if (current != NULL) {
/*
* We've got an exact match but DNS_RBTFIND_NOEXACT
* was set. The DNSSEC predecessor is the current
* name. It's important that we handle this case
* here, because the predecessor setting code below
* assumes the match was not exact.
*/
INSIST((options & DNS_RBTFIND_NOEXACT) != 0);
chain->end = current;
} else if (chain != &localchain) {
/*
* Since there was no exact match, the chain argument
* needs to be pointed at the DNSSEC predecessor of
......@@ -1060,7 +1079,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* Get the data pointer associated with 'name'.
*/
isc_result_t
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name,
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
dns_name_t *foundname, void **data) {
dns_rbtnode_t *node = NULL;
isc_result_t result;
......@@ -1068,7 +1087,7 @@ dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name,
REQUIRE(data != NULL && *data == NULL);
result = dns_rbt_findnode(rbt, name, foundname, &node, NULL,
ISC_FALSE, NULL, NULL);
options, NULL, NULL);
if (node != NULL && DATA(node) != NULL)
*data = DATA(node);
......@@ -1103,7 +1122,7 @@ dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
* ->dirty, ->locknum and ->references are ignored; they are
* solely the province of rbtdb.c.
*/
result = dns_rbt_findnode(rbt, name, NULL, &node, NULL, ISC_FALSE,
result = dns_rbt_findnode(rbt, name, NULL, &node, NULL, 0,
NULL, NULL);
if (result == ISC_R_SUCCESS)
......
......@@ -126,17 +126,22 @@ dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone) {
}
isc_result_t
dns_zt_find(dns_zt_t *zt, dns_name_t *name, dns_name_t *foundname,
dns_zone_t **zonep)
dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
dns_name_t *foundname, dns_zone_t **zonep)
{
isc_result_t result;
dns_zone_t *dummy = NULL;
unsigned int rbtoptions = 0;
REQUIRE(VALID_ZT(zt));
if ((options & DNS_ZTFIND_NOEXACT) != 0)
rbtoptions |= DNS_RBTFIND_NOEXACT;
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_rbt_findname(zt->table, name, foundname, (void **)&dummy);
result = dns_rbt_findname(zt->table, name, rbtoptions, foundname,
(void **)&dummy);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
dns_zone_attach(dummy, zonep);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment