From 6278e64230ad436edd29cef967a086bc3487b646 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 19 Sep 2013 10:53:05 +0200 Subject: [PATCH] trap-manager: Make sure a config is not trapped twice --- src/libcharon/sa/trap_manager.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 5a4c06c2d..1f66d6ceb 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Tobias Brunner + * Copyright (C) 2011-2013 Tobias Brunner * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -61,6 +62,11 @@ struct private_trap_manager_t { */ rwlock_t *lock; + /** + * track if the current thread is installing a trap policy + */ + thread_value_t *installing; + /** * listener to track acquiring IKE_SAs */ @@ -131,6 +137,7 @@ METHOD(trap_manager_t, install, u_int32_t, } this->lock->write_lock(this->lock); + this->installing->set(this->installing, this); enumerator = this->traps->create_enumerator(this->traps); while (enumerator->enumerate(enumerator, &entry)) { @@ -143,7 +150,6 @@ METHOD(trap_manager_t, install, u_int32_t, } } enumerator->destroy(enumerator); - this->lock->unlock(this->lock); if (found) { /* config might have changed so update everything */ @@ -188,11 +194,11 @@ METHOD(trap_manager_t, install, u_int32_t, .child_sa = child_sa, .peer_cfg = peer->get_ref(peer), ); - this->lock->write_lock(this->lock); this->traps->insert_last(this->traps, entry); - this->lock->unlock(this->lock); reqid = child_sa->get_reqid(child_sa); } + this->installing->set(this->installing, NULL); + this->lock->unlock(this->lock); if (status != SUCCESS) { @@ -269,6 +275,10 @@ METHOD(trap_manager_t, find_reqid, u_int32_t, entry_t *entry; u_int32_t reqid = 0; + if (this->installing->get(this->installing)) + { /* current thread holds the lock */ + return reqid; + } this->lock->read_lock(this->lock); enumerator = this->traps->create_enumerator(this->traps); while (enumerator->enumerate(enumerator, &entry)) @@ -435,6 +445,7 @@ METHOD(trap_manager_t, destroy, void, { charon->bus->remove_listener(charon->bus, &this->listener.listener); this->traps->destroy_function(this->traps, (void*)destroy_entry); + this->installing->destroy(this->installing); this->lock->destroy(this->lock); free(this); } @@ -465,6 +476,7 @@ trap_manager_t *trap_manager_create(void) }, .traps = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .installing = thread_value_create(NULL), ); charon->bus->add_listener(charon->bus, &this->listener.listener);