diff --git a/src/lib/ares_qcache.c b/src/lib/ares_qcache.c index 2af1125a..97a6ab38 100644 --- a/src/lib/ares_qcache.c +++ b/src/lib/ares_qcache.c @@ -147,7 +147,9 @@ static void ares__qcache_expire(ares__qcache_t *cache, while ((node = ares__slist_node_first(cache->expire)) != NULL) { const ares__qcache_entry_t *entry = ares__slist_node_val(node); - if (entry->expire_ts > now->tv_sec) { + + /* If now is NULL, we're flushing everything, so don't break */ + if (now != NULL && entry->expire_ts > now->tv_sec) { break; } @@ -158,9 +160,7 @@ static void ares__qcache_expire(ares__qcache_t *cache, void ares__qcache_flush(ares__qcache_t *cache) { - struct timeval now; - memset(&now, 0, sizeof(now)); - ares__qcache_expire(cache, &now); + ares__qcache_expire(cache, NULL /* flush all */); } void ares__qcache_destroy(ares__qcache_t *cache) diff --git a/src/lib/ares_update_servers.c b/src/lib/ares_update_servers.c index fce79147..83e46716 100644 --- a/src/lib/ares_update_servers.c +++ b/src/lib/ares_update_servers.c @@ -663,9 +663,10 @@ static ares_bool_t ares__server_in_newconfig(const struct server_state *server, return ARES_FALSE; } -static void ares__servers_remove_stale(ares_channel_t *channel, - ares__llist_t *srvlist) +static ares_bool_t ares__servers_remove_stale(ares_channel_t *channel, + ares__llist_t *srvlist) { + ares_bool_t stale_removed = ARES_FALSE; ares__slist_node_t *snode = ares__slist_node_first(channel->servers); while (snode != NULL) { @@ -675,9 +676,11 @@ static void ares__servers_remove_stale(ares_channel_t *channel, /* This will clean up all server state via the destruction callback and * move any queries to new servers */ ares__slist_node_destroy(snode); + stale_removed = ARES_TRUE; } snode = snext; } + return stale_removed; } static void ares__servers_trim_single(ares_channel_t *channel) @@ -694,6 +697,7 @@ ares_status_t ares__servers_update(ares_channel_t *channel, ares__llist_node_t *node; size_t idx = 0; ares_status_t status; + ares_bool_t list_changed = ARES_FALSE; if (channel == NULL) { return ARES_EFORMERR; @@ -739,13 +743,17 @@ ares_status_t ares__servers_update(ares_channel_t *channel, if (status != ARES_SUCCESS) { goto done; } + + list_changed = ARES_TRUE; } idx++; } /* Remove any servers that don't exist in the current configuration */ - ares__servers_remove_stale(channel, server_list); + if (ares__servers_remove_stale(channel, server_list)) { + list_changed = ARES_TRUE; + } /* Trim to one server if ARES_FLAG_PRIMARY is set. */ if (channel->flags & ARES_FLAG_PRIMARY) { @@ -757,8 +765,10 @@ ares_status_t ares__servers_update(ares_channel_t *channel, channel->optmask |= ARES_OPT_SERVERS; } - /* Clear any cached query results */ - ares__qcache_flush(channel->qcache); + /* Clear any cached query results only if the server list changed */ + if (list_changed) { + ares__qcache_flush(channel->qcache); + } status = ARES_SUCCESS;