]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Keep the PDP connections lock while accessing its objects
authorMartin Willi <martin@revosec.ch>
Wed, 19 Dec 2012 16:55:47 +0000 (17:55 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 14 Feb 2013 16:19:56 +0000 (17:19 +0100)
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
src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c
src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h

index 39939d34ee8d8894453c1ece196479f5b6836830..422c28bc9a62a8254c712790e1b9d3305d26c29e 100644 (file)
@@ -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;
 }
-
index 7948ad2f8276dc6f1bb4abe1f0bc4af90c94f19e..3682f8f0d12776e88a7798ba7e545e0e066298c5 100644 (file)
@@ -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(),
index 16492020e0a70abfe4526de1400d1268f72d4bf2..442f29ce93308105a287c70a9ed300ea230efe31 100644 (file)
@@ -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.
         */