diff options
Diffstat (limited to 'lib/dns/zone.c')
-rw-r--r-- | lib/dns/zone.c | 267 |
1 files changed, 188 insertions, 79 deletions
diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c212bf68490b6..c2aeabc1dd356 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -427,6 +427,7 @@ struct dns_unreachable { isc_sockaddr_t local; isc_uint32_t expire; isc_uint32_t last; + isc_uint32_t count; }; struct dns_zonemgr { @@ -438,7 +439,8 @@ struct dns_zonemgr { isc_socketmgr_t * socketmgr; isc_taskpool_t * zonetasks; isc_task_t * task; - isc_ratelimiter_t * rl; + isc_ratelimiter_t * notifyrl; + isc_ratelimiter_t * refreshrl; isc_rwlock_t rwlock; isc_mutex_t iolock; isc_rwlock_t urlock; @@ -686,8 +688,6 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, dns_diff_t *diff); static void zone_rekey(dns_zone_t *zone); -static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, - dst_key_t **keys, unsigned int nkeys); #define ENTER zone_debuglog(zone, me, 1, "enter") @@ -1431,6 +1431,18 @@ dns_zone_get_rpz(dns_zone_t *zone) { return (zone->is_rpz); } +/* + * If a zone is a response policy zone, mark its new database. + */ +isc_result_t +dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { +#ifdef BIND9 + if (zone->is_rpz) + return (dns_db_rpz_enabled(db, NULL)); +#endif + return (ISC_R_SUCCESS); +} + static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { isc_result_t result; @@ -1679,9 +1691,7 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { result = dns_master_loadfileinc3(load->zone->masterfile, dns_db_origin(load->db), dns_db_origin(load->db), - load->zone->rdclass, - options, - load->zone->sigresigninginterval, + load->zone->rdclass, options, 0, &load->callbacks, task, zone_loaddone, load, &load->zone->lctx, load->zone->mctx, @@ -1715,12 +1725,17 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { + const dns_master_style_t *output_style; + dns_db_currentversion(zone->db, &version); + if (zone->type == dns_zone_key) + output_style = &dns_master_style_keyzone; + else + output_style = &dns_master_style_default; result = dns_master_dumpinc2(zone->mctx, zone->db, version, - &dns_master_style_default, - zone->masterfile, zone->task, - dump_done, zone, &zone->dctx, - zone->masterformat); + output_style, zone->masterfile, + zone->task, dump_done, zone, + &zone->dctx, zone->masterformat); dns_db_closeversion(zone->db, &version, ISC_FALSE); } else result = ISC_R_CANCELED; @@ -1741,14 +1756,9 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; -#ifdef BIND9 - if (zone->is_rpz) { - result = dns_db_rpz_enabled(db, NULL); - if (result != ISC_R_SUCCESS) - return (result); - } -#endif - + result = dns_zone_rpz_enable_db(zone, db); + if (result != ISC_R_SUCCESS) + return (result); options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; @@ -1795,9 +1805,8 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { return (result); result = dns_master_loadfile3(zone->masterfile, &zone->origin, &zone->origin, zone->rdclass, - options, zone->sigresigninginterval, - &callbacks, zone->mctx, - zone->masterformat); + options, 0, &callbacks, + zone->mctx, zone->masterformat); tresult = dns_db_endload(db, &callbacks.add_private); if (result == ISC_R_SUCCESS) result = tresult; @@ -2230,7 +2239,7 @@ isspf(const dns_rdata_t *rdata) { INSIST(tl <= rdl); if (len > sizeof(buf) - i - 1) len = sizeof(buf) - i - 1; - memcpy(buf + i, data, len); + memmove(buf + i, data, len); i += len; data += tl; rdl -= tl; @@ -2552,7 +2561,7 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { nsec3chain->nsec3param.iterations = nsec3param->iterations; nsec3chain->nsec3param.flags = nsec3param->flags; nsec3chain->nsec3param.salt_length = nsec3param->salt_length; - memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); + memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); nsec3chain->nsec3param.salt = nsec3chain->salt; nsec3chain->seen_nsec = ISC_FALSE; nsec3chain->delete_nsec = ISC_FALSE; @@ -2701,20 +2710,35 @@ set_resigntime(dns_zone_t *zone) { unsigned int resign; isc_result_t result; isc_uint32_t nanosecs; + dns_db_t *db = NULL; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); - result = dns_db_getsigningtime(zone->db, &rdataset, + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) { + isc_time_settoepoch(&zone->resigntime); + return; + } + + result = dns_db_getsigningtime(db, &rdataset, dns_fixedname_name(&fixed)); if (result != ISC_R_SUCCESS) { isc_time_settoepoch(&zone->resigntime); - return; + goto cleanup; } - resign = rdataset.resign; + + resign = rdataset.resign - zone->sigresigninginterval; dns_rdataset_disassociate(&rdataset); isc_random_get(&nanosecs); nanosecs %= 1000000000; isc_time_set(&zone->resigntime, resign, nanosecs); + cleanup: + dns_db_detach(&db); + return; } static isc_result_t @@ -3057,6 +3081,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { /* Convert rdata to keydata. */ result = dns_rdata_tostruct(&rdata, &keydata, NULL); + if (result == ISC_R_UNEXPECTEDEND) + continue; RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Set the key refresh timer. */ @@ -3110,7 +3136,6 @@ do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); - temp_diff.resign = diff->resign; ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); /* @@ -3501,8 +3526,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, else options = 0; result = dns_journal_rollforward2(zone->mctx, db, options, - zone->sigresigninginterval, - zone->journal); + 0, zone->journal); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && result != ISC_R_RANGE) { @@ -3759,7 +3783,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, dns_zone_log(zone, ISC_LOG_DEBUG(3), "next resign: %s/%s in %d seconds", namebuf, typebuf, - next.resign - timenow); + next.resign - timenow - + zone->sigresigninginterval); dns_rdataset_disassociate(&next); } else dns_zone_log(zone, ISC_LOG_WARNING, @@ -4407,7 +4432,7 @@ dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, UNLOCK_ZONE(zone); return (ISC_R_NOMEMORY); } - memcpy(new, notify, count * sizeof(*new)); + memmove(new, notify, count * sizeof(*new)); zone->notify = new; zone->notifycnt = count; } @@ -4529,7 +4554,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, result = ISC_R_NOMEMORY; goto unlock; } - memcpy(new, masters, count * sizeof(*new)); + memmove(new, masters, count * sizeof(*new)); /* * Similarly for mastersok. @@ -4736,19 +4761,39 @@ set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) * have no new key. */ static isc_boolean_t -delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { +delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, + isc_boolean_t *warn) +{ unsigned int i = 0; + isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE; + isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE; - /* - * It's okay to delete a signature if there is an active ZSK - * with the same algorithm - */ for (i = 0; i < nkeys; i++) { - if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) && - (dst_key_isprivate(keys[i])) && !KSK(keys[i])) - return (ISC_TRUE); + if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) + continue; + if (dst_key_isprivate(keys[i])) { + if (KSK(keys[i])) + have_ksk = have_pksk = ISC_TRUE; + else + have_zsk = have_pzsk = ISC_TRUE; + } else { + if (KSK(keys[i])) + have_ksk = ISC_TRUE; + else + have_zsk = ISC_TRUE; + } } + if (have_zsk && have_ksk && !have_pzsk) + *warn = ISC_TRUE; + + /* + * It's okay to delete a signature if there is an active key + * with the same algorithm to replace it. + */ + if (have_pksk || have_pzsk) + return (ISC_TRUE); + /* * Failing that, it is *not* okay to delete a signature * if the associated public key is still in the DNSKEY RRset @@ -4816,7 +4861,8 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, RUNTIME_CHECK(result == ISC_R_SUCCESS); if (type != dns_rdatatype_dnskey) { - if (delsig_ok(&rrsig, keys, nkeys)) { + isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE; + if (delsig_ok(&rrsig, keys, nkeys, &warn)) { result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); @@ -4824,7 +4870,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, changed = ISC_TRUE; if (result != ISC_R_SUCCESS) break; - } else { + deleted = ISC_TRUE; + } + if (warn) { /* * At this point, we've got an RRSIG, * which is signed by an inactive key. @@ -4834,7 +4882,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * offline will prevent us spinning waiting * for the private part. */ - if (incremental) { + if (incremental && !deleted) { result = offline(db, ver, zonediff, name, rdataset.ttl, &rdata); @@ -4882,7 +4930,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * We want the earliest offline expire time * iff there is a new offline signature. */ - if (!dst_key_isprivate(keys[i])) { + if (!dst_key_inactive(keys[i]) && + !dst_key_isprivate(keys[i])) + { isc_int64_t timeexpire = dns_time64_from32(rrsig.timeexpire); if (warn != 0 && warn > timeexpire) @@ -4900,6 +4950,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, result = offline(db, ver, zonediff, name, rdataset.ttl, &rdata); + changed = ISC_TRUE; break; } result = update_one_rr(db, ver, zonediff->diff, @@ -5068,7 +5119,6 @@ zone_resigninc(dns_zone_t *zone) { dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); dns_diff_init(zone->mctx, &_sig_diff); - _sig_diff.resign = zone->sigresigninginterval; zonediff_init(&zonediff, &_sig_diff); /* @@ -5125,7 +5175,7 @@ zone_resigninc(dns_zone_t *zone) { i = 0; while (result == ISC_R_SUCCESS) { - resign = rdataset.resign; + resign = rdataset.resign - zone->sigresigninginterval; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); @@ -5987,7 +6037,6 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_init(zone->mctx, &nsec3_diff); dns_diff_init(zone->mctx, &nsec_diff); dns_diff_init(zone->mctx, &_sig_diff); - _sig_diff.resign = zone->sigresigninginterval; zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); @@ -6831,7 +6880,6 @@ zone_sign(dns_zone_t *zone) { dns_fixedname_init(&nextfixed); nextname = dns_fixedname_name(&nextfixed); dns_diff_init(zone->mctx, &_sig_diff); - _sig_diff.resign = zone->sigresigninginterval; dns_diff_init(zone->mctx, &post_diff); zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); @@ -7264,7 +7312,7 @@ zone_sign(dns_zone_t *zone) { isc_time_settoepoch(&zone->signingtime); } -static void +static isc_result_t normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, int size) { dns_rdata_dnskey_t dnskey; @@ -7285,6 +7333,8 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target, break; case dns_rdatatype_keydata: result = dns_rdata_tostruct(rr, &keydata, NULL); + if (result == ISC_R_UNEXPECTEDEND) + return (result); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_todnskey(&keydata, &dnskey, NULL); dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, @@ -7293,6 +7343,7 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target, default: INSIST(0); } + return (ISC_R_SUCCESS); } /* @@ -7316,14 +7367,18 @@ matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { dns_rdata_init(&rdata1); dns_rdata_init(&rdata2); - normalize_key(rr, &rdata1, data1, sizeof(data1)); + result = normalize_key(rr, &rdata1, data1, sizeof(data1)); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdset, &rdata); - normalize_key(&rdata, &rdata2, data2, sizeof(data2)); + result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); + if (result != ISC_R_SUCCESS) + continue; if (dns_rdata_compare(&rdata1, &rdata2) == 0) return (ISC_TRUE); } @@ -7430,7 +7485,11 @@ minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) name, 0, &rdata)); /* Update refresh timer */ - CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL)); + result = dns_rdata_tostruct(&rdata, &keydata, NULL); + if (result == ISC_R_UNEXPECTEDEND) + continue; + if (result != ISC_R_SUCCESS) + goto failure; keydata.refresh = refresh_time(kfetch, ISC_TRUE); set_refreshkeytimer(zone, &keydata, now); @@ -7581,7 +7640,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { INSIST(result == ISC_R_SUCCESS); dns_diff_init(mctx, &diff); - diff.resign = zone->sigresigninginterval; CHECK(dns_db_newversion(kfetch->db, &ver)); @@ -8605,10 +8663,16 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { result = DNS_R_CONTINUE; UNLOCK_ZONE(zone); } else { + const dns_master_style_t *output_style; + + if (zone->type == dns_zone_key) + output_style = &dns_master_style_keyzone; + else + output_style = &dns_master_style_default; dns_db_currentversion(db, &version); result = dns_master_dump2(zone->mctx, db, version, - &dns_master_style_default, - masterfile, masterformat); + output_style, masterfile, + masterformat); dns_db_closeversion(db, &version, ISC_FALSE); } fail: @@ -8988,7 +9052,7 @@ notify_send_queue(dns_notify_t *notify) { return (ISC_R_NOMEMORY); e->ev_arg = notify; e->ev_sender = NULL; - result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, + result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, notify->zone->task, &e); if (result != ISC_R_SUCCESS) isc_event_free(&e); @@ -10112,7 +10176,7 @@ queue_soa_query(dns_zone_t *zone) { e->ev_arg = zone; e->ev_sender = NULL; - result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e); + result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); if (result != ISC_R_SUCCESS) { zone_idetach(&dummy); isc_event_free(&e); @@ -10812,10 +10876,10 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { isc_time_compare(&zone->refreshtime, &next) < 0) next = zone->refreshtime; } - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - INSIST(!isc_time_isepoch(&zone->expiretime)); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && + !isc_time_isepoch(&zone->expiretime)) { if (isc_time_isepoch(&next) || - isc_time_compare(&zone->expiretime, &next) < 0) + isc_time_compare(&zone->expiretime, &next) < 0) next = zone->expiretime; } if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && @@ -11467,7 +11531,7 @@ zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { /* * Leave space for terminating '\0'. */ - isc_buffer_init(&buffer, buf, length - 1); + isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (dns_name_dynamic(&zone->origin)) result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); if (result != ISC_R_SUCCESS && @@ -11499,7 +11563,7 @@ zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { /* * Leave space for terminating '\0'. */ - isc_buffer_init(&buffer, buf, length - 1); + isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (dns_name_dynamic(&zone->origin)) result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); if (result != ISC_R_SUCCESS && @@ -11519,7 +11583,7 @@ zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { /* * Leave space for terminating '\0'. */ - isc_buffer_init(&buffer, buf, length - 1); + isc_buffer_init(&buffer, buf, (unsigned int)length - 1); (void)dns_rdataclass_totext(zone->rdclass, &buffer); buf[isc_buffer_usedlength(&buffer)] = '\0'; @@ -11536,7 +11600,7 @@ zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { /* * Leave space for terminating '\0'. */ - isc_buffer_init(&buffer, buf, length - 1); + isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (zone->view == NULL) { isc_buffer_putstr(&buffer, "_none"); @@ -12335,9 +12399,18 @@ dns_zone_getsigvalidityinterval(dns_zone_t *zone) { void dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { + isc_time_t now; + REQUIRE(DNS_ZONE_VALID(zone)); + LOCK_ZONE(zone); zone->sigresigninginterval = interval; + set_resigntime(zone); + if (zone->task != NULL) { + TIME_NOW(&now); + zone_settimer(zone, &now); + } + UNLOCK_ZONE(zone); } isc_uint32_t @@ -12658,8 +12731,18 @@ forward_callback(isc_task_t *task, isc_event_t *event) { case dns_rcode_yxrrset: case dns_rcode_nxrrset: case dns_rcode_refused: - case dns_rcode_nxdomain: + case dns_rcode_nxdomain: { + char rcode[128]; + isc_buffer_t rb; + + isc_buffer_init(&rb, rcode, sizeof(rcode)); + (void)dns_rcode_totext(msg->rcode, &rb); + dns_zone_log(zone, ISC_LOG_INFO, + "forwarded dynamic update: " + "master %s returned: %.*s", + master, (int)rb.used, rcode); break; + } /* These should not occur if the masters/zone are valid. */ case dns_rcode_notzone: @@ -12807,7 +12890,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, zmgr->socketmgr = socketmgr; zmgr->zonetasks = NULL; zmgr->task = NULL; - zmgr->rl = NULL; + zmgr->notifyrl = NULL; + zmgr->refreshrl = NULL; ISC_LIST_INIT(zmgr->zones); ISC_LIST_INIT(zmgr->waiting_for_xfrin); ISC_LIST_INIT(zmgr->xfrin_in_progress); @@ -12831,15 +12915,24 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_task_setname(zmgr->task, "zmgr", zmgr); result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, - &zmgr->rl); + &zmgr->notifyrl); if (result != ISC_R_SUCCESS) goto free_task; + result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, + &zmgr->refreshrl); + if (result != ISC_R_SUCCESS) + goto free_notifyrl; + /* default to 20 refresh queries / notifies per second. */ isc_interval_set(&interval, 0, 1000000000/2); - result = isc_ratelimiter_setinterval(zmgr->rl, &interval); + result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_ratelimiter_setpertic(zmgr->notifyrl, 10); + + result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval); RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_ratelimiter_setpertic(zmgr->rl, 10); + isc_ratelimiter_setpertic(zmgr->refreshrl, 10); zmgr->iolimit = 1; zmgr->ioactive = 0; @@ -12848,7 +12941,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, result = isc_mutex_init(&zmgr->iolock); if (result != ISC_R_SUCCESS) - goto free_rl; + goto free_refreshrl; zmgr->magic = ZONEMGR_MAGIC; @@ -12859,8 +12952,10 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, free_iolock: DESTROYLOCK(&zmgr->iolock); #endif - free_rl: - isc_ratelimiter_detach(&zmgr->rl); + free_refreshrl: + isc_ratelimiter_detach(&zmgr->refreshrl); + free_notifyrl: + isc_ratelimiter_detach(&zmgr->notifyrl); free_task: isc_task_detach(&zmgr->task); free_urlock: @@ -13028,7 +13123,8 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); - isc_ratelimiter_shutdown(zmgr->rl); + isc_ratelimiter_shutdown(zmgr->notifyrl); + isc_ratelimiter_shutdown(zmgr->refreshrl); if (zmgr->task != NULL) isc_task_destroy(&zmgr->task); @@ -13086,7 +13182,8 @@ zonemgr_free(dns_zonemgr_t *zmgr) { zmgr->magic = 0; DESTROYLOCK(&zmgr->iolock); - isc_ratelimiter_detach(&zmgr->rl); + isc_ratelimiter_detach(&zmgr->notifyrl); + isc_ratelimiter_detach(&zmgr->refreshrl); isc_rwlock_destroy(&zmgr->urlock); isc_rwlock_destroy(&zmgr->rwlock); @@ -13475,9 +13572,14 @@ dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { } isc_interval_set(&interval, s, ns); - result = isc_ratelimiter_setinterval(zmgr->rl, &interval); + + result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_ratelimiter_setpertic(zmgr->notifyrl, pertic); + + result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval); RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_ratelimiter_setpertic(zmgr->rl, pertic); + isc_ratelimiter_setpertic(zmgr->refreshrl, pertic); zmgr->serialqueryrate = value; } @@ -13497,6 +13599,7 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_rwlocktype_t locktype; isc_result_t result; isc_uint32_t seconds = isc_time_seconds(now); + isc_uint32_t count = 0; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); @@ -13510,12 +13613,13 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].last = seconds; + count = zmgr->unreachable[i].count; } break; } } RWUNLOCK(&zmgr->urlock, locktype); - return (ISC_TF(i < UNREACH_CHACHE_SIZE)); + return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U)); } void @@ -13589,6 +13693,10 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, */ zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; zmgr->unreachable[i].last = seconds; + if (zmgr->unreachable[i].expire < seconds) + zmgr->unreachable[i].count = 1; + else + zmgr->unreachable[i].count++; } else if (slot != UNREACH_CHACHE_SIZE) { /* * Found a empty slot. Add a new entry to the cache. @@ -13597,6 +13705,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, zmgr->unreachable[slot].last = seconds; zmgr->unreachable[slot].remote = *remote; zmgr->unreachable[slot].local = *local; + zmgr->unreachable[slot].count = 1; } else { /* * Replace the least recently used entry in the cache. @@ -13605,6 +13714,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, zmgr->unreachable[oldest].last = seconds; zmgr->unreachable[oldest].remote = *remote; zmgr->unreachable[oldest].local = *local; + zmgr->unreachable[oldest].count = 1; } RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); } @@ -14453,7 +14563,6 @@ zone_rekey(dns_zone_t *zone) { mctx = zone->mctx; dns_diff_init(mctx, &diff); dns_diff_init(mctx, &_sig_diff); - _sig_diff.resign = zone->sigresigninginterval; zonediff_init(&zonediff, &_sig_diff); CHECK(dns_zone_getdb(zone, &db)); |