From 3d849d116f85c656a97d07937f73307399babc07 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 9 Jan 2012 16:08:25 -0800 Subject: [PATCH] dnsproxy: Delete expired cache entries when they expire The DNS cache has logic to never replace cached data if it already exists. However, this only works well if we actually delete the data parts of the cache entries as they expire. This patch creates a cache_enforce_validity() function, which will delete the data portion of cache entries if they are expired. With this in place, consecutive lookups of the same name can get cached again. --- src/dnsproxy.c | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index cdc5b11..4810c6e 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -422,23 +422,50 @@ static gboolean cache_check_is_valid(struct cache_data *data, return TRUE; } +/* + * remove stale cached entries so that they can be refreshed + */ +static void cache_enforce_validity(struct cache_entry *entry) +{ + time_t current_time = time(0); + + if (cache_check_is_valid(entry->ipv4, current_time) == FALSE + && entry->ipv4) { + DBG("cache timeout \"%s\" type A", entry->key); + g_free(entry->ipv4->data); + g_free(entry->ipv4); + entry->ipv4 = NULL; + + } + + if (cache_check_is_valid(entry->ipv6, current_time) == FALSE + && entry->ipv6) { + DBG("cache timeout \"%s\" type AAAA", entry->key); + g_free(entry->ipv6->data); + g_free(entry->ipv6); + entry->ipv6 = NULL; + } +} + + static uint16_t cache_check_validity(char *question, uint16_t type, - struct cache_data *ipv4, - struct cache_data *ipv6) + struct cache_entry *entry) { time_t current_time = time(0); + cache_enforce_validity(entry); + switch (type) { case 1: /* IPv4 */ - if (cache_check_is_valid(ipv4, current_time) == FALSE) { - DBG("cache %s \"%s\" type A", - ipv4 ? "timeout" : "entry missing", question); + if (cache_check_is_valid(entry->ipv4, current_time) == FALSE) { + DBG("cache %s \"%s\" type A", entry->ipv4 ? + "timeout" : "entry missing", question); /* * We do not remove cache entry if there is still * valid IPv6 entry found in the cache. */ - if (cache_check_is_valid(ipv6, current_time) == FALSE) + if (cache_check_is_valid(entry->ipv6, current_time) == FALSE) g_hash_table_remove(cache, question); type = 0; @@ -446,11 +473,11 @@ static uint16_t cache_check_validity(char *question, uint16_t type, break; case 28: /* IPv6 */ - if (cache_check_is_valid(ipv6, current_time) == FALSE) { - DBG("cache %s \"%s\" type AAAA", - ipv6 ? "timeout" : "entry missing", question); + if (cache_check_is_valid(entry->ipv6, current_time) == FALSE) { + DBG("cache %s \"%s\" type AAAA", entry->ipv6 ? + "timeout" : "entry missing", question); - if (cache_check_is_valid(ipv4, current_time) == FALSE) + if (cache_check_is_valid(entry->ipv4, current_time) == FALSE) g_hash_table_remove(cache, question); type = 0; @@ -481,7 +508,7 @@ static struct cache_entry *cache_check(gpointer request, int *qtype) if (entry == NULL) return NULL; - type = cache_check_validity(question, type, entry->ipv4, entry->ipv6); + type = cache_check_validity(question, type, entry); if (type == 0) return NULL; -- 2.7.4