mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
add an update quota
limit the number of simultaneous DNS UPDATE events that can be processed by adding a quota for update and update forwarding. this quota currently, arbitrarily, defaults to 100. also add a statistics counter to record when the update quota has been exceeded.
This commit is contained in:
parent
6ecc0a2693
commit
7c47254a14
7 changed files with 52 additions and 5 deletions
|
|
@ -15,7 +15,7 @@
|
|||
<xsl:output method="html" indent="yes" version="4.0"/>
|
||||
<!-- the version number **below** must match version in bin/named/statschannel.c -->
|
||||
<!-- don't forget to update "/xml/v<STATS_XML_VERSION_MAJOR>" in the HTTP endpoints listed below -->
|
||||
<xsl:template match="statistics[@version="3.12"]">
|
||||
<xsl:template match="statistics[@version="3.13"]">
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@
|
|||
#include "xsl_p.h"
|
||||
|
||||
#define STATS_XML_VERSION_MAJOR "3"
|
||||
#define STATS_XML_VERSION_MINOR "12"
|
||||
#define STATS_XML_VERSION_MINOR "13"
|
||||
#define STATS_XML_VERSION STATS_XML_VERSION_MAJOR "." STATS_XML_VERSION_MINOR
|
||||
|
||||
#define STATS_JSON_VERSION_MAJOR "1"
|
||||
#define STATS_JSON_VERSION_MINOR "6"
|
||||
#define STATS_JSON_VERSION_MINOR "7"
|
||||
#define STATS_JSON_VERSION STATS_JSON_VERSION_MAJOR "." STATS_JSON_VERSION_MINOR
|
||||
|
||||
#define CHECK(m) \
|
||||
|
|
@ -352,6 +352,7 @@ init_desc(void) {
|
|||
SET_NSSTATDESC(reclimitdropped,
|
||||
"queries dropped due to recursive client limit",
|
||||
"RecLimitDropped");
|
||||
SET_NSSTATDESC(updatequota, "Update quota exceeded", "UpdateQuota");
|
||||
|
||||
INSIST(i == ns_statscounter_max);
|
||||
|
||||
|
|
|
|||
|
|
@ -7838,6 +7838,11 @@ Name Server Statistics Counters
|
|||
``UpdateBadPrereq``
|
||||
This indicates the number of dynamic updates rejected due to a prerequisite failure.
|
||||
|
||||
``UpdateQuota``
|
||||
This indicates the number of times a dynamic update or update
|
||||
forwarding request was rejected because the number of pending
|
||||
requests exceeded :any:`update-quota`.
|
||||
|
||||
``RateDropped``
|
||||
This indicates the number of responses dropped due to rate limits.
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ struct ns_server {
|
|||
isc_quota_t recursionquota;
|
||||
isc_quota_t tcpquota;
|
||||
isc_quota_t xfroutquota;
|
||||
isc_quota_t updquota;
|
||||
ISC_LIST(isc_quota_t) http_quotas;
|
||||
isc_mutex_t http_quotas_lock;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,9 @@ enum {
|
|||
|
||||
ns_statscounter_reclimitdropped = 66,
|
||||
|
||||
ns_statscounter_max = 67,
|
||||
ns_statscounter_updatequota = 67,
|
||||
|
||||
ns_statscounter_max = 68,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
|
|||
isc_quota_init(&sctx->xfroutquota, 10);
|
||||
isc_quota_init(&sctx->tcpquota, 10);
|
||||
isc_quota_init(&sctx->recursionquota, 100);
|
||||
isc_quota_init(&sctx->updquota, 100);
|
||||
ISC_LIST_INIT(sctx->http_quotas);
|
||||
isc_mutex_init(&sctx->http_quotas_lock);
|
||||
|
||||
|
|
@ -133,6 +134,7 @@ ns_server_detach(ns_server_t **sctxp) {
|
|||
isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
|
||||
}
|
||||
|
||||
isc_quota_destroy(&sctx->updquota);
|
||||
isc_quota_destroy(&sctx->recursionquota);
|
||||
isc_quota_destroy(&sctx->tcpquota);
|
||||
isc_quota_destroy(&sctx->xfroutquota);
|
||||
|
|
|
|||
|
|
@ -1644,6 +1644,19 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
|
|||
update_event_t *event = NULL;
|
||||
isc_task_t *zonetask = NULL;
|
||||
|
||||
result = isc_quota_attach(&client->manager->sctx->updquota,
|
||||
&(isc_quota_t *){ NULL });
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update failed: too many DNS UPDATEs queued (%s)",
|
||||
isc_result_totext(result));
|
||||
ns_stats_increment(client->manager->sctx->nsstats,
|
||||
ns_statscounter_updatequota);
|
||||
ns_client_drop(client, result);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
return (DNS_R_DROP);
|
||||
}
|
||||
|
||||
event = (update_event_t *)isc_event_allocate(
|
||||
client->manager->mctx, client, DNS_EVENT_UPDATE, update_action,
|
||||
NULL, sizeof(*event));
|
||||
|
|
@ -1780,12 +1793,19 @@ failure:
|
|||
dns_zone_gettype(zone) == dns_zone_mirror);
|
||||
inc_stats(client, zone, ns_statscounter_updaterej);
|
||||
}
|
||||
|
||||
/*
|
||||
* We failed without having sent an update event to the zone.
|
||||
* We are still in the client task context, so we can
|
||||
* simply give an error response without switching tasks.
|
||||
*/
|
||||
respond(client, result);
|
||||
if (result == DNS_R_DROP) {
|
||||
ns_client_drop(client, result);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
} else {
|
||||
respond(client, result);
|
||||
}
|
||||
|
||||
if (zone != NULL) {
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
|
@ -3582,6 +3602,7 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
respond(client, uev->result);
|
||||
|
||||
isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
}
|
||||
|
|
@ -3596,6 +3617,8 @@ forward_fail(isc_task_t *task, isc_event_t *event) {
|
|||
UNUSED(task);
|
||||
|
||||
respond(client, DNS_R_SERVFAIL);
|
||||
|
||||
isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
}
|
||||
|
|
@ -3631,6 +3654,8 @@ forward_done(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
ns_client_sendraw(client, uev->answer);
|
||||
dns_message_detach(&uev->answer);
|
||||
|
||||
isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
|
|
@ -3666,6 +3691,17 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
|
|||
update_event_t *event = NULL;
|
||||
isc_task_t *zonetask = NULL;
|
||||
|
||||
result = isc_quota_attach(&client->manager->sctx->updquota,
|
||||
&(isc_quota_t *){ NULL });
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update failed: too many DNS UPDATEs queued (%s)",
|
||||
isc_result_totext(result));
|
||||
ns_stats_increment(client->manager->sctx->nsstats,
|
||||
ns_statscounter_updatequota);
|
||||
return (DNS_R_DROP);
|
||||
}
|
||||
|
||||
event = (update_event_t *)isc_event_allocate(
|
||||
client->manager->mctx, client, DNS_EVENT_UPDATE, forward_action,
|
||||
NULL, sizeof(*event));
|
||||
|
|
|
|||
Loading…
Reference in a new issue