summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2010-01-13 19:42:21 +0100
committerStephen Gallagher <sgallagh@redhat.com>2010-01-14 09:09:45 -0500
commit06296dd5e75fb93733623bce519a8efda52871fe (patch)
tree4b2b5f98c1ea1268ab5e424a08d1c79fecec978a
parent995d26977acbb705e17ff9c01558d9d64208058d (diff)
downloadsssd_unused-06296dd5e75fb93733623bce519a8efda52871fe.tar.gz
sssd_unused-06296dd5e75fb93733623bce519a8efda52871fe.tar.xz
sssd_unused-06296dd5e75fb93733623bce519a8efda52871fe.zip
Make sure callbacks never retry when ares channel is destroyed
When the resolv context destructor is invoked, the callbacks for pending queries could have been called with ARES_EDESTRUCTION and try to re-send the query.
-rw-r--r--server/resolv/async_resolv.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/server/resolv/async_resolv.c b/server/resolv/async_resolv.c
index ff84b386..0be79185 100644
--- a/server/resolv/async_resolv.c
+++ b/server/resolv/async_resolv.c
@@ -272,6 +272,8 @@ fd_event_close(struct resolv_ctx *ctx, int s)
static int
resolv_ctx_destructor(struct resolv_ctx *ctx)
{
+ ares_channel channel;
+
DLIST_REMOVE(context_list, ctx);
if (ctx->channel == NULL) {
@@ -279,8 +281,11 @@ resolv_ctx_destructor(struct resolv_ctx *ctx)
return -1;
}
- ares_destroy(ctx->channel);
+ /* Set ctx->channel to NULL first, so that callbacks that get
+ * ARES_EDESTRUCTION won't retry. */
+ channel = ctx->channel;
ctx->channel = NULL;
+ ares_destroy(channel);
return 0;
}
@@ -489,7 +494,8 @@ resolv_gethostbyname_done(void *arg, int status, int timeouts, struct hostent *h
struct tevent_req *req = talloc_get_type(arg, struct tevent_req);
struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);
- if (state->retrying == 0 && status == ARES_EDESTRUCTION) {
+ if (state->retrying == 0 && status == ARES_EDESTRUCTION
+ && state->resolv_ctx->channel != NULL) {
state->retrying = 1;
ares_gethostbyname(state->resolv_ctx->channel, state->name,
state->family, resolv_gethostbyname_done, req);
@@ -692,7 +698,8 @@ resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int
int ret;
struct ares_srv_reply *reply_list;
- if (state->retrying == 0 && status == ARES_EDESTRUCTION) {
+ if (state->retrying == 0 && status == ARES_EDESTRUCTION
+ && state->resolv_ctx->channel != NULL) {
state->retrying = 1;
ares_query(state->resolv_ctx->channel, state->query,
ns_c_in, ns_t_srv, resolv_getsrv_done, req);
@@ -895,7 +902,8 @@ resolv_gettxt_done(void *arg, int status, int timeouts, unsigned char *abuf, int
int ret;
struct ares_txt_reply *reply_list;
- if (state->retrying == 0 && status == ARES_EDESTRUCTION) {
+ if (state->retrying == 0 && status == ARES_EDESTRUCTION
+ && state->resolv_ctx->channel != NULL) {
state->retrying = 1;
ares_query(state->resolv_ctx->channel, state->query,
ns_c_in, ns_t_txt, resolv_gettxt_done, req);