mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 08:05:21 +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);
|
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
|
* Check for a deactivation or shutdown request and take appropriate
|
||||||
* action. Returns ISC_TRUE if either is in progress; in this case
|
* 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)
|
if (client->state <= client->newstate)
|
||||||
return (ISC_FALSE); /* Business as usual. */
|
return (ISC_FALSE); /* Business as usual. */
|
||||||
|
|
||||||
|
INSIST(client->newstate < NS_CLIENTSTATE_WORKING);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to detach from the view early when shutting down
|
* We need to detach from the view early when shutting down
|
||||||
* the server to break the following vicious circle:
|
* 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_socket_cancel(socket, client->task,
|
||||||
ISC_SOCKCANCEL_SEND);
|
ISC_SOCKCANCEL_SEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (client->nsends == 0 && client->references == 0)) {
|
if (! (client->nsends == 0 && client->references == 0)) {
|
||||||
/*
|
/*
|
||||||
* Still waiting for I/O cancel completion.
|
* Still waiting for I/O cancel completion.
|
||||||
@@ -339,6 +358,9 @@ exit_check(ns_client_t *client) {
|
|||||||
if (client->tcpquota != NULL)
|
if (client->tcpquota != NULL)
|
||||||
isc_quota_detach(&client->tcpquota);
|
isc_quota_detach(&client->tcpquota);
|
||||||
|
|
||||||
|
(void) isc_timer_reset(client->timer, isc_timertype_inactive,
|
||||||
|
NULL, NULL, ISC_TRUE);
|
||||||
|
|
||||||
client->state = NS_CLIENTSTATE_READY;
|
client->state = NS_CLIENTSTATE_READY;
|
||||||
if (NS_CLIENTSTATE_READY == client->newstate) {
|
if (NS_CLIENTSTATE_READY == client->newstate) {
|
||||||
if (TCP_CLIENT(client)) {
|
if (TCP_CLIENT(client)) {
|
||||||
@@ -389,7 +411,6 @@ exit_check(ns_client_t *client) {
|
|||||||
return (ISC_TRUE);
|
return (ISC_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSIST(0);
|
|
||||||
return (ISC_TRUE);
|
return (ISC_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,11 +429,14 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
CTRACE("shutdown");
|
CTRACE("shutdown");
|
||||||
|
|
||||||
if (client->shutdown != NULL)
|
|
||||||
(client->shutdown)(client->shutdown_arg);
|
|
||||||
|
|
||||||
isc_event_free(&event);
|
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;
|
client->newstate = NS_CLIENTSTATE_FREED;
|
||||||
(void) exit_check(client);
|
(void) exit_check(client);
|
||||||
}
|
}
|
||||||
@@ -778,6 +802,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_stdtime_get(&client->requesttime);
|
isc_stdtime_get(&client->requesttime);
|
||||||
client->now = client->requesttime;
|
client->now = client->requesttime;
|
||||||
|
|
||||||
|
set_timeout(client, 60);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
if (TCP_CLIENT(client))
|
if (TCP_CLIENT(client))
|
||||||
ns_client_next(client, result);
|
ns_client_next(client, result);
|
||||||
@@ -984,6 +1010,12 @@ client_timeout(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
isc_event_free(&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)
|
if (client->newstate > NS_CLIENTSTATE_READY)
|
||||||
client->newstate = NS_CLIENTSTATE_READY;
|
client->newstate = NS_CLIENTSTATE_READY;
|
||||||
(void) exit_check(client);
|
(void) exit_check(client);
|
||||||
@@ -1106,29 +1138,20 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
|
|||||||
static void
|
static void
|
||||||
client_read(ns_client_t *client) {
|
client_read(ns_client_t *client) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
#ifdef notyet
|
|
||||||
isc_interval_t interval;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CTRACE("read");
|
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,
|
result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task,
|
||||||
client_request, client);
|
client_request, client);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto fail;
|
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;
|
client->state = client->newstate = NS_CLIENTSTATE_READING;
|
||||||
INSIST(client->nreads == 0);
|
INSIST(client->nreads == 0);
|
||||||
client->nreads++;
|
client->nreads++;
|
||||||
|
@@ -106,7 +106,7 @@ struct ns_client {
|
|||||||
dns_rdataset_t * opt;
|
dns_rdataset_t * opt;
|
||||||
isc_uint16_t udpsize;
|
isc_uint16_t udpsize;
|
||||||
void (*next)(ns_client_t *);
|
void (*next)(ns_client_t *);
|
||||||
void (*shutdown)(void *arg);
|
void (*shutdown)(void *arg, isc_result_t result);
|
||||||
void *shutdown_arg;
|
void *shutdown_arg;
|
||||||
ns_query_t query;
|
ns_query_t query;
|
||||||
isc_stdtime_t requesttime;
|
isc_stdtime_t requesttime;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -745,7 +745,6 @@ typedef struct {
|
|||||||
dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
|
dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
|
||||||
dns_rdata_any_tsig_t *lasttsig; /* the last TSIG */
|
dns_rdata_any_tsig_t *lasttsig; /* the last TSIG */
|
||||||
isc_boolean_t many_answers;
|
isc_boolean_t many_answers;
|
||||||
isc_timer_t *timer;
|
|
||||||
int sends; /* Send in progress */
|
int sends; /* Send in progress */
|
||||||
isc_boolean_t shuttingdown;
|
isc_boolean_t shuttingdown;
|
||||||
} xfrout_ctx_t;
|
} 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 sendstream(xfrout_ctx_t *xfr);
|
||||||
|
|
||||||
static void xfrout_senddone(isc_task_t *task, isc_event_t *event);
|
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_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg);
|
||||||
static void xfrout_maybe_destroy(xfrout_ctx_t *xfr);
|
static void xfrout_maybe_destroy(xfrout_ctx_t *xfr);
|
||||||
static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
|
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
|
static isc_result_t
|
||||||
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
||||||
dns_name_t *qname, dns_rdatatype_t qtype,
|
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->txmem = NULL;
|
||||||
xfr->txmemlen = 0;
|
xfr->txmemlen = 0;
|
||||||
xfr->nmsg = 0;
|
xfr->nmsg = 0;
|
||||||
xfr->timer = NULL;
|
|
||||||
xfr->many_answers =
|
xfr->many_answers =
|
||||||
(ns_g_server->transfer_format == dns_many_answers) ?
|
(ns_g_server->transfer_format == dns_many_answers) ?
|
||||||
ISC_TRUE : ISC_FALSE;
|
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));
|
CHECK(isc_time_nowplusinterval(&expires, &maxinterval));
|
||||||
isc_interval_set(&idleinterval, idletime, 0);
|
isc_interval_set(&idleinterval, idletime, 0);
|
||||||
|
|
||||||
CHECK(isc_timer_create(ns_g_timermgr, isc_timertype_once,
|
CHECK(isc_timer_reset(xfr->client->timer,
|
||||||
|
isc_timertype_once,
|
||||||
&expires, &idleinterval,
|
&expires, &idleinterval,
|
||||||
xfr->client->task,
|
ISC_FALSE));
|
||||||
xfrout_timeout, xfr, &xfr->timer));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register a shutdown callback with the client, so that we
|
* 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 = NULL;
|
||||||
xfr->client->shutdown_arg = NULL;
|
xfr->client->shutdown_arg = NULL;
|
||||||
|
|
||||||
if (xfr->timer != NULL)
|
|
||||||
isc_timer_detach(&xfr->timer);
|
|
||||||
if (xfr->stream != NULL)
|
if (xfr->stream != NULL)
|
||||||
xfr->stream->methods->destroy(&xfr->stream);
|
xfr->stream->methods->destroy(&xfr->stream);
|
||||||
if (xfr->buf.base != NULL)
|
if (xfr->buf.base != NULL)
|
||||||
@@ -1414,7 +1412,7 @@ xfrout_senddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
xfr->sends--;
|
xfr->sends--;
|
||||||
INSIST(xfr->sends == 0);
|
INSIST(xfr->sends == 0);
|
||||||
(void) isc_timer_touch(xfr->timer);
|
(void) isc_timer_touch(xfr->client->timer);
|
||||||
if (xfr->shuttingdown == ISC_TRUE) {
|
if (xfr->shuttingdown == ISC_TRUE) {
|
||||||
xfrout_maybe_destroy(xfr);
|
xfrout_maybe_destroy(xfr);
|
||||||
} else if (evresult != ISC_R_SUCCESS) {
|
} 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
|
static void
|
||||||
xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg)
|
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
|
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_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