From dae33533eaefea2c78fc24f3ecccb59e4b9edd21 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 25 Apr 2012 10:41:59 +0300 Subject: [PATCH] dnsproxy: Delay cache removal The idea here is to delay cache removal few seconds if there are no cache users any more (refcount goes to 0). This is useful for IPv6 RDNSS where new DNS servers are created right after old one is removed. In this case we do not want to loose the cache that still has perfectly valid data. --- src/dnsproxy.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 4033f2a..5006739 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -1627,6 +1627,18 @@ static void cache_element_destroy(gpointer value) cache_size = 0; } +static gboolean try_remove_cache(gpointer user_data) +{ + if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) { + DBG("No cache users, removing it."); + + g_hash_table_destroy(cache); + cache = NULL; + } + + return FALSE; +} + static void destroy_server(struct server_data *server) { GList *list; @@ -1656,10 +1668,16 @@ static void destroy_server(struct server_data *server) } g_free(server->interface); - if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) { - g_hash_table_destroy(cache); - cache = NULL; - } + /* + * We do not remove cache right away but delay it few seconds. + * The idea is that when IPv6 DNS server is added via RDNSS, it has a + * lifetime. When the lifetime expires we decrease the refcount so it + * is possible that the cache is then removed. Because a new DNS server + * is usually created almost immediately we would then loose the cache + * without any good reason. The small delay allows the new RDNSS to + * create a new DNS server instance and the refcount does not go to 0. + */ + g_timeout_add_seconds(3, try_remove_cache, NULL); g_free(server); } -- 2.7.4