From: Tobias Brunner Date: Mon, 12 Jul 2021 12:47:57 +0000 (+0200) Subject: ike: Initiate new IKE_SA not until all children are queued X-Git-Tag: 5.9.4dr2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c0d7ec531c1de948e04ac1b5de7fca9898b3ea4;p=thirdparty%2Fstrongswan.git ike: Initiate new IKE_SA not until all children are queued 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). --- diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index ba59b052b5..a891aff497 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -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,