QueryCache: Fix flushing on server list changes

The query cache wasn't properly flushing on server list changes
and was attempting to flush even when the server list didn't
actually change.

Fix By: Brad House (@bradh352)
pull/774/head
Brad House 8 months ago
parent 1dff8f6576
commit a6c8fe685d
  1. 8
      src/lib/ares_qcache.c
  2. 20
      src/lib/ares_update_servers.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)

@ -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;

Loading…
Cancel
Save