summaryrefslogtreecommitdiff
path: root/src/dnsproxy.c
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2012-01-09 16:08:53 -0800
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-10 13:43:57 +0100
commit8252d73cdc5f1686fef035d6ea8ce27ed29bf5d1 (patch)
tree678e699c149fe8ea223395eb93c9bf7e5bc49ffb /src/dnsproxy.c
parent475c2450978e5354370756402b4f88e58c84f30a (diff)
downloadconnman-8252d73cdc5f1686fef035d6ea8ce27ed29bf5d1.tar.gz
connman-8252d73cdc5f1686fef035d6ea8ce27ed29bf5d1.tar.bz2
connman-8252d73cdc5f1686fef035d6ea8ce27ed29bf5d1.zip
dnsproxy: Add a "invalidate cache" function
When something changes in the network topology, we need to invalidate the cache. This first implementation will delete all entries (which could have been done more efficiently), but in later patches in this series we'll enhance this logic to only delete the cached data, not the names. With keeping the names, we can then re-lookup popular data in the new topology.
Diffstat (limited to 'src/dnsproxy.c')
-rw-r--r--src/dnsproxy.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 730b0333..b97b1d49 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -1028,6 +1028,44 @@ static void cache_cleanup(void)
max_timeout = 0;
}
+static gboolean cache_invalidate_entry(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct cache_entry *entry = value;
+
+ /* first, delete any expired elements */
+ cache_enforce_validity(entry);
+
+ /* delete the cached data */
+ if (entry->ipv4) {
+ g_free(entry->ipv4->data);
+ g_free(entry->ipv4);
+ entry->ipv4 = NULL;
+ }
+
+ if (entry->ipv6) {
+ g_free(entry->ipv6->data);
+ g_free(entry->ipv6);
+ entry->ipv6 = NULL;
+ }
+
+ return TRUE;
+}
+
+/*
+ * cache_invalidate is called from places where the DNS landscape
+ * has changed, say because connections are added or we entered a VPN.
+ * The logic is to wipe all cache data, but mark all non-expired
+ * parts of the cache for refresh rather than deleting the whole cache.
+ */
+static void cache_invalidate(void)
+{
+ DBG("Invalidating the DNS cache");
+ g_hash_table_foreach_remove(cache, cache_invalidate_entry,
+ NULL);
+}
+
+
static int reply_query_type(unsigned char *msg, int len)
{
unsigned char *c;
@@ -2014,9 +2052,11 @@ static void dnsproxy_offline_mode(connman_bool_t enabled)
if (enabled == FALSE) {
connman_info("Enabling DNS server %s", data->server);
data->enabled = TRUE;
+ cache_invalidate();
} else {
connman_info("Disabling DNS server %s", data->server);
data->enabled = FALSE;
+ cache_invalidate();
}
}
}
@@ -2028,6 +2068,9 @@ static void dnsproxy_default_changed(struct connman_service *service)
DBG("service %p", service);
+ /* DNS has changed, invalidate the cache */
+ cache_invalidate();
+
if (service == NULL) {
/* When no services are active, then disable DNS proxying */
dnsproxy_offline_mode(TRUE);