Skip to content

Commit

Permalink
cares: fix set_servers during active queries
Browse files Browse the repository at this point in the history
`ares_set_servers()` should terminate all active queries to previous
servers before destroying them.

When invoking query callback remove it from the queue, to ensure that it
won't be called two times.

Fix: nodejs#894
  • Loading branch information
indutny committed Feb 20, 2015
1 parent 9b6b055 commit 4c09623
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
3 changes: 2 additions & 1 deletion deps/cares/src/ares_cancel.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ void ares_cancel(ares_channel channel)
{
query = list_node->data;
list_node = list_node->next; /* since we're deleting the query */
ares__free_query_pre(query);
query->callback(query->arg, ARES_ECANCELLED, 0, NULL, 0);
ares__free_query(query);
ares__free_query_post(query);
}
}
if (!(channel->flags & ARES_FLAG_STAYOPEN) && ares__is_list_empty(&(channel->all_queries)))
Expand Down
46 changes: 23 additions & 23 deletions deps/cares/src/ares_destroy.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,32 @@ void ares_destroy_options(struct ares_options *options)
void ares_destroy(ares_channel channel)
{
int i;

ares__destroy_servers_state(channel);

if (channel->domains) {
for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]);
free(channel->domains);
}

if(channel->sortlist)
free(channel->sortlist);

if (channel->lookups)
free(channel->lookups);

free(channel);
}

void ares__destroy_servers_state(ares_channel channel)
{
struct server_state *server;
int i;
struct query *query;
struct list_node* list_head;
struct list_node* list_node;

if (!channel)
return;

Expand All @@ -71,28 +93,6 @@ void ares_destroy(ares_channel channel)
}
#endif

ares__destroy_servers_state(channel);

if (channel->domains) {
for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]);
free(channel->domains);
}

if(channel->sortlist)
free(channel->sortlist);

if (channel->lookups)
free(channel->lookups);

free(channel);
}

void ares__destroy_servers_state(ares_channel channel)
{
struct server_state *server;
int i;

if (channel->servers)
{
for (i = 0; i < channel->nservers; i++)
Expand Down
2 changes: 2 additions & 0 deletions deps/cares/src/ares_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ void ares__close_sockets(ares_channel channel, struct server_state *server);
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
void ares__free_query(struct query *query);
void ares__free_query_pre(struct query *query);
void ares__free_query_post(struct query *query);
unsigned short ares__generate_new_id(rc4_key* key);
struct timeval ares__tvnow(void);
int ares__expand_name_for_response(const unsigned char *encoded,
Expand Down
16 changes: 14 additions & 2 deletions deps/cares/src/ares_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1298,9 +1298,11 @@ static void end_query (ares_channel channel, struct query *query, int status,
}
}

ares__free_query_pre(query);

/* Invoke the callback */
query->callback(query->arg, status, query->timeouts, abuf, alen);
ares__free_query(query);
ares__free_query_post(query);

/* Simple cleanup policy: if no queries are remaining, close all network
* sockets unless STAYOPEN is set.
Expand All @@ -1313,13 +1315,17 @@ static void end_query (ares_channel channel, struct query *query, int status,
}
}

void ares__free_query(struct query *query)
void ares__free_query_pre(struct query *query)
{
/* Remove the query from all the lists in which it is linked */
ares__remove_from_list(&(query->queries_by_qid));
ares__remove_from_list(&(query->queries_by_timeout));
ares__remove_from_list(&(query->queries_to_server));
ares__remove_from_list(&(query->all_queries));
}

void ares__free_query_post(struct query *query)
{
/* Zero out some important stuff, to help catch bugs */
query->callback = NULL;
query->arg = NULL;
Expand All @@ -1328,3 +1334,9 @@ void ares__free_query(struct query *query)
free(query->server_info);
free(query);
}

void ares__free_query(struct query *query)
{
ares__free_query_pre(query);
ares__free_query_post(query);
}

0 comments on commit 4c09623

Please sign in to comment.