mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
1905. [bug] Recursive clients soft quota support wasn't working
as expected. [RT #15103]
This commit is contained in:
parent
0992797c70
commit
8abe06b25d
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
||||
1905. [bug] Recursive clients soft quota support wasn't working
|
||||
as expected. [RT #15103]
|
||||
|
||||
1904. [bug] A escaped character is, potentially, converted to
|
||||
the output character set too early. [RT #14666]
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: client.c,v 1.228 2005/06/07 00:15:59 marka Exp $ */
|
||||
/* $Id: client.c,v 1.229 2005/07/27 02:28:58 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -181,23 +181,29 @@ static void client_request(isc_task_t *task, isc_event_t *event);
|
||||
static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
|
||||
|
||||
void
|
||||
ns_client_recursing(ns_client_t *client, isc_boolean_t killoldest) {
|
||||
ns_client_recursing(ns_client_t *client) {
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
LOCK(&client->manager->lock);
|
||||
ISC_LIST_UNLINK(*client->list, client, link);
|
||||
ISC_LIST_APPEND(client->manager->recursing, client, link);
|
||||
client->list = &client->manager->recursing;
|
||||
UNLOCK(&client->manager->lock);
|
||||
}
|
||||
|
||||
void
|
||||
ns_client_killoldestquery(ns_client_t *client) {
|
||||
ns_client_t *oldest;
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
LOCK(&client->manager->lock);
|
||||
if (killoldest) {
|
||||
oldest = ISC_LIST_HEAD(client->manager->recursing);
|
||||
if (oldest != NULL) {
|
||||
ns_query_cancel(oldest);
|
||||
ISC_LIST_UNLINK(*oldest->list, oldest, link);
|
||||
ISC_LIST_APPEND(client->manager->active, oldest, link);
|
||||
oldest->list = &client->manager->active;
|
||||
}
|
||||
oldest = ISC_LIST_HEAD(client->manager->recursing);
|
||||
if (oldest != NULL) {
|
||||
ns_query_cancel(oldest);
|
||||
ISC_LIST_UNLINK(*oldest->list, oldest, link);
|
||||
ISC_LIST_APPEND(client->manager->active, oldest, link);
|
||||
oldest->list = &client->manager->active;
|
||||
}
|
||||
ISC_LIST_UNLINK(*client->list, client, link);
|
||||
ISC_LIST_APPEND(client->manager->recursing, client, link);
|
||||
client->list = &client->manager->recursing;
|
||||
UNLOCK(&client->manager->lock);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: client.h,v 1.75 2005/07/18 05:58:57 marka Exp $ */
|
||||
/* $Id: client.h,v 1.76 2005/07/27 02:28:59 marka Exp $ */
|
||||
|
||||
#ifndef NAMED_CLIENT_H
|
||||
#define NAMED_CLIENT_H 1
|
||||
@ -326,10 +326,15 @@ ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
|
||||
DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
|
||||
|
||||
void
|
||||
ns_client_recursing(ns_client_t *client, isc_boolean_t killoldest);
|
||||
ns_client_recursing(ns_client_t *client);
|
||||
/*%
|
||||
* Add client to end of recursing list. If 'killoldest' is true
|
||||
* kill the oldest recursive client (list head).
|
||||
* Add client to end of th recursing list.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_killoldestquery(ns_client_t *client);
|
||||
/*%
|
||||
* Kill the oldest recursive query (recursing list head).
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.268 2005/06/27 00:15:42 marka Exp $ */
|
||||
/* $Id: query.c,v 1.269 2005/07/27 02:28:58 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -2701,33 +2701,37 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
|
||||
* connection was accepted (if allowed by the TCP quota).
|
||||
*/
|
||||
if (client->recursionquota == NULL) {
|
||||
isc_boolean_t killoldest = ISC_FALSE;
|
||||
result = isc_quota_attach(&ns_g_server->recursionquota,
|
||||
&client->recursionquota);
|
||||
if (result == ISC_R_SOFTQUOTA) {
|
||||
if (result == ISC_R_SOFTQUOTA) {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||
"recursive-clients limit exceeded, "
|
||||
"recursive-clients soft limit exceeded, "
|
||||
"aborting oldest query");
|
||||
killoldest = ISC_TRUE;
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
if (dns_resolver_nrunning(client->view->resolver) >
|
||||
(unsigned int)ns_g_server->recursionquota.max)
|
||||
result = ISC_R_QUOTA;
|
||||
if (result == ISC_R_SUCCESS && !client->mortal &&
|
||||
(client->attributes & NS_CLIENTATTR_TCP) == 0)
|
||||
result = ns_client_replace(client);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ns_client_killoldestquery(client);
|
||||
result == ISC_R_SUCCESS;
|
||||
} else if (result == ISC_R_QUOTA) {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||
"no more recursive clients: %s",
|
||||
isc_result_totext(result));
|
||||
if (client->recursionquota != NULL)
|
||||
isc_quota_detach(&client->recursionquota);
|
||||
return (result);
|
||||
ns_client_killoldestquery(client);
|
||||
}
|
||||
ns_client_recursing(client, killoldest);
|
||||
if (result == ISC_R_SUCCESS && !client->mortal &&
|
||||
(client->attributes & NS_CLIENTATTR_TCP) == 0) {
|
||||
result = ns_client_replace(client);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_QUERY,
|
||||
ISC_LOG_WARNING,
|
||||
"ns_client_replace() failed: %s",
|
||||
isc_result_totext(result));
|
||||
isc_quota_detach(&client->recursionquota);
|
||||
}
|
||||
}
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
ns_client_recursing(client);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.c,v 1.445 2005/06/27 00:15:42 marka Exp $ */
|
||||
/* $Id: server.c,v 1.446 2005/07/27 02:28:58 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1882,7 +1882,7 @@ configure_server_quota(cfg_obj_t **maps, const char *name, isc_quota_t *quota)
|
||||
|
||||
result = ns_config_get(maps, name, &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
quota->max = cfg_obj_asuint32(obj);
|
||||
isc_quota_max(quota, cfg_obj_asuint32(obj));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2309,6 +2309,11 @@ load_configuration(const char *filename, ns_server_t *server,
|
||||
configure_server_quota(maps, "tcp-clients", &server->tcpquota);
|
||||
configure_server_quota(maps, "recursive-clients",
|
||||
&server->recursionquota);
|
||||
if (server->recursionquota.max > 1000)
|
||||
isc_quota_soft(&server->recursionquota,
|
||||
server->recursionquota.max - 100);
|
||||
else
|
||||
isc_quota_soft(&server->recursionquota, 0);
|
||||
|
||||
CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx,
|
||||
ns_g_mctx, &server->blackholeacl));
|
||||
@ -3036,7 +3041,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
result = isc_quota_init(&server->recursionquota, 100);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
isc_quota_soft(&server->recursionquota, ISC_FALSE);
|
||||
|
||||
result = dns_aclenv_init(mctx, &server->aclenv);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
@ -4147,12 +4151,13 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
|
||||
"xfers deferred: %u\n"
|
||||
"soa queries in progress: %u\n"
|
||||
"query logging is %s\n"
|
||||
"recursive clients: %d/%d\n"
|
||||
"recursive clients: %d/%d/%d\n"
|
||||
"tcp clients: %d/%d\n"
|
||||
"server is up and running",
|
||||
zonecount, ns_g_debuglevel, xferrunning, xferdeferred,
|
||||
soaqueries, server->log_queries ? "ON" : "OFF",
|
||||
server->recursionquota.used, server->recursionquota.max,
|
||||
server->recursionquota.used, server->recursionquota.soft,
|
||||
server->recursionquota.max,
|
||||
server->tcpquota.used, server->tcpquota.max);
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
return (ISC_R_NOSPACE);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: quota.h,v 1.12 2005/04/29 00:23:42 marka Exp $ */
|
||||
/* $Id: quota.h,v 1.13 2005/07/27 02:29:01 marka Exp $ */
|
||||
|
||||
#ifndef ISC_QUOTA_H
|
||||
#define ISC_QUOTA_H 1
|
||||
@ -72,9 +72,15 @@ isc_quota_destroy(isc_quota_t *quota);
|
||||
*/
|
||||
|
||||
void
|
||||
isc_quota_soft(isc_quota_t *quota, isc_boolean_t soft);
|
||||
isc_quota_soft(isc_quota_t *quota, int soft);
|
||||
/*%<
|
||||
* Turn on/off soft quotas.
|
||||
* Set a soft quota.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_quota_max(isc_quota_t *quota, int max);
|
||||
/*%<
|
||||
* Re-set a maximum quota.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
@ -83,9 +89,9 @@ isc_quota_reserve(isc_quota_t *quota);
|
||||
* Attempt to reserve one unit of 'quota'.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_SOFTQUOTA Success soft quota reached
|
||||
*\li #ISC_R_QUOTA Quota is full
|
||||
* \li #ISC_R_SUCCESS Success
|
||||
* \li #ISC_R_SOFTQUOTA Success soft quota reached
|
||||
* \li #ISC_R_QUOTA Quota is full
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: quota.c,v 1.15 2005/04/29 00:23:29 marka Exp $ */
|
||||
/* $Id: quota.c,v 1.16 2005/07/27 02:29:00 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -30,38 +30,45 @@ isc_result_t
|
||||
isc_quota_init(isc_quota_t *quota, int max) {
|
||||
quota->max = max;
|
||||
quota->used = 0;
|
||||
quota->soft = ISC_FALSE;
|
||||
quota->soft = 0;
|
||||
return (isc_mutex_init("a->lock));
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_destroy(isc_quota_t *quota) {
|
||||
INSIST(quota->used == 0);
|
||||
quota->max = -1;
|
||||
quota->used = -1;
|
||||
quota->soft = ISC_FALSE;
|
||||
quota->max = 0;
|
||||
quota->used = 0;
|
||||
quota->soft = 0;
|
||||
DESTROYLOCK("a->lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_soft(isc_quota_t *quota, isc_boolean_t soft) {
|
||||
isc_quota_soft(isc_quota_t *quota, int soft) {
|
||||
LOCK("a->lock);
|
||||
quota->soft = soft;
|
||||
UNLOCK("a->lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_max(isc_quota_t *quota, int max) {
|
||||
LOCK("a->lock);
|
||||
quota->max = max;
|
||||
UNLOCK("a->lock);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_quota_reserve(isc_quota_t *quota) {
|
||||
isc_result_t result;
|
||||
LOCK("a->lock);
|
||||
if (quota->used < quota->max) {
|
||||
quota->used++;
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
if (quota->soft) {
|
||||
quota->used++;
|
||||
if (quota->max == 0 || quota->used < quota->max) {
|
||||
if (quota->soft == 0 || quota->used < quota->soft)
|
||||
result = ISC_R_SUCCESS;
|
||||
else
|
||||
result = ISC_R_SOFTQUOTA;
|
||||
} else
|
||||
result = ISC_R_QUOTA;
|
||||
}
|
||||
quota->used++;
|
||||
} else
|
||||
result = ISC_R_QUOTA;
|
||||
UNLOCK("a->lock);
|
||||
return (result);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user