From d18d98734f64a7eaf07df6acc2b611e9a081b521 Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Mon, 14 Feb 2000 23:56:47 +0000 Subject: [PATCH] implemented client timeouts; made outgoing zone transfers use the client timers instead of creating their own --- bin/named/client.c | 63 ++++++++++++++++++++++---------- bin/named/include/named/client.h | 2 +- bin/named/xfrout.c | 35 ++++++------------ 3 files changed, 56 insertions(+), 44 deletions(-) diff --git a/bin/named/client.c b/bin/named/client.c index 366a866eed..6af4d53aa1 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -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++; diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 9f5e325188..e857950962 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -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; diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index 1f3344f9c8..12966ff6ac 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -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 @@ -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"); }