00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <isc/file.h>
00023 #include <isc/hash.h>
00024 #include <isc/lex.h>
00025 #include <isc/print.h>
00026 #include <isc/sha2.h>
00027 #include <isc/stats.h>
00028 #include <isc/string.h>
00029 #include <isc/task.h>
00030 #include <isc/util.h>
00031
00032 #include <dns/acache.h>
00033 #include <dns/acl.h>
00034 #include <dns/adb.h>
00035 #include <dns/badcache.h>
00036 #include <dns/cache.h>
00037 #include <dns/db.h>
00038 #include <dns/dispatch.h>
00039 #include <dns/dlz.h>
00040 #include <dns/dns64.h>
00041 #include <dns/dnssec.h>
00042 #include <dns/events.h>
00043 #include <dns/forward.h>
00044 #include <dns/keytable.h>
00045 #include <dns/keyvalues.h>
00046 #include <dns/master.h>
00047 #include <dns/masterdump.h>
00048 #include <dns/nta.h>
00049 #include <dns/order.h>
00050 #include <dns/peer.h>
00051 #include <dns/rrl.h>
00052 #include <dns/rbt.h>
00053 #include <dns/rdataset.h>
00054 #include <dns/request.h>
00055 #include <dns/resolver.h>
00056 #include <dns/result.h>
00057 #include <dns/rpz.h>
00058 #include <dns/stats.h>
00059 #include <dns/time.h>
00060 #include <dns/tsig.h>
00061 #include <dns/zone.h>
00062 #include <dns/zt.h>
00063
00064 #define CHECK(op) \
00065 do { result = (op); \
00066 if (result != ISC_R_SUCCESS) goto cleanup; \
00067 } while (0)
00068
00069 #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0)
00070 #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0)
00071 #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0)
00072
00073 #define DNS_VIEW_DELONLYHASH 111
00074 #define DNS_VIEW_FAILCACHESIZE 1021
00075
00076 static void resolver_shutdown(isc_task_t *task, isc_event_t *event);
00077 static void adb_shutdown(isc_task_t *task, isc_event_t *event);
00078 static void req_shutdown(isc_task_t *task, isc_event_t *event);
00079
00080 isc_result_t
00081 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
00082 const char *name, dns_view_t **viewp)
00083 {
00084 dns_view_t *view;
00085 isc_result_t result;
00086 char buffer[1024];
00087
00088
00089
00090
00091
00092 REQUIRE(name != NULL);
00093 REQUIRE(viewp != NULL && *viewp == NULL);
00094
00095 view = isc_mem_get(mctx, sizeof(*view));
00096 if (view == NULL)
00097 return (ISC_R_NOMEMORY);
00098
00099 view->nta_file = NULL;
00100 view->mctx = NULL;
00101 isc_mem_attach(mctx, &view->mctx);
00102 view->name = isc_mem_strdup(mctx, name);
00103 if (view->name == NULL) {
00104 result = ISC_R_NOMEMORY;
00105 goto cleanup_view;
00106 }
00107
00108 result = isc_file_sanitize(NULL, view->name, "nta",
00109 buffer, sizeof(buffer));
00110 if (result != ISC_R_SUCCESS)
00111 goto cleanup_name;
00112 view->nta_file = isc_mem_strdup(mctx, buffer);
00113 if (view->nta_file == NULL) {
00114 result = ISC_R_NOMEMORY;
00115 goto cleanup_name;
00116 }
00117
00118 result = isc_mutex_init(&view->lock);
00119 if (result != ISC_R_SUCCESS)
00120 goto cleanup_name;
00121
00122 view->zonetable = NULL;
00123 if (isc_bind9) {
00124 result = dns_zt_create(mctx, rdclass, &view->zonetable);
00125 if (result != ISC_R_SUCCESS) {
00126 UNEXPECTED_ERROR(__FILE__, __LINE__,
00127 "dns_zt_create() failed: %s",
00128 isc_result_totext(result));
00129 result = ISC_R_UNEXPECTED;
00130 goto cleanup_mutex;
00131 }
00132 }
00133 view->secroots_priv = NULL;
00134 view->ntatable_priv = NULL;
00135 view->fwdtable = NULL;
00136 result = dns_fwdtable_create(mctx, &view->fwdtable);
00137 if (result != ISC_R_SUCCESS) {
00138 UNEXPECTED_ERROR(__FILE__, __LINE__,
00139 "dns_fwdtable_create() failed: %s",
00140 isc_result_totext(result));
00141 result = ISC_R_UNEXPECTED;
00142 goto cleanup_zt;
00143 }
00144
00145 view->acache = NULL;
00146 view->cache = NULL;
00147 view->cachedb = NULL;
00148 ISC_LIST_INIT(view->dlz_searched);
00149 ISC_LIST_INIT(view->dlz_unsearched);
00150 view->hints = NULL;
00151 view->resolver = NULL;
00152 view->adb = NULL;
00153 view->requestmgr = NULL;
00154 view->rdclass = rdclass;
00155 view->frozen = ISC_FALSE;
00156 view->task = NULL;
00157 result = isc_refcount_init(&view->references, 1);
00158 if (result != ISC_R_SUCCESS)
00159 goto cleanup_fwdtable;
00160 view->weakrefs = 0;
00161 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
00162 DNS_VIEWATTR_REQSHUTDOWN);
00163 view->statickeys = NULL;
00164 view->dynamickeys = NULL;
00165 view->matchclients = NULL;
00166 view->matchdestinations = NULL;
00167 view->matchrecursiveonly = ISC_FALSE;
00168 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
00169 if (result != ISC_R_SUCCESS)
00170 goto cleanup_references;
00171 view->peers = NULL;
00172 view->order = NULL;
00173 view->delonly = NULL;
00174 view->rootdelonly = ISC_FALSE;
00175 view->rootexclude = NULL;
00176 view->adbstats = NULL;
00177 view->resstats = NULL;
00178 view->resquerystats = NULL;
00179 view->cacheshared = ISC_FALSE;
00180 ISC_LIST_INIT(view->dns64);
00181 view->dns64cnt = 0;
00182
00183
00184
00185
00186 view->recursion = ISC_TRUE;
00187 view->auth_nxdomain = ISC_FALSE;
00188 view->additionalfromcache = ISC_TRUE;
00189 view->additionalfromauth = ISC_TRUE;
00190 view->enablednssec = ISC_TRUE;
00191 view->enablevalidation = ISC_TRUE;
00192 view->acceptexpired = ISC_FALSE;
00193 view->minimalresponses = ISC_FALSE;
00194 view->transfer_format = dns_one_answer;
00195 view->cacheacl = NULL;
00196 view->cacheonacl = NULL;
00197 view->queryacl = NULL;
00198 view->queryonacl = NULL;
00199 view->recursionacl = NULL;
00200 view->recursiononacl = NULL;
00201 view->sortlist = NULL;
00202 view->transferacl = NULL;
00203 view->notifyacl = NULL;
00204 view->updateacl = NULL;
00205 view->upfwdacl = NULL;
00206 view->denyansweracl = NULL;
00207 view->nocasecompress = NULL;
00208 view->answeracl_exclude = NULL;
00209 view->denyanswernames = NULL;
00210 view->answernames_exclude = NULL;
00211 view->rrl = NULL;
00212 view->provideixfr = ISC_TRUE;
00213 view->maxcachettl = 7 * 24 * 3600;
00214 view->maxncachettl = 3 * 3600;
00215 view->nta_lifetime = 0;
00216 view->nta_recheck = 0;
00217 view->prefetch_eligible = 0;
00218 view->prefetch_trigger = 0;
00219 view->dstport = 53;
00220 view->preferred_glue = 0;
00221 view->flush = ISC_FALSE;
00222 view->dlv = NULL;
00223 view->maxudp = 0;
00224 view->situdp = 0;
00225 view->maxbits = 0;
00226 view->v4_aaaa = dns_aaaa_ok;
00227 view->v6_aaaa = dns_aaaa_ok;
00228 view->aaaa_acl = NULL;
00229 view->rpzs = NULL;
00230 dns_fixedname_init(&view->dlv_fixed);
00231 view->managed_keys = NULL;
00232 view->redirect = NULL;
00233 view->redirectzone = NULL;
00234 dns_fixedname_init(&view->redirectfixed);
00235 view->requestnsid = ISC_FALSE;
00236 view->requestsit = ISC_TRUE;
00237 view->new_zone_file = NULL;
00238 view->new_zone_config = NULL;
00239 view->cfg_destroy = NULL;
00240 view->fail_ttl = 0;
00241 view->failcache = NULL;
00242 dns_badcache_init(view->mctx, DNS_VIEW_FAILCACHESIZE, &view->failcache);
00243
00244 if (isc_bind9) {
00245 result = dns_order_create(view->mctx, &view->order);
00246 if (result != ISC_R_SUCCESS)
00247 goto cleanup_dynkeys;
00248 }
00249
00250 result = dns_peerlist_new(view->mctx, &view->peers);
00251 if (result != ISC_R_SUCCESS)
00252 goto cleanup_order;
00253
00254 result = dns_aclenv_init(view->mctx, &view->aclenv);
00255 if (result != ISC_R_SUCCESS)
00256 goto cleanup_peerlist;
00257
00258 ISC_LINK_INIT(view, link);
00259 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
00260 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
00261 view, NULL, NULL, NULL);
00262 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
00263 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
00264 view, NULL, NULL, NULL);
00265 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
00266 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
00267 view, NULL, NULL, NULL);
00268 view->viewlist = NULL;
00269 view->magic = DNS_VIEW_MAGIC;
00270
00271 *viewp = view;
00272
00273 return (ISC_R_SUCCESS);
00274
00275 cleanup_peerlist:
00276 if (view->peers != NULL)
00277 dns_peerlist_detach(&view->peers);
00278
00279 cleanup_order:
00280 if (view->order != NULL)
00281 dns_order_detach(&view->order);
00282
00283 cleanup_dynkeys:
00284 if (view->dynamickeys != NULL)
00285 dns_tsigkeyring_detach(&view->dynamickeys);
00286
00287 cleanup_references:
00288 isc_refcount_destroy(&view->references);
00289
00290 cleanup_fwdtable:
00291 if (view->fwdtable != NULL)
00292 dns_fwdtable_destroy(&view->fwdtable);
00293
00294 cleanup_zt:
00295 if (view->zonetable != NULL)
00296 dns_zt_detach(&view->zonetable);
00297
00298 cleanup_mutex:
00299 DESTROYLOCK(&view->lock);
00300
00301 if (view->nta_file != NULL)
00302 isc_mem_free(mctx, view->nta_file);
00303
00304 cleanup_name:
00305 isc_mem_free(mctx, view->name);
00306
00307 cleanup_view:
00308 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
00309
00310 return (result);
00311 }
00312
00313 static inline void
00314 destroy(dns_view_t *view) {
00315 dns_dns64_t *dns64;
00316 dns_dlzdb_t *dlzdb;
00317
00318 REQUIRE(!ISC_LINK_LINKED(view, link));
00319 REQUIRE(isc_refcount_current(&view->references) == 0);
00320 REQUIRE(view->weakrefs == 0);
00321 REQUIRE(RESSHUTDOWN(view));
00322 REQUIRE(ADBSHUTDOWN(view));
00323 REQUIRE(REQSHUTDOWN(view));
00324
00325 if (view->order != NULL)
00326 dns_order_detach(&view->order);
00327 if (view->peers != NULL)
00328 dns_peerlist_detach(&view->peers);
00329
00330 if (view->dynamickeys != NULL) {
00331 isc_result_t result;
00332 char template[20];
00333 char keyfile[20];
00334 FILE *fp = NULL;
00335 int n;
00336
00337 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
00338 view->name);
00339 if (n > 0 && (size_t)n < sizeof(keyfile)) {
00340 result = isc_file_mktemplate(keyfile, template,
00341 sizeof(template));
00342 if (result == ISC_R_SUCCESS)
00343 (void)isc_file_openuniqueprivate(template, &fp);
00344 }
00345 if (fp == NULL)
00346 dns_tsigkeyring_detach(&view->dynamickeys);
00347 else {
00348 result = dns_tsigkeyring_dumpanddetach(
00349 &view->dynamickeys, fp);
00350 if (result == ISC_R_SUCCESS) {
00351 if (fclose(fp) == 0)
00352 result = isc_file_rename(template,
00353 keyfile);
00354 if (result != ISC_R_SUCCESS)
00355 (void)remove(template);
00356 } else {
00357 (void)fclose(fp);
00358 (void)remove(template);
00359 }
00360 }
00361 }
00362 if (view->statickeys != NULL)
00363 dns_tsigkeyring_detach(&view->statickeys);
00364 if (view->adb != NULL)
00365 dns_adb_detach(&view->adb);
00366 if (view->resolver != NULL)
00367 dns_resolver_detach(&view->resolver);
00368 if (view->acache != NULL) {
00369 if (view->cachedb != NULL)
00370 dns_acache_putdb(view->acache, view->cachedb);
00371 dns_acache_detach(&view->acache);
00372 }
00373 dns_rrl_view_destroy(view);
00374 if (view->rpzs != NULL)
00375 dns_rpz_detach_rpzs(&view->rpzs);
00376 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
00377 dlzdb != NULL;
00378 dlzdb = ISC_LIST_HEAD(view->dlz_searched)) {
00379 ISC_LIST_UNLINK(view->dlz_searched, dlzdb, link);
00380 dns_dlzdestroy(&dlzdb);
00381 }
00382 for (dlzdb = ISC_LIST_HEAD(view->dlz_unsearched);
00383 dlzdb != NULL;
00384 dlzdb = ISC_LIST_HEAD(view->dlz_unsearched)) {
00385 ISC_LIST_UNLINK(view->dlz_unsearched, dlzdb, link);
00386 dns_dlzdestroy(&dlzdb);
00387 }
00388 if (view->requestmgr != NULL)
00389 dns_requestmgr_detach(&view->requestmgr);
00390 if (view->task != NULL)
00391 isc_task_detach(&view->task);
00392 if (view->hints != NULL)
00393 dns_db_detach(&view->hints);
00394 if (view->cachedb != NULL)
00395 dns_db_detach(&view->cachedb);
00396 if (view->cache != NULL)
00397 dns_cache_detach(&view->cache);
00398 if (view->nocasecompress != NULL)
00399 dns_acl_detach(&view->nocasecompress);
00400 if (view->matchclients != NULL)
00401 dns_acl_detach(&view->matchclients);
00402 if (view->matchdestinations != NULL)
00403 dns_acl_detach(&view->matchdestinations);
00404 if (view->cacheacl != NULL)
00405 dns_acl_detach(&view->cacheacl);
00406 if (view->cacheonacl != NULL)
00407 dns_acl_detach(&view->cacheonacl);
00408 if (view->queryacl != NULL)
00409 dns_acl_detach(&view->queryacl);
00410 if (view->queryonacl != NULL)
00411 dns_acl_detach(&view->queryonacl);
00412 if (view->recursionacl != NULL)
00413 dns_acl_detach(&view->recursionacl);
00414 if (view->recursiononacl != NULL)
00415 dns_acl_detach(&view->recursiononacl);
00416 if (view->sortlist != NULL)
00417 dns_acl_detach(&view->sortlist);
00418 if (view->transferacl != NULL)
00419 dns_acl_detach(&view->transferacl);
00420 if (view->notifyacl != NULL)
00421 dns_acl_detach(&view->notifyacl);
00422 if (view->updateacl != NULL)
00423 dns_acl_detach(&view->updateacl);
00424 if (view->upfwdacl != NULL)
00425 dns_acl_detach(&view->upfwdacl);
00426 if (view->denyansweracl != NULL)
00427 dns_acl_detach(&view->denyansweracl);
00428 if (view->aaaa_acl != NULL)
00429 dns_acl_detach(&view->aaaa_acl);
00430 if (view->answeracl_exclude != NULL)
00431 dns_rbt_destroy(&view->answeracl_exclude);
00432 if (view->denyanswernames != NULL)
00433 dns_rbt_destroy(&view->denyanswernames);
00434 if (view->answernames_exclude != NULL)
00435 dns_rbt_destroy(&view->answernames_exclude);
00436 if (view->delonly != NULL) {
00437 dns_name_t *name;
00438 int i;
00439
00440 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
00441 name = ISC_LIST_HEAD(view->delonly[i]);
00442 while (name != NULL) {
00443 ISC_LIST_UNLINK(view->delonly[i], name, link);
00444 dns_name_free(name, view->mctx);
00445 isc_mem_put(view->mctx, name, sizeof(*name));
00446 name = ISC_LIST_HEAD(view->delonly[i]);
00447 }
00448 }
00449 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
00450 DNS_VIEW_DELONLYHASH);
00451 view->delonly = NULL;
00452 }
00453 if (view->rootexclude != NULL) {
00454 dns_name_t *name;
00455 int i;
00456
00457 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
00458 name = ISC_LIST_HEAD(view->rootexclude[i]);
00459 while (name != NULL) {
00460 ISC_LIST_UNLINK(view->rootexclude[i],
00461 name, link);
00462 dns_name_free(name, view->mctx);
00463 isc_mem_put(view->mctx, name, sizeof(*name));
00464 name = ISC_LIST_HEAD(view->rootexclude[i]);
00465 }
00466 }
00467 isc_mem_put(view->mctx, view->rootexclude,
00468 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
00469 view->rootexclude = NULL;
00470 }
00471 if (view->adbstats != NULL)
00472 isc_stats_detach(&view->adbstats);
00473 if (view->resstats != NULL)
00474 isc_stats_detach(&view->resstats);
00475 if (view->resquerystats != NULL)
00476 dns_stats_detach(&view->resquerystats);
00477 if (view->secroots_priv != NULL)
00478 dns_keytable_detach(&view->secroots_priv);
00479 if (view->ntatable_priv != NULL)
00480 dns_ntatable_detach(&view->ntatable_priv);
00481 for (dns64 = ISC_LIST_HEAD(view->dns64);
00482 dns64 != NULL;
00483 dns64 = ISC_LIST_HEAD(view->dns64)) {
00484 dns_dns64_unlink(&view->dns64, dns64);
00485 dns_dns64_destroy(&dns64);
00486 }
00487 if (view->managed_keys != NULL)
00488 dns_zone_detach(&view->managed_keys);
00489 if (view->redirect != NULL)
00490 dns_zone_detach(&view->redirect);
00491 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
00492 dns_fwdtable_destroy(&view->fwdtable);
00493 dns_aclenv_destroy(&view->aclenv);
00494 dns_badcache_destroy(&view->failcache);
00495 DESTROYLOCK(&view->lock);
00496 isc_refcount_destroy(&view->references);
00497 isc_mem_free(view->mctx, view->nta_file);
00498 isc_mem_free(view->mctx, view->name);
00499 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
00500 }
00501
00502
00503
00504
00505
00506 static isc_boolean_t
00507 all_done(dns_view_t *view) {
00508
00509 if (isc_refcount_current(&view->references) == 0 &&
00510 view->weakrefs == 0 &&
00511 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
00512 return (ISC_TRUE);
00513
00514 return (ISC_FALSE);
00515 }
00516
00517 void
00518 dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
00519
00520 REQUIRE(DNS_VIEW_VALID(source));
00521 REQUIRE(targetp != NULL && *targetp == NULL);
00522
00523 isc_refcount_increment(&source->references, NULL);
00524
00525 *targetp = source;
00526 }
00527
00528 static void
00529 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
00530 dns_view_t *view;
00531 unsigned int refs;
00532 isc_boolean_t done = ISC_FALSE;
00533
00534 REQUIRE(viewp != NULL);
00535 view = *viewp;
00536 REQUIRE(DNS_VIEW_VALID(view));
00537
00538 if (flush)
00539 view->flush = ISC_TRUE;
00540 isc_refcount_decrement(&view->references, &refs);
00541 if (refs == 0) {
00542 dns_zone_t *mkzone = NULL, *rdzone = NULL;
00543
00544 LOCK(&view->lock);
00545 if (!RESSHUTDOWN(view))
00546 dns_resolver_shutdown(view->resolver);
00547 if (!ADBSHUTDOWN(view))
00548 dns_adb_shutdown(view->adb);
00549 if (!REQSHUTDOWN(view))
00550 dns_requestmgr_shutdown(view->requestmgr);
00551 if (view->acache != NULL)
00552 dns_acache_shutdown(view->acache);
00553 if (view->zonetable != NULL) {
00554 if (view->flush)
00555 dns_zt_flushanddetach(&view->zonetable);
00556 else
00557 dns_zt_detach(&view->zonetable);
00558 }
00559 if (view->managed_keys != NULL) {
00560 mkzone = view->managed_keys;
00561 view->managed_keys = NULL;
00562 if (view->flush)
00563 dns_zone_flush(mkzone);
00564 }
00565 if (view->redirect != NULL) {
00566 rdzone = view->redirect;
00567 view->redirect = NULL;
00568 if (view->flush)
00569 dns_zone_flush(rdzone);
00570 }
00571 done = all_done(view);
00572 UNLOCK(&view->lock);
00573
00574
00575 if (mkzone != NULL)
00576 dns_zone_detach(&mkzone);
00577
00578 if (rdzone != NULL)
00579 dns_zone_detach(&rdzone);
00580 }
00581
00582 *viewp = NULL;
00583
00584 if (done)
00585 destroy(view);
00586 }
00587
00588 void
00589 dns_view_flushanddetach(dns_view_t **viewp) {
00590 view_flushanddetach(viewp, ISC_TRUE);
00591 }
00592
00593 void
00594 dns_view_detach(dns_view_t **viewp) {
00595 view_flushanddetach(viewp, ISC_FALSE);
00596 }
00597
00598 static isc_result_t
00599 dialup(dns_zone_t *zone, void *dummy) {
00600 UNUSED(dummy);
00601 dns_zone_dialup(zone);
00602 return (ISC_R_SUCCESS);
00603 }
00604
00605 void
00606 dns_view_dialup(dns_view_t *view) {
00607 REQUIRE(DNS_VIEW_VALID(view));
00608 REQUIRE(view->zonetable != NULL);
00609
00610 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
00611 }
00612
00613 void
00614 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
00615
00616 REQUIRE(DNS_VIEW_VALID(source));
00617 REQUIRE(targetp != NULL && *targetp == NULL);
00618
00619 LOCK(&source->lock);
00620 source->weakrefs++;
00621 UNLOCK(&source->lock);
00622
00623 *targetp = source;
00624 }
00625
00626 void
00627 dns_view_weakdetach(dns_view_t **viewp) {
00628 dns_view_t *view;
00629 isc_boolean_t done = ISC_FALSE;
00630
00631 REQUIRE(viewp != NULL);
00632 view = *viewp;
00633 REQUIRE(DNS_VIEW_VALID(view));
00634
00635 LOCK(&view->lock);
00636
00637 INSIST(view->weakrefs > 0);
00638 view->weakrefs--;
00639 done = all_done(view);
00640
00641 UNLOCK(&view->lock);
00642
00643 *viewp = NULL;
00644
00645 if (done)
00646 destroy(view);
00647 }
00648
00649 static void
00650 resolver_shutdown(isc_task_t *task, isc_event_t *event) {
00651 dns_view_t *view = event->ev_arg;
00652 isc_boolean_t done;
00653
00654 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
00655 REQUIRE(DNS_VIEW_VALID(view));
00656 REQUIRE(view->task == task);
00657
00658 UNUSED(task);
00659
00660 isc_event_free(&event);
00661
00662 LOCK(&view->lock);
00663
00664 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
00665 done = all_done(view);
00666
00667 UNLOCK(&view->lock);
00668
00669 if (done)
00670 destroy(view);
00671 }
00672
00673 static void
00674 adb_shutdown(isc_task_t *task, isc_event_t *event) {
00675 dns_view_t *view = event->ev_arg;
00676 isc_boolean_t done;
00677
00678 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
00679 REQUIRE(DNS_VIEW_VALID(view));
00680 REQUIRE(view->task == task);
00681
00682 UNUSED(task);
00683
00684 isc_event_free(&event);
00685
00686 LOCK(&view->lock);
00687
00688 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
00689 done = all_done(view);
00690
00691 UNLOCK(&view->lock);
00692
00693 if (done)
00694 destroy(view);
00695 }
00696
00697 static void
00698 req_shutdown(isc_task_t *task, isc_event_t *event) {
00699 dns_view_t *view = event->ev_arg;
00700 isc_boolean_t done;
00701
00702 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
00703 REQUIRE(DNS_VIEW_VALID(view));
00704 REQUIRE(view->task == task);
00705
00706 UNUSED(task);
00707
00708 isc_event_free(&event);
00709
00710 LOCK(&view->lock);
00711
00712 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
00713 done = all_done(view);
00714
00715 UNLOCK(&view->lock);
00716
00717 if (done)
00718 destroy(view);
00719 }
00720
00721 isc_result_t
00722 dns_view_createzonetable(dns_view_t *view) {
00723
00724 REQUIRE(DNS_VIEW_VALID(view));
00725 REQUIRE(!view->frozen);
00726 REQUIRE(view->zonetable == NULL);
00727
00728 return (dns_zt_create(view->mctx, view->rdclass, &view->zonetable));
00729 }
00730
00731 isc_result_t
00732 dns_view_createresolver(dns_view_t *view,
00733 isc_taskmgr_t *taskmgr,
00734 unsigned int ntasks, unsigned int ndisp,
00735 isc_socketmgr_t *socketmgr,
00736 isc_timermgr_t *timermgr,
00737 unsigned int options,
00738 dns_dispatchmgr_t *dispatchmgr,
00739 dns_dispatch_t *dispatchv4,
00740 dns_dispatch_t *dispatchv6)
00741 {
00742 isc_result_t result;
00743 isc_event_t *event;
00744 isc_mem_t *mctx = NULL;
00745
00746 REQUIRE(DNS_VIEW_VALID(view));
00747 REQUIRE(!view->frozen);
00748 REQUIRE(view->resolver == NULL);
00749
00750 result = isc_task_create(taskmgr, 0, &view->task);
00751 if (result != ISC_R_SUCCESS)
00752 return (result);
00753 isc_task_setname(view->task, "view", view);
00754
00755 result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
00756 timermgr, options, dispatchmgr,
00757 dispatchv4, dispatchv6,
00758 &view->resolver);
00759 if (result != ISC_R_SUCCESS) {
00760 isc_task_detach(&view->task);
00761 return (result);
00762 }
00763 event = &view->resevent;
00764 dns_resolver_whenshutdown(view->resolver, view->task, &event);
00765 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
00766
00767 result = isc_mem_create(0, 0, &mctx);
00768 if (result != ISC_R_SUCCESS) {
00769 dns_resolver_shutdown(view->resolver);
00770 return (result);
00771 }
00772
00773 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
00774 isc_mem_setname(mctx, "ADB", NULL);
00775 isc_mem_detach(&mctx);
00776 if (result != ISC_R_SUCCESS) {
00777 dns_resolver_shutdown(view->resolver);
00778 return (result);
00779 }
00780 event = &view->adbevent;
00781 dns_adb_whenshutdown(view->adb, view->task, &event);
00782 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
00783
00784 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
00785 dns_resolver_taskmgr(view->resolver),
00786 dns_resolver_dispatchmgr(view->resolver),
00787 dispatchv4, dispatchv6,
00788 &view->requestmgr);
00789 if (result != ISC_R_SUCCESS) {
00790 dns_adb_shutdown(view->adb);
00791 dns_resolver_shutdown(view->resolver);
00792 return (result);
00793 }
00794 event = &view->reqevent;
00795 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
00796 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
00797
00798 return (ISC_R_SUCCESS);
00799 }
00800
00801 void
00802 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
00803 dns_view_setcache2(view, cache, ISC_FALSE);
00804 }
00805
00806 void
00807 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
00808 REQUIRE(DNS_VIEW_VALID(view));
00809 REQUIRE(!view->frozen);
00810
00811 view->cacheshared = shared;
00812 if (view->cache != NULL) {
00813 if (view->acache != NULL)
00814 dns_acache_putdb(view->acache, view->cachedb);
00815 dns_db_detach(&view->cachedb);
00816 dns_cache_detach(&view->cache);
00817 }
00818 dns_cache_attach(cache, &view->cache);
00819 dns_cache_attachdb(cache, &view->cachedb);
00820 INSIST(DNS_DB_VALID(view->cachedb));
00821
00822 if (view->acache != NULL)
00823 dns_acache_setdb(view->acache, view->cachedb);
00824 }
00825
00826 isc_boolean_t
00827 dns_view_iscacheshared(dns_view_t *view) {
00828 REQUIRE(DNS_VIEW_VALID(view));
00829
00830 return (view->cacheshared);
00831 }
00832
00833 void
00834 dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
00835 REQUIRE(DNS_VIEW_VALID(view));
00836 REQUIRE(!view->frozen);
00837 REQUIRE(view->hints == NULL);
00838 REQUIRE(dns_db_iszone(hints));
00839
00840 dns_db_attach(hints, &view->hints);
00841 }
00842
00843 void
00844 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
00845 REQUIRE(DNS_VIEW_VALID(view));
00846 REQUIRE(ring != NULL);
00847 if (view->statickeys != NULL)
00848 dns_tsigkeyring_detach(&view->statickeys);
00849 dns_tsigkeyring_attach(ring, &view->statickeys);
00850 }
00851
00852 void
00853 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
00854 REQUIRE(DNS_VIEW_VALID(view));
00855 REQUIRE(ring != NULL);
00856 if (view->dynamickeys != NULL)
00857 dns_tsigkeyring_detach(&view->dynamickeys);
00858 dns_tsigkeyring_attach(ring, &view->dynamickeys);
00859 }
00860
00861 void
00862 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
00863 REQUIRE(DNS_VIEW_VALID(view));
00864 REQUIRE(ringp != NULL && *ringp == NULL);
00865 if (view->dynamickeys != NULL)
00866 dns_tsigkeyring_attach(view->dynamickeys, ringp);
00867 }
00868
00869 void
00870 dns_view_restorekeyring(dns_view_t *view) {
00871 FILE *fp;
00872 char keyfile[20];
00873 int n;
00874
00875 REQUIRE(DNS_VIEW_VALID(view));
00876
00877 if (view->dynamickeys != NULL) {
00878 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
00879 view->name);
00880 if (n > 0 && (size_t)n < sizeof(keyfile)) {
00881 fp = fopen(keyfile, "r");
00882 if (fp != NULL) {
00883 dns_keyring_restore(view->dynamickeys, fp);
00884 (void)fclose(fp);
00885 }
00886 }
00887 }
00888 }
00889
00890 void
00891 dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
00892 REQUIRE(DNS_VIEW_VALID(view));
00893 view->dstport = dstport;
00894 }
00895
00896 void
00897 dns_view_freeze(dns_view_t *view) {
00898 REQUIRE(DNS_VIEW_VALID(view));
00899 REQUIRE(!view->frozen);
00900
00901 if (view->resolver != NULL) {
00902 INSIST(view->cachedb != NULL);
00903 dns_resolver_freeze(view->resolver);
00904 }
00905 view->frozen = ISC_TRUE;
00906 }
00907
00908 void
00909 dns_view_thaw(dns_view_t *view) {
00910 REQUIRE(DNS_VIEW_VALID(view));
00911 REQUIRE(view->frozen);
00912
00913 view->frozen = ISC_FALSE;
00914 }
00915
00916 isc_result_t
00917 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
00918 isc_result_t result;
00919
00920 REQUIRE(DNS_VIEW_VALID(view));
00921 REQUIRE(!view->frozen);
00922 REQUIRE(view->zonetable != NULL);
00923
00924 result = dns_zt_mount(view->zonetable, zone);
00925
00926 return (result);
00927 }
00928
00929 isc_result_t
00930 dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
00931 isc_result_t result;
00932
00933 REQUIRE(DNS_VIEW_VALID(view));
00934
00935 LOCK(&view->lock);
00936 if (view->zonetable != NULL) {
00937 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
00938 if (result == DNS_R_PARTIALMATCH) {
00939 dns_zone_detach(zonep);
00940 result = ISC_R_NOTFOUND;
00941 }
00942 } else
00943 result = ISC_R_NOTFOUND;
00944 UNLOCK(&view->lock);
00945
00946 return (result);
00947 }
00948
00949 isc_result_t
00950 dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
00951 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
00952 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
00953 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
00954 return (dns_view_find2(view, name, type, now, options, use_hints,
00955 ISC_FALSE, dbp, nodep, foundname, rdataset,
00956 sigrdataset));
00957 }
00958
00959 isc_result_t
00960 dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
00961 isc_stdtime_t now, unsigned int options,
00962 isc_boolean_t use_hints, isc_boolean_t use_static_stub,
00963 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
00964 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00965 {
00966 isc_result_t result;
00967 dns_db_t *db, *zdb;
00968 dns_dbnode_t *node, *znode;
00969 isc_boolean_t is_cache, is_staticstub_zone;
00970 dns_rdataset_t zrdataset, zsigrdataset;
00971 dns_zone_t *zone;
00972
00973
00974
00975
00976
00977
00978 REQUIRE(DNS_VIEW_VALID(view));
00979 REQUIRE(view->frozen);
00980 REQUIRE(type != dns_rdatatype_rrsig);
00981 REQUIRE(rdataset != NULL);
00982 REQUIRE(nodep == NULL || *nodep == NULL);
00983
00984
00985
00986
00987 dns_rdataset_init(&zrdataset);
00988 dns_rdataset_init(&zsigrdataset);
00989 zdb = NULL;
00990 znode = NULL;
00991
00992
00993
00994
00995 db = NULL;
00996 node = NULL;
00997 is_staticstub_zone = ISC_FALSE;
00998 zone = NULL;
00999 LOCK(&view->lock);
01000 if (view->zonetable != NULL)
01001 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
01002 else
01003 result = ISC_R_NOTFOUND;
01004 UNLOCK(&view->lock);
01005 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
01006 !use_static_stub)
01007 result = ISC_R_NOTFOUND;
01008 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
01009 result = dns_zone_getdb(zone, &db);
01010 if (result != ISC_R_SUCCESS && view->cachedb != NULL)
01011 dns_db_attach(view->cachedb, &db);
01012 else if (result != ISC_R_SUCCESS)
01013 goto cleanup;
01014 if (dns_zone_gettype(zone) == dns_zone_staticstub &&
01015 dns_name_equal(name, dns_zone_getorigin(zone))) {
01016 is_staticstub_zone = ISC_TRUE;
01017 }
01018 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
01019 dns_db_attach(view->cachedb, &db);
01020 else
01021 goto cleanup;
01022
01023 is_cache = dns_db_iscache(db);
01024
01025 db_find:
01026
01027
01028
01029 result = dns_db_find(db, name, NULL, type, options,
01030 now, &node, foundname, rdataset, sigrdataset);
01031
01032 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
01033 if (dns_rdataset_isassociated(rdataset))
01034 dns_rdataset_disassociate(rdataset);
01035 if (sigrdataset != NULL &&
01036 dns_rdataset_isassociated(sigrdataset))
01037 dns_rdataset_disassociate(sigrdataset);
01038 if (node != NULL)
01039 dns_db_detachnode(db, &node);
01040 if (!is_cache) {
01041 dns_db_detach(&db);
01042 if (view->cachedb != NULL && !is_staticstub_zone) {
01043
01044
01045
01046
01047
01048
01049
01050 is_cache = ISC_TRUE;
01051 dns_db_attach(view->cachedb, &db);
01052 goto db_find;
01053 }
01054 } else {
01055
01056
01057
01058
01059 if (dns_rdataset_isassociated(&zrdataset)) {
01060 dns_rdataset_clone(&zrdataset, rdataset);
01061 if (sigrdataset != NULL &&
01062 dns_rdataset_isassociated(&zsigrdataset))
01063 dns_rdataset_clone(&zsigrdataset,
01064 sigrdataset);
01065 result = DNS_R_GLUE;
01066 if (db != NULL)
01067 dns_db_detach(&db);
01068 dns_db_attach(zdb, &db);
01069 dns_db_attachnode(db, znode, &node);
01070 goto cleanup;
01071 }
01072 }
01073
01074
01075
01076 result = ISC_R_NOTFOUND;
01077 } else if (result == DNS_R_GLUE) {
01078 if (view->cachedb != NULL && !is_staticstub_zone) {
01079
01080
01081
01082
01083 is_cache = ISC_TRUE;
01084 dns_rdataset_clone(rdataset, &zrdataset);
01085 dns_rdataset_disassociate(rdataset);
01086 if (sigrdataset != NULL &&
01087 dns_rdataset_isassociated(sigrdataset)) {
01088 dns_rdataset_clone(sigrdataset, &zsigrdataset);
01089 dns_rdataset_disassociate(sigrdataset);
01090 }
01091 dns_db_attach(db, &zdb);
01092 dns_db_attachnode(zdb, node, &znode);
01093 dns_db_detachnode(db, &node);
01094 dns_db_detach(&db);
01095 dns_db_attach(view->cachedb, &db);
01096 goto db_find;
01097 }
01098
01099
01100
01101 result = ISC_R_SUCCESS;
01102 }
01103
01104 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
01105 if (dns_rdataset_isassociated(rdataset))
01106 dns_rdataset_disassociate(rdataset);
01107 if (sigrdataset != NULL &&
01108 dns_rdataset_isassociated(sigrdataset))
01109 dns_rdataset_disassociate(sigrdataset);
01110 if (db != NULL) {
01111 if (node != NULL)
01112 dns_db_detachnode(db, &node);
01113 dns_db_detach(&db);
01114 }
01115 result = dns_db_find(view->hints, name, NULL, type, options,
01116 now, &node, foundname,
01117 rdataset, sigrdataset);
01118 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) {
01119
01120
01121
01122
01123 dns_resolver_prime(view->resolver);
01124 dns_db_attach(view->hints, &db);
01125 result = DNS_R_HINT;
01126 } else if (result == DNS_R_NXRRSET) {
01127 dns_db_attach(view->hints, &db);
01128 result = DNS_R_HINTNXRRSET;
01129 } else if (result == DNS_R_NXDOMAIN)
01130 result = ISC_R_NOTFOUND;
01131
01132
01133
01134
01135 if (db == NULL && node != NULL)
01136 dns_db_detachnode(view->hints, &node);
01137 }
01138
01139 cleanup:
01140 if (dns_rdataset_isassociated(&zrdataset)) {
01141 dns_rdataset_disassociate(&zrdataset);
01142 if (dns_rdataset_isassociated(&zsigrdataset))
01143 dns_rdataset_disassociate(&zsigrdataset);
01144 }
01145
01146 if (zdb != NULL) {
01147 if (znode != NULL)
01148 dns_db_detachnode(zdb, &znode);
01149 dns_db_detach(&zdb);
01150 }
01151
01152 if (db != NULL) {
01153 if (node != NULL) {
01154 if (nodep != NULL)
01155 *nodep = node;
01156 else
01157 dns_db_detachnode(db, &node);
01158 }
01159 if (dbp != NULL)
01160 *dbp = db;
01161 else
01162 dns_db_detach(&db);
01163 } else
01164 INSIST(node == NULL);
01165
01166 if (zone != NULL)
01167 dns_zone_detach(&zone);
01168
01169 return (result);
01170 }
01171
01172 isc_result_t
01173 dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
01174 isc_stdtime_t now, unsigned int options,
01175 isc_boolean_t use_hints,
01176 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
01177 {
01178 isc_result_t result;
01179 dns_fixedname_t foundname;
01180
01181 dns_fixedname_init(&foundname);
01182 result = dns_view_find(view, name, type, now, options, use_hints,
01183 NULL, NULL, dns_fixedname_name(&foundname),
01184 rdataset, sigrdataset);
01185 if (result == DNS_R_NXDOMAIN) {
01186
01187
01188
01189
01190
01191
01192 if (dns_rdataset_isassociated(rdataset))
01193 dns_rdataset_disassociate(rdataset);
01194 if (sigrdataset != NULL &&
01195 dns_rdataset_isassociated(sigrdataset))
01196 dns_rdataset_disassociate(sigrdataset);
01197 } else if (result != ISC_R_SUCCESS &&
01198 result != DNS_R_GLUE &&
01199 result != DNS_R_HINT &&
01200 result != DNS_R_NCACHENXDOMAIN &&
01201 result != DNS_R_NCACHENXRRSET &&
01202 result != DNS_R_NXRRSET &&
01203 result != DNS_R_HINTNXRRSET &&
01204 result != ISC_R_NOTFOUND) {
01205 if (dns_rdataset_isassociated(rdataset))
01206 dns_rdataset_disassociate(rdataset);
01207 if (sigrdataset != NULL &&
01208 dns_rdataset_isassociated(sigrdataset))
01209 dns_rdataset_disassociate(sigrdataset);
01210 result = ISC_R_NOTFOUND;
01211 }
01212
01213 return (result);
01214 }
01215
01216 isc_result_t
01217 dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
01218 isc_stdtime_t now, unsigned int options,
01219 isc_boolean_t use_hints,
01220 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
01221 {
01222 return(dns_view_findzonecut2(view, name, fname, now, options,
01223 use_hints, ISC_TRUE,
01224 rdataset, sigrdataset));
01225 }
01226
01227 isc_result_t
01228 dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
01229 isc_stdtime_t now, unsigned int options,
01230 isc_boolean_t use_hints, isc_boolean_t use_cache,
01231 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
01232 {
01233 isc_result_t result;
01234 dns_db_t *db;
01235 isc_boolean_t is_cache, use_zone, try_hints;
01236 dns_zone_t *zone;
01237 dns_name_t *zfname;
01238 dns_rdataset_t zrdataset, zsigrdataset;
01239 dns_fixedname_t zfixedname;
01240 unsigned int ztoptions = 0;
01241
01242 REQUIRE(DNS_VIEW_VALID(view));
01243 REQUIRE(view->frozen);
01244
01245 db = NULL;
01246 use_zone = ISC_FALSE;
01247 try_hints = ISC_FALSE;
01248 zfname = NULL;
01249
01250
01251
01252
01253 dns_fixedname_init(&zfixedname);
01254 dns_rdataset_init(&zrdataset);
01255 dns_rdataset_init(&zsigrdataset);
01256
01257
01258
01259
01260 zone = NULL;
01261 LOCK(&view->lock);
01262 if (view->zonetable != NULL) {
01263 if ((options & DNS_DBFIND_NOEXACT) != 0)
01264 ztoptions |= DNS_ZTFIND_NOEXACT;
01265 result = dns_zt_find(view->zonetable, name, ztoptions,
01266 NULL, &zone);
01267 } else
01268 result = ISC_R_NOTFOUND;
01269 UNLOCK(&view->lock);
01270 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
01271 result = dns_zone_getdb(zone, &db);
01272 if (result == ISC_R_NOTFOUND) {
01273
01274
01275
01276
01277
01278 if (use_cache && view->cachedb != NULL) {
01279
01280
01281
01282 dns_db_attach(view->cachedb, &db);
01283 } else {
01284
01285
01286
01287 try_hints = ISC_TRUE;
01288 goto finish;
01289 }
01290 } else if (result != ISC_R_SUCCESS) {
01291
01292
01293
01294 goto cleanup;
01295 }
01296 is_cache = dns_db_iscache(db);
01297
01298 db_find:
01299
01300
01301
01302 if (!is_cache) {
01303 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options,
01304 now, NULL, fname, rdataset, sigrdataset);
01305 if (result == DNS_R_DELEGATION)
01306 result = ISC_R_SUCCESS;
01307 else if (result != ISC_R_SUCCESS)
01308 goto cleanup;
01309 if (use_cache && view->cachedb != NULL && db != view->hints) {
01310
01311
01312
01313 zfname = dns_fixedname_name(&zfixedname);
01314 result = dns_name_copy(fname, zfname, NULL);
01315 if (result != ISC_R_SUCCESS)
01316 goto cleanup;
01317 dns_rdataset_clone(rdataset, &zrdataset);
01318 dns_rdataset_disassociate(rdataset);
01319 if (sigrdataset != NULL &&
01320 dns_rdataset_isassociated(sigrdataset)) {
01321 dns_rdataset_clone(sigrdataset, &zsigrdataset);
01322 dns_rdataset_disassociate(sigrdataset);
01323 }
01324 dns_db_detach(&db);
01325 dns_db_attach(view->cachedb, &db);
01326 is_cache = ISC_TRUE;
01327 goto db_find;
01328 }
01329 } else {
01330 result = dns_db_findzonecut(db, name, options, now, NULL,
01331 fname, rdataset, sigrdataset);
01332 if (result == ISC_R_SUCCESS) {
01333 if (zfname != NULL &&
01334 (!dns_name_issubdomain(fname, zfname) ||
01335 (dns_zone_staticstub &&
01336 dns_name_equal(fname, zfname)))) {
01337
01338
01339
01340
01341 use_zone = ISC_TRUE;
01342 }
01343 } else if (result == ISC_R_NOTFOUND) {
01344 if (zfname != NULL) {
01345
01346
01347
01348
01349 use_zone = ISC_TRUE;
01350 } else {
01351
01352
01353
01354 try_hints = ISC_TRUE;
01355 }
01356 } else {
01357
01358
01359
01360 goto cleanup;
01361 }
01362 }
01363
01364 finish:
01365 if (use_zone) {
01366 if (dns_rdataset_isassociated(rdataset)) {
01367 dns_rdataset_disassociate(rdataset);
01368 if (sigrdataset != NULL &&
01369 dns_rdataset_isassociated(sigrdataset))
01370 dns_rdataset_disassociate(sigrdataset);
01371 }
01372 result = dns_name_copy(zfname, fname, NULL);
01373 if (result != ISC_R_SUCCESS)
01374 goto cleanup;
01375 dns_rdataset_clone(&zrdataset, rdataset);
01376 if (sigrdataset != NULL &&
01377 dns_rdataset_isassociated(&zrdataset))
01378 dns_rdataset_clone(&zsigrdataset, sigrdataset);
01379 } else if (try_hints && use_hints && view->hints != NULL) {
01380
01381
01382
01383 result = dns_db_find(view->hints, dns_rootname, NULL,
01384 dns_rdatatype_ns, 0, now, NULL, fname,
01385 rdataset, NULL);
01386 if (result != ISC_R_SUCCESS) {
01387
01388
01389
01390
01391 if (dns_rdataset_isassociated(rdataset))
01392 dns_rdataset_disassociate(rdataset);
01393 result = ISC_R_NOTFOUND;
01394 }
01395 }
01396
01397 cleanup:
01398 if (dns_rdataset_isassociated(&zrdataset)) {
01399 dns_rdataset_disassociate(&zrdataset);
01400 if (dns_rdataset_isassociated(&zsigrdataset))
01401 dns_rdataset_disassociate(&zsigrdataset);
01402 }
01403 if (db != NULL)
01404 dns_db_detach(&db);
01405 if (zone != NULL)
01406 dns_zone_detach(&zone);
01407
01408 return (result);
01409 }
01410
01411 isc_result_t
01412 dns_viewlist_find(dns_viewlist_t *list, const char *name,
01413 dns_rdataclass_t rdclass, dns_view_t **viewp)
01414 {
01415 dns_view_t *view;
01416
01417 REQUIRE(list != NULL);
01418
01419 for (view = ISC_LIST_HEAD(*list);
01420 view != NULL;
01421 view = ISC_LIST_NEXT(view, link)) {
01422 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
01423 break;
01424 }
01425 if (view == NULL)
01426 return (ISC_R_NOTFOUND);
01427
01428 dns_view_attach(view, viewp);
01429
01430 return (ISC_R_SUCCESS);
01431 }
01432
01433 isc_result_t
01434 dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
01435 isc_boolean_t allclasses, dns_rdataclass_t rdclass,
01436 dns_zone_t **zonep)
01437 {
01438 dns_view_t *view;
01439 isc_result_t result;
01440 dns_zone_t *zone1 = NULL, *zone2 = NULL;
01441 dns_zone_t **zp = NULL;;
01442
01443 REQUIRE(list != NULL);
01444 REQUIRE(zonep != NULL && *zonep == NULL);
01445
01446 for (view = ISC_LIST_HEAD(*list);
01447 view != NULL;
01448 view = ISC_LIST_NEXT(view, link)) {
01449 if (allclasses == ISC_FALSE && view->rdclass != rdclass)
01450 continue;
01451
01452
01453
01454
01455
01456 zp = (zone1 == NULL) ? &zone1 : &zone2;
01457 LOCK(&view->lock);
01458 if (view->zonetable != NULL)
01459 result = dns_zt_find(view->zonetable, name, 0,
01460 NULL, zp);
01461 else
01462 result = ISC_R_NOTFOUND;
01463 UNLOCK(&view->lock);
01464 INSIST(result == ISC_R_SUCCESS ||
01465 result == ISC_R_NOTFOUND ||
01466 result == DNS_R_PARTIALMATCH);
01467
01468
01469 if (result == DNS_R_PARTIALMATCH) {
01470 dns_zone_detach(zp);
01471 result = ISC_R_NOTFOUND;
01472 POST(result);
01473 }
01474
01475 if (zone2 != NULL) {
01476 dns_zone_detach(&zone1);
01477 dns_zone_detach(&zone2);
01478 return (ISC_R_MULTIPLE);
01479 }
01480 }
01481
01482 if (zone1 != NULL) {
01483 dns_zone_attach(zone1, zonep);
01484 dns_zone_detach(&zone1);
01485 return (ISC_R_SUCCESS);
01486 }
01487
01488 return (ISC_R_NOTFOUND);
01489 }
01490
01491 isc_result_t
01492 dns_view_load(dns_view_t *view, isc_boolean_t stop) {
01493
01494 REQUIRE(DNS_VIEW_VALID(view));
01495 REQUIRE(view->zonetable != NULL);
01496
01497 return (dns_zt_load(view->zonetable, stop));
01498 }
01499
01500 isc_result_t
01501 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
01502
01503 REQUIRE(DNS_VIEW_VALID(view));
01504 REQUIRE(view->zonetable != NULL);
01505
01506 return (dns_zt_loadnew(view->zonetable, stop));
01507 }
01508
01509 isc_result_t
01510 dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
01511 REQUIRE(DNS_VIEW_VALID(view));
01512 REQUIRE(view->zonetable != NULL);
01513
01514 return (dns_zt_asyncload(view->zonetable, callback, arg));
01515 }
01516
01517 isc_result_t
01518 dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
01519 {
01520 isc_result_t result;
01521 REQUIRE(keyp != NULL && *keyp == NULL);
01522
01523 result = dns_tsigkey_find(keyp, keyname, NULL,
01524 view->statickeys);
01525 if (result == ISC_R_NOTFOUND)
01526 result = dns_tsigkey_find(keyp, keyname, NULL,
01527 view->dynamickeys);
01528 return (result);
01529 }
01530
01531 isc_result_t
01532 dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
01533 dns_tsigkey_t **keyp)
01534 {
01535 isc_result_t result;
01536 dns_name_t *keyname = NULL;
01537 dns_peer_t *peer = NULL;
01538
01539 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
01540 if (result != ISC_R_SUCCESS)
01541 return (result);
01542
01543 result = dns_peer_getkey(peer, &keyname);
01544 if (result != ISC_R_SUCCESS)
01545 return (result);
01546
01547 result = dns_view_gettsig(view, keyname, keyp);
01548 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
01549 }
01550
01551 isc_result_t
01552 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
01553 REQUIRE(DNS_VIEW_VALID(view));
01554 REQUIRE(source != NULL);
01555
01556 return (dns_tsig_verify(source, msg, view->statickeys,
01557 view->dynamickeys));
01558 }
01559
01560 isc_result_t
01561 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
01562 isc_result_t result;
01563
01564 REQUIRE(DNS_VIEW_VALID(view));
01565
01566 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
01567 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
01568 &dns_master_style_cache, fp);
01569 if (result != ISC_R_SUCCESS)
01570 return (result);
01571 dns_adb_dump(view->adb, fp);
01572 dns_resolver_printbadcache(view->resolver, fp);
01573 dns_badcache_print(view->failcache, "SERVFAIL cache", fp);
01574 return (ISC_R_SUCCESS);
01575 }
01576
01577 isc_result_t
01578 dns_view_flushcache(dns_view_t *view) {
01579 return (dns_view_flushcache2(view, ISC_FALSE));
01580 }
01581
01582 isc_result_t
01583 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
01584 isc_result_t result;
01585
01586 REQUIRE(DNS_VIEW_VALID(view));
01587
01588 if (view->cachedb == NULL)
01589 return (ISC_R_SUCCESS);
01590 if (!fixuponly) {
01591 result = dns_cache_flush(view->cache);
01592 if (result != ISC_R_SUCCESS)
01593 return (result);
01594 }
01595 if (view->acache != NULL)
01596 dns_acache_putdb(view->acache, view->cachedb);
01597 dns_db_detach(&view->cachedb);
01598 dns_cache_attachdb(view->cache, &view->cachedb);
01599 if (view->acache != NULL)
01600 dns_acache_setdb(view->acache, view->cachedb);
01601 if (view->resolver != NULL)
01602 dns_resolver_flushbadcache(view->resolver, NULL);
01603 if (view->failcache != NULL)
01604 dns_badcache_flush(view->failcache);
01605
01606 dns_adb_flush(view->adb);
01607 return (ISC_R_SUCCESS);
01608 }
01609
01610 isc_result_t
01611 dns_view_flushname(dns_view_t *view, dns_name_t *name) {
01612 return (dns_view_flushnode(view, name, ISC_FALSE));
01613 }
01614
01615 isc_result_t
01616 dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
01617 isc_result_t result = ISC_R_SUCCESS;
01618
01619 REQUIRE(DNS_VIEW_VALID(view));
01620
01621 if (tree) {
01622 if (view->adb != NULL)
01623 dns_adb_flushnames(view->adb, name);
01624 if (view->resolver != NULL)
01625 dns_resolver_flushbadnames(view->resolver, name);
01626 if (view->failcache != NULL)
01627 dns_badcache_flushtree(view->failcache, name);
01628 } else {
01629 if (view->adb != NULL)
01630 dns_adb_flushname(view->adb, name);
01631 if (view->resolver != NULL)
01632 dns_resolver_flushbadcache(view->resolver, name);
01633 if (view->failcache != NULL)
01634 dns_badcache_flushname(view->failcache, name);
01635 }
01636
01637 if (view->cache != NULL)
01638 result = dns_cache_flushnode(view->cache, name, tree);
01639
01640 return (result);
01641 }
01642
01643 isc_result_t
01644 dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
01645 isc_result_t result;
01646 dns_name_t *new;
01647 isc_uint32_t hash;
01648
01649 REQUIRE(DNS_VIEW_VALID(view));
01650
01651 if (view->delonly == NULL) {
01652 view->delonly = isc_mem_get(view->mctx,
01653 sizeof(dns_namelist_t) *
01654 DNS_VIEW_DELONLYHASH);
01655 if (view->delonly == NULL)
01656 return (ISC_R_NOMEMORY);
01657 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
01658 ISC_LIST_INIT(view->delonly[hash]);
01659 }
01660 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
01661 new = ISC_LIST_HEAD(view->delonly[hash]);
01662 while (new != NULL && !dns_name_equal(new, name))
01663 new = ISC_LIST_NEXT(new, link);
01664 if (new != NULL)
01665 return (ISC_R_SUCCESS);
01666 new = isc_mem_get(view->mctx, sizeof(*new));
01667 if (new == NULL)
01668 return (ISC_R_NOMEMORY);
01669 dns_name_init(new, NULL);
01670 result = dns_name_dup(name, view->mctx, new);
01671 if (result == ISC_R_SUCCESS)
01672 ISC_LIST_APPEND(view->delonly[hash], new, link);
01673 else
01674 isc_mem_put(view->mctx, new, sizeof(*new));
01675 return (result);
01676 }
01677
01678 isc_result_t
01679 dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
01680 isc_result_t result;
01681 dns_name_t *new;
01682 isc_uint32_t hash;
01683
01684 REQUIRE(DNS_VIEW_VALID(view));
01685
01686 if (view->rootexclude == NULL) {
01687 view->rootexclude = isc_mem_get(view->mctx,
01688 sizeof(dns_namelist_t) *
01689 DNS_VIEW_DELONLYHASH);
01690 if (view->rootexclude == NULL)
01691 return (ISC_R_NOMEMORY);
01692 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
01693 ISC_LIST_INIT(view->rootexclude[hash]);
01694 }
01695 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
01696 new = ISC_LIST_HEAD(view->rootexclude[hash]);
01697 while (new != NULL && !dns_name_equal(new, name))
01698 new = ISC_LIST_NEXT(new, link);
01699 if (new != NULL)
01700 return (ISC_R_SUCCESS);
01701 new = isc_mem_get(view->mctx, sizeof(*new));
01702 if (new == NULL)
01703 return (ISC_R_NOMEMORY);
01704 dns_name_init(new, NULL);
01705 result = dns_name_dup(name, view->mctx, new);
01706 if (result == ISC_R_SUCCESS)
01707 ISC_LIST_APPEND(view->rootexclude[hash], new, link);
01708 else
01709 isc_mem_put(view->mctx, new, sizeof(*new));
01710 return (result);
01711 }
01712
01713 isc_boolean_t
01714 dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
01715 dns_name_t *new;
01716 isc_uint32_t hash;
01717
01718 REQUIRE(DNS_VIEW_VALID(view));
01719
01720 if (!view->rootdelonly && view->delonly == NULL)
01721 return (ISC_FALSE);
01722
01723 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
01724 if (view->rootdelonly && dns_name_countlabels(name) <= 2) {
01725 if (view->rootexclude == NULL)
01726 return (ISC_TRUE);
01727 new = ISC_LIST_HEAD(view->rootexclude[hash]);
01728 while (new != NULL && !dns_name_equal(new, name))
01729 new = ISC_LIST_NEXT(new, link);
01730 if (new == NULL)
01731 return (ISC_TRUE);
01732 }
01733
01734 if (view->delonly == NULL)
01735 return (ISC_FALSE);
01736
01737 new = ISC_LIST_HEAD(view->delonly[hash]);
01738 while (new != NULL && !dns_name_equal(new, name))
01739 new = ISC_LIST_NEXT(new, link);
01740 if (new == NULL)
01741 return (ISC_FALSE);
01742 return (ISC_TRUE);
01743 }
01744
01745 void
01746 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
01747 REQUIRE(DNS_VIEW_VALID(view));
01748 view->rootdelonly = value;
01749 }
01750
01751 isc_boolean_t
01752 dns_view_getrootdelonly(dns_view_t *view) {
01753 REQUIRE(DNS_VIEW_VALID(view));
01754 return (view->rootdelonly);
01755 }
01756
01757 isc_result_t
01758 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
01759
01760 REQUIRE(DNS_VIEW_VALID(view));
01761 REQUIRE(view->zonetable != NULL);
01762
01763 return (dns_zt_freezezones(view->zonetable, value));
01764 }
01765
01766 void
01767 dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) {
01768 REQUIRE(DNS_VIEW_VALID(view));
01769 REQUIRE(!view->frozen);
01770 REQUIRE(view->adbstats == NULL);
01771
01772 isc_stats_attach(stats, &view->adbstats);
01773 }
01774
01775 void
01776 dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) {
01777 REQUIRE(DNS_VIEW_VALID(view));
01778 REQUIRE(statsp != NULL && *statsp == NULL);
01779
01780 if (view->adbstats != NULL)
01781 isc_stats_attach(view->adbstats, statsp);
01782 }
01783
01784 void
01785 dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
01786
01787 REQUIRE(DNS_VIEW_VALID(view));
01788 REQUIRE(!view->frozen);
01789 REQUIRE(view->resstats == NULL);
01790
01791 isc_stats_attach(stats, &view->resstats);
01792 }
01793
01794 void
01795 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
01796 REQUIRE(DNS_VIEW_VALID(view));
01797 REQUIRE(statsp != NULL && *statsp == NULL);
01798
01799 if (view->resstats != NULL)
01800 isc_stats_attach(view->resstats, statsp);
01801 }
01802
01803 void
01804 dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
01805 REQUIRE(DNS_VIEW_VALID(view));
01806 REQUIRE(!view->frozen);
01807 REQUIRE(view->resquerystats == NULL);
01808
01809 dns_stats_attach(stats, &view->resquerystats);
01810 }
01811
01812 void
01813 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
01814 REQUIRE(DNS_VIEW_VALID(view));
01815 REQUIRE(statsp != NULL && *statsp == NULL);
01816
01817 if (view->resquerystats != NULL)
01818 dns_stats_attach(view->resquerystats, statsp);
01819 }
01820
01821 isc_result_t
01822 dns_view_initntatable(dns_view_t *view,
01823 isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr)
01824 {
01825 REQUIRE(DNS_VIEW_VALID(view));
01826 if (view->ntatable_priv != NULL)
01827 dns_ntatable_detach(&view->ntatable_priv);
01828 return (dns_ntatable_create(view, taskmgr, timermgr,
01829 &view->ntatable_priv));
01830 }
01831
01832 isc_result_t
01833 dns_view_getntatable(dns_view_t *view, dns_ntatable_t **ntp) {
01834 REQUIRE(DNS_VIEW_VALID(view));
01835 REQUIRE(ntp != NULL && *ntp == NULL);
01836 if (view->ntatable_priv == NULL)
01837 return (ISC_R_NOTFOUND);
01838 dns_ntatable_attach(view->ntatable_priv, ntp);
01839 return (ISC_R_SUCCESS);
01840 }
01841
01842 isc_result_t
01843 dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
01844 REQUIRE(DNS_VIEW_VALID(view));
01845 if (view->secroots_priv != NULL)
01846 dns_keytable_detach(&view->secroots_priv);
01847 return (dns_keytable_create(mctx, &view->secroots_priv));
01848 }
01849
01850 isc_result_t
01851 dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) {
01852 REQUIRE(DNS_VIEW_VALID(view));
01853 REQUIRE(ktp != NULL && *ktp == NULL);
01854 if (view->secroots_priv == NULL)
01855 return (ISC_R_NOTFOUND);
01856 dns_keytable_attach(view->secroots_priv, ktp);
01857 return (ISC_R_SUCCESS);
01858 }
01859
01860 isc_boolean_t
01861 dns_view_ntacovers(dns_view_t *view, isc_stdtime_t now,
01862 dns_name_t *name, dns_name_t *anchor)
01863 {
01864 REQUIRE(DNS_VIEW_VALID(view));
01865
01866 if (view->ntatable_priv == NULL)
01867 return (ISC_FALSE);
01868
01869 return (dns_ntatable_covered(view->ntatable_priv, now, name, anchor));
01870 }
01871
01872 isc_result_t
01873 dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
01874 isc_stdtime_t now, isc_boolean_t checknta,
01875 isc_boolean_t *secure_domain)
01876 {
01877 isc_result_t result;
01878 isc_boolean_t secure = ISC_FALSE;
01879 dns_fixedname_t fn;
01880 dns_name_t *anchor;
01881
01882 REQUIRE(DNS_VIEW_VALID(view));
01883
01884 if (view->secroots_priv == NULL)
01885 return (ISC_R_NOTFOUND);
01886
01887 dns_fixedname_init(&fn);
01888 anchor = dns_fixedname_name(&fn);
01889
01890 result = dns_keytable_issecuredomain(view->secroots_priv, name,
01891 anchor, &secure);
01892 if (result != ISC_R_SUCCESS)
01893 return (result);
01894
01895 if (checknta && secure && view->ntatable_priv != NULL &&
01896 dns_ntatable_covered(view->ntatable_priv, now, name, anchor))
01897 secure = ISC_FALSE;
01898
01899 *secure_domain = secure;
01900 return (ISC_R_SUCCESS);
01901 }
01902
01903 void
01904 dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
01905 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
01906 {
01907 isc_result_t result;
01908 unsigned char data[4096];
01909 dns_rdata_t rdata = DNS_RDATA_INIT;
01910 isc_buffer_t buffer;
01911 dst_key_t *key = NULL;
01912 dns_keytable_t *sr = NULL;
01913
01914
01915
01916
01917
01918 dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
01919
01920
01921 isc_buffer_init(&buffer, data, sizeof(data));
01922 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
01923 dns_rdatatype_dnskey, dnskey, &buffer);
01924 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
01925 if (result != ISC_R_SUCCESS)
01926 return;
01927 result = dns_view_getsecroots(view, &sr);
01928 if (result == ISC_R_SUCCESS) {
01929 dns_keytable_deletekeynode(sr, key);
01930 dns_keytable_detach(&sr);
01931 }
01932 dst_key_free(&key);
01933 }
01934
01935 void
01936 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
01937 void (*cfg_destroy)(void **))
01938 {
01939 REQUIRE(DNS_VIEW_VALID(view));
01940 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
01941
01942 if (view->new_zone_file != NULL) {
01943 isc_mem_free(view->mctx, view->new_zone_file);
01944 view->new_zone_file = NULL;
01945 }
01946
01947 if (view->new_zone_config != NULL) {
01948 view->cfg_destroy(&view->new_zone_config);
01949 view->cfg_destroy = NULL;
01950 }
01951
01952 if (allow) {
01953 isc_result_t result;
01954 char buffer[1024];
01955
01956 result = isc_file_sanitize(NULL, view->name, "nzf",
01957 buffer, sizeof(buffer));
01958 if (result == ISC_R_SUCCESS) {
01959 view->new_zone_file = isc_mem_strdup(view->mctx,
01960 buffer);
01961 view->new_zone_config = cfgctx;
01962 view->cfg_destroy = cfg_destroy;
01963 }
01964 }
01965 }
01966
01967 isc_result_t
01968 dns_view_searchdlz(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
01969 dns_clientinfomethods_t *methods,
01970 dns_clientinfo_t *clientinfo,
01971 dns_db_t **dbp)
01972 {
01973 dns_fixedname_t fname;
01974 dns_name_t *zonename;
01975 unsigned int namelabels;
01976 unsigned int i;
01977 isc_result_t result;
01978 dns_dlzfindzone_t findzone;
01979 dns_dlzdb_t *dlzdb;
01980 dns_db_t *db, *best = NULL;
01981
01982
01983
01984
01985 REQUIRE(DNS_VIEW_VALID(view));
01986 REQUIRE(name != NULL);
01987 REQUIRE(dbp != NULL && *dbp == NULL);
01988
01989
01990 dns_fixedname_init(&fname);
01991 zonename = dns_fixedname_name(&fname);
01992
01993
01994 namelabels = dns_name_countlabels(name);
01995
01996 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
01997 dlzdb != NULL;
01998 dlzdb = ISC_LIST_NEXT(dlzdb, link))
01999 {
02000 REQUIRE(DNS_DLZ_VALID(dlzdb));
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012 for (i = namelabels; i > minlabels && i > 1; i--) {
02013 if (i == namelabels) {
02014 result = dns_name_copy(name, zonename, NULL);
02015 if (result != ISC_R_SUCCESS)
02016 return (result);
02017 } else
02018 dns_name_split(name, i, NULL, zonename);
02019
02020
02021 db = NULL;
02022 findzone = dlzdb->implementation->methods->findzone;
02023 result = (*findzone)(dlzdb->implementation->driverarg,
02024 dlzdb->dbdata, dlzdb->mctx,
02025 view->rdclass, zonename,
02026 methods, clientinfo, &db);
02027
02028 if (result != ISC_R_NOTFOUND) {
02029 if (best != NULL)
02030 dns_db_detach(&best);
02031 if (result == ISC_R_SUCCESS) {
02032 INSIST(db != NULL);
02033 dns_db_attach(db, &best);
02034 dns_db_detach(&db);
02035 minlabels = i;
02036 } else {
02037 if (db != NULL)
02038 dns_db_detach(&db);
02039 break;
02040 }
02041 } else if (db != NULL)
02042 dns_db_detach(&db);
02043 }
02044 }
02045
02046 if (best != NULL) {
02047 dns_db_attach(best, dbp);
02048 dns_db_detach(&best);
02049 return (ISC_R_SUCCESS);
02050 }
02051
02052 return (ISC_R_NOTFOUND);
02053 }
02054
02055 isc_uint32_t
02056 dns_view_getfailttl(dns_view_t *view) {
02057 REQUIRE(DNS_VIEW_VALID(view));
02058 return (view->fail_ttl);
02059 }
02060
02061 void
02062 dns_view_setfailttl(dns_view_t *view, isc_uint32_t fail_ttl) {
02063 REQUIRE(DNS_VIEW_VALID(view));
02064 view->fail_ttl = fail_ttl;
02065 }
02066
02067 isc_result_t
02068 dns_view_saventa(dns_view_t *view) {
02069 isc_result_t result;
02070 isc_boolean_t removefile = ISC_FALSE;
02071 dns_ntatable_t *ntatable = NULL;
02072 FILE *fp = NULL;
02073
02074 REQUIRE(DNS_VIEW_VALID(view));
02075
02076 if (view->nta_lifetime == 0)
02077 return (ISC_R_SUCCESS);
02078
02079
02080 CHECK(isc_stdio_open(view->nta_file, "w", &fp));
02081
02082 result = dns_view_getntatable(view, &ntatable);
02083 if (result == ISC_R_NOTFOUND) {
02084 removefile = ISC_TRUE;
02085 result = ISC_R_SUCCESS;
02086 goto cleanup;
02087 } else
02088 CHECK(result);
02089
02090 result = dns_ntatable_save(ntatable, fp);
02091 if (result == ISC_R_NOTFOUND) {
02092 removefile = ISC_TRUE;
02093 result = ISC_R_SUCCESS;
02094 }
02095
02096 cleanup:
02097 if (ntatable != NULL)
02098 dns_ntatable_detach(&ntatable);
02099
02100 if (fp != NULL)
02101 isc_stdio_close(fp);
02102
02103
02104 if (result != ISC_R_SUCCESS || removefile)
02105 (void) isc_file_remove(view->nta_file);
02106
02107 return (result);
02108 }
02109
02110 #define TSTR(t) ((t).value.as_textregion.base)
02111 #define TLEN(t) ((t).value.as_textregion.length)
02112
02113 isc_result_t
02114 dns_view_loadnta(dns_view_t *view) {
02115 isc_result_t result;
02116 dns_ntatable_t *ntatable = NULL;
02117 isc_lex_t *lex = NULL;
02118 isc_token_t token;
02119 isc_stdtime_t now;
02120
02121 REQUIRE(DNS_VIEW_VALID(view));
02122
02123 if (view->nta_lifetime == 0)
02124 return (ISC_R_SUCCESS);
02125
02126 CHECK(isc_lex_create(view->mctx, 1025, &lex));
02127 CHECK(isc_lex_openfile(lex, view->nta_file));
02128 CHECK(dns_view_getntatable(view, &ntatable));
02129 isc_stdtime_get(&now);
02130
02131 for (;;) {
02132 int options = (ISC_LEXOPT_EOL | ISC_LEXOPT_EOF);
02133 char *name, *type, *timestamp;
02134 size_t len;
02135 dns_fixedname_t fn;
02136 dns_name_t *ntaname;
02137 isc_buffer_t b;
02138 isc_stdtime_t t;
02139 isc_boolean_t forced;
02140
02141 CHECK(isc_lex_gettoken(lex, options, &token));
02142 if (token.type == isc_tokentype_eof)
02143 break;
02144 else if (token.type != isc_tokentype_string)
02145 CHECK(ISC_R_UNEXPECTEDTOKEN);
02146 name = TSTR(token);
02147 len = TLEN(token);
02148
02149 if (strcmp(name, ".") == 0)
02150 ntaname = dns_rootname;
02151 else {
02152 dns_fixedname_init(&fn);
02153 ntaname = dns_fixedname_name(&fn);
02154
02155 isc_buffer_init(&b, name, (unsigned int)len);
02156 isc_buffer_add(&b, (unsigned int)len);
02157 CHECK(dns_name_fromtext(ntaname, &b, dns_rootname,
02158 0, NULL));
02159 }
02160
02161 CHECK(isc_lex_gettoken(lex, options, &token));
02162 if (token.type != isc_tokentype_string)
02163 CHECK(ISC_R_UNEXPECTEDTOKEN);
02164 type = TSTR(token);
02165
02166 if (strcmp(type, "regular") == 0)
02167 forced = ISC_FALSE;
02168 else if (strcmp(type, "forced") == 0)
02169 forced = ISC_TRUE;
02170 else
02171 CHECK(ISC_R_UNEXPECTEDTOKEN);
02172
02173 CHECK(isc_lex_gettoken(lex, options, &token));
02174 if (token.type != isc_tokentype_string)
02175 CHECK(ISC_R_UNEXPECTEDTOKEN);
02176 timestamp = TSTR(token);
02177 CHECK(dns_time32_fromtext(timestamp, &t));
02178
02179 CHECK(isc_lex_gettoken(lex, options, &token));
02180 if (token.type != isc_tokentype_eol &&
02181 token.type != isc_tokentype_eof)
02182 CHECK(ISC_R_UNEXPECTEDTOKEN);
02183
02184 if (now <= t) {
02185 if (t > (now + 604800))
02186 t = now + 604800;
02187
02188 (void) dns_ntatable_add(ntatable, ntaname,
02189 forced, 0, t);
02190 }
02191 };
02192
02193 cleanup:
02194 if (ntatable != NULL)
02195 dns_ntatable_detach(&ntatable);
02196
02197 if (lex != NULL) {
02198 isc_lex_close(lex);
02199 isc_lex_destroy(&lex);
02200 }
02201
02202 return (result);
02203 }