3571. [bug] Address race condition in dns_client_startresolve().

[RT #33234]
This commit is contained in:
Mark Andrews 2013-05-09 08:41:24 +10:00
parent 22bca01405
commit e24b9972c0
5 changed files with 65 additions and 12 deletions

View file

@ -1,6 +1,9 @@
3574. [doc] The 'hostname' keyword was missing from server-id
description in the named.conf man page. [RT #33476]
3571. [bug] Address race condition in dns_client_startresolve().
[RT #33234]
--- 9.9.3 released ---
3568. [cleanup] Add a product description line to the version file,

View file

@ -1094,11 +1094,23 @@ client_resfind(resctx_t *rctx, dns_fetchevent_t *event) {
UNLOCK(&rctx->lock);
}
static void
suspend(isc_task_t *task, isc_event_t *event) {
isc_appctx_t *actx = event->ev_arg;
UNUSED(task);
isc_app_ctxsuspend(actx);
isc_event_free(&event);
}
static void
resolve_done(isc_task_t *task, isc_event_t *event) {
resarg_t *resarg = event->ev_arg;
dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
dns_name_t *name;
isc_result_t result;
UNUSED(task);
@ -1117,8 +1129,16 @@ resolve_done(isc_task_t *task, isc_event_t *event) {
if (!resarg->canceled) {
UNLOCK(&resarg->lock);
/* Exit from the internal event loop */
isc_app_ctxsuspend(resarg->actx);
/*
* We may or may not be running. isc__appctx_onrun will
* fail if we are currently running otherwise we post a
* action to call isc_app_ctxsuspend when we do start
* running.
*/
result = isc_app_ctxonrun(resarg->actx, resarg->client->mctx,
task, suspend, resarg->actx);
if (result == ISC_R_ALREADYRUNNING)
isc_app_ctxsuspend(resarg->actx);
} else {
/*
* We have already exited from the loop (due to some
@ -1310,9 +1330,8 @@ dns_client_startresolve(dns_client_t *client, dns_name_t *name,
ISC_LIST_APPEND(client->resctxs, rctx, link);
UNLOCK(&client->lock);
client_resfind(rctx, NULL);
*transp = (dns_clientrestrans_t *)rctx;
client_resfind(rctx, NULL);
return (ISC_R_SUCCESS);

View file

@ -90,6 +90,16 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
return (ctx->methods->ctxrun(ctx));
}
isc_result_t
isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx,
isc_task_t *task, isc_taskaction_t action,
void *arg)
{
REQUIRE(ISCAPI_APPCTX_VALID(ctx));
return (ctx->methods->ctxonrun(ctx, mctx, task, action, arg));
}
isc_result_t
isc_app_ctxsuspend(isc_appctx_t *ctx) {
REQUIRE(ISCAPI_APPCTX_VALID(ctx));

View file

@ -117,6 +117,9 @@ typedef struct isc_appmethods {
isc_socketmgr_t *timermgr);
void (*settimermgr)(isc_appctx_t *ctx,
isc_timermgr_t *timermgr);
isc_result_t (*ctxonrun)(isc_appctx_t *ctx, isc_mem_t *mctx,
isc_task_t *task, isc_taskaction_t action,
void *arg);
} isc_appmethods_t;
/*%
@ -153,10 +156,13 @@ isc_app_start(void);
* close to the beginning of the application as possible.
*
* Requires:
* 'ctx' is a valid application context (for app_ctxstart()).
*\li 'ctx' is a valid application context (for app_ctxstart()).
*/
isc_result_t
isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task,
isc_taskaction_t action, void *arg);
isc_result_t
isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
void *arg);
/*!<
@ -164,6 +170,7 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
*
* Requires:
*\li isc_app_start() has been called.
*\li 'ctx' is a valid application context (for app_ctxonrun()).
*
* Returns:
* ISC_R_SUCCESS

View file

@ -107,6 +107,11 @@ ISC_APPFUNC_SCOPE void isc__appctx_setsocketmgr(isc_appctx_t *ctx,
isc_socketmgr_t *socketmgr);
ISC_APPFUNC_SCOPE void isc__appctx_settimermgr(isc_appctx_t *ctx,
isc_timermgr_t *timermgr);
ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxonrun(isc_appctx_t *ctx,
isc_mem_t *mctx,
isc_task_t *task,
isc_taskaction_t action,
void *arg);
/*
* The application context of this module. This implementation actually
@ -148,8 +153,7 @@ static struct {
* The following are defined just for avoiding unused static functions.
*/
#ifndef BIND9
void *run, *shutdown, *start, *onrun, *reload, *finish,
*block, *unblock;
void *run, *shutdown, *start, *reload, *finish, *block, *unblock;
#endif
} appmethods = {
{
@ -161,7 +165,8 @@ static struct {
isc__app_ctxfinish,
isc__appctx_settaskmgr,
isc__appctx_setsocketmgr,
isc__appctx_settimermgr
isc__appctx_settimermgr,
isc__app_ctxonrun
}
#ifndef BIND9
,
@ -387,13 +392,22 @@ ISC_APPFUNC_SCOPE isc_result_t
isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
void *arg)
{
return (isc__app_ctxonrun((isc_appctx_t *)&isc_g_appctx, mctx,
task, action, arg));
}
isc_result_t
isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task,
isc_taskaction_t action, void *arg)
{
isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_event_t *event;
isc_task_t *cloned_task = NULL;
isc_result_t result;
LOCK(&isc_g_appctx.lock);
LOCK(&ctx->lock);
if (isc_g_appctx.running) {
if (ctx->running) {
result = ISC_R_ALREADYRUNNING;
goto unlock;
}
@ -410,12 +424,12 @@ isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
goto unlock;
}
ISC_LIST_APPEND(isc_g_appctx.on_run, event, ev_link);
ISC_LIST_APPEND(ctx->on_run, event, ev_link);
result = ISC_R_SUCCESS;
unlock:
UNLOCK(&isc_g_appctx.lock);
UNLOCK(&ctx->lock);
return (result);
}