Don't requeue IKEv1 init tasks if they already exist in a second keyingtry
[strongswan.git] / src / libcharon / sa / ikev1 / task_manager_v1.c
index d23b237..f31f497 100644 (file)
@@ -1013,14 +1013,51 @@ METHOD(task_manager_t, queue_task, void,
        this->queued_tasks->insert_last(this->queued_tasks, task);
 }
 
+/**
+ * Check if a given task has been queued already
+ */
+static bool has_queued(private_task_manager_t *this, task_type_t type)
+{
+       enumerator_t *enumerator;
+       bool found = FALSE;
+       task_t *task;
+
+       enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+       while (enumerator->enumerate(enumerator, &task))
+       {
+               if (task->get_type(task) == type)
+               {
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
 METHOD(task_manager_t, queue_ike, void,
        private_task_manager_t *this)
 {
-       queue_task(this, (task_t*)isakmp_vendor_create(this->ike_sa, TRUE));
-       queue_task(this, (task_t*)isakmp_cert_pre_create(this->ike_sa, TRUE));
-       queue_task(this, (task_t*)main_mode_create(this->ike_sa, TRUE));
-       queue_task(this, (task_t*)isakmp_cert_post_create(this->ike_sa, TRUE));
-       queue_task(this, (task_t*)isakmp_natd_create(this->ike_sa, TRUE));
+       if (!has_queued(this, TASK_ISAKMP_VENDOR))
+       {
+               queue_task(this, (task_t*)isakmp_vendor_create(this->ike_sa, TRUE));
+       }
+       if (!has_queued(this, TASK_ISAKMP_CERT_PRE))
+       {
+               queue_task(this, (task_t*)isakmp_cert_pre_create(this->ike_sa, TRUE));
+       }
+       if (!has_queued(this, TASK_MAIN_MODE))
+       {
+               queue_task(this, (task_t*)main_mode_create(this->ike_sa, TRUE));
+       }
+       if (!has_queued(this, TASK_ISAKMP_CERT_POST))
+       {
+               queue_task(this, (task_t*)isakmp_cert_post_create(this->ike_sa, TRUE));
+       }
+       if (!has_queued(this, TASK_ISAKMP_NATD))
+       {
+               queue_task(this, (task_t*)isakmp_natd_create(this->ike_sa, TRUE));
+       }
 }
 
 METHOD(task_manager_t, queue_ike_rekey, void,
@@ -1041,6 +1078,12 @@ METHOD(task_manager_t, queue_ike_delete, void,
        queue_task(this, (task_t*)isakmp_delete_create(this->ike_sa, TRUE));
 }
 
+METHOD(task_manager_t, queue_mobike, void,
+       private_task_manager_t *this, bool roam, bool address)
+{
+       /* Not supported in IKEv1 */
+}
+
 METHOD(task_manager_t, queue_child, void,
        private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid,
        traffic_selector_t *tsi, traffic_selector_t *tsr)
@@ -1097,6 +1140,34 @@ METHOD(task_manager_t, incr_mid, void,
 METHOD(task_manager_t, reset, void,
        private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
 {
+       enumerator_t *enumerator;
+       task_t *task;
+
+       /* reset message counters and retransmit packets */
+       DESTROY_IF(this->responding.packet);
+       DESTROY_IF(this->initiating.packet);
+       this->responding.packet = NULL;
+       this->initiating.packet = NULL;
+       this->initiating.mid = 0;
+       this->initiating.seqnr = 0;
+       this->initiating.retransmitted = 0;
+       this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
+
+       /* reset queued tasks */
+       enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+       while (enumerator->enumerate(enumerator, &task))
+       {
+               task->migrate(task, this->ike_sa);
+       }
+       enumerator->destroy(enumerator);
+
+       /* reset active tasks */
+       while (this->active_tasks->remove_last(this->active_tasks,
+                                                                                  (void**)&task) == SUCCESS)
+       {
+               task->migrate(task, this->ike_sa);
+               this->queued_tasks->insert_first(this->queued_tasks, task);
+       }
 }
 
 METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
@@ -1147,6 +1218,7 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
                                .queue_ike_rekey = _queue_ike_rekey,
                                .queue_ike_reauth = _queue_ike_reauth,
                                .queue_ike_delete = _queue_ike_delete,
+                               .queue_mobike = _queue_mobike,
                                .queue_child = _queue_child,
                                .queue_child_rekey = _queue_child_rekey,
                                .queue_child_delete = _queue_child_delete,