diff options
Diffstat (limited to 'lib/dns/zone.c')
-rw-r--r-- | lib/dns/zone.c | 81 |
1 files changed, 56 insertions, 25 deletions
diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 108aefbd9b4a..606c59b28b89 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,12 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.483.36.23 2010-12-14 00:48:22 marka Exp $ */ +/* $Id: zone.c,v 1.483.36.33 2011-07-21 06:23:20 marka Exp $ */ /*! \file */ #include <config.h> #include <errno.h> +#include <stdlib.h> #include <isc/file.h> #include <isc/mutex.h> @@ -1326,6 +1327,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { isc_time_t now; isc_time_t loadtime, filetime; dns_db_t *db = NULL; + isc_boolean_t rbt; REQUIRE(DNS_ZONE_VALID(zone)); @@ -1341,14 +1343,15 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } - if (zone->db != NULL && zone->masterfile == NULL) { + + INSIST(zone->db_argc >= 1); + + rbt = strcmp(zone->db_argv[0], "rbt") == 0 || + strcmp(zone->db_argv[0], "rbt64") == 0; + + if (zone->db != NULL && zone->masterfile == NULL && rbt) { /* - * The zone has no master file configured, but it already - * has a database. It could be the built-in - * version.bind. CH zone, a zone with a persistent - * database being reloaded, or maybe a zone that - * used to have a master file but whose configuration - * was changed so that it no longer has one. Do nothing. + * The zone has no master file configured. */ result = ISC_R_SUCCESS; goto cleanup; @@ -1367,7 +1370,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } - /* * Store the current time before the zone is loaded, so that if the * file changes between the time of the load and the time that @@ -1407,21 +1409,20 @@ zone_load(dns_zone_t *zone, unsigned int flags) { } } - INSIST(zone->db_argc >= 1); - /* - * Built in zones don't need to be reloaded. + * Built in zones (with the exception of empty zones) don't need + * to be reloaded. */ if (zone->type == dns_zone_master && strcmp(zone->db_argv[0], "_builtin") == 0 && + (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { result = ISC_R_SUCCESS; goto cleanup; } if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && - (strcmp(zone->db_argv[0], "rbt") == 0 || - strcmp(zone->db_argv[0], "rbt64") == 0)) { + rbt) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { if (zone->masterfile != NULL) { @@ -1541,7 +1542,8 @@ get_master_options(dns_zone_t *zone) { if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; if (zone->type == dns_zone_master && - (zone->update_acl != NULL || zone->ssutable != NULL)) + ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) || + zone->ssutable != NULL)) options |= DNS_MASTER_RESIGN; return (options); } @@ -1933,8 +1935,7 @@ zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_rdataset_disassociate(&aaaa); return (answer); } - } else - tresult = result; + } dns_name_format(owner, ownerbuf, sizeof ownerbuf); dns_name_format(name, namebuf, sizeof namebuf); @@ -5325,6 +5326,7 @@ zone_nsec3chain(dns_zone_t *zone) { LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); UNLOCK_ZONE(zone); done: @@ -5527,7 +5529,7 @@ zone_sign(dns_zone_t *zone) { isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE; isc_boolean_t first; isc_result_t result; - isc_stdtime_t now, inception, soaexpire, expire, stop; + isc_stdtime_t now, inception, soaexpire, expire; isc_uint32_t jitter; unsigned int i; unsigned int nkeys = 0; @@ -5582,7 +5584,6 @@ zone_sign(dns_zone_t *zone) { */ isc_random_get(&jitter); expire = soaexpire - jitter % 3600; - stop = now + 5; check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); if (check_ksk) @@ -6098,7 +6099,8 @@ void dns_zone_markdirty(dns_zone_t *zone) { LOCK_ZONE(zone); - set_resigntime(zone); /* XXXMPA make separate call back */ + if (zone->type == dns_zone_master) + set_resigntime(zone); /* XXXMPA make separate call back */ zone_needdump(zone, DNS_DUMP_DELAY); UNLOCK_ZONE(zone); } @@ -6169,7 +6171,7 @@ dns_zone_refresh(dns_zone_t *zone) { isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 0); result = isc_time_nowplusinterval(&zone->refreshtime, &i); - if (result |= ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_WARNING, "isc_time_nowplusinterval() failed: %s", dns_result_totext(result)); @@ -7523,7 +7525,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { goto tcp_transfer; } dns_zone_log(zone, ISC_LOG_DEBUG(1), - "refresh: skipped tcp fallback" + "refresh: skipped tcp fallback " "as master %s (source %s) is " "unreachable (cached)", master, source); @@ -7704,6 +7706,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { } else zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", serial); + if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || isc_serial_gt(serial, oldserial)) { @@ -8278,6 +8281,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { * XXX Optimisation: Create message when zone is setup and reuse. */ result = create_query(zone, dns_rdatatype_ns, &message); + INSIST(result == ISC_R_SUCCESS); INSIST(zone->masterscnt > 0); INSIST(zone->curmaster < zone->masterscnt); @@ -8351,6 +8355,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { break; default: result = ISC_R_NOTIMPLEMENTED; + POST(result); goto cleanup; } timeout = 15; @@ -10472,6 +10477,28 @@ dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { return (ISC_R_SUCCESS); } +/* + * Size of the zone task table. For best results, this should be a + * prime number, approximately 1% of the maximum number of authoritative + * zones expected to be served by this server. + */ +#define DEFAULT_ZONE_TASKS 101 +static int +calculate_zone_tasks(void) { + int ntasks = DEFAULT_ZONE_TASKS; + +#ifdef HAVE_GETENV + char *env = getenv("BIND9_ZONE_TASKS_HINT"); + if (env != NULL) + ntasks = atoi(env); + + if (ntasks < DEFAULT_ZONE_TASKS) + ntasks = DEFAULT_ZONE_TASKS; +#endif + + return (ntasks); +} + /*** *** Zone manager. ***/ @@ -10484,6 +10511,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, dns_zonemgr_t *zmgr; isc_result_t result; isc_interval_t interval; + int zone_tasks = calculate_zone_tasks(); zmgr = isc_mem_get(mctx, sizeof(*zmgr)); if (zmgr == NULL) @@ -10509,11 +10537,14 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, zmgr->transfersperns = 2; /* Create the zone task pool. */ - result = isc_taskpool_create(taskmgr, mctx, - 8 /* XXX */, 2, &zmgr->zonetasks); + result = isc_taskpool_create(taskmgr, mctx, zone_tasks, 2, + &zmgr->zonetasks); if (result != ISC_R_SUCCESS) goto free_rwlock; + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, + ISC_LOG_NOTICE, "Using %d tasks for zone loading", zone_tasks); + /* Create a single task for queueing of SOA queries. */ result = isc_task_create(taskmgr, 1, &zmgr->task); if (result != ISC_R_SUCCESS) |