From: Adrian-Ken Rueegsegger Date: Wed, 22 Aug 2012 08:17:59 +0000 (+0200) Subject: Add chunk map X-Git-Tag: 5.0.3rc1~39^2~88 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=3242a178b3c9cfcf2abea5d87b247034df8bfb08 Add chunk map This data structure allows to store mappings of chunks to ids. This will be used to map nonces to their corresponding nonce context ids. --- diff --git a/src/charon-tkm/src/tkm/tkm.c b/src/charon-tkm/src/tkm/tkm.c index f78d49b..e9862e0 100644 --- a/src/charon-tkm/src/tkm/tkm.c +++ b/src/charon-tkm/src/tkm/tkm.c @@ -81,6 +81,7 @@ bool tkm_init() INIT(this, .public = { .idmgr = tkm_id_manager_create(limits), + .chunk_map = tkm_chunk_map_create(), }, ); 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); + this->public.chunk_map->destroy(this->public.chunk_map); tkmlib_final(); free(this); diff --git a/src/charon-tkm/src/tkm/tkm.h b/src/charon-tkm/src/tkm/tkm.h index 6bb8331..9d559d9 100644 --- a/src/charon-tkm/src/tkm/tkm.h +++ b/src/charon-tkm/src/tkm/tkm.h @@ -18,6 +18,7 @@ #define TKM_H_ #include "tkm_id_manager.h" +#include "tkm_chunk_map.h" typedef struct tkm_t tkm_t; @@ -31,6 +32,11 @@ struct tkm_t { */ 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 index 0000000..2a1a944 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_chunk_map.c @@ -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 . + * + * 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 +#include +#include +#include + +#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 index 0000000..746de7d --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_chunk_map.h @@ -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 . + * + * 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 +#include + +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 index 0000000..6deef9a --- /dev/null +++ b/src/charon-tkm/tests/chunk_map_tests.c @@ -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 . + * + * 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 + +#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; +} diff --git a/src/charon-tkm/tests/test_runner.c b/src/charon-tkm/tests/test_runner.c index 5c795f8..e1190fb 100644 --- a/src/charon-tkm/tests/test_runner.c +++ b/src/charon-tkm/tests/test_runner.c @@ -28,6 +28,7 @@ int main(void) 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()); diff --git a/src/charon-tkm/tests/test_runner.h b/src/charon-tkm/tests/test_runner.h index 1de47d5..47ffd0c 100644 --- a/src/charon-tkm/tests/test_runner.h +++ b/src/charon-tkm/tests/test_runner.h @@ -20,6 +20,7 @@ #include TCase *make_id_manager_tests(void); +TCase *make_chunk_map_tests(void); TCase *make_nonceg_tests(void); TCase *make_diffie_hellman_tests(void);