First draft implementation of random-access cache

(refs #25)
This commit is contained in:
Viktor Krikun 2011-11-25 19:13:16 +00:00 committed by Travis Cross
parent be03cdc27a
commit e8a376a87f
5 changed files with 326 additions and 50 deletions

View File

@ -34,8 +34,8 @@ extern "C"
*/
typedef uint8_t zrtp_cache_id_t[24];
#define ZRTP_MITMCACHE_ELEM_LENGTH (sizeof(zrtp_cache_id_t) + sizeof(zrtp_string64_t))
#define ZRTP_CACHE_ELEM_LENGTH (sizeof(zrtp_cache_elem_t) - sizeof(mlist_t))
#define ZRTP_MITMCACHE_ELEM_LENGTH ( sizeof(zrtp_cache_id_t) + sizeof(zrtp_string64_t) )
#define ZRTP_CACHE_ELEM_LENGTH ( sizeof(zrtp_cache_elem_t) - sizeof(mlist_t) - (sizeof(uint32_t)*2) )
#define ZFONE_CACHE_NAME_LENGTH 256
/**
@ -51,10 +51,12 @@ typedef struct zrtp_cache_elem
uint32_t verified; /** Verified flag for the cache value */
uint32_t lastused_at; /** Last usage time-stamp in seconds */
uint32_t ttl; /** Cache TTL since lastused_at in seconds */
uint32_t secure_since; /** Secure since date in seconds. Utility field. Doen't required by libzrtp. */
uint32_t secure_since; /** Secure since date in seconds. Utility field. Don't required by libzrtp. */
char name[ZFONE_CACHE_NAME_LENGTH]; /** name of the user associated with this cache entry */
uint32_t name_length; /** cache name lengths */
uint32_t presh_counter; /** number of Preshared streams made since last DH echange */
uint32_t presh_counter; /** number of Preshared streams made since last DH exchange */
uint32_t _index; /** cache element index in the cache file */
uint32_t _is_dirty; /** dirty flag means the entry has unsaved changes */
mlist_t _mlist;
} zrtp_cache_elem_t;

View File

@ -359,6 +359,7 @@ struct zrtp_global_t
/** RNG unit initialization flag. */
uint8_t rand_initialized;
/** Full path to ZRTP cache file. */
zrtp_string256_t def_cache_path;
/** This object is used to protect the shared RNG hash zrtp#rand_ctx */

View File

@ -11,33 +11,47 @@ TOP_SRCDIR=$(top_srcdir)/../..
INCLUDES = -I$(TOP_SRCDIR)/include \
-I$(TOP_SRCDIR)/include/enterprise \
-I$(TOP_SRCDIR)/. \
-I$(TOP_SRCDIR)/test \
-I$(TOP_SRCDIR)/test/cmockery \
-I$(TOP_SRCDIR)/third_party/bgaes \
-I$(TOP_SRCDIR)/third_party/bnlib
check_PROGRAMS = libzrtp_test
#check_PROGRAMS = cache_test libzrtp_test
check_PROGRAMS = cache_test
### ZRTP Cache testing
cache_test_SOURCES = $(TOP_SRCDIR)/test/cmockery/cmockery.c \
$(TOP_SRCDIR)/test/cache_test.c
cache_test_LDADD = ../libzrtp.a $(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
### ZRTP high-level test-case
libzrtp_test_SOURCES = $(TOP_SRCDIR)/test/pc/zrtp_test_core.c \
$(TOP_SRCDIR)/test/pc/zrtp_test_crypto.c \
$(TOP_SRCDIR)/test/pc/zrtp_test_queue.c \
$(TOP_SRCDIR)/test/pc/zrtp_test_ui.c
libzrtp_test_LDADD = ../libzrtp.a \
$(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
libzrtp_test_LDADD = ../libzrtp.a $(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
SUBDIRS = .
check:
@echo ""
@echo "*========================================================================*"
@echo "* starting libZRTP tests *"
@echo "*========================================================================*"
@echo ""
@./libzrtp_test
check:
# @ ./cache_test
@echo ""
@echo "*========================================================================*"
@echo "* In case you have a test FAILED send the generated log file *"
@echo "* with your comment to <zrtp_support@zfoneproject.com>. *"
@echo "*========================================================================*"
@echo ""
# check:
# @echo ""
# @echo "*========================================================================*"
# @echo "* starting libZRTP tests *"
# @echo "*========================================================================*"
# @echo ""
# @./libzrtp_test
#
# @echo ""
# @echo "*========================================================================*"
# @echo "* In case you have a test FAILED send the generated log file *"
# @echo "* with your comment to <zrtp_support@zfoneproject.com>. *"
# @echo "*========================================================================*"
# @echo ""

View File

@ -18,7 +18,9 @@
#if (ZRTP_PLATFORM != ZP_WIN32_KERNEL)
static mlist_t cache_head;
static uint32_t g_cache_elems_counter = 0;
static mlist_t mitmcache_head;
static uint32_t g_mitmcache_elems_counter = 0;
static uint8_t inited = 0;
static zrtp_global_t* zrtp;
@ -95,6 +97,7 @@ void zrtp_def_cache_down()
zrtp_mutex_destroy(def_cache_protector);
inited = 0;
zrtp = NULL;
}
}
@ -158,7 +161,7 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
new_elem = get_elem(id, is_mitm);
if (!new_elem)
{
/* If cache doesn't exist - create ne one */
/* If cache doesn't exist - create new one */
if (!( new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t)) )) {
break;
}
@ -171,9 +174,15 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
mlist_add_tail(is_mitm ? &mitmcache_head : &cache_head, &new_elem->_mlist);
zrtp_memcpy(new_elem->id, id, sizeof(zrtp_cache_id_t));
if (is_mitm) {
new_elem->_index = g_mitmcache_elems_counter++;
} else {
new_elem->_index = g_cache_elems_counter++;
}
}
/* Save current cache value as previous one and new as a current */
/* Save current cache value as previous one and new as a current */
if (!is_mitm) {
if (new_elem->curr_cache.length > 0) {
zrtp_zstrcpy(ZSTR_GV(new_elem->prev_cache), ZSTR_GV(new_elem->curr_cache));
@ -185,6 +194,8 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
if (!is_mitm) {
new_elem->ttl = rss->ttl;
}
new_elem->_is_dirty = 1;
} while (0);
zrtp_mutex_unlock(def_cache_protector);
@ -193,7 +204,7 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
zrtp_status_t zrtp_def_cache_put( const zrtp_stringn_t* one_ZID,
const zrtp_stringn_t* another_ZID,
zrtp_shared_secret_t *rss) {
zrtp_shared_secret_t *rss) {
return cache_put(one_ZID, another_ZID, rss, 0);
}
@ -270,6 +281,8 @@ zrtp_status_t zrtp_def_cache_set_presh_counter( const zrtp_stringn_t* one_zid,
if (new_elem) {
ZRTP_LOG(3,(_ZTU_,"\tTEST! Update counter to %u.\n", counter));
new_elem->presh_counter = counter;
new_elem->_is_dirty = 1;
}
zrtp_mutex_unlock(def_cache_protector);
@ -394,6 +407,7 @@ zrtp_status_t zrtp_cache_user_init()
uint32_t i = 0;
unsigned is_unsupported = 0;
ZRTP_LOG(3,(_ZTU_,"\tLoad ZRTP cache from <%s>...\n", zrtp->def_cache_path.buffer));
/* Try to open existing file. If ther is no cache file - start with empty cache */
#if (ZRTP_PLATFORM == ZP_WIN32)
@ -402,6 +416,7 @@ zrtp_status_t zrtp_cache_user_init()
}
#else
if (0 == (cache_file = fopen(zrtp->def_cache_path.buffer, "rb"))) {
ZRTP_LOG(3,(_ZTU_,"\tCan't open file for reading.\n"));
return zrtp_status_ok;
}
#endif
@ -413,43 +428,50 @@ zrtp_status_t zrtp_cache_user_init()
*/
do {
char version_buff[256];
memset(version_buff, 0, sizeof(version_buff));
if (fread(version_buff, strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL), 1, cache_file) <= 0) {
ZRTP_LOG(3,(_ZTU_,"Cache file is too small.\n"));
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Cache file is too small.\n"));
is_unsupported = 1;
break;
}
if (0 != zrtp_memcmp(version_buff, ZRTP_DEF_CACHE_VERSION_STR, strlen(ZRTP_DEF_CACHE_VERSION_STR))) {
ZRTP_LOG(3,(_ZTU_,"Can't find ZRTP Version tag in the cache file.\n"));
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Can't find ZRTP Version tag in the cache file.\n"));
is_unsupported = 1;
break;
}
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file has version=%s\n", version_buff+strlen(ZRTP_DEF_CACHE_VERSION_STR)));
if (0 != zrtp_memcmp(version_buff+strlen(ZRTP_DEF_CACHE_VERSION_STR), ZRTP_DEF_CACHE_VERSION_VAL, strlen(ZRTP_DEF_CACHE_VERSION_VAL))) {
ZRTP_LOG(3,(_ZTU_,"Usupported ZRTP cache version.\n"));
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Unsupported ZRTP cache version.\n"));
is_unsupported = 1;
break;
}
}
} while (0);
if (is_unsupported) {
ZRTP_LOG(3,(_ZTU_,"Unsupported version of ZRTP cache file detected - white-out the cache.\n"));
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Unsupported version of ZRTP cache file detected - white-out the cache.\n"));
fclose(cache_file);
return zrtp_status_ok;
}
g_mitmcache_elems_counter = 0;
/*
* Load MitM caches: first 32 bits is a mitm secrets counter. Read it and then
* Load MitM caches: first 32 bits is a MiTM secrets counter. Read it and then
* upload appropriate number of MitM secrets.
*/
do {
cache_elems_count = 0;
if (fread(&mitmcache_elems_count, 4, 1, cache_file) <= 0) {
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
}
mitmcache_elems_count = zrtp_ntoh32(mitmcache_elems_count);
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file contains %u MiTM secrets.\n", mitmcache_elems_count));
mitmcache_elems_count = zrtp_ntoh32(mitmcache_elems_count);
for (i=0; i<mitmcache_elems_count; i++)
{
new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t));
@ -458,11 +480,17 @@ zrtp_status_t zrtp_cache_user_init()
}
if (fread(new_elem, ZRTP_MITMCACHE_ELEM_LENGTH, 1, cache_file) <= 0) {
ZRTP_LOG(3,(_ZTU_,"\tERROR! MiTM cache element read fail (id=%u).\n", i));
zrtp_sys_free(new_elem);
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
}
cache_make_cross(NULL, new_elem, 1);
new_elem->_index = g_mitmcache_elems_counter++;
new_elem->_is_dirty = 0;
mlist_add_tail(&mitmcache_head, &new_elem->_mlist);
}
@ -474,18 +502,25 @@ zrtp_status_t zrtp_cache_user_init()
zrtp_def_cache_down();
return s;
}
ZRTP_LOG(3,(_ZTU_,"\tAll %u MiTM Cache entries have been uploaded.\n", g_mitmcache_elems_counter));
/*
* Load regular caches: first 32 bits is a secrets counter. Read it and then
* upload appropriate number of regular secrets.
*/
cache_elems_count = 0;
if (fread(&cache_elems_count, 4, 1, cache_file) <= 0) {
fclose(cache_file);
zrtp_def_cache_down();
return zrtp_status_read_fail;
}
}
cache_elems_count = zrtp_ntoh32(cache_elems_count);
g_cache_elems_counter = 0;
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file contains %u RS secrets.\n", cache_elems_count));
for (i=0; i<cache_elems_count; i++)
{
new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t));
@ -494,11 +529,16 @@ zrtp_status_t zrtp_cache_user_init()
}
if (fread(new_elem, ZRTP_CACHE_ELEM_LENGTH, 1, cache_file) <= 0) {
ZRTP_LOG(3,(_ZTU_,"\tERROR! RS cache element read fail (id=%u).\n", i));
zrtp_sys_free(new_elem);
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
}
cache_make_cross(NULL, new_elem, 1);
new_elem->_index = g_cache_elems_counter++;
new_elem->_is_dirty = 0;
mlist_add_tail(&cache_head, &new_elem->_mlist);
}
if (i != cache_elems_count) {
@ -510,6 +550,8 @@ zrtp_status_t zrtp_cache_user_init()
return zrtp_status_fail;
}
ZRTP_LOG(3,(_ZTU_,"\tAll of %u RS Cache entries have been uploaded.\n", g_cache_elems_counter));
return s;
}
@ -525,15 +567,65 @@ zrtp_status_t zrtp_cache_user_init()
return s;\
};
static zrtp_status_t flush_elem_(zrtp_cache_elem_t *elem, FILE *cache_file, unsigned is_mitm) {
zrtp_cache_elem_t tmp_elem;
uint32_t pos = 0;
/*
* Let's calculate cache element position in the file
*/
printf("flush_elem_(): calculate Element offset for %s..\n", is_mitm?"MiTM":"RS");
/* Skip the header */
pos += strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL);
pos += sizeof(uint32_t); /* Skip MiTM secretes count. */
printf("flush_elem_(): \t pos=%u (Header, MiTM Count).\n", pos);
if (is_mitm) {
/* position within MiTM secrets block. */
pos += (elem->_index * ZRTP_MITMCACHE_ELEM_LENGTH);
printf("flush_elem_(): \t pos=%u (Header, MiTM Count + %u MiTM Secrets).\n", pos, elem->_index);
} else {
/* Skip MiTM Secrets block */
pos += (g_mitmcache_elems_counter * ZRTP_MITMCACHE_ELEM_LENGTH);
pos += sizeof(uint32_t); /* Skip RS elements count. */
pos += (elem->_index * ZRTP_CACHE_ELEM_LENGTH); /* Skip previous RS elements */
printf("flush_elem_(): \t pos=%u (Header, MiTM Count + ALL %u Secrets, RS counter and %u prev. RS).\n", pos, g_mitmcache_elems_counter, elem->_index);
}
fseek(cache_file, pos, SEEK_SET);
/* Prepare element for storing, convert all fields to the network byte-order. */
cache_make_cross(elem, &tmp_elem, 0);
printf("flush_elem_(): write to offset=%lu\n", ftell(cache_file));
/* Flush the element. */
if (fwrite(&tmp_elem, (is_mitm ? ZRTP_MITMCACHE_ELEM_LENGTH : ZRTP_CACHE_ELEM_LENGTH), 1, cache_file) != 1) {
printf("flush_elem_(): ERROR!!! write failed!\n");
return zrtp_status_write_fail;
} else {
elem->_is_dirty = 0;
printf("flush_elem_(): OK! %lu bytes were written\n", (is_mitm ? ZRTP_MITMCACHE_ELEM_LENGTH : ZRTP_CACHE_ELEM_LENGTH));
return zrtp_status_ok;
}
}
zrtp_status_t zrtp_cache_user_down()
{
FILE* cache_file = 0;
zrtp_cache_elem_t tmp_elem;
mlist_t *node = 0;
uint32_t count = 0;
uint32_t pos = 0;
ZRTP_LOG(3,(_ZTU_,"\tStoring ZRTP cache to the file...\n"));
ZRTP_LOG(3,(_ZTU_,"\tStoring ZRTP cache to <%s>...\n", zrtp->def_cache_path.buffer));
/* Open/create file for writing */
#if (ZRTP_PLATFORM == ZP_WIN32)
if (0 != fopen_s(&cache_file, zrtp->def_cache_path.buffer, "wb+")) {
@ -550,53 +642,81 @@ zrtp_status_t zrtp_cache_user_down()
/* Store version string first. Format: &ZRTP_DEF_CACHE_VERSION_STR&ZRTP_DEF_CACHE_VERSION_VAL */
if (1 != fwrite(ZRTP_DEF_CACHE_VERSION_STR, strlen(ZRTP_DEF_CACHE_VERSION_STR), 1, cache_file)) {
ZRTP_LOG(2,(_ZTU_,"\tERROR! unable to write header to the cache file\n"));
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
if (1 != fwrite(ZRTP_DEF_CACHE_VERSION_VAL, strlen(ZRTP_DEF_CACHE_VERSION_VAL), 1, cache_file)) {
ZRTP_LOG(2,(_ZTU_,"\tERROR! unable to write header to the cache file\n"));
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
/* Store PBX secrets first. Format: <secrets count>, <secrets' data> */
/*
* Store PBX secrets first. Format: <secrets count>, <secrets' data>
*
* NOTE!!! It's IMPORTANT to store PBX secrets before the Regular secrets!!!
*/
pos = ftell(cache_file);
count = 0;
fwrite(&count, sizeof(count), 1, cache_file);
mlist_for_each(node, &mitmcache_head) {
zrtp_cache_elem_t* elem = mlist_get_struct(zrtp_cache_elem_t, _mlist, node);
cache_make_cross(elem, &tmp_elem, 0);
if (fwrite(&tmp_elem, ZRTP_MITMCACHE_ELEM_LENGTH, 1, cache_file) != 1) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
/* Store dirty values only. */
if (elem->_is_dirty) {
printf("zrtp_cache_user_down: Store MiTM elem index=%u, not modified.\n", elem->_index);
if (zrtp_status_ok != flush_elem_(elem, cache_file, 1)) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
} else {
printf("zrtp_cache_user_down: Skip MiTM elem index=%u, not modified.\n", elem->_index);
}
count++;
}
fseek(cache_file, pos, SEEK_SET);
count = zrtp_hton32(count);
count = zrtp_hton32(g_mitmcache_elems_counter);
if (fwrite(&count, sizeof(count), 1, cache_file) != 1) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
fseek(cache_file, 0L, SEEK_END);
ZRTP_LOG(3,(_ZTU_,"\t%u MiTM cache entries have been stored sucessfully.\n",zrtp_ntoh32(count)));
ZRTP_LOG(3,(_ZTU_,"\t%u MiTM cache entries have been stored successfully.\n",zrtp_ntoh32(count)));
/*
* Store regular secrets. Format: <secrets count>, <secrets' data>
*/
/* Seek to the beginning of the Regular secrets block */
pos = strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL);
pos += sizeof(uint32_t); /* Skip MiTM secrets count. */
pos += (g_mitmcache_elems_counter * ZRTP_MITMCACHE_ELEM_LENGTH); /* Skip MiTM Secrets block */
fseek(cache_file, pos, SEEK_SET);
/* Store reqular secrets. Format: <secrets count>, <secrets' data> */
pos = ftell(cache_file);
count = 0;
fwrite(&count, sizeof(count), 1, cache_file);
mlist_for_each(node, &cache_head) {
zrtp_cache_elem_t* elem = mlist_get_struct(zrtp_cache_elem_t, _mlist, node);
cache_make_cross(elem, &tmp_elem, 0);
if (fwrite(&tmp_elem, ZRTP_CACHE_ELEM_LENGTH, 1, cache_file) != 1) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
/* Store dirty values only. */
if (elem->_is_dirty) {
printf("zrtp_cache_user_down: Store RS elem index=%u, not modified.\n", elem->_index);
if (zrtp_status_ok != flush_elem_(elem, cache_file, 0)) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
} else {
printf("zrtp_cache_user_down: Skip RS elem index=%u, not modified.\n", elem->_index);
}
count++;
}
fseek(cache_file, pos, SEEK_SET);
count = zrtp_hton32(count);
count = zrtp_hton32(g_cache_elems_counter);
if (fwrite(&count, sizeof(count), 1, cache_file) != 1) {
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
}
ZRTP_LOG(3,(_ZTU_,"\t%u regular cache entries have been stored sucessfully.\n", zrtp_ntoh32(count)));
ZRTP_LOG(3,(_ZTU_,"\t%u regular cache entries have been stored successfully.\n", zrtp_ntoh32(count)));
ZRTP_DOWN_CACHE_RETURN(zrtp_status_ok, cache_file);
}
@ -633,6 +753,8 @@ static zrtp_status_t put_name( const zrtp_stringn_t* one_ZID,
new_elem->name_length = ZRTP_MIN(name->length, ZFONE_CACHE_NAME_LENGTH-1);
zrtp_memset(new_elem->name, 0, sizeof(new_elem->name));
zrtp_memcpy(new_elem->name, name->buffer, new_elem->name_length);
new_elem->_is_dirty = 1;
} while (0);
zrtp_mutex_unlock(def_cache_protector);
@ -720,6 +842,8 @@ zrtp_status_t zrtp_def_cache_reset_since( const zrtp_stringn_t* one_zid,
new_elem = get_elem(id, 0);
if (new_elem) {
new_elem->secure_since = (uint32_t)(zrtp_time_now()/1000);
new_elem->_is_dirty = 1;
}
zrtp_mutex_unlock(def_cache_protector);
@ -743,6 +867,14 @@ void zrtp_def_cache_foreach( zrtp_global_t *global,
result = callback(elem, is_mitm, data, &delete);
if (delete) {
mlist_del(&elem->_mlist);
if (is_mitm)
g_mitmcache_elems_counter--;
else
g_cache_elems_counter--;
// TODO: rearrange INDEXES here!
}
if (!result) {
break;

127
test/cache_test.c Normal file
View File

@ -0,0 +1,127 @@
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <string.h>
#include <stdio.h>
#include "zrtp.h"
#include "cmockery/cmockery.h"
#define TEST_CACHE_PATH "./zrtp_cache_test.dat"
static zrtp_global_t g_zrtp_cfg;
void cache_setup() {
remove(TEST_CACHE_PATH);
ZSTR_SET_EMPTY(g_zrtp_cfg.def_cache_path);
/* Configure and Initialize ZRTP cache */
zrtp_zstrcpyc(ZSTR_GV(g_zrtp_cfg.def_cache_path), TEST_CACHE_PATH);
}
void cache_teardown() {
zrtp_def_cache_down();
}
static void init_rs_secret_(zrtp_shared_secret_t *sec) {
ZSTR_SET_EMPTY(sec->value);
sec->_cachedflag = 0;
sec->ttl = 0;
sec->lastused_at = 0;
}
/*
* Simply init ZRTP cache with empty or non-existing filer and close it.
* The app should not crash and trigger no errors.
*/
void cache_init_store_empty_test() {
zrtp_status_t status;
/* It should NOT crash and return OK. */
status = zrtp_def_cache_init(&g_zrtp_cfg);
assert_int_equal(status, zrtp_status_ok);
zrtp_def_cache_down();
}
/*
* Add few entries to the empty cache, flush it and then load again. Check if
* all the entries were restored successfully.
*/
void cache_add2empty_test() {
zrtp_status_t status;
int intres;
zrtp_string16_t zid_my = ZSTR_INIT_WITH_CONST_CSTRING("000000000_01");
zrtp_string16_t zid_a = ZSTR_INIT_WITH_CONST_CSTRING("000000000_02");
zrtp_string16_t zid_b = ZSTR_INIT_WITH_CONST_CSTRING("000000000_03");
zrtp_string16_t zid_c = ZSTR_INIT_WITH_CONST_CSTRING("000000000_04");
zrtp_string16_t zid_mitm1 = ZSTR_INIT_WITH_CONST_CSTRING("000000000_04");
zrtp_shared_secret_t rs_my4a, rs_my4b, rs_my4c, rs_my4mitm1;
zrtp_shared_secret_t rs_my4a_r, rs_my4b_r, rs_my4c_r, rs_my4mitm1_r;
init_rs_secret_(&rs_my4a); init_rs_secret_(&rs_my4b);
init_rs_secret_(&rs_my4c); init_rs_secret_(&rs_my4mitm1);
init_rs_secret_(&rs_my4a_r); init_rs_secret_(&rs_my4b_r);
init_rs_secret_(&rs_my4c_r); init_rs_secret_(&rs_my4mitm1_r);
printf("Open empty cache file for.\n");
status = zrtp_def_cache_init(&g_zrtp_cfg);
assert_int_equal(status, zrtp_status_ok);
/* Test if cache-init does bot corrupt config. */
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
/* Add few values into it */
printf("Add few test entries.\n");
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_a), &rs_my4a);
assert_int_equal(status, zrtp_status_ok);
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_b), &rs_my4b);
assert_int_equal(status, zrtp_status_ok);
status = zrtp_def_cache_put_mitm(ZSTR_GV(zid_my), ZSTR_GV(zid_mitm1), &rs_my4mitm1);
assert_int_equal(status, zrtp_status_ok);
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_c), &rs_my4c);
assert_int_equal(status, zrtp_status_ok);
/* Close the cache, it should be flushed to the file. */
printf("Close the cache.\n");
zrtp_def_cache_down();
/* Test if cache-close does bot corrupt config. */
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
/* Now, let's open the cache again and check if all the previously added values were restored successfully */
printf("And open it again, it should contain all the stored values.\n");
status = zrtp_def_cache_init(&g_zrtp_cfg);
assert_int_equal(status, zrtp_status_ok);
status = zrtp_def_cache_get(ZSTR_GV(zid_my), ZSTR_GV(zid_a), &rs_my4a_r, 0);
assert_int_equal(status, zrtp_status_ok);
assert_false(zrtp_zstrcmp(ZSTR_GV(rs_my4a_r.value), ZSTR_GV(rs_my4a.value)));
/* Test if cache-close does bot corrupt config. */
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
}
int main(void) {
const UnitTest tests[] = {
//unit_test_setup_teardown(cache_init_store_empty_test, cache_setup, cache_teardown),
unit_test_setup_teardown(cache_add2empty_test, cache_setup, cache_teardown),
};
return run_tests(tests);
}