Add chunk map
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Wed, 22 Aug 2012 08:17:59 +0000 (10:17 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:46 +0000 (15:23 +0100)
This data structure allows to store mappings of chunks to ids. This will
be used to map nonces to their corresponding nonce context ids.

src/charon-tkm/src/tkm/tkm.c
src/charon-tkm/src/tkm/tkm.h
src/charon-tkm/src/tkm/tkm_chunk_map.c [new file with mode: 0644]
src/charon-tkm/src/tkm/tkm_chunk_map.h [new file with mode: 0644]
src/charon-tkm/tests/chunk_map_tests.c [new file with mode: 0644]
src/charon-tkm/tests/test_runner.c
src/charon-tkm/tests/test_runner.h

index f78d49b..e9862e0 100644 (file)
@@ -81,6 +81,7 @@ bool tkm_init()
        INIT(this,
                .public = {
                        .idmgr = tkm_id_manager_create(limits),
        INIT(this,
                .public = {
                        .idmgr = tkm_id_manager_create(limits),
+                       .chunk_map = tkm_chunk_map_create(),
                },
        );
        tkm = &this->public;
                },
        );
        tkm = &this->public;
@@ -99,6 +100,7 @@ void tkm_deinit()
        }
        private_tkm_t *this = (private_tkm_t*)tkm;
        this->public.idmgr->destroy(this->public.idmgr);
        }
        private_tkm_t *this = (private_tkm_t*)tkm;
        this->public.idmgr->destroy(this->public.idmgr);
+       this->public.chunk_map->destroy(this->public.chunk_map);
 
        tkmlib_final();
        free(this);
 
        tkmlib_final();
        free(this);
index 6bb8331..9d559d9 100644 (file)
@@ -18,6 +18,7 @@
 #define TKM_H_
 
 #include "tkm_id_manager.h"
 #define TKM_H_
 
 #include "tkm_id_manager.h"
+#include "tkm_chunk_map.h"
 
 typedef struct tkm_t tkm_t;
 
 
 typedef struct tkm_t tkm_t;
 
@@ -31,6 +32,11 @@ struct tkm_t {
         */
        tkm_id_manager_t *idmgr;
 
         */
        tkm_id_manager_t *idmgr;
 
+       /**
+        * Chunk-to-ID mappings.
+        */
+       tkm_chunk_map_t *chunk_map;
+
 };
 
 /**
 };
 
 /**
diff --git a/src/charon-tkm/src/tkm/tkm_chunk_map.c b/src/charon-tkm/src/tkm/tkm_chunk_map.c
new file mode 100644 (file)
index 0000000..2a1a944
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <collections/hashtable.h>
+#include <threading/rwlock.h>
+#include <utils/chunk.h>
+#include <utils/debug.h>
+
+#include "tkm_chunk_map.h"
+
+typedef struct private_tkm_chunk_map_t private_tkm_chunk_map_t;
+
+/**
+ * Private data of tkm chunk map.
+ */
+struct private_tkm_chunk_map_t {
+
+       /**
+        * public functions
+        */
+       tkm_chunk_map_t public;
+
+       /**
+        * Hashtable to store mappings.
+        */
+       hashtable_t *mappings;
+
+       /**
+        * rwlock for table.
+        */
+       rwlock_t *lock;
+
+};
+
+METHOD(tkm_chunk_map_t, insert, void,
+       private_tkm_chunk_map_t * const this, const chunk_t * const data,
+       const uint64_t id)
+{
+       uint64_t *value = malloc_thing(uint64_t);
+       *value = id;
+
+       this->lock->write_lock(this->lock);
+       value = this->mappings->put(this->mappings, (void*)data, value);
+       this->lock->unlock(this->lock);
+
+       if (value)
+       {
+               free(value);
+       }
+}
+
+METHOD(tkm_chunk_map_t, get_id, uint64_t,
+       private_tkm_chunk_map_t * const this, chunk_t *data)
+{
+       uint64_t *value;
+       this->lock->read_lock(this->lock);
+       value = this->mappings->get(this->mappings, data);
+       this->lock->unlock(this->lock);
+
+       return value == NULL ? 0 : *value;
+}
+
+METHOD(tkm_chunk_map_t, remove_, bool,
+       private_tkm_chunk_map_t * const this, chunk_t *data)
+{
+       this->lock->write_lock(this->lock);
+       uint64_t *value = this->mappings->remove(this->mappings, data);
+       this->lock->unlock(this->lock);
+
+       if (value)
+       {
+               free(value);
+               return TRUE;
+       }
+       else
+       {
+               return FALSE;
+       }
+}
+
+METHOD(tkm_chunk_map_t, destroy, void,
+       private_tkm_chunk_map_t *this)
+{
+       uint64_t *value;
+       enumerator_t *enumerator;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->mappings->create_enumerator(this->mappings);
+       while (enumerator->enumerate(enumerator, NULL, &value))
+       {
+               this->mappings->remove_at(this->mappings, enumerator);
+               free(value);
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+
+       this->lock->destroy(this->lock);
+       this->mappings->destroy(this->mappings);
+       free(this);
+}
+
+/**
+ * Hashtable hash function.
+ */
+static u_int hash(chunk_t *key)
+{
+       return chunk_hash(*key);
+}
+
+/*
+ * see header file
+ */
+tkm_chunk_map_t *tkm_chunk_map_create()
+{
+       private_tkm_chunk_map_t *this;
+
+       INIT(this,
+               .public = {
+                       .insert = _insert,
+                       .get_id = _get_id,
+                       .remove = _remove_,
+                       .destroy = _destroy,
+               },
+               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+               .mappings = hashtable_create((hashtable_hash_t)hash,
+                                                                        (hashtable_equals_t)chunk_equals_ptr, 32),
+       );
+
+       return &this->public;
+}
diff --git a/src/charon-tkm/src/tkm/tkm_chunk_map.h b/src/charon-tkm/src/tkm/tkm_chunk_map.h
new file mode 100644 (file)
index 0000000..746de7d
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef TKM_CHUNK_MAP_H_
+#define TKM_CHUNK_MAP_H_
+
+#include <stdint.h>
+#include <utils/chunk.h>
+
+typedef struct tkm_chunk_map_t tkm_chunk_map_t;
+
+/**
+ * The tkm chunk map handles mappings of chunks to ids.
+ */
+struct tkm_chunk_map_t {
+
+       /**
+        * Store new mapping for given chunk and id.
+        *
+        * @param data  data associated with id
+        * @param id    id associated with data
+        */
+       void (*insert)(tkm_chunk_map_t * const this, const chunk_t * const data,
+                       const uint64_t id);
+
+       /**
+        * Get id for given chunk.
+        *
+        * @param data  data specifying the mapping
+        * @return              id of given chunk, 0 if not found
+        */
+       uint64_t (*get_id)(tkm_chunk_map_t * const this, chunk_t *data);
+
+       /**
+        * Remove mapping for given chunk.
+        *
+        * @param data  data specifiying the mapping to remove
+        * @return              TRUE if mapping was removed, FALSE otherwise
+        */
+       bool (*remove)(tkm_chunk_map_t * const this, chunk_t *data);
+
+       /**
+        * Destroy a tkm chunk map instance.
+        */
+       void (*destroy)(tkm_chunk_map_t *this);
+
+};
+
+/**
+ * Create a tkm chunk map instance.
+ */
+tkm_chunk_map_t *tkm_chunk_map_create();
+
+#endif /** TKM_CHUNK_MAP_H_ */
diff --git a/src/charon-tkm/tests/chunk_map_tests.c b/src/charon-tkm/tests/chunk_map_tests.c
new file mode 100644 (file)
index 0000000..6deef9a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <check.h>
+
+#include "tkm_chunk_map.h"
+
+START_TEST(test_chunk_map_creation)
+{
+       tkm_chunk_map_t *map = NULL;
+
+       map = tkm_chunk_map_create();
+       fail_if(map == NULL, "Error creating chunk map");
+
+       map->destroy(map);
+}
+END_TEST
+
+START_TEST(test_chunk_map_handling)
+{
+       tkm_chunk_map_t *map = NULL;
+       const int ref = 35;
+       chunk_t data = chunk_from_thing(ref);
+
+       map = tkm_chunk_map_create();
+       fail_if(map == NULL, "Error creating chunk map");
+
+       map->insert(map, &data, 24);
+       fail_if(map->get_id(map, &data) != 24, "Id mismatch");
+
+       fail_unless(map->remove(map, &data), "Unable to remove mapping");
+       fail_unless(!map->get_id(map, &data), "Error removing mapping");
+
+       map->destroy(map);
+}
+END_TEST
+
+TCase *make_chunk_map_tests(void)
+{
+       TCase *tc = tcase_create("Chunk map tests");
+       tcase_add_test(tc, test_chunk_map_creation);
+       tcase_add_test(tc, test_chunk_map_handling);
+
+       return tc;
+}
index 5c795f8..e1190fb 100644 (file)
@@ -28,6 +28,7 @@ int main(void)
        int number_failed;
        Suite *s = suite_create("TKM tests");
        suite_add_tcase(s, make_id_manager_tests());
        int number_failed;
        Suite *s = suite_create("TKM tests");
        suite_add_tcase(s, make_id_manager_tests());
+       suite_add_tcase(s, make_chunk_map_tests());
        suite_add_tcase(s, make_nonceg_tests());
        suite_add_tcase(s, make_diffie_hellman_tests());
 
        suite_add_tcase(s, make_nonceg_tests());
        suite_add_tcase(s, make_diffie_hellman_tests());
 
index 1de47d5..47ffd0c 100644 (file)
@@ -20,6 +20,7 @@
 #include <check.h>
 
 TCase *make_id_manager_tests(void);
 #include <check.h>
 
 TCase *make_id_manager_tests(void);
+TCase *make_chunk_map_tests(void);
 TCase *make_nonceg_tests(void);
 TCase *make_diffie_hellman_tests(void);
 
 TCase *make_nonceg_tests(void);
 TCase *make_diffie_hellman_tests(void);