If a peer does not respond to the IKE_AUTH request after a successful
IKE_SA_INIT and the IKE_SA is reset, the task manager of this IKE_SA
gets confused and is stuck since it finds the IKE_SA to be in state
IKE_CREATED while there's not IKE_SA_INIT task present anymore. If an
acquire job for this particular IKE_SA is triggered it cannot be
executed until this IKE_SA is manually initiated (via stroke etc.). This
behavior ultimately results in an unusable, 'starved' IKE_SA.
---
 src/libcharon/sa/task_manager.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c
index ecf77ed..48908b4 100644
--- a/src/libcharon/sa/task_manager.c
+++ b/src/libcharon/sa/task_manager.c
@@ -307,14 +307,35 @@ static status_t build_request(private_task_manager_t 
*this)
                DBG2(DBG_IKE, "activating new tasks");
                switch (this->ike_sa->get_state(this->ike_sa))
                {
+                       bool ike_init = FALSE;
+
                        case IKE_CREATED:
                                activate_task(this, IKE_VENDOR);
                                if (activate_task(this, IKE_INIT))
                                {
-                                       this->initiating.mid = 0;
-                                       exchange = IKE_SA_INIT;
                                        activate_task(this, IKE_NATD);
                                        activate_task(this, IKE_CERT_PRE);
+                                       ike_init = TRUE;
+                               }
+                               else if (activate_task(this, IKE_CERT_PRE))
+                               {
+                                       task_t *task;
+                                       /* if an ike_sa is reset after the 
successful IKE_SA_INIT we
+                                        * have to recover by adding an 
IKE_INIT and IKE_NATD task
+                                        */
+                                       DBG2(DBG_IKE, "recovering from reset 
after successful "
+                                                       "IKE_SA_INIT");
+                                       task = 
(task_t*)ike_natd_create(this->ike_sa, TRUE);
+                                       
this->active_tasks->insert_first(this->active_tasks, task);
+                                       task = 
(task_t*)ike_init_create(this->ike_sa, TRUE, NULL);
+                                       
this->active_tasks->insert_first(this->active_tasks, task);
+                                       ike_init = TRUE;
+                               }
+
+                               if (ike_init)
+                               {
+                                       this->initiating.mid = 0;
+                                       exchange = IKE_SA_INIT;
 #ifdef ME
                                        /* this task has to be activated before 
the IKE_AUTHENTICATE
                                         * task, because that task pregenerates 
the packet after
-- 1.5.6.5

_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to