From e4daefbadc9c518cf897338424c6b1c09df7e39e Mon Sep 17 00:00:00 2001
From: Viktor Krykun <viktor@krykun.com>
Date: Fri, 15 Jun 2012 10:23:13 +0300
Subject: [PATCH] Flush zrtp cache automatically

Add option to flush zrtp cache to persistent storage automatically
immediately after the cache is modified. See
zrtp_config_t#cache_auto_store.

Modified-by: Travis Cross <tc@traviscross.com>
Signed-off-by: Travis Cross <tc@traviscross.com>
---
 libs/libzrtp/include/zrtp.h         | 11 +++++++++++
 libs/libzrtp/src/zrtp.c             |  3 +++
 libs/libzrtp/src/zrtp_iface_cache.c | 14 +++++++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/libs/libzrtp/include/zrtp.h b/libs/libzrtp/include/zrtp.h
index 44bd194843..88f549e025 100644
--- a/libs/libzrtp/include/zrtp.h
+++ b/libs/libzrtp/include/zrtp.h
@@ -161,6 +161,17 @@ typedef struct zrtp_config_t
 
 	/** @brief Path to zrtp cache file (set if you use built-in realization) */
 	zrtp_string256_t		def_cache_path;
+
+	/**
+	 * @brief Flush the cache automatically
+	 * Set to 1 if you want libzrtp to flush the cache to the persistent storage
+	 * right after it is modified. If cache_auto_store is 0, libzrtp will flush
+	 * the cache on going down only and the app is responsible for storing the
+	 * cache in unexpected situations. Enabled by default.
+	 *
+	 * @sa zrtp_def_cache_store()
+	 */
+	unsigned				cache_auto_store;
 } zrtp_config_t;
 
 /**
diff --git a/libs/libzrtp/src/zrtp.c b/libs/libzrtp/src/zrtp.c
index 139d0b733d..9ee078082b 100644
--- a/libs/libzrtp/src/zrtp.c
+++ b/libs/libzrtp/src/zrtp.c
@@ -34,6 +34,8 @@ void zrtp_config_defaults(zrtp_config_t* config)
 	ZSTR_SET_EMPTY(config->def_cache_path);
 	zrtp_zstrncpyc(ZSTR_GV(config->def_cache_path), "./zrtp_def_cache_path.dat", 25);
 
+	config->cache_auto_store = 1; /* cache auto flushing should be enabled by default */
+
 #if (defined(ZRTP_USE_BUILTIN_CACHE) && (ZRTP_USE_BUILTIN_CACHE == 1))
 	config->cb.cache_cb.on_init					= zrtp_def_cache_init;
 	config->cb.cache_cb.on_down					= zrtp_def_cache_down;
@@ -81,6 +83,7 @@ zrtp_status_t zrtp_init(zrtp_config_t* config, zrtp_global_t** zrtp)
 	ZSTR_SET_EMPTY(new_zrtp->def_cache_path);
 	zrtp_zstrcpy(ZSTR_GV(new_zrtp->def_cache_path), ZSTR_GV(config->def_cache_path));
 	zrtp_memcpy(&new_zrtp->cb, &config->cb, sizeof(zrtp_callback_t));
+	new_zrtp->cache_auto_store = config->cache_auto_store;
         
 	ZSTR_SET_EMPTY(new_zrtp->client_id);
 	zrtp_memset(new_zrtp->client_id.buffer, ' ', sizeof(zrtp_client_id_t));
diff --git a/libs/libzrtp/src/zrtp_iface_cache.c b/libs/libzrtp/src/zrtp_iface_cache.c
index 204546b079..c7f187b9ab 100644
--- a/libs/libzrtp/src/zrtp_iface_cache.c
+++ b/libs/libzrtp/src/zrtp_iface_cache.c
@@ -82,7 +82,9 @@ void zrtp_def_cache_down()
 	if (inited) {
 		mlist_t *node = NULL, *tmp = NULL;				
 		
-		zrtp_cache_user_down();
+		/* If automatic cache flushing enabled we don't need to store it in a disk as it should be already in sync. */
+		if (!zrtp->cache_auto_store)
+			zrtp_cache_user_down();
 
 		mlist_for_each_safe(node, tmp, &cache_head) {
 			zrtp_sys_free(mlist_get_struct(zrtp_cache_elem_t, _mlist, node));
@@ -119,6 +121,8 @@ zrtp_status_t zrtp_def_cache_set_verified( const zrtp_stringn_t* one_ZID,
 	}
 	zrtp_mutex_unlock(def_cache_protector);
 	
+	if (zrtp->cache_auto_store) zrtp_def_cache_store(zrtp);
+
 	return (new_elem) ? zrtp_status_ok : zrtp_status_fail;
 }
 
@@ -211,6 +215,8 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
 	} while (0);
 	zrtp_mutex_unlock(def_cache_protector);
 
+	if (zrtp->cache_auto_store) zrtp_def_cache_store(zrtp);
+
     return (new_elem) ? zrtp_status_ok : zrtp_status_fail;
 }
 
@@ -304,6 +310,8 @@ zrtp_status_t zrtp_def_cache_set_presh_counter( const zrtp_stringn_t* one_zid,
 	}
 	zrtp_mutex_unlock(def_cache_protector);
 	
+	if (zrtp->cache_auto_store) zrtp_def_cache_store(zrtp);
+
 	return (new_elem) ? zrtp_status_ok : zrtp_status_fail;
 }
 
@@ -783,6 +791,8 @@ static zrtp_status_t put_name( const zrtp_stringn_t* one_ZID,
 	} while (0);
 	zrtp_mutex_unlock(def_cache_protector);
 	
+	if (zrtp->cache_auto_store) zrtp_def_cache_store(zrtp);
+
 	return s;
 }
 
@@ -872,6 +882,8 @@ zrtp_status_t zrtp_def_cache_reset_since( const zrtp_stringn_t* one_zid,
 	}
 	zrtp_mutex_unlock(def_cache_protector);
 	
+	if (zrtp->cache_auto_store) zrtp_def_cache_store(zrtp);
+
 	return (new_elem) ? zrtp_status_ok : zrtp_status_fail;
 }