2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

merged the two functions ns_clientmgr_addtodispatch() and

ns_clientmgr_accepttcp() into a new single function,
ns_clientmgr_createclients()
This commit is contained in:
Andreas Gustafsson
2000-01-17 23:48:15 +00:00
parent 28dff2287e
commit e57d7e30f1
4 changed files with 52 additions and 100 deletions

View File

@@ -1038,20 +1038,17 @@ ns_client_replace(ns_client_t *client) {
isc_result_t result; isc_result_t result;
CTRACE("replace"); CTRACE("replace");
if (TCP_CLIENT(client)) { result = ns_clientmgr_createclients(client->manager,
result = ns_clientmgr_accepttcp(client->manager, 1, client->interface,
1, client->interface); (TCP_CLIENT(client) ?
} else { ISC_TRUE : ISC_FALSE));
result = ns_clientmgr_addtodispatch(client->manager,
1, client->interface);
}
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
/* /*
* The new client is ready to listen for new requests, therefore we * The responsibility for listening for new requests is hereby
* should refrain from listening from any more requests when we are * transferred to the new client. Therefore, the old client
* done with this one. * should refrain from listening for any more requests.
*/ */
client->mortal = ISC_TRUE; client->mortal = ISC_TRUE;
@@ -1141,8 +1138,8 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
} }
isc_result_t isc_result_t
ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n, ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
ns_interface_t *ifp) ns_interface_t *ifp, isc_boolean_t tcp)
{ {
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
unsigned int i; unsigned int i;
@@ -1151,7 +1148,7 @@ ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n,
REQUIRE(VALID_MANAGER(manager)); REQUIRE(VALID_MANAGER(manager));
REQUIRE(n > 0); REQUIRE(n > 0);
MTRACE("addtodispatch"); MTRACE("createclients");
/* /*
* We MUST lock the manager lock for the entire client creation * We MUST lock the manager lock for the entire client creation
@@ -1166,15 +1163,24 @@ ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n,
result = client_create(manager, ifp, &client); result = client_create(manager, ifp, &client);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
break; break;
dns_dispatch_attach(ifp->udpdispatch, &client->dispatch); if (tcp) {
result = dns_dispatch_addrequest(client->dispatch, client->attributes |= NS_CLIENTATTR_TCP;
client->task, isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
client_request, client_accept(client);
client, &client->dispentry); } else {
if (result != ISC_R_SUCCESS) { dns_dispatch_attach(ifp->udpdispatch, &client->dispatch);
client->shuttingdown = ISC_TRUE; result = dns_dispatch_addrequest(client->dispatch,
maybe_free(client); /* Will free immediately. */ client->task,
break; client_request,
client, &client->dispentry);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"dns_dispatch_addrequest() failed: %s",
isc_result_totext(result));
isc_task_shutdown(client->task);
break;
}
} }
client->manager = manager; client->manager = manager;
ISC_LIST_APPEND(manager->clients, client, link); ISC_LIST_APPEND(manager->clients, client, link);
@@ -1193,63 +1199,6 @@ ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n,
return (result); return (result);
} }
isc_result_t
ns_clientmgr_accepttcp(ns_clientmgr_t *manager, unsigned int n,
ns_interface_t *ifp)
{
isc_result_t result = ISC_R_SUCCESS;
unsigned int i;
ns_client_t *client;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(n > 0);
MTRACE("accepttcp");
/*
* XXXRTH
*
* This does not represent the planned method for TCP support,
* because we are dedicating a few clients to servicing TCP requests
* instead of allocating TCP clients from a pool and applying quotas.
*
* All this will be fixed later, but this code will allow parts of
* the server that need TCP support, e.g. IXFR and AXFR, to progress.
*/
/*
* We MUST lock the manager lock for the entire client creation
* process. If we didn't do this, then a client could get a
* shutdown event and disappear out from under us.
*/
LOCK(&manager->lock);
for (i = 0; i < n; i++) {
client = NULL;
result = client_create(manager, ifp, &client);
if (result != ISC_R_SUCCESS)
break;
client->attributes |= NS_CLIENTATTR_TCP;
isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
client_accept(client);
client->manager = manager;
ISC_LIST_APPEND(manager->clients, client, link);
manager->nclients++;
}
if (i != 0) {
/*
* We managed to create at least one client, so we
* declare victory.
*/
result = ISC_R_SUCCESS;
}
UNLOCK(&manager->lock);
return (result);
}
isc_sockaddr_t * isc_sockaddr_t *
ns_client_getsockaddr(ns_client_t *client) { ns_client_getsockaddr(ns_client_t *client) {
if (TCP_CLIENT(client)) if (TCP_CLIENT(client))

View File

@@ -52,8 +52,8 @@
* *
* A ns_clientmgr_t manages a number of ns_client_t objects. * A ns_clientmgr_t manages a number of ns_client_t objects.
* New ns_client_t objects are created by calling * New ns_client_t objects are created by calling
* ns_clientmgr_addtodispatch() (UDP) or ns_clientmgr_accepttcp() (TCP). * ns_clientmgr_createclients(). They are destroyed by
* They are destroyed by destroying their manager. * destroying their manager.
*/ */
/*** /***
@@ -174,19 +174,12 @@ void
ns_clientmgr_destroy(ns_clientmgr_t **managerp); ns_clientmgr_destroy(ns_clientmgr_t **managerp);
isc_result_t isc_result_t
ns_clientmgr_addtodispatch(ns_clientmgr_t *manager, unsigned int n, ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
ns_interface_t *ifp); ns_interface_t *ifp, isc_boolean_t tcp);
/* /*
* Create up to 'n' UDP clients listening for requests through the * Create up to 'n' clients listening on interface 'ifp'.
* dispatch of interface 'ifp'. * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections,
*/ * otherwise for UDP requests.
isc_result_t
ns_clientmgr_accepttcp(ns_clientmgr_t *manager, unsigned int n,
ns_interface_t *ifp);
/*
* Create up to 'n' TCP clients accepting requests on the
* socket of interface 'ifp'.
*/ */
isc_sockaddr_t * isc_sockaddr_t *

View File

@@ -75,7 +75,8 @@ struct ns_interface {
dns_dispatch_t * udpdispatch; /* UDP dispatcher. */ dns_dispatch_t * udpdispatch; /* UDP dispatcher. */
isc_socket_t * tcpsocket; /* TCP socket. */ isc_socket_t * tcpsocket; /* TCP socket. */
isc_task_t * task; isc_task_t * task;
int ntcptarget; /* Desired # of TCP accepts */ int ntcptarget; /* Desired number of concurrent
TCP accepts */
int ntcpcurrent; /* Current ditto, locked */ int ntcpcurrent; /* Current ditto, locked */
ISC_LINK(ns_interface_t) link; ISC_LINK(ns_interface_t) link;
}; };

View File

@@ -195,7 +195,13 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
ifp->udpdispatch = NULL; ifp->udpdispatch = NULL;
ifp->tcpsocket = NULL; ifp->tcpsocket = NULL;
ifp->ntcptarget = ns_g_cpus; /*
* Create a single TCP client object. It will replace itself
* with a new one as soon as it gets a connection, so the actual
* connections will be handled in parallel even though there is
* only one client initially.
*/
ifp->ntcptarget = 1;
ifp->ntcpcurrent = 0; ifp->ntcpcurrent = 0;
ns_interfacemgr_attach(mgr, &ifp->mgr); ns_interfacemgr_attach(mgr, &ifp->mgr);
@@ -257,10 +263,11 @@ ns_interface_listenudp(ns_interface_t *ifp) {
goto udp_dispatch_failure; goto udp_dispatch_failure;
} }
result = ns_clientmgr_addtodispatch(ifp->mgr->clientmgr, ns_g_cpus, ifp); result = ns_clientmgr_createclients(ifp->mgr->clientmgr, ns_g_cpus, ifp,
ISC_FALSE);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"UDP ns_clientmgr_addtodispatch(): %s", "UDP ns_clientmgr_createclients(): %s",
isc_result_totext(result)); isc_result_totext(result));
goto addtodispatch_failure; goto addtodispatch_failure;
} }
@@ -306,11 +313,13 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
isc_result_totext(result)); isc_result_totext(result));
goto tcp_listen_failure; goto tcp_listen_failure;
} }
result = ns_clientmgr_accepttcp(ifp->mgr->clientmgr,
ifp->ntcptarget, ifp); result = ns_clientmgr_createclients(ifp->mgr->clientmgr,
ifp->ntcptarget, ifp,
ISC_TRUE);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"TCP ns_clientmgr_accepttcp(): %s", "TCP ns_clientmgr_createclients(): %s",
isc_result_totext(result)); isc_result_totext(result));
goto accepttcp_failure; goto accepttcp_failure;
} }