]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
ike: Initiate new IKE_SA not until all children are queued
authorTobias Brunner <tobias@strongswan.org>
Mon, 12 Jul 2021 12:47:57 +0000 (14:47 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 24 Aug 2021 12:31:55 +0000 (14:31 +0200)
If there are many CHILD_SAs, the time between initiating the new IKE_SA
and checking it in might be longer (depending on what else is going on
in the daemon) than the retransmission timeout and no retransmits might
be sent afterwards for this SA (it will just linger around dead).
Calling initiate() last should avoid that (we do this similarly for MBB
reauthentication).

src/libcharon/sa/ike_sa.c

index ba59b052b5b1cda49574639d28fbe4d68bde5a7a..a891aff4970a0a62a8058b44745f726c92f68411 100644 (file)
@@ -2041,11 +2041,11 @@ static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue)
 static status_t reestablish_children(private_ike_sa_t *this, ike_sa_t *new,
                                                                         bool force)
 {
+       private_ike_sa_t *other = (private_ike_sa_t*)new;
        enumerator_t *enumerator;
        child_sa_t *child_sa;
        child_cfg_t *child_cfg;
        action_t action;
-       status_t status = FAILED;
 
        /* handle existing CHILD_SAs */
        enumerator = create_child_sa_enumerator(this);
@@ -2075,35 +2075,23 @@ static status_t reestablish_children(private_ike_sa_t *this, ike_sa_t *new,
                                action = child_sa->get_dpd_action(child_sa);
                        }
                }
-               switch (action)
+               if (action == ACTION_RESTART)
                {
-                       case ACTION_RESTART:
-                               child_cfg = child_sa->get_config(child_sa);
-                               DBG1(DBG_IKE, "restarting CHILD_SA %s",
-                                        child_cfg->get_name(child_cfg));
-                               child_cfg->get_ref(child_cfg);
-                               status = new->initiate(new, child_cfg,
-                                                               child_sa->get_reqid(child_sa), NULL, NULL);
-                               break;
-                       default:
-                               continue;
-               }
-               if (status == DESTROY_ME)
-               {
-                       break;
+                       child_cfg = child_sa->get_config(child_sa);
+                       DBG1(DBG_IKE, "restarting CHILD_SA %s",
+                                child_cfg->get_name(child_cfg));
+                       other->task_manager->queue_child(other->task_manager,
+                                                                                        child_cfg->get_ref(child_cfg),
+                                                                                        child_sa->get_reqid(child_sa),
+                                                                                        NULL, NULL);
                }
        }
        enumerator->destroy(enumerator);
+
        /* adopt any active or queued CHILD-creating tasks */
-       if (status != DESTROY_ME)
-       {
-               new->adopt_child_tasks(new, &this->public);
-               if (new->get_state(new) == IKE_CREATED)
-               {
-                       status = new->initiate(new, NULL, 0, NULL, NULL);
-               }
-       }
-       return status;
+       new->adopt_child_tasks(new, &this->public);
+
+       return new->initiate(new, NULL, 0, NULL, NULL);
 }
 
 METHOD(ike_sa_t, reestablish, status_t,