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:
120
lib/dns/sdlz.c
120
lib/dns/sdlz.c
@@ -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));
|
||||
|
Reference in New Issue
Block a user