aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>2017-09-01 17:15:41 +0200
committerTobias Brunner <tobias@strongswan.org>2017-09-15 12:16:57 +0200
commit1b2a8d963a1503456fb5af47cae82536076a2880 (patch)
tree771445ee5c16cb31562b1a6506f5d081ade828be
parentfcde9686f67f5724f7de47ed27737bc2457310dc (diff)
downloadstrongswan-1b2a8d963a1503456fb5af47cae82536076a2880.tar.bz2
strongswan-1b2a8d963a1503456fb5af47cae82536076a2880.tar.xz
charon-tkm: Add acquire_ref method to ID manager
The function acquires a reference to the given context reference id for a specific context kind.
-rw-r--r--src/charon-tkm/src/tkm/tkm_id_manager.c28
-rw-r--r--src/charon-tkm/src/tkm/tkm_id_manager.h12
-rw-r--r--src/charon-tkm/tests/id_manager_tests.c68
3 files changed, 108 insertions, 0 deletions
diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.c b/src/charon-tkm/src/tkm/tkm_id_manager.c
index b07409d19..2d28c3c45 100644
--- a/src/charon-tkm/src/tkm/tkm_id_manager.c
+++ b/src/charon-tkm/src/tkm/tkm_id_manager.c
@@ -103,6 +103,33 @@ METHOD(tkm_id_manager_t, acquire_id, int,
return id;
}
+METHOD(tkm_id_manager_t, acquire_ref, bool,
+ private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
+ const int ref_id)
+{
+ const int idx = ref_id - 1;
+
+ if (!is_valid_kind(kind))
+ {
+ DBG1(DBG_LIB, "tried to acquire reference for invalid context kind '%d'",
+ kind);
+ return FALSE;
+ }
+
+ if (ref_id < 1 || (uint64_t)ref_id > this->limits[kind])
+ {
+ DBG1(DBG_LIB, "tried to acquire reference for context id %d out of "
+ "bounds (max %llu)", ref_id, this->limits[kind]);
+ return FALSE;
+ }
+
+ this->locks[kind]->write_lock(this->locks[kind]);
+ this->ctxids[kind][idx]++;
+ this->locks[kind]->unlock(this->locks[kind]);
+
+ return TRUE;
+}
+
METHOD(tkm_id_manager_t, release_id, bool,
private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
const int id)
@@ -150,6 +177,7 @@ tkm_id_manager_t *tkm_id_manager_create(const tkm_limits_t limits)
INIT(this,
.public = {
.acquire_id = _acquire_id,
+ .acquire_ref = _acquire_ref,
.release_id = _release_id,
.destroy = _destroy,
},
diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.h b/src/charon-tkm/src/tkm/tkm_id_manager.h
index 0fc9ff8ef..ec7b07f7e 100644
--- a/src/charon-tkm/src/tkm/tkm_id_manager.h
+++ b/src/charon-tkm/src/tkm/tkm_id_manager.h
@@ -74,6 +74,18 @@ struct tkm_id_manager_t {
const tkm_context_kind_t kind);
/**
+ * Acquire reference to given context id for a specific context kind.
+ *
+ * @param kind kind of context id
+ * @param ref_id id to acquire a reference for
+ * @return TRUE if reference could be acquired,
+ * FALSE otherwise
+ */
+ bool (*acquire_ref)(tkm_id_manager_t * const this,
+ const tkm_context_kind_t kind,
+ const int ref_id);
+
+ /**
* Release a previously acquired context id.
*
* @param kind kind of context id to release
diff --git a/src/charon-tkm/tests/id_manager_tests.c b/src/charon-tkm/tests/id_manager_tests.c
index 8157496ca..392379aa9 100644
--- a/src/charon-tkm/tests/id_manager_tests.c
+++ b/src/charon-tkm/tests/id_manager_tests.c
@@ -84,6 +84,71 @@ START_TEST(test_acquire_id_same)
}
END_TEST
+START_TEST(test_acquire_ref)
+{
+ int i, id = 0;
+ bool acquired = false;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ for (i = 0; i < TKM_CTX_MAX; i++)
+ {
+ id = idmgr->acquire_id(idmgr, i);
+ acquired = idmgr->acquire_ref(idmgr, i, id);
+ fail_unless(acquired, "Error acquiring reference context kind %d", i);
+
+ /* Reset test variable */
+ acquired = false;
+ }
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_acquire_ref_invalid_kind)
+{
+ bool acquired;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ acquired = idmgr->acquire_ref(idmgr, TKM_CTX_MAX, 1);
+ fail_if(acquired, "Acquired reference for invalid context kind %d", TKM_CTX_MAX);
+
+ /* Reset test variable */
+ acquired = 0;
+
+ acquired = idmgr->acquire_ref(idmgr, -1, 1);
+ fail_if(acquired, "Acquired reference for invalid context kind %d", -1);
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_acquire_ref_invalid_id)
+{
+ int i;
+ bool acquired;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ for (i = 0; i < TKM_CTX_MAX; i++)
+ {
+ acquired = idmgr->acquire_ref(idmgr, i, -1);
+ fail_if(acquired,
+ "Acquired reference for negative id of context kind %d", i);
+
+ /* Reset test variable */
+ acquired = false;
+
+ acquired = idmgr->acquire_ref(idmgr, i, limits[i] + 1);
+ fail_if(acquired,
+ "Acquired reference exceeding limit of context kind %d", i);
+
+ /* Reset test variable */
+ acquired = false;
+ }
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
START_TEST(test_release_id)
{
int i, id = 0;
@@ -150,6 +215,9 @@ Suite *make_id_manager_tests()
tcase_add_test(tc, test_acquire_id);
tcase_add_test(tc, test_acquire_id_invalid_kind);
tcase_add_test(tc, test_acquire_id_same);
+ tcase_add_test(tc, test_acquire_ref);
+ tcase_add_test(tc, test_acquire_ref_invalid_kind);
+ tcase_add_test(tc, test_acquire_ref_invalid_id);
suite_add_tcase(s, tc);
tc = tcase_create("release");