mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
implemented client timeouts; made outgoing zone transfers
use the client timers instead of creating their own
This commit is contained in:
@@ -254,6 +254,22 @@ client_free(ns_client_t *client) {
|
||||
clientmgr_destroy(manager);
|
||||
}
|
||||
|
||||
static void
|
||||
set_timeout(ns_client_t *client, unsigned int seconds) {
|
||||
isc_result_t result;
|
||||
isc_interval_t interval;
|
||||
isc_interval_set(&interval, seconds, 0);
|
||||
result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
|
||||
&interval, ISC_FALSE);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
|
||||
"setting timouet: %s",
|
||||
isc_result_totext(result));
|
||||
/* Continue anyway. */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a deactivation or shutdown request and take appropriate
|
||||
* action. Returns ISC_TRUE if either is in progress; in this case
|
||||
@@ -267,6 +283,8 @@ exit_check(ns_client_t *client) {
|
||||
if (client->state <= client->newstate)
|
||||
return (ISC_FALSE); /* Business as usual. */
|
||||
|
||||
INSIST(client->newstate < NS_CLIENTSTATE_WORKING);
|
||||
|
||||
/*
|
||||
* We need to detach from the view early when shutting down
|
||||
* the server to break the following vicious circle:
|
||||
@@ -295,6 +313,7 @@ exit_check(ns_client_t *client) {
|
||||
isc_socket_cancel(socket, client->task,
|
||||
ISC_SOCKCANCEL_SEND);
|
||||
}
|
||||
|
||||
if (! (client->nsends == 0 && client->references == 0)) {
|
||||
/*
|
||||
* Still waiting for I/O cancel completion.
|
||||
@@ -338,7 +357,10 @@ exit_check(ns_client_t *client) {
|
||||
|
||||
if (client->tcpquota != NULL)
|
||||
isc_quota_detach(&client->tcpquota);
|
||||
|
||||
|
||||
(void) isc_timer_reset(client->timer, isc_timertype_inactive,
|
||||
NULL, NULL, ISC_TRUE);
|
||||
|
||||
client->state = NS_CLIENTSTATE_READY;
|
||||
if (NS_CLIENTSTATE_READY == client->newstate) {
|
||||
if (TCP_CLIENT(client)) {
|
||||
@@ -389,7 +411,6 @@ exit_check(ns_client_t *client) {
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
INSIST(0);
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
@@ -408,11 +429,14 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
CTRACE("shutdown");
|
||||
|
||||
if (client->shutdown != NULL)
|
||||
(client->shutdown)(client->shutdown_arg);
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (client->shutdown != NULL) {
|
||||
(client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);
|
||||
client->shutdown = NULL;
|
||||
client->shutdown_arg = NULL;
|
||||
}
|
||||
|
||||
client->newstate = NS_CLIENTSTATE_FREED;
|
||||
(void) exit_check(client);
|
||||
}
|
||||
@@ -778,6 +802,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
||||
isc_stdtime_get(&client->requesttime);
|
||||
client->now = client->requesttime;
|
||||
|
||||
set_timeout(client, 60);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (TCP_CLIENT(client))
|
||||
ns_client_next(client, result);
|
||||
@@ -984,6 +1010,12 @@ client_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (client->shutdown != NULL) {
|
||||
(client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT);
|
||||
client->shutdown = NULL;
|
||||
client->shutdown_arg = NULL;
|
||||
}
|
||||
|
||||
if (client->newstate > NS_CLIENTSTATE_READY)
|
||||
client->newstate = NS_CLIENTSTATE_READY;
|
||||
(void) exit_check(client);
|
||||
@@ -1106,29 +1138,20 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
|
||||
static void
|
||||
client_read(ns_client_t *client) {
|
||||
isc_result_t result;
|
||||
#ifdef notyet
|
||||
isc_interval_t interval;
|
||||
#endif
|
||||
|
||||
CTRACE("read");
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Set a timeout to limit the amount of time we will wait
|
||||
* for a request on this TCP connection.
|
||||
*/
|
||||
isc_interval_set(&interval, 2, 0); /* XXX */
|
||||
result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
|
||||
&interval, ISC_FALSE);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task,
|
||||
client_request, client);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Set a timeout to limit the amount of time we will wait
|
||||
* for a request on this TCP connection.
|
||||
*/
|
||||
set_timeout(client, 30);
|
||||
|
||||
client->state = client->newstate = NS_CLIENTSTATE_READING;
|
||||
INSIST(client->nreads == 0);
|
||||
client->nreads++;
|
||||
|
@@ -106,7 +106,7 @@ struct ns_client {
|
||||
dns_rdataset_t * opt;
|
||||
isc_uint16_t udpsize;
|
||||
void (*next)(ns_client_t *);
|
||||
void (*shutdown)(void *arg);
|
||||
void (*shutdown)(void *arg, isc_result_t result);
|
||||
void *shutdown_arg;
|
||||
ns_query_t query;
|
||||
isc_stdtime_t requesttime;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrout.c,v 1.43 2000/02/11 20:56:18 gson Exp $ */
|
||||
/* $Id: xfrout.c,v 1.44 2000/02/14 23:56:46 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -745,7 +745,6 @@ typedef struct {
|
||||
dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
|
||||
dns_rdata_any_tsig_t *lasttsig; /* the last TSIG */
|
||||
isc_boolean_t many_answers;
|
||||
isc_timer_t *timer;
|
||||
int sends; /* Send in progress */
|
||||
isc_boolean_t shuttingdown;
|
||||
} xfrout_ctx_t;
|
||||
@@ -763,11 +762,10 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client,
|
||||
static void sendstream(xfrout_ctx_t *xfr);
|
||||
|
||||
static void xfrout_senddone(isc_task_t *task, isc_event_t *event);
|
||||
static void xfrout_timeout(isc_task_t *task, isc_event_t *event);
|
||||
static void xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg);
|
||||
static void xfrout_maybe_destroy(xfrout_ctx_t *xfr);
|
||||
static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
|
||||
static void xfrout_client_shutdown(void *arg);
|
||||
static void xfrout_client_shutdown(void *arg, isc_result_t result);
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -1032,6 +1030,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static isc_result_t
|
||||
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
||||
dns_name_t *qname, dns_rdatatype_t qtype,
|
||||
@@ -1067,7 +1068,6 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
||||
xfr->txmem = NULL;
|
||||
xfr->txmemlen = 0;
|
||||
xfr->nmsg = 0;
|
||||
xfr->timer = NULL;
|
||||
xfr->many_answers =
|
||||
(ns_g_server->transfer_format == dns_many_answers) ?
|
||||
ISC_TRUE : ISC_FALSE;
|
||||
@@ -1112,10 +1112,10 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
||||
CHECK(isc_time_nowplusinterval(&expires, &maxinterval));
|
||||
isc_interval_set(&idleinterval, idletime, 0);
|
||||
|
||||
CHECK(isc_timer_create(ns_g_timermgr, isc_timertype_once,
|
||||
&expires, &idleinterval,
|
||||
xfr->client->task,
|
||||
xfrout_timeout, xfr, &xfr->timer));
|
||||
CHECK(isc_timer_reset(xfr->client->timer,
|
||||
isc_timertype_once,
|
||||
&expires, &idleinterval,
|
||||
ISC_FALSE));
|
||||
|
||||
/*
|
||||
* Register a shutdown callback with the client, so that we
|
||||
@@ -1378,8 +1378,6 @@ xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
|
||||
xfr->client->shutdown = NULL;
|
||||
xfr->client->shutdown_arg = NULL;
|
||||
|
||||
if (xfr->timer != NULL)
|
||||
isc_timer_detach(&xfr->timer);
|
||||
if (xfr->stream != NULL)
|
||||
xfr->stream->methods->destroy(&xfr->stream);
|
||||
if (xfr->buf.base != NULL)
|
||||
@@ -1414,7 +1412,7 @@ xfrout_senddone(isc_task_t *task, isc_event_t *event) {
|
||||
isc_event_free(&event);
|
||||
xfr->sends--;
|
||||
INSIST(xfr->sends == 0);
|
||||
(void) isc_timer_touch(xfr->timer);
|
||||
(void) isc_timer_touch(xfr->client->timer);
|
||||
if (xfr->shuttingdown == ISC_TRUE) {
|
||||
xfrout_maybe_destroy(xfr);
|
||||
} else if (evresult != ISC_R_SUCCESS) {
|
||||
@@ -1430,15 +1428,6 @@ xfrout_senddone(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xfrout_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
xfrout_ctx_t *xfr = (xfrout_ctx_t *) event->arg;
|
||||
UNUSED(task);
|
||||
/* This will log "giving up: timeout". */
|
||||
xfrout_fail(xfr, ISC_R_TIMEDOUT, "giving up");
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
static void
|
||||
xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg)
|
||||
{
|
||||
@@ -1466,8 +1455,8 @@ xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
|
||||
}
|
||||
|
||||
static void
|
||||
xfrout_client_shutdown(void *arg)
|
||||
xfrout_client_shutdown(void *arg, isc_result_t result)
|
||||
{
|
||||
xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg;
|
||||
xfrout_fail(xfr, ISC_R_SHUTTINGDOWN, "aborted");
|
||||
xfrout_fail(xfr, result, "aborted");
|
||||
}
|
||||
|
Reference in New Issue
Block a user