diff --git a/bin/delv/delv.c b/bin/delv/delv.c index e06322de11..5af7c15653 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -2117,12 +2117,13 @@ cleanup: static isc_result_t matchview(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, - dns_message_t *message, dns_aclenv_t *env, isc_result_t *sigresultp, - dns_view_t **viewp) { + dns_message_t *message, dns_aclenv_t *env, ns_server_t *lsctx, + isc_result_t *sigresultp, dns_view_t **viewp) { UNUSED(srcaddr); UNUSED(destaddr); UNUSED(message); UNUSED(env); + UNUSED(lsctx); UNUSED(sigresultp); *viewp = view; diff --git a/bin/named/config.c b/bin/named/config.c index 732e28e606..62c05a8314 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -109,6 +109,8 @@ options {\n\ # session-keyfile \"" NAMED_LOCALSTATEDIR "/run/named/session.key\";\n\ session-keyname local-ddns;\n\ startup-notify-rate 20;\n\ + sig0checks-quota 1;\n\ + sig0checks-quota-maxwait-ms 1500;\n\ statistics-file \"named.stats\";\n\ tcp-advertised-timeout 300;\n\ tcp-clients 150;\n\ diff --git a/bin/named/server.c b/bin/named/server.c index c41f5d9b24..162b556542 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8412,6 +8412,8 @@ load_configuration(const char *filename, named_server_t *server, configure_server_quota(maps, "recursive-clients", &server->sctx->recursionquota); configure_server_quota(maps, "update-quota", &server->sctx->updquota); + configure_server_quota(maps, "sig0checks-quota", + &server->sctx->sig0checksquota); max = isc_quota_getmax(&server->sctx->recursionquota); if (max > 1000) { @@ -8430,9 +8432,23 @@ load_configuration(const char *filename, named_server_t *server, } else { softquota = (max * 90) / 100; } - isc_quota_soft(&server->sctx->recursionquota, softquota); + obj = NULL; + result = named_config_get(maps, "sig0checks-quota-exempt", &obj); + if (result == ISC_R_SUCCESS) { + result = cfg_acl_fromconfig( + obj, config, named_g_lctx, named_g_aclconfctx, + named_g_mctx, 0, &server->sctx->sig0checksquota_exempt); + INSIST(result == ISC_R_SUCCESS); + } + + obj = NULL; + result = named_config_get(maps, "sig0checks-quota-maxwait-ms", &obj); + if (result == ISC_R_SUCCESS) { + server->sctx->sig0checksquota_maxwaitms = cfg_obj_asuint32(obj); + } + /* * Set "blackhole". Only legal at options level; there is * no default. @@ -10048,11 +10064,12 @@ shutdown_server(void *arg) { */ static isc_result_t get_matching_view(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, - dns_message_t *message, dns_aclenv_t *env, + dns_message_t *message, dns_aclenv_t *env, ns_server_t *sctx, isc_result_t *sigresult, dns_view_t **viewp) { dns_view_t *view; REQUIRE(message != NULL); + REQUIRE(sctx != NULL); REQUIRE(sigresult != NULL); REQUIRE(viewp != NULL && *viewp == NULL); @@ -10063,13 +10080,49 @@ get_matching_view(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, message->rdclass == dns_rdataclass_any) { const dns_name_t *tsig = NULL; + int exempt_match; + isc_result_t sig0_qresult = ISC_R_UNSET; + if (message->sig0 != NULL) { + /* + * If the message has a SIG0 signature and the + * client is not exempt from the quota, then + * acquire a quota. If quota is reached, then + * return early. + */ + if (sctx->sig0checksquota_exempt != NULL) { + isc_result_t result = dns_acl_match( + srcaddr, NULL, + sctx->sig0checksquota_exempt, + env, &exempt_match, NULL); + if (result == ISC_R_SUCCESS && + exempt_match > 0) + { + sig0_qresult = ISC_R_EXISTS; + } + } + if (sig0_qresult == ISC_R_UNSET) { + sig0_qresult = isc_quota_acquire( + &sctx->sig0checksquota); + } + if (sig0_qresult == ISC_R_SOFTQUOTA) { + isc_quota_release( + &sctx->sig0checksquota); + } + if (sig0_qresult != ISC_R_SUCCESS && + sig0_qresult != ISC_R_EXISTS) + { + return (ISC_R_QUOTA); + } + } + + /* Check the signature, then release the quota */ *sigresult = dns_message_rechecksig(message, view); + if (sig0_qresult == ISC_R_SUCCESS) { + isc_quota_release(&sctx->sig0checksquota); + } if (*sigresult == ISC_R_SUCCESS) { - dns_tsigkey_t *tsigkey; - - tsigkey = message->tsigkey; - tsig = dns_tsigkey_identity(tsigkey); + tsig = dns_tsigkey_identity(message->tsigkey); } if (dns_acl_allowed(srcaddr, tsig, view->matchclients, diff --git a/bin/tests/system/checkconf/bad-sig0checks-quota-exempt.conf b/bin/tests/system/checkconf/bad-sig0checks-quota-exempt.conf new file mode 100644 index 0000000000..c54227dd91 --- /dev/null +++ b/bin/tests/system/checkconf/bad-sig0checks-quota-exempt.conf @@ -0,0 +1,16 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + sig0checks-quota-exempt { unknownacl; }; +}; diff --git a/bin/tests/system/checkconf/good-sig0checks-quota-exempt.conf b/bin/tests/system/checkconf/good-sig0checks-quota-exempt.conf new file mode 100644 index 0000000000..2968ebefe0 --- /dev/null +++ b/bin/tests/system/checkconf/good-sig0checks-quota-exempt.conf @@ -0,0 +1,20 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +acl goodacl { + 192.168.0.1; +}; + +options { + sig0checks-quota-exempt { 10.0.0.0/8; 2001:db8::100; goodacl; }; +}; diff --git a/doc/misc/options b/doc/misc/options index de24eef2c2..d003e9e741 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -277,6 +277,9 @@ options { sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; // obsolete + sig0checks-quota ; + sig0checks-quota-exempt { ; ... }; + sig0checks-quota-maxwait-ms ; sortlist { ; ... }; // deprecated stale-answer-client-timeout ( disabled | off | ); stale-answer-enable ; diff --git a/lib/isccfg/check.c b/lib/isccfg/check.c index e0c4bdc5b8..8dd8efa934 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -2073,6 +2073,21 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config, cfg_aclconfctx_create(mctx, &actx); + obj = NULL; + (void)cfg_map_get(options, "sig0checks-quota-exempt", &obj); + if (obj != NULL) { + dns_acl_t *acl = NULL; + + tresult = cfg_acl_fromconfig(obj, config, logctx, actx, mctx, 0, + &acl); + if (acl != NULL) { + dns_acl_detach(&acl); + } + if (result == ISC_R_SUCCESS) { + result = tresult; + } + } + obj = NULL; (void)cfg_map_get(options, "listen-on", &obj); if (obj != NULL) { diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 18b40fab7f..3a27432f7e 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1361,6 +1361,9 @@ static cfg_clausedef_t options_clauses[] = { { "session-keyalg", &cfg_type_astring, 0 }, { "session-keyfile", &cfg_type_qstringornone, 0 }, { "session-keyname", &cfg_type_astring, 0 }, + { "sig0checks-quota", &cfg_type_uint32, 0 }, + { "sig0checks-quota-maxwait-ms", &cfg_type_uint32, 0 }, + { "sig0checks-quota-exempt", &cfg_type_bracketed_aml, 0 }, { "sit-secret", NULL, CFG_CLAUSEFLAG_ANCIENT }, { "stacksize", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT }, { "startup-notify-rate", &cfg_type_uint32, 0 }, diff --git a/lib/ns/client.c b/lib/ns/client.c index c1341be828..03afc4d25c 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -118,11 +118,27 @@ atomic_uint_fast64_t ns_client_requests = 0; +static atomic_uint_fast32_t last_sigchecks_quota_log = 0; + +static bool +can_log_sigchecks_quota(void) { + isc_stdtime_t last; + isc_stdtime_t now = isc_stdtime_now(); + last = atomic_exchange_relaxed(&last_sigchecks_quota_log, now); + if (now != last) { + return (true); + } + + return (false); +} + static void clientmgr_destroy_cb(void *arg); static void ns_client_dumpmessage(ns_client_t *client, const char *reason); static void +ns_client_request_continue(void *arg); +static void compute_cookie(ns_client_t *client, uint32_t when, const unsigned char *secret, isc_buffer_t *buf); @@ -1739,6 +1755,53 @@ ns__client_put_cb(void *client0) { ns_clientmgr_detach(&manager); } +static isc_result_t +ns_client_setup_view(ns_client_t *client, isc_netaddr_t *netaddr) { + isc_result_t result; + + result = client->manager->sctx->matchingview( + netaddr, &client->destaddr, client->message, + client->manager->aclenv, client->manager->sctx, + &client->sigresult, &client->view); + if (result != ISC_R_SUCCESS) { + if (result == ISC_R_QUOTA) { + if (can_log_sigchecks_quota()) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_INFO, + "SIG(0) checks quota reached"); + ns_client_dumpmessage( + client, "SIG(0) checks quota reached"); + } + } else { + char classname[DNS_RDATACLASS_FORMATSIZE]; + isc_buffer_t b; + isc_region_t *r; + + /* + * Do a dummy TSIG verification attempt so that the + * response will have a TSIG if the query did, as + * required by RFC2845. + */ + dns_message_resetsig(client->message); + r = dns_message_getrawmessage(client->message); + isc_buffer_init(&b, r->base, r->length); + isc_buffer_add(&b, r->length); + (void)dns_tsig_verify(&b, client->message, NULL, NULL); + + dns_rdataclass_format(client->message->rdclass, + classname, sizeof(classname)); + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), + "no matching view in class '%s'", + classname); + ns_client_dumpmessage(client, + "no matching view in class"); + } + } + + return (result); +} + /* * Handle an incoming request event from the socket (UDP case) * or tcpmsg (TCP case). @@ -1748,12 +1811,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *arg) { ns_client_t *client = NULL; isc_result_t result; - isc_result_t sigresult = ISC_R_SUCCESS; - isc_buffer_t *buffer = NULL; - isc_buffer_t tbuffer; dns_rdataset_t *opt = NULL; - const dns_name_t *signame = NULL; - bool ra; /* Recursion available. */ isc_netaddr_t netaddr; int match; dns_messageid_t id; @@ -1761,28 +1819,6 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, bool notimp; size_t reqsize; dns_aclenv_t *env = NULL; -#ifdef HAVE_DNSTAP - dns_transport_type_t transport_type; - dns_dtmsgtype_t dtmsgtype; -#endif /* ifdef HAVE_DNSTAP */ - static const char *ra_reasons[] = { - "ACLs not processed yet", - "no resolver in view", - "recursion not enabled for view", - "allow-recursion did not match", - "allow-query-cache did not match", - "allow-recursion-on did not match", - "allow-query-cache-on did not match", - }; - enum refusal_reasons { - INVALID, - NO_RESOLVER, - RECURSION_DISABLED, - ALLOW_RECURSION, - ALLOW_QUERY_CACHE, - ALLOW_RECURSION_ON, - ALLOW_QUERY_CACHE_ON - } ra_refusal_reason = INVALID; if (eresult != ISC_R_SUCCESS) { return; @@ -1830,14 +1866,14 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, (void)atomic_fetch_add_relaxed(&ns_client_requests, 1); - isc_buffer_init(&tbuffer, region->base, region->length); - isc_buffer_add(&tbuffer, region->length); - buffer = &tbuffer; + isc_buffer_init(&client->tbuffer, region->base, region->length); + isc_buffer_add(&client->tbuffer, region->length); + client->buffer = &client->tbuffer; client->peeraddr = isc_nmhandle_peeraddr(handle); client->peeraddr_valid = true; - reqsize = isc_buffer_usedlength(buffer); + reqsize = isc_buffer_usedlength(client->buffer); client->state = NS_CLIENTSTATE_WORKING; @@ -1876,7 +1912,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, ISC_LOG_DEBUG(3), "%s request", TCP_CLIENT(client) ? "TCP" : "UDP"); - result = dns_message_peekheader(buffer, &id, &flags); + result = dns_message_peekheader(client->buffer, &id, &flags); if (result != ISC_R_SUCCESS) { /* * There isn't enough header to determine whether @@ -1951,7 +1987,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, /* * It's a request. Parse it. */ - result = dns_message_parse(client->message, buffer, 0); + result = dns_message_parse(client->message, client->buffer, 0); if (result != ISC_R_SUCCESS) { /* * Parsing the request failed. Send a response @@ -2080,38 +2116,119 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, client->destsockaddr = isc_nmhandle_localaddr(handle); isc_netaddr_fromsockaddr(&client->destaddr, &client->destsockaddr); - result = client->manager->sctx->matchingview( - &netaddr, &client->destaddr, client->message, env, &sigresult, - &client->view); - if (result != ISC_R_SUCCESS) { - char classname[DNS_RDATACLASS_FORMATSIZE]; - - /* - * Do a dummy TSIG verification attempt so that the - * response will have a TSIG if the query did, as - * required by RFC2845. - */ - isc_buffer_t b; - isc_region_t *r; - - dns_message_resetsig(client->message); - - r = dns_message_getrawmessage(client->message); - isc_buffer_init(&b, r->base, r->length); - isc_buffer_add(&b, r->length); - (void)dns_tsig_verify(&b, client->message, NULL, NULL); - - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); + result = ns_client_setup_view(client, &netaddr); + if (result == ISC_R_QUOTA) { ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "no matching view in class '%s'", classname); - ns_client_dumpmessage(client, "no matching view in class"); + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), + "client is starting to wait for quota"); + client->async = true; + isc_nmhandle_ref(client->handle); + isc_async_run(client->manager->loop, ns_client_request_continue, + client); + return; + } else if (result != ISC_R_SUCCESS) { ns_client_extendederror(client, DNS_EDE_PROHIBITED, NULL); ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); return; } + ns_client_request_continue(client); +} + +static void +ns_client_request_continue(void *arg) { + ns_client_t *client = arg; + isc_netaddr_t netaddr; + const dns_name_t *signame = NULL; + bool ra; /* Recursion available. */ + isc_result_t result; + static const char *ra_reasons[] = { + "ACLs not processed yet", + "no resolver in view", + "recursion not enabled for view", + "allow-recursion did not match", + "allow-query-cache did not match", + "allow-recursion-on did not match", + "allow-query-cache-on did not match", + }; + enum refusal_reasons { + INVALID, + NO_RESOLVER, + RECURSION_DISABLED, + ALLOW_RECURSION, + ALLOW_QUERY_CACHE, + ALLOW_RECURSION_ON, + ALLOW_QUERY_CACHE_ON + } ra_refusal_reason = INVALID; +#ifdef HAVE_DNSTAP + dns_transport_type_t transport_type; + dns_dtmsgtype_t dtmsgtype; +#endif /* ifdef HAVE_DNSTAP */ + + /* + * This function could be running asynchronously if a quota was reached + * before, and named was waiting for available quota. In that case we + * need to update the current 'now', and check that named doesn't wait + * for too long. + */ + if (client->async) { + uint64_t wait_us; + uint64_t maxwait_us; + + client->tnow = isc_time_now(); + client->now = isc_time_seconds(&client->tnow); + + wait_us = isc_time_microdiff(&client->tnow, + &client->requesttime); + maxwait_us = US_PER_MS * + client->manager->sctx->sig0checksquota_maxwaitms; + if (wait_us > maxwait_us) { + isc_buffer_t b; + isc_region_t *r; + + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), + "client reached max wait time for quota"); + + /* + * Do a dummy TSIG verification attempt so that the + * response will have a TSIG if the query did, as + * required by RFC2845. + */ + dns_message_resetsig(client->message); + r = dns_message_getrawmessage(client->message); + isc_buffer_init(&b, r->base, r->length); + isc_buffer_add(&b, r->length); + (void)dns_tsig_verify(&b, client->message, NULL, NULL); + + ns_client_extendederror(client, DNS_EDE_PROHIBITED, + NULL); + ns_client_error(client, DNS_R_REFUSED); + goto cleanup; + } + } + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + + if (client->view == NULL) { + result = ns_client_setup_view(client, &netaddr); + if (result == ISC_R_QUOTA) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), + "client continues waiting for quota"); + client->async = true; + isc_nmhandle_ref(client->handle); + isc_async_run(client->manager->loop, + ns_client_request_continue, client); + goto cleanup; + } else if (result != ISC_R_SUCCESS) { + ns_client_extendederror(client, DNS_EDE_PROHIBITED, + NULL); + ns_client_error(client, DNS_R_REFUSED); + goto cleanup; + } + } + if (isc_nm_is_proxy_handle(client->handle)) { char fmtbuf[ISC_SOCKADDR_FORMATSIZE] = { 0 }; isc_netaddr_t real_local_addr, real_peer_addr; @@ -2140,8 +2257,8 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, "ACL", fmtbuf); } - isc_nm_bad_request(handle); - return; + isc_nm_bad_request(client->handle); + goto cleanup; } /* allow by default */ @@ -2161,8 +2278,8 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, "'allow-proxy-on' ACL", fmtbuf); } - isc_nm_bad_request(handle); - return; + isc_nm_bad_request(client->handle); + goto cleanup; } } @@ -2255,8 +2372,8 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, if (!(client->message->tsigstatus == dns_tsigerror_badkey && client->message->opcode == dns_opcode_update)) { - ns_client_error(client, sigresult); - return; + ns_client_error(client, client->sigresult); + goto cleanup; } } @@ -2340,25 +2457,25 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, dns_dt_send(client->view, dtmsgtype, &client->peeraddr, &client->destsockaddr, transport_type, NULL, - &client->requesttime, NULL, buffer); + &client->requesttime, NULL, client->buffer); #endif /* HAVE_DNSTAP */ - ns_query_start(client, handle); + ns_query_start(client, client->handle); break; case dns_opcode_update: CTRACE("update"); #ifdef HAVE_DNSTAP dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr, &client->destsockaddr, transport_type, NULL, - &client->requesttime, NULL, buffer); + &client->requesttime, NULL, client->buffer); #endif /* HAVE_DNSTAP */ ns_client_settimeout(client, 60); - ns_update_start(client, handle, sigresult); + ns_update_start(client, client->handle, client->sigresult); break; case dns_opcode_notify: CTRACE("notify"); ns_client_settimeout(client, 60); - ns_notify_start(client, handle); + ns_notify_start(client, client->handle); break; case dns_opcode_iquery: CTRACE("iquery"); @@ -2368,6 +2485,15 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult, CTRACE("unknown opcode"); ns_client_error(client, DNS_R_NOTIMP); } + +cleanup: + if (client->async) { + /* + * Do not detach, only 'unref' the corresponding 'ref' when + * async was used, because the client can still be reused. + */ + isc_nmhandle_unref(client->handle); + } } isc_result_t diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index 67126b01f7..39c1fa0a86 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -167,6 +167,7 @@ struct ns_client { ns_clientmgr_t *manager; ns_clientstate_t state; bool nodetach; + bool async; unsigned int attributes; dns_view_t *view; dns_dispatch_t *dispatch; @@ -192,6 +193,9 @@ struct ns_client { isc_time_t tnow; dns_name_t signername; /*%< [T]SIG key name */ dns_name_t *signer; /*%< NULL if not valid sig */ + isc_result_t sigresult; + isc_buffer_t *buffer; + isc_buffer_t tbuffer; isc_sockaddr_t peeraddr; bool peeraddr_valid; diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h index 84003bf57f..fae2040b74 100644 --- a/lib/ns/include/ns/server.h +++ b/lib/ns/include/ns/server.h @@ -64,9 +64,12 @@ typedef void (*ns_fuzzcb_t)(void); /*% * Type for callback function to get the view that can answer a query. */ -typedef isc_result_t (*ns_matchview_t)( - isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, dns_message_t *message, - dns_aclenv_t *env, isc_result_t *sigresultp, dns_view_t **viewp); +typedef isc_result_t (*ns_matchview_t)(isc_netaddr_t *srcaddr, + isc_netaddr_t *destaddr, + dns_message_t *message, + dns_aclenv_t *env, ns_server_t *sctx, + isc_result_t *sigresultp, + dns_view_t **viewp); /*% * Server context. @@ -88,6 +91,9 @@ struct ns_server { isc_quota_t tcpquota; isc_quota_t xfroutquota; isc_quota_t updquota; + isc_quota_t sig0checksquota; + uint32_t sig0checksquota_maxwaitms; + dns_acl_t *sig0checksquota_exempt; ISC_LIST(isc_quota_t) http_quotas; isc_mutex_t http_quotas_lock; diff --git a/lib/ns/server.c b/lib/ns/server.c index d853848a76..ea4a588c18 100644 --- a/lib/ns/server.c +++ b/lib/ns/server.c @@ -66,6 +66,7 @@ ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview, isc_quota_init(&sctx->tcpquota, 10); isc_quota_init(&sctx->recursionquota, 100); isc_quota_init(&sctx->updquota, 100); + isc_quota_init(&sctx->sig0checksquota, 1); ISC_LIST_INIT(sctx->http_quotas); isc_mutex_init(&sctx->http_quotas_lock); @@ -134,6 +135,11 @@ ns_server_detach(ns_server_t **sctxp) { isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret)); } + if (sctx->sig0checksquota_exempt != NULL) { + dns_acl_detach(&sctx->sig0checksquota_exempt); + } + + isc_quota_destroy(&sctx->sig0checksquota); isc_quota_destroy(&sctx->updquota); isc_quota_destroy(&sctx->recursionquota); isc_quota_destroy(&sctx->tcpquota); diff --git a/tests/libtest/ns.c b/tests/libtest/ns.c index 91799a774c..f09b20045c 100644 --- a/tests/libtest/ns.c +++ b/tests/libtest/ns.c @@ -57,12 +57,13 @@ ns_server_t *sctx = NULL; static isc_result_t matchview(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, - dns_message_t *message, dns_aclenv_t *env, isc_result_t *sigresultp, - dns_view_t **viewp) { + dns_message_t *message, dns_aclenv_t *env, ns_server_t *lsctx, + isc_result_t *sigresultp, dns_view_t **viewp) { UNUSED(srcaddr); UNUSED(destaddr); UNUSED(message); UNUSED(env); + UNUSED(lsctx); UNUSED(sigresultp); UNUSED(viewp);