diff --git a/src/lib/ares_qcache.c b/src/lib/ares_qcache.c index cf841dcb..e1ee3cc3 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->sec) { + + /* If now is NULL, we're flushing everything, so don't break */ + if (now != NULL && entry->expire_ts > now->sec) { break; } @@ -158,9 +160,7 @@ static void ares__qcache_expire(ares__qcache_t *cache, void ares__qcache_flush(ares__qcache_t *cache) { - ares_timeval_t 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 a3e9f0d0..181dbb39 100644 --- a/src/lib/ares_update_servers.c +++ b/src/lib/ares_update_servers.c @@ -671,9 +671,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) { @@ -683,9 +684,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) @@ -702,6 +705,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; @@ -747,13 +751,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) { @@ -765,8 +773,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;