mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
client can now reserve multiple types of quota simultaneously;
removed unused clienttype argument; client quota bug fixes
This commit is contained in:
@@ -98,6 +98,14 @@ static void clientmgr_destroy(ns_clientmgr_t *manager);
|
|||||||
* task to change the client, then the client will have to be locked.
|
* task to change the client, then the client will have to be locked.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_quotas(ns_client_t *client) {
|
||||||
|
if (client->tcpquota != NULL)
|
||||||
|
isc_quota_detach(&client->tcpquota);
|
||||||
|
if (client->recursionquota != NULL)
|
||||||
|
isc_quota_detach(&client->recursionquota);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free a client immediately if possible, otherwise start
|
* Free a client immediately if possible, otherwise start
|
||||||
* shutting it down and postpone freeing to later.
|
* shutting it down and postpone freeing to later.
|
||||||
@@ -121,9 +129,15 @@ maybe_free(ns_client_t *client) {
|
|||||||
ISC_SOCKCANCEL_ACCEPT);
|
ISC_SOCKCANCEL_ACCEPT);
|
||||||
if (client->nreads > 0)
|
if (client->nreads > 0)
|
||||||
dns_tcpmsg_cancelread(&client->tcpmsg);
|
dns_tcpmsg_cancelread(&client->tcpmsg);
|
||||||
if (client->nsends > 0)
|
if (client->nsends > 0) {
|
||||||
|
isc_socket_t *socket;
|
||||||
|
if (TCP_CLIENT(client))
|
||||||
|
socket = client->tcpsocket;
|
||||||
|
else
|
||||||
|
socket = dns_dispatch_getsocket(client->dispatch);
|
||||||
isc_socket_cancel(client->tcpsocket, client->task,
|
isc_socket_cancel(client->tcpsocket, client->task,
|
||||||
ISC_SOCKCANCEL_SEND);
|
ISC_SOCKCANCEL_SEND);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(client->nreads == 0 && client->naccepts == 0 &&
|
if (!(client->nreads == 0 && client->naccepts == 0 &&
|
||||||
client->nsends == 0 && client->nwaiting == 0)) {
|
client->nsends == 0 && client->nwaiting == 0)) {
|
||||||
@@ -179,11 +193,8 @@ maybe_free(ns_client_t *client) {
|
|||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->quota != NULL) {
|
release_quotas(client);
|
||||||
isc_quota_release(client->quota);
|
|
||||||
client->quota = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTRACE("free");
|
CTRACE("free");
|
||||||
client->magic = 0;
|
client->magic = 0;
|
||||||
isc_mem_put(client->mctx, client, sizeof *client);
|
isc_mem_put(client->mctx, client, sizeof *client);
|
||||||
@@ -247,10 +258,9 @@ ns_client_next(ns_client_t *client, isc_result_t result) {
|
|||||||
|
|
||||||
client->udpsize = 512;
|
client->udpsize = 512;
|
||||||
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
|
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
|
||||||
if (client->quota != NULL) {
|
|
||||||
isc_quota_release(client->quota);
|
release_quotas(client);
|
||||||
client->quota = NULL;
|
|
||||||
}
|
|
||||||
if (client->mortal) {
|
if (client->mortal) {
|
||||||
/*
|
/*
|
||||||
* This client object is supposed to die now, but if we
|
* This client object is supposed to die now, but if we
|
||||||
@@ -277,8 +287,9 @@ ns_client_next(ns_client_t *client, isc_result_t result) {
|
|||||||
isc_task_shutdown(client->task);
|
isc_task_shutdown(client->task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
client->mortal = ISC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->dispevent != NULL) {
|
if (client->dispevent != NULL) {
|
||||||
/*
|
/*
|
||||||
* Give the processed dispatch event back to the dispatch.
|
* Give the processed dispatch event back to the dispatch.
|
||||||
@@ -580,6 +591,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
REQUIRE(NS_CLIENT_VALID(client));
|
REQUIRE(NS_CLIENT_VALID(client));
|
||||||
REQUIRE(task == client->task);
|
REQUIRE(task == client->task);
|
||||||
|
|
||||||
|
INSIST(client->recursionquota == NULL);
|
||||||
|
|
||||||
if (event->type == DNS_EVENT_DISPATCH) {
|
if (event->type == DNS_EVENT_DISPATCH) {
|
||||||
devent = (dns_dispatchevent_t *)event;
|
devent = (dns_dispatchevent_t *)event;
|
||||||
REQUIRE(client->dispentry != NULL);
|
REQUIRE(client->dispentry != NULL);
|
||||||
@@ -782,7 +795,7 @@ client_timeout(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
client_create(ns_clientmgr_t *manager, ns_clienttype_t type,
|
client_create(ns_clientmgr_t *manager,
|
||||||
ns_interface_t *ifp, ns_client_t **clientp)
|
ns_interface_t *ifp, ns_client_t **clientp)
|
||||||
{
|
{
|
||||||
ns_client_t *client;
|
ns_client_t *client;
|
||||||
@@ -836,7 +849,6 @@ client_create(ns_clientmgr_t *manager, ns_clienttype_t type,
|
|||||||
client->magic = NS_CLIENT_MAGIC;
|
client->magic = NS_CLIENT_MAGIC;
|
||||||
client->mctx = manager->mctx;
|
client->mctx = manager->mctx;
|
||||||
client->manager = NULL;
|
client->manager = NULL;
|
||||||
client->type = type;
|
|
||||||
client->shuttingdown = ISC_FALSE;
|
client->shuttingdown = ISC_FALSE;
|
||||||
client->waiting_for_bufs = ISC_FALSE;
|
client->waiting_for_bufs = ISC_FALSE;
|
||||||
client->naccepts = 0;
|
client->naccepts = 0;
|
||||||
@@ -858,7 +870,8 @@ client_create(ns_clientmgr_t *manager, ns_clienttype_t type,
|
|||||||
client->shutdown_arg = NULL;
|
client->shutdown_arg = NULL;
|
||||||
dns_name_init(&client->signername, NULL);
|
dns_name_init(&client->signername, NULL);
|
||||||
client->mortal = ISC_FALSE;
|
client->mortal = ISC_FALSE;
|
||||||
client->quota = NULL;
|
client->tcpquota = NULL;
|
||||||
|
client->recursionquota = NULL;
|
||||||
client->interface = NULL;
|
client->interface = NULL;
|
||||||
ISC_LINK_INIT(client, link);
|
ISC_LINK_INIT(client, link);
|
||||||
|
|
||||||
@@ -948,7 +961,10 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
|
|||||||
* telnetting to port 35 (once per CPU) will
|
* telnetting to port 35 (once per CPU) will
|
||||||
* deny service to legititmate TCP clients.
|
* deny service to legititmate TCP clients.
|
||||||
*/
|
*/
|
||||||
result = ns_client_replace(client, &ns_g_server->tcpquota);
|
result = isc_quota_attach(&ns_g_server->tcpquota,
|
||||||
|
&client->tcpquota);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
result = ns_client_replace(client);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
|
||||||
NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
|
NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
|
||||||
@@ -1017,37 +1033,10 @@ ns_client_unwait(ns_client_t *client) {
|
|||||||
maybe_free(client);
|
maybe_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_client_getquota(ns_client_t *client, isc_quota_t *quota) {
|
ns_client_replace(ns_client_t *client) {
|
||||||
isc_result_t result;
|
|
||||||
/*
|
|
||||||
* A client can only use one quota at a time.
|
|
||||||
* If we are already using a quota, release it.
|
|
||||||
*/
|
|
||||||
if (client->quota != NULL) {
|
|
||||||
isc_quota_release(client->quota);
|
|
||||||
client->quota = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = isc_quota_reserve(quota);
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
|
||||||
client->quota = quota;
|
|
||||||
} else {
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_result_t
|
|
||||||
ns_client_replace(ns_client_t *client, isc_quota_t *quota) {
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
CTRACE("replace");
|
CTRACE("replace");
|
||||||
if (quota != NULL) {
|
|
||||||
result = ns_client_getquota(client, quota);
|
|
||||||
if (result != DNS_R_SUCCESS)
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TCP_CLIENT(client)) {
|
if (TCP_CLIENT(client)) {
|
||||||
result = ns_clientmgr_accepttcp(client->manager,
|
result = ns_clientmgr_accepttcp(client->manager,
|
||||||
@@ -1174,8 +1163,7 @@ ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n,
|
|||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
client = NULL;
|
client = NULL;
|
||||||
result = client_create(manager, ns_clienttype_basic,
|
result = client_create(manager, ifp, &client);
|
||||||
ifp, &client);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
break;
|
break;
|
||||||
dns_dispatch_attach(ifp->udpdispatch, &client->dispatch);
|
dns_dispatch_attach(ifp->udpdispatch, &client->dispatch);
|
||||||
@@ -1239,8 +1227,7 @@ ns_clientmgr_accepttcp(ns_clientmgr_t *manager, unsigned int n,
|
|||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
client = NULL;
|
client = NULL;
|
||||||
result = client_create(manager, ns_clienttype_tcp,
|
result = client_create(manager, ifp, &client);
|
||||||
ifp, &client);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
break;
|
break;
|
||||||
client->attributes |= NS_CLIENTATTR_TCP;
|
client->attributes |= NS_CLIENTATTR_TCP;
|
||||||
|
Reference in New Issue
Block a user