Queue Mode Config tasks when required
[strongswan.git] / src / libcharon / sa / task_manager_v1.c
index d557d97..e899b06 100755 (executable)
@@ -22,7 +22,8 @@
 #include <sa/tasks/child_delete.h>
 #include <sa/tasks/main_mode.h>
 #include <sa/tasks/quick_mode.h>
-#include <sa/tasks/xauth_request.h>
+#include <sa/tasks/xauth.h>
+#include <sa/tasks/mode_config.h>
 #include <sa/tasks/ike_delete.h>
 #include <sa/tasks/ike_natd_v1.h>
 #include <sa/tasks/ike_vendor_v1.h>
@@ -280,13 +281,19 @@ METHOD(task_manager_t, initiate, status_t,
                                }
                                break;
                        case IKE_CONNECTING:
-                               if (activate_task(this, TASK_XAUTH_REQUEST))
+                               if (activate_task(this, TASK_XAUTH))
                                {
                                        exchange = TRANSACTION;
                                        new_mid = TRUE;
                                }
                                break;
                        case IKE_ESTABLISHED:
+                               if (activate_task(this, TASK_MODE_CONFIG))
+                               {
+                                       exchange = TRANSACTION;
+                                       new_mid = TRUE;
+                                       break;
+                               }
                                if (activate_task(this, TASK_QUICK_MODE))
                                {
                                        exchange = QUICK_MODE;
@@ -313,7 +320,7 @@ METHOD(task_manager_t, initiate, status_t,
                                case TASK_QUICK_MODE:
                                        exchange = QUICK_MODE;
                                        break;
-                               case TASK_XAUTH_REQUEST:
+                               case TASK_XAUTH:
                                        exchange = TRANSACTION;
                                        new_mid = TRUE;
                                        break;
@@ -400,15 +407,11 @@ METHOD(task_manager_t, initiate, status_t,
        {
                return retransmit(this, this->initiating.seqnr);
        }
-       else
-       {
-               charon->sender->send(charon->sender,
-                                       this->initiating.packet->clone(this->initiating.packet));
-
-               this->initiating.packet->destroy(this->initiating.packet);
-               this->initiating.packet = NULL;
-               return SUCCESS;
-       }
+       charon->sender->send(charon->sender,
+                               this->initiating.packet->clone(this->initiating.packet));
+       this->initiating.packet->destroy(this->initiating.packet);
+       this->initiating.packet = NULL;
+       return SUCCESS;
 }
 
 /**
@@ -592,6 +595,12 @@ static status_t process_request(private_task_manager_t *this,
                                /* TODO-IKEv1: agressive mode */
                                return FAILED;
                        case QUICK_MODE:
+                               if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+                               {
+                                       DBG1(DBG_IKE, "received quick mode request for "
+                                                "unestablished IKE_SA, ignored");
+                                       return FAILED;
+                               }
                                task = (task_t *)quick_mode_create(this->ike_sa, NULL,
                                                                                                   NULL, NULL);
                                this->passive_tasks->insert_last(this->passive_tasks, task);
@@ -648,7 +657,14 @@ static status_t process_request(private_task_manager_t *this,
                                enumerator->destroy(enumerator);
                                break;
                        case TRANSACTION:
-                               task = (task_t *)xauth_request_create(this->ike_sa, FALSE);
+                               if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+                               {
+                                       task = (task_t *)mode_config_create(this->ike_sa, FALSE);
+                               }
+                               else
+                               {
+                                       task = (task_t *)xauth_create(this->ike_sa, FALSE);
+                               }
                                this->passive_tasks->insert_last(this->passive_tasks, task);
                                break;
                        default:
@@ -688,7 +704,17 @@ static status_t process_request(private_task_manager_t *this,
 
        if (send_response)
        {
-               return build_response(this, message);
+               if (build_response(this, message) != SUCCESS)
+               {
+                       return DESTROY_ME;
+               }
+       }
+       if (this->passive_tasks->get_count(this->passive_tasks) == 0 &&
+               this->queued_tasks->get_count(this->queued_tasks) > 0)
+       {
+               /* passive tasks completed, check if an active task has been queued,
+                * such as XAUTH or modeconfig push */
+               return initiate(this);
        }
        return SUCCESS;
 }