[strongSwan-dev] [PATCH 5/5] Recover IKE_SA reset after successful IKE_SA_INIT

Thomas Egerer thomas.egerer at secunet.com
Sun Jun 6 22:53:48 CEST 2010


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




More information about the Dev mailing list