Commit c56c5586 authored by Bob Halley's avatar Bob Halley
Browse files

add dns_view_find(); add comments

parent 67b37ae0
......@@ -25,12 +25,27 @@
/*
* DNS View
*
* XXX <TBS> XXX
* A "view" is a DNS namespace, together with an optional resolver and a
* forwarding policy. A "DNS namespace" is a (possibly empty) set of
* authoritative zones together with an optional cache and optional
* "hints" information.
*
* XXXRTH Not all of this items can be set currently, but future revisions
* of this code will support them.
*
* Views start out "unfrozen". In this state, core attributes like
* the cache, set of zones, and forwarding policy may be set. While
* "unfrozen", the caller (e.g. nameserver configuration loading
* code), must ensure exclusive access to the view. When the view is
* "frozen", the core attributes become immutable, and the view module
* will ensure synchronization. Freezing allows the view's core attributes
* to be accessed without locking.
*
* MP:
* The module ensures appropriate synchronization of data structures it
* creates and manipulates, with the exception that the caller is
* responsible for the safe creation and destruction of view managers.
* Before the view is frozen, the caller must ensure synchronization.
*
* After the view is frozen, the module guarantees appropriate
* synchronization of any data structures it creates and manipulates.
*
* Reliability:
* No anticipated impact.
......@@ -42,13 +57,13 @@
* No anticipated impact.
*
* Standards:
* None.
*/
* None. */
#include <isc/types.h>
#include <isc/lang.h>
#include <isc/event.h>
#include <isc/mutex.h>
#include <isc/stdtime.h>
#include <dns/types.h>
#include <dns/result.h>
......@@ -65,9 +80,9 @@ struct dns_view {
dns_resolver_t * resolver;
dns_db_t * cachedb;
isc_mutex_t lock;
isc_boolean_t frozen;
/* Locked by lock. */
unsigned int references;
unsigned int attributes;
/* Under owner's locking control. */
ISC_LINK(struct dns_view) link;
};
......@@ -76,29 +91,191 @@ struct dns_view {
#define DNS_VIEW_VALID(view) ((view) != NULL && \
(view)->magic == DNS_VIEW_MAGIC)
#define DNS_VIEWATTR_FROZEN 0x01
isc_result_t
dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, char *name,
dns_view_t **viewp);
/*
* Create a view.
*
* Notes:
*
* The newly created view has no cache, no resolver, and an empty
* zone table. The view is not frozen.
*
* Requires:
*
* 'mctx' is a valid memory context.
*
* 'rdclass' is a valid class.
*
* 'name' is a valid C string.
*
* viewp != NULL && *viewp == NULL
*
* Returns:
*
* ISC_R_SUCCESS
* ISC_R_NOMEMORY
*
* Other errors are possible.
*/
void
dns_view_attach(dns_view_t *source, dns_view_t **targetp);
/*
* Attach '*targetp' to 'source'.
*
* Requires:
*
* 'source' is a valid, frozen view.
*
* 'targetp' points to a NULL dns_view_t *.
*
* Ensures:
*
* *targetp is attached to source.
*/
void
dns_view_detach(dns_view_t **viewp);
/*
* Detach '*viewp' from its view.
*
* Requires:
*
* 'viewp' points to a valid dns_view_t *.
*
* Ensures:
*
* *viewp is NULL.
*
* If '*viewp' is the last reference to the view,
*
* All resources used by the view will be freed.
*/
void
dns_view_setresolver(dns_view_t *view, dns_resolver_t *resolver);
/*
* Set the view's resolver.
*
* Requires:
*
* 'view' is a valid, unfrozen view, whose resolver has not been
* set.
*
* 'resolver' is a valid resolver whose view is 'view'.
*
* Ensures:
*
* The resolver of 'view' is 'resolver'.
*/
void
dns_view_setcachedb(dns_view_t *view, dns_db_t *cachedb);
/*
* Set the view's cache database.
*
* Note:
*
* WARNING! THIS ROUTINE WILL BE REPLACED WITH dns_view_setcache()
* WHEN WE HAVE INTEGRATED CACHE OBJECT SUPPORT INTO THE LIBRARY.
*
* Requires:
*
* 'view' is a valid, unfrozen view, whose cache database has not been
* set.
*
* 'cachedb' is a valid cache database.
*
* Ensures:
*
* The cache database of 'view' is 'cachedb'.
*/
isc_result_t
dns_view_addzone(dns_view_t *view, dns_db_t *db);
dns_view_addzonedb(dns_view_t *view, dns_db_t *db);
/*
* Add zone database 'db' to 'view'.
*
* Note:
*
* WARNING! THIS ROUTINE WILL BE REPLACED WITH dns_view_addzone()
* WHEN WE HAVE INTEGRATED ZONE OBJECT SUPPORT INTO THE LIBRARY.
*
* Requires:
*
* 'view' is a valid, unfrozen view.
*
* 'db' is a valid zone database.
*
* Ensures:
*
* The cache database of 'view' is 'cachedb'.
*/
void
dns_view_freeze(dns_view_t *view);
/*
* Freeze view.
*
* Requires:
*
* 'view' is a valid, unfrozen view.
*
* Ensures:
*
* 'view' is frozen.
*/
isc_result_t
dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/*
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
*
* Notes:
*
* This routine is appropriate for simple, exact-match queries of the
* view.
*
* See the description of dns_db_find() for information about 'options'.
* If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name'
* and 'type' are appropriate for glue retrieval.
*
* If 'now' is zero, then the current time will be used.
*
* If 'sigrdataset' is not NULL, and there is a SIG rdataset which
* covers 'type', then 'sigrdataset' will be bound to it.
*
* Requires:
*
* 'view' is a valid, frozen view.
*
* 'name' is valid name.
*
* 'type' is a valid dns_rdatatype_t, and is not a meta query type
* (e.g. dns_rdatatype_any), or dns_rdatatype_sig.
*
* 'rdataset' is a valid, disassociated rdataset.
*
* 'sigrdataset' is NULL, or is a valid, disassociated rdataset.
*
* Ensures:
*
* If the result is ISC_R_SUCCESS or DNS_R_GLUE, then 'rdataset', and
* possibly 'sigrdataset', are bound to the found data.
*
* Returns:
*
* ISC_R_SUCCESS Success.
* DNS_R_GLUE Success; result is glue.
* ISC_R_NOTFOUND Not matching data found.
*
* Other results are possible, and indicate an error.
*/
ISC_LANG_ENDDECLS
......
......@@ -24,18 +24,17 @@
#include <isc/mem.h>
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/rwlock.h>
#include <dns/types.h>
#include <dns/dbtable.h>
#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/rdataset.h>
#include <dns/resolver.h>
#include <dns/view.h>
#include "../isc/util.h" /* XXXRTH */
#define FROZEN(v) (((v)->attributes & DNS_VIEWATTR_FROZEN) != 0)
isc_result_t
dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, char *name,
dns_view_t **viewp)
......@@ -80,8 +79,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, char *name,
view->resolver = NULL;
view->mctx = mctx;
view->rdclass = rdclass;
view->frozen = ISC_FALSE;
view->references = 1;
view->attributes = 0;
view->magic = DNS_VIEW_MAGIC;
*viewp = view;
......@@ -102,6 +101,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, char *name,
void
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
/*
* Attach '*targetp' to 'source'.
*/
REQUIRE(DNS_VIEW_VALID(source));
REQUIRE(targetp != NULL && *targetp == NULL);
......@@ -135,6 +139,10 @@ dns_view_detach(dns_view_t **viewp) {
dns_view_t *view;
isc_boolean_t need_destroy = ISC_FALSE;
/*
* Detach '*viewp' from its view.
*/
REQUIRE(viewp != NULL);
view = *viewp;
REQUIRE(DNS_VIEW_VALID(view));
......@@ -156,8 +164,13 @@ dns_view_detach(dns_view_t **viewp) {
void
dns_view_setresolver(dns_view_t *view, dns_resolver_t *resolver) {
/*
* Set the view's resolver.
*/
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!FROZEN(view));
REQUIRE(!view->frozen);
REQUIRE(view->resolver == NULL);
view->resolver = resolver;
......@@ -165,25 +178,177 @@ dns_view_setresolver(dns_view_t *view, dns_resolver_t *resolver) {
void
dns_view_setcachedb(dns_view_t *view, dns_db_t *cachedb) {
/*
* Set the view's cache database.
*/
/*
* WARNING! THIS ROUTINE WILL BE REPLACED WITH dns_view_setcache()
* WHEN WE HAVE INTEGRATED CACHE OBJECT SUPPORT INTO THE LIBRARY.
*/
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!FROZEN(view));
REQUIRE(!view->frozen);
REQUIRE(view->cachedb == NULL);
REQUIRE(dns_db_iscache(cachedb));
dns_db_attach(cachedb, &view->cachedb);
}
isc_result_t
dns_view_addzone(dns_view_t *view, dns_db_t *db) {
dns_view_addzonedb(dns_view_t *view, dns_db_t *db) {
isc_result_t result;
/*
* Add zone database 'db' to 'view'.
*/
/*
* WARNING! THIS ROUTINE WILL BE REPLACED WITH dns_view_addzone()
* WHEN WE HAVE INTEGRATED ZONE OBJECT SUPPORT INTO THE LIBRARY.
*/
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!FROZEN(view));
REQUIRE(dns_db_iszone(db));
REQUIRE(!view->frozen);
result = dns_dbtable_add(view->dbtable, db);
return (dns_dbtable_add(view->dbtable, db));
return (result);
}
void
dns_view_freeze(dns_view_t *view) {
/*
* Freeze view.
*/
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!view->frozen);
view->frozen = ISC_TRUE;
}
isc_result_t
dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
isc_result_t result;
dns_fixedname_t foundname;
dns_db_t *db;
dns_dbversion_t *version;
isc_boolean_t is_zone;
dns_rdataset_t zrdataset, zsigrdataset;
/*
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
*/
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!FROZEN(view));
REQUIRE(view->frozen);
REQUIRE(type != dns_rdatatype_any && type != dns_rdatatype_sig);
/*
* Initialize.
*/
dns_rdataset_init(&zrdataset);
dns_rdataset_init(&zsigrdataset);
/*
* Find a database to answer the query.
*/
db = NULL;
result = dns_dbtable_find(view->dbtable, name, &db);
if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
dns_db_attach(view->cachedb, &db);
else if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH)
goto cleanup;
is_zone = dns_db_iszone(db);
view->attributes |= DNS_VIEWATTR_FROZEN;
db_find:
/*
* Now look for an answer in the database.
*/
dns_fixedname_init(&foundname);
result = dns_db_find(db, name, NULL, type, options,
now, NULL, dns_fixedname_name(&foundname),
rdataset, sigrdataset);
if (result == DNS_R_DELEGATION ||
result == DNS_R_NOTFOUND ||
result == DNS_R_NXGLUE) {
if (rdataset->methods != NULL)
dns_rdataset_disassociate(rdataset);
if (sigrdataset->methods != NULL)
dns_rdataset_disassociate(sigrdataset);
if (is_zone) {
if (view->cachedb != NULL) {
/*
* Either the answer is in the cache, or we
* don't know it.
*/
is_zone = ISC_FALSE;
version = NULL;
dns_db_detach(&db);
dns_db_attach(view->cachedb, &db);
goto db_find;
}
} else {
/*
* We don't have the data in the cache. If we've got
* glue from the zone, use it.
*/
if (zrdataset.methods != NULL) {
dns_rdataset_clone(&zrdataset, rdataset);
if (zsigrdataset.methods != NULL)
dns_rdataset_clone(&zsigrdataset,
sigrdataset);
result = DNS_R_GLUE;
goto cleanup;
}
}
/*
* We don't know the answer.
*/
result = DNS_R_NOTFOUND;
} else if (result == DNS_R_GLUE) {
if (view->cachedb != NULL) {
/*
* We found an answer, but the cache may be better.
* Remember what we've got and go look in the cache.
*/
is_zone = ISC_FALSE;
version = NULL;
dns_rdataset_clone(rdataset, &zrdataset);
dns_rdataset_disassociate(rdataset);
if (sigrdataset->methods != NULL) {
dns_rdataset_clone(sigrdataset, &zsigrdataset);
dns_rdataset_disassociate(sigrdataset);
}
dns_db_detach(&db);
dns_db_attach(view->cachedb, &db);
goto db_find;
}
/*
* Otherwise, the glue is the best answer.
*/
result = ISC_R_SUCCESS;
} else if (result != ISC_R_SUCCESS)
result = DNS_R_NOTFOUND;
cleanup:
if (zrdataset.methods != NULL) {
dns_rdataset_disassociate(&zrdataset);
if (zsigrdataset.methods != NULL)
dns_rdataset_disassociate(&zsigrdataset);
}
if (db != NULL)
dns_db_detach(&db);
return (result);
}
Markdown is supported
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