2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

[master] suppress unnecessary db lookups in DLZ redirect zones

3876.	[bug]		Improve efficiency of DLZ redirect zones by
			suppressing unnecessary database lookups. [RT #35835]
This commit is contained in:
Evan Hunt
2014-06-10 16:25:26 -07:00
parent 206e697f24
commit 8d8f9f7f86
20 changed files with 218 additions and 257 deletions

View File

@@ -186,8 +186,13 @@ typedef struct sdlz_rdatasetiter {
#endif
/*
* Forward references. Try to keep these to a minimum.
* Forward references.
*/
static isc_result_t getnodedata(dns_db_t *db, dns_name_t *name,
isc_boolean_t create, unsigned int options,
dns_clientinfomethods_t *methods,
dns_clientinfo_t *clientinfo,
dns_dbnode_t **nodep);
static void list_tordataset(dns_rdatalist_t *rdatalist,
dns_db_t *db, dns_dbnode_t *node,
@@ -536,9 +541,9 @@ destroynode(dns_sdlznode_t *node) {
}
static isc_result_t
findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
dns_dbnode_t **nodep)
getnodedata(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
unsigned int options, dns_clientinfomethods_t *methods,
dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
{
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
dns_sdlznode_t *node = NULL;
@@ -563,7 +568,7 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
unsigned int labels;
labels = dns_name_countlabels(name) -
dns_name_countlabels(&db->origin);
dns_name_countlabels(&sdlz->common.origin);
dns_name_init(&relname, NULL);
dns_name_getlabelsequence(name, 0, labels, &relname);
result = dns_name_totext(&relname, ISC_TRUE, &b);
@@ -601,14 +606,53 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
methods, clientinfo);
/*
* if the host (namestr) was not found, try to lookup a
* "wildcard" host.
* If the name was not found and DNS_DBFIND_NOWILD is not
* set, then we try to find a wildcard entry.
*
* If DNS_DBFIND_NOZONECUT is set and there are multiple
* levels between the host and the zone origin, we also look
* for wildcards at each level.
*/
if (result == ISC_R_NOTFOUND && !create)
result = sdlz->dlzimp->methods->lookup(zonestr, "*",
if (result == ISC_R_NOTFOUND && !create &&
(options & DNS_DBFIND_NOWILD) == 0)
{
unsigned int i, dlabels, nlabels;
nlabels = dns_name_countlabels(name);
dlabels = nlabels - dns_name_countlabels(&sdlz->common.origin);
for (i = 0; i < dlabels; i++) {
char wildstr[DNS_NAME_MAXTEXT + 1];
dns_fixedname_t fixed;
dns_name_t *wild;
dns_fixedname_init(&fixed);
if (i == dlabels)
wild = dns_wildcardname;
else {
wild = dns_fixedname_name(&fixed);
dns_name_getlabelsequence(name, i + 1,
dlabels - i - 1,
wild);
result = dns_name_concatenate(dns_wildcardname,
wild, wild, NULL);
if (result != ISC_R_SUCCESS)
return (result);
}
isc_buffer_init(&b, wildstr, sizeof(wildstr));
result = dns_name_totext(wild, ISC_TRUE, &b);
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_putuint8(&b, 0);
result = sdlz->dlzimp->methods->lookup(zonestr, wildstr,
sdlz->dlzimp->driverarg,
sdlz->dbdata, node,
methods, clientinfo);
if (result == ISC_R_SUCCESS)
break;
}
}
MAYBE_UNLOCK(sdlz->dlzimp);
@@ -655,11 +699,19 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
return (ISC_R_SUCCESS);
}
static isc_result_t
findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
dns_dbnode_t **nodep)
{
return (getnodedata(db, name, create, 0, methods, clientinfo, nodep));
}
static isc_result_t
findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_dbnode_t **nodep)
{
return (findnodeext(db, name, create, NULL, NULL, nodep));
return (getnodedata(db, name, create, 0, NULL, NULL, nodep));
}
static isc_result_t
@@ -857,7 +909,6 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
version == (void*)&sdlz->dummy_version ||
version == sdlz->future_version);
UNUSED(options);
UNUSED(sdlz);
if (!dns_name_issubdomain(name, &db->origin))
@@ -876,12 +927,22 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
result = DNS_R_NXDOMAIN;
/*
* If we're not walking down searching for zone
* cuts, we can cut straight to the chase
*/
if ((options & DNS_DBFIND_NOZONECUT) != 0) {
i = nlabels;
goto search;
}
for (i = olabels; i <= nlabels; i++) {
search:
/*
* Look up the next label.
*/
dns_name_getlabelsequence(name, nlabels - i, i, xname);
result = findnodeext(db, xname, ISC_FALSE,
result = getnodedata(db, xname, ISC_FALSE, options,
methods, clientinfo, &node);
if (result == ISC_R_NOTFOUND) {
result = DNS_R_NXDOMAIN;
@@ -905,25 +966,26 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
/*
* Look for an NS at the current label, unless this is the
* origin or glue is ok.
* origin, glue is ok, or there are known to be no zone cuts.
*/
if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0 &&
(options & DNS_DBFIND_NOZONECUT) == 0)
{
result = findrdataset(db, node, version,
dns_rdatatype_ns, 0, now,
rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
if (i == nlabels && type == dns_rdatatype_any)
{
result = DNS_R_ZONECUT;
dns_rdataset_disassociate(rdataset);
if (sigrdataset != NULL &&
dns_rdataset_isassociated
(sigrdataset)) {
dns_rdataset_disassociate
(sigrdataset);
}
} else
result = DNS_R_DELEGATION;
if (result == ISC_R_SUCCESS &&
i == nlabels && type == dns_rdatatype_any)
{
result = DNS_R_ZONECUT;
dns_rdataset_disassociate(rdataset);
if (sigrdataset != NULL &&
dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
break;
} else if (result == ISC_R_SUCCESS) {
result = DNS_R_DELEGATION;
break;
}
}
@@ -1219,8 +1281,8 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
if (sdlz->dlzimp->methods->newversion == NULL)
return (ISC_R_NOTIMPLEMENTED);
result = findnodeext(db, &sdlz->common.origin, ISC_FALSE,
NULL, NULL, nodep);
result = getnodedata(db, &sdlz->common.origin, ISC_FALSE,
0, NULL, NULL, nodep);
if (result != ISC_R_SUCCESS)
sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s",
isc_result_totext(result));