summaryrefslogtreecommitdiffstats
path: root/server
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:00:08 -0500
commit1780b903ca4b2f59735acdcd436b27ff7de21976 (patch)
tree7d5f382ea61f9697e99005855ef7acbbd42fb6b6 /server
parent9654795a488f0094f525ef505353fd5de4e6878f (diff)
downloadsssd-1780b903ca4b2f59735acdcd436b27ff7de21976.tar.gz
sssd-1780b903ca4b2f59735acdcd436b27ff7de21976.tar.xz
sssd-1780b903ca4b2f59735acdcd436b27ff7de21976.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.
Diffstat (limited to 'server')
-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 ff84b386d..0be791851 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);