diff options
author | Martin Nagy <mnagy@redhat.com> | 2010-01-13 19:42:21 +0100 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-01-14 09:00:08 -0500 |
commit | 1780b903ca4b2f59735acdcd436b27ff7de21976 (patch) | |
tree | 7d5f382ea61f9697e99005855ef7acbbd42fb6b6 /server/resolv | |
parent | 9654795a488f0094f525ef505353fd5de4e6878f (diff) | |
download | sssd-1780b903ca4b2f59735acdcd436b27ff7de21976.tar.gz sssd-1780b903ca4b2f59735acdcd436b27ff7de21976.tar.bz2 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/resolv')
-rw-r--r-- | server/resolv/async_resolv.c | 16 |
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); |