From dadd9744b60ce6a0dee2d23d7b981b28af6d5d7e Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 19 Dec 2012 17:55:47 +0100 Subject: [PATCH] Keep the PDP connections lock while accessing its objects When we introduce connection timeouts, the state may disappear at any time. This change prevents that, but is not very clear. We probably have to refactor connection handling. --- src/libcharon/plugins/tnc_pdp/tnc_pdp.c | 12 +++++++----- .../plugins/tnc_pdp/tnc_pdp_connections.c | 19 ++++++++++++++++++- .../plugins/tnc_pdp/tnc_pdp_connections.h | 10 +++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c index 39939d34ee..422c28bc9a 100644 --- a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c @@ -378,7 +378,10 @@ static void process_eap(private_tnc_pdp_t *this, radius_message_t *request, } this->connections->add(this->connections, nas_id, user_name, peer, method); - method->initiate(method, &out); + if (method->initiate(method, &out) == NEED_MORE) + { + send_response(this, request, code, out, group, msk, source); + } } else { @@ -428,16 +431,16 @@ static void process_eap(private_tnc_pdp_t *this, radius_message_t *request, in->get_identifier(in)); } charon->bus->set_sa(charon->bus, NULL); + send_response(this, request, code, out, group, msk, source); + this->connections->unlock(this->connections); } - send_response(this, request, code, out, group, msk, source); - out->destroy(out); - if (code == RMC_ACCESS_ACCEPT || code == RMC_ACCESS_REJECT) { this->connections->remove(this->connections, nas_id, user_name); } + out->destroy(out); end: free(message.ptr); in->destroy(in); @@ -648,4 +651,3 @@ tnc_pdp_t *tnc_pdp_create(u_int16_t port) return &this->public; } - diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c index 7948ad2f82..3682f8f0d1 100644 --- a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c @@ -67,6 +67,11 @@ struct entry_t { * IKE SA used for bus communication */ ike_sa_t *ike_sa; + + /** + * Timestamp this entry has been created + */ + time_t created; }; /** @@ -138,6 +143,7 @@ METHOD(tnc_pdp_connections_t, add, void, DBG1(DBG_CFG, "removed stale RADIUS connection"); entry->method = method; entry->ike_sa = ike_sa; + entry->created = time_monotonic(NULL); break; } } @@ -151,6 +157,7 @@ METHOD(tnc_pdp_connections_t, add, void, .user_name = chunk_clone(user_name), .method = method, .ike_sa = ike_sa, + .created = time_monotonic(NULL), ); this->lock->write_lock(this->lock); this->list->insert_last(this->list, entry); @@ -201,12 +208,21 @@ METHOD(tnc_pdp_connections_t, get_state, eap_method_t*, } } enumerator->destroy(enumerator); - this->lock->unlock(this->lock); + if (!found) + { + this->lock->unlock(this->lock); + } dbg_nas_user(nas_id, user_name, !found, "found"); return found; } +METHOD(tnc_pdp_connections_t, unlock, void, + private_tnc_pdp_connections_t *this) +{ + this->lock->unlock(this->lock); +} + METHOD(tnc_pdp_connections_t, destroy, void, private_tnc_pdp_connections_t *this) { @@ -227,6 +243,7 @@ tnc_pdp_connections_t *tnc_pdp_connections_create(void) .add = _add, .remove = _remove_, .get_state = _get_state, + .unlock = _unlock, .destroy = _destroy, }, .list = linked_list_create(), diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h index 16492020e0..442f29ce93 100644 --- a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h @@ -53,7 +53,10 @@ struct tnc_pdp_connections_t { chunk_t user_name); /** - * Get the EAP method and IKE_SA of a registered TNC PEP RADIUS Connection + * Get the EAP method and IKE_SA of a registered TNC PEP RADIUS Connection. + * + * If this call succeeds, the connection manager is locked. Call unlock + * after using the return objects. * * @param nas_id NAS identifier of Policy Enforcement Point * @param user_name User name of TNC Client @@ -63,6 +66,11 @@ struct tnc_pdp_connections_t { eap_method_t* (*get_state)(tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name, ike_sa_t **ike_sa); + /** + * Unlock connections after successfully calling get_state(). + */ + void (*unlock)(tnc_pdp_connections_t *this); + /** * Destroys a tnc_pdp_connections_t object. */ -- 2.47.2