int i;
struct query *query;
- for (i = 0; i < channel->nservers; i++)
- ares__close_sockets(channel, &channel->servers[i]);
- free(channel->servers);
- for (i = 0; i < channel->ndomains; i++)
- free(channel->domains[i]);
- free(channel->domains);
+ if (!channel)
+ return;
+
+ if (channel->servers) {
+ for (i = 0; i < channel->nservers; i++)
+ ares__close_sockets(channel, &channel->servers[i]);
+ free(channel->servers);
+ }
+
+ if (channel->domains) {
+ for (i = 0; i < channel->ndomains; i++)
+ free(channel->domains[i]);
+ free(channel->domains);
+ }
+
if(channel->sortlist)
free(channel->sortlist);
- free(channel->lookups);
- while (channel->queries)
- {
- query = channel->queries;
- channel->queries = query->next;
- query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+
+ if (channel->lookups)
+ free(channel->lookups);
+
+ while (channel->queries) {
+ query = channel->queries;
+ channel->queries = query->next;
+ query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+ if (query->tcpbuf)
free(query->tcpbuf);
+ if (query->skip_server)
free(query->skip_server);
- free(query);
- }
+ free(query);
+ }
+
free(channel);
}
channel->queries = NULL;
channel->domains = NULL;
channel->sortlist = NULL;
+ channel->servers = NULL;
channel->sock_state_cb = NULL;
+ channel->sock_state_cb_data = NULL;
/* Initialize configuration by each of the four sources, from highest
* precedence to lowest.
if (status != ARES_SUCCESS)
{
/* Something failed; clean up memory we may have allocated. */
- if (channel->nservers != -1)
+ if (channel->servers)
free(channel->servers);
if (channel->domains)
{
/* Copy the servers, if given. */
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
{
- channel->servers =
- malloc(options->nservers * sizeof(struct server_state));
- if (!channel->servers && options->nservers != 0)
- return ARES_ENOMEM;
- for (i = 0; i < options->nservers; i++)
- channel->servers[i].addr = options->servers[i];
+ /* Avoid zero size allocations at any cost */
+ if (options->nservers > 0)
+ {
+ channel->servers =
+ malloc(options->nservers * sizeof(struct server_state));
+ if (!channel->servers)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->nservers; i++)
+ channel->servers[i].addr = options->servers[i];
+ }
channel->nservers = options->nservers;
}
*/
if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
{
- channel->domains = malloc(options->ndomains * sizeof(char *));
- if (!channel->domains && options->ndomains != 0)
- return ARES_ENOMEM;
- for (i = 0; i < options->ndomains; i++)
- {
- channel->ndomains = i;
- channel->domains[i] = strdup(options->domains[i]);
- if (!channel->domains[i])
- return ARES_ENOMEM;
- }
+ /* Avoid zero size allocations at any cost */
+ if (options->ndomains > 0)
+ {
+ channel->domains = malloc(options->ndomains * sizeof(char *));
+ if (!channel->domains)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->ndomains; i++)
+ {
+ channel->ndomains = i;
+ channel->domains[i] = strdup(options->domains[i]);
+ if (!channel->domains[i])
+ return ARES_ENOMEM;
+ }
+ }
channel->ndomains = options->ndomains;
}
if (gethostname(hostname, sizeof(hostname)) == -1
|| !strchr(hostname, '.'))
{
- channel->domains = malloc(0);
channel->ndomains = 0;
}
else
for(n=0; n < channel->ndomains; n++)
free(channel->domains[n]);
free(channel->domains);
+ channel->domains = NULL;
channel->ndomains = -1;
}
n++;
}
+ if (!n)
+ {
+ channel->ndomains = 0;
+ return ARES_SUCCESS;
+ }
+
channel->domains = malloc(n * sizeof(char *));
- if (!channel->domains && n)
+ if (!channel->domains)
return ARES_ENOMEM;
/* Now copy the domains. */