Add locking to TNC-PDP connections

This commit is contained in:
Martin Willi
2013-02-14 17:19:49 +01:00
parent d20a2cc5f3
commit 37884ab10f
@@ -17,6 +17,7 @@
#include <collections/linked_list.h> #include <collections/linked_list.h>
#include <utils/debug.h> #include <utils/debug.h>
#include <threading/rwlock.h>
typedef struct private_tnc_pdp_connections_t private_tnc_pdp_connections_t; typedef struct private_tnc_pdp_connections_t private_tnc_pdp_connections_t;
typedef struct entry_t entry_t; typedef struct entry_t entry_t;
@@ -32,9 +33,14 @@ struct private_tnc_pdp_connections_t {
tnc_pdp_connections_t public; tnc_pdp_connections_t public;
/** /**
* List of TNC PEP RADIUS Connections * TNC PEP RADIUS Connections
*/ */
linked_list_t *list; linked_list_t *list;
/**
* Lock to access PEP connection list
*/
rwlock_t *lock;
}; };
/** /**
@@ -120,6 +126,7 @@ METHOD(tnc_pdp_connections_t, add, void,
ike_sa_id->destroy(ike_sa_id); ike_sa_id->destroy(ike_sa_id);
ike_sa->set_other_id(ike_sa, peer); ike_sa->set_other_id(ike_sa, peer);
this->lock->read_lock(this->lock);
enumerator = this->list->create_enumerator(this->list); enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry)) while (enumerator->enumerate(enumerator, &entry))
{ {
@@ -135,15 +142,19 @@ METHOD(tnc_pdp_connections_t, add, void,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
if (!found) if (!found)
{ {
entry = malloc_thing(entry_t); INIT(entry,
entry->nas_id = chunk_clone(nas_id); .nas_id = chunk_clone(nas_id),
entry->user_name = chunk_clone(user_name); .user_name = chunk_clone(user_name),
entry->method = method; .method = method,
entry->ike_sa = ike_sa; .ike_sa = ike_sa,
);
this->lock->write_lock(this->lock);
this->list->insert_last(this->list, entry); this->list->insert_last(this->list, entry);
this->lock->unlock(this->lock);
} }
dbg_nas_user(nas_id, user_name, FALSE, "created"); dbg_nas_user(nas_id, user_name, FALSE, "created");
} }
@@ -154,6 +165,7 @@ METHOD(tnc_pdp_connections_t, remove_, void,
enumerator_t *enumerator; enumerator_t *enumerator;
entry_t *entry; entry_t *entry;
this->lock->write_lock(this->lock);
enumerator = this->list->create_enumerator(this->list); enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry)) while (enumerator->enumerate(enumerator, &entry))
{ {
@@ -166,6 +178,7 @@ METHOD(tnc_pdp_connections_t, remove_, void,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
} }
METHOD(tnc_pdp_connections_t, get_state, eap_method_t*, METHOD(tnc_pdp_connections_t, get_state, eap_method_t*,
@@ -176,6 +189,7 @@ METHOD(tnc_pdp_connections_t, get_state, eap_method_t*,
entry_t *entry; entry_t *entry;
eap_method_t *found = NULL; eap_method_t *found = NULL;
this->lock->read_lock(this->lock);
enumerator = this->list->create_enumerator(this->list); enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry)) while (enumerator->enumerate(enumerator, &entry))
{ {
@@ -187,6 +201,7 @@ METHOD(tnc_pdp_connections_t, get_state, eap_method_t*,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
dbg_nas_user(nas_id, user_name, !found, "found"); dbg_nas_user(nas_id, user_name, !found, "found");
return found; return found;
@@ -195,6 +210,7 @@ METHOD(tnc_pdp_connections_t, get_state, eap_method_t*,
METHOD(tnc_pdp_connections_t, destroy, void, METHOD(tnc_pdp_connections_t, destroy, void,
private_tnc_pdp_connections_t *this) private_tnc_pdp_connections_t *this)
{ {
this->lock->destroy(this->lock);
this->list->destroy_function(this->list, (void*)free_entry); this->list->destroy_function(this->list, (void*)free_entry);
free(this); free(this);
} }
@@ -214,8 +230,8 @@ tnc_pdp_connections_t *tnc_pdp_connections_create(void)
.destroy = _destroy, .destroy = _destroy,
}, },
.list = linked_list_create(), .list = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
); );
return &this->public; return &this->public;
} }