view.c revision 801707fe19600313a0b1f7845a518100f69e58b6
/*
* Copyright (C) 1999-2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*! \file */
#include <config.h>
#ifdef HAVE_LMDB
#include <lmdb.h>
#endif
#include <dns/badcache.h>
#include <dns/dispatch.h>
#include <dns/keytable.h>
#include <dns/keyvalues.h>
#include <dns/masterdump.h>
#include <dns/rdataset.h>
#include <dns/resolver.h>
} while (0)
#define DNS_VIEW_DELONLYHASH 111
#define DNS_VIEW_FAILCACHESIZE 1021
{
char buffer[1024];
/*
* Create a view.
*/
return (ISC_R_NOMEMORY);
goto cleanup_view;
}
if (result != ISC_R_SUCCESS)
goto cleanup_name;
goto cleanup_name;
}
if (result != ISC_R_SUCCESS)
goto cleanup_name;
if (isc_bind9) {
if (result != ISC_R_SUCCESS) {
"dns_zt_create() failed: %s",
goto cleanup_mutex;
}
}
if (result != ISC_R_SUCCESS) {
"dns_fwdtable_create() failed: %s",
goto cleanup_zt;
}
if (result != ISC_R_SUCCESS)
goto cleanup_fwdtable;
if (result != ISC_R_SUCCESS)
goto cleanup_references;
/*
* Initialize configuration data with default values.
*/
view->nta_lifetime = 0;
view->nta_recheck = 0;
view->prefetch_eligible = 0;
view->prefetch_trigger = 0;
view->preferred_glue = 0;
view->nocookieudp = 0;
if (isc_bind9) {
if (result != ISC_R_SUCCESS)
goto cleanup_dynkeys;
}
if (result != ISC_R_SUCCESS)
goto cleanup_order;
if (result != ISC_R_SUCCESS)
goto cleanup_peerlist;
return (ISC_R_SUCCESS);
return (result);
}
static inline void
char template[20];
char keyfile[20];
int n;
sizeof(template));
if (result == ISC_R_SUCCESS)
}
else {
if (result == ISC_R_SUCCESS) {
keyfile);
if (result != ISC_R_SUCCESS)
} else {
}
}
}
}
}
}
int i;
for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
}
}
}
int i;
for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
}
}
sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
}
}
#ifdef HAVE_DNSTAP
#endif /* HAVE_DNSTAP */
}
#ifdef HAVE_LMDB
}
#endif /* HAVE_LMDB */
}
/*
* Return true iff 'view' may be freed.
* The caller must be holding the view lock.
*/
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
}
void
}
static void
unsigned int refs;
if (flush)
if (refs == 0) {
if (!RESSHUTDOWN(view))
if (!ADBSHUTDOWN(view))
if (!REQSHUTDOWN(view))
else
}
}
}
}
/* Need to detach zones outside view lock */
}
if (done)
}
void
}
void
}
static isc_result_t
return (ISC_R_SUCCESS);
}
void
}
void
}
void
if (done)
}
static void
if (done)
}
static void
if (done)
}
static void
if (done)
}
}
unsigned int ntasks,
unsigned int ndisp,
unsigned int options,
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
&view->requestmgr);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
void
}
void
}
}
return (view->cacheshared);
}
void
}
void
}
void
}
void
}
void
char keyfile[20];
int n;
}
}
}
}
void
}
void
}
}
void
}
return (result);
}
if (result == DNS_R_PARTIALMATCH) {
}
} else
return (result);
}
sigrdataset));
}
{
/*
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
*/
/*
* Initialize.
*/
/*
* Find a database to answer the query.
*/
else
else if (result != ISC_R_SUCCESS)
goto cleanup;
}
else
goto cleanup;
/*
* Now look for an answer in the database.
*/
if (sigrdataset != NULL &&
if (!is_cache) {
dns_db_detach(&db);
/*
* Either the answer is in the cache, or we
* don't know it.
* Note that if the result comes from a
* static-stub zone we stop the search here
* (see the function description in view.h).
*/
goto db_find;
}
} else {
/*
* We don't have the data in the cache. If we've got
* glue from the zone, use it.
*/
if (dns_rdataset_isassociated(&zrdataset)) {
if (sigrdataset != NULL &&
result = DNS_R_GLUE;
dns_db_detach(&db);
goto cleanup;
}
}
/*
* We don't know the answer.
*/
} else if (result == DNS_R_GLUE) {
/*
* We found an answer, but the cache may be better.
* Remember what we've got and go look in the cache.
*/
if (sigrdataset != NULL &&
}
dns_db_detach(&db);
goto db_find;
}
/*
* Otherwise, the glue is the best answer.
*/
}
if (sigrdataset != NULL &&
dns_db_detach(&db);
}
/*
* We just used a hint. Let the resolver know it
* should consider priming.
*/
result = DNS_R_HINT;
} else if (result == DNS_R_NXRRSET) {
} else if (result == DNS_R_NXDOMAIN)
/*
* Cleanup if non-standard hints are used.
*/
}
if (dns_rdataset_isassociated(&zrdataset)) {
}
dns_db_detach(&zdb);
}
else
}
else
dns_db_detach(&db);
} else
return (result);
}
{
if (result == DNS_R_NXDOMAIN) {
/*
* The rdataset and sigrdataset of the relevant NSEC record
* may be returned, but the caller cannot use them because
* foundname is not returned by this simplified API. We
* disassociate them here to prevent any misuse by the caller.
*/
if (sigrdataset != NULL &&
} else if (result != ISC_R_SUCCESS &&
result != DNS_R_GLUE &&
result != DNS_R_HINT &&
result != DNS_R_NCACHENXDOMAIN &&
result != DNS_R_NCACHENXRRSET &&
result != DNS_R_NXRRSET &&
result != DNS_R_HINTNXRRSET &&
result != ISC_R_NOTFOUND) {
if (sigrdataset != NULL &&
}
return (result);
}
{
rdataset, sigrdataset));
}
{
unsigned int ztoptions = 0;
/*
* Initialize.
*/
/*
* Find the right database.
*/
if ((options & DNS_DBFIND_NOEXACT) != 0)
} else
if (result == ISC_R_NOTFOUND) {
/*
* We're not directly authoritative for this query name, nor
* is it a subdomain of any zone for which we're
* authoritative.
*/
/*
* We have a cache; try it.
*/
} else {
/*
* Maybe we have hints...
*/
goto finish;
}
} else if (result != ISC_R_SUCCESS) {
/*
* Something is broken.
*/
goto cleanup;
}
/*
* Look for the zonecut.
*/
if (!is_cache) {
if (result == DNS_R_DELEGATION)
else if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* We found an answer, but the cache may be better.
*/
if (result != ISC_R_SUCCESS)
goto cleanup;
if (sigrdataset != NULL &&
}
dns_db_detach(&db);
goto db_find;
}
} else {
if (result == ISC_R_SUCCESS) {
/*
* We found a zonecut in the cache, but our
* zone delegation is better.
*/
}
} else if (result == ISC_R_NOTFOUND) {
/*
* We didn't find anything in the cache, but we
* have a zone delegation, so use it.
*/
} else {
/*
* Maybe we have hints...
*/
}
} else {
/*
* Something bad happened.
*/
goto cleanup;
}
}
if (use_zone) {
if (dns_rdataset_isassociated(rdataset)) {
if (sigrdataset != NULL &&
}
if (result != ISC_R_SUCCESS)
goto cleanup;
if (sigrdataset != NULL &&
/*
* We've found nothing so far, but we have hints.
*/
if (result != ISC_R_SUCCESS) {
/*
* We can't even find the hints for the root
* nameservers!
*/
}
}
if (dns_rdataset_isassociated(&zrdataset)) {
}
dns_db_detach(&db);
return (result);
}
{
break;
}
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
}
dns_zone_t **zonep)
{
continue;
/*
* If the zone is defined in more than one view,
* treat it as not found.
*/
else
result == ISC_R_NOTFOUND ||
result == DNS_R_PARTIALMATCH);
/* Treat a partial match as no match */
if (result == DNS_R_PARTIALMATCH) {
}
return (ISC_R_MULTIPLE);
}
}
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
}
}
}
}
{
view->statickeys);
if (result == ISC_R_NOTFOUND)
view->dynamickeys);
return (result);
}
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS)
return (result);
}
view->dynamickeys));
}
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
}
}
return (ISC_R_SUCCESS);
if (!fixuponly) {
if (result != ISC_R_SUCCESS)
return (result);
}
return (ISC_R_SUCCESS);
}
}
if (tree) {
} else {
}
return (result);
}
sizeof(dns_namelist_t) *
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
if (result == ISC_R_SUCCESS)
else
return (result);
}
sizeof(dns_namelist_t) *
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
if (result == ISC_R_SUCCESS)
else
return (result);
}
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_TRUE);
}
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
}
void
}
return (view->rootdelonly);
}
}
void
}
void
}
void
}
void
}
void
}
void
}
{
&view->ntatable_priv));
}
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
}
}
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
}
{
return (ISC_FALSE);
}
{
return (ISC_R_NOTFOUND);
if (result != ISC_R_SUCCESS)
return (result);
*secure_domain = secure;
return (ISC_R_SUCCESS);
}
void
{
unsigned char data[4096];
/*
* Clear the revoke bit, if set, so that the key will match what's
* in secroots now.
*/
/* Convert dnskey to DST key. */
if (result != ISC_R_SUCCESS)
return;
if (result == ISC_R_SUCCESS) {
/*
* If key was found in secroots, then it was a
* configured trust anchor, and we want to fail
* secure. If there are no other configured keys,
* then leave a null key so that we can't validate
* anymore.
*/
if (result == ISC_R_SUCCESS)
}
dst_key_free(&key);
}
void (*cfg_destroy)(void **))
{
char buffer[1024];
#ifdef HAVE_LMDB
int status;
#endif
}
#ifdef HAVE_LMDB
}
}
#endif /* HAVE_LMDB */
}
if (!allow)
return (ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS)
goto out;
#ifdef HAVE_LMDB
if (result != ISC_R_SUCCESS)
goto out;
if (status != 0) {
goto out;
}
if (status != 0) {
goto out;
}
#endif /* HAVE_LMDB */
out:
if (result != ISC_R_SUCCESS) {
}
#ifdef HAVE_LMDB
}
#endif /* HAVE_LMDB */
}
return (result);
}
{
unsigned int namelabels;
unsigned int i;
/*
* Performs checks to make sure data is as we expect it to be.
*/
/* setup a "fixed" dns name */
/* count the number of labels in the name */
{
/*
* loop through starting with the longest domain name and
* trying shorter names portions of the name until we find a
* match, have an error, or are below the 'minlabels'
* threshold. minlabels is 0, if neither the standard
* database nor any previous DLZ database had a zone name
* match. Otherwise minlabels is the number of labels
* in that name. We need to beat that for a "better"
* match for this DLZ database to be authoritative.
*/
if (i == namelabels) {
if (result != ISC_R_SUCCESS)
return (result);
} else
/* ask SDLZ driver if the zone is supported */
if (result != ISC_R_NOTFOUND) {
if (result == ISC_R_SUCCESS) {
dns_db_detach(&db);
minlabels = i;
} else {
dns_db_detach(&db);
break;
}
dns_db_detach(&db);
}
}
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
}
}
void
}
if (view->nta_lifetime == 0)
return (ISC_R_SUCCESS);
/* Open NTA save file for overwrite. */
if (result == ISC_R_NOTFOUND) {
goto cleanup;
} else
if (result == ISC_R_NOTFOUND) {
}
/* Don't leave half-baked NTA save files lying around. */
return (result);
}
if (view->nta_lifetime == 0)
return (ISC_R_SUCCESS);
for (;;) {
isc_buffer_t b;
break;
else {
isc_buffer_add(&b, (unsigned int)len);
0, NULL));
}
else
if (now <= t) {
if (t > (now + 604800))
t = now + 604800;
forced, 0, t);
} else {
char nb[DNS_NAME_FORMATSIZE];
"ignoring expired NTA at %s", nb);
}
};
}
return (result);
}