]> git.ipfire.org Git - thirdparty/strongswan.git/commit
ikev2: Make CHILD_SAs properly trackable during rekey collisions
authorTobias Brunner <tobias@strongswan.org>
Mon, 22 Aug 2022 13:43:16 +0000 (15:43 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 22 Mar 2023 10:35:11 +0000 (11:35 +0100)
commit8f0701c11516b7680518517a1a6f57c57f10de49
tree655158f7575882cd5f5137a84b5185a3724889f1
parentff424de04eeb986edeac0d9064442e77e8cf19f7
ikev2: Make CHILD_SAs properly trackable during rekey collisions

As the winner of a rekey collision, we previously always triggered the
child_rekey() event once when creating the redundant SA on behalf of the
peer in the passive child-rekey task and then a second time when
creating the winning SA in the active task.  However, both calls passed
the replaced CHILD_SA as "old". This made tracking CHILD_SAs impossible
because there was no transition from the redundant, "new" SA of the
first event to the "new", winning SA of the second.  Of course, when the
second event was triggered, the redundant SA might not have existed
anymore because the peer is expected to delete it, which could happen
before the CREATE_CHILD_SA response arrives at the initiator.

This refactoring ensures that the child_rekey() event is triggered in
a way that makes the CHILD_SAs trackable in all reasonable (and even
some unreasonable) scenarios.  The event is generally only triggered
once after installing the outbound SA for the new/winning CHILD_SA.
This can be when processing the CREATE_CHILD_SA in the active child-rekey
task, or when processing the DELETE for the old SA in a passive
child-delete task.  There are some cases where the event is still
triggered twice, but it is now ensured that listeners can properly
transition to the winning SA.

Some corner cases are now also handled correctly, e.g. if a responder's
DELETE for the new CHILD_SA arrives before its CREATE_CHILD_SA response
that actually creates it on the initiator.  Also handled properly are
responders of rekeyings that incorrectly send a DELETE for the old
CHILD_SA (previously this caused both, the new and the old SA, to get
deleted).
src/libcharon/sa/child_sa.c
src/libcharon/sa/child_sa.h
src/libcharon/sa/ikev2/task_manager_v2.c
src/libcharon/sa/ikev2/tasks/child_create.c
src/libcharon/sa/ikev2/tasks/child_create.h
src/libcharon/sa/ikev2/tasks/child_delete.c
src/libcharon/sa/ikev2/tasks/child_delete.h
src/libcharon/sa/ikev2/tasks/child_rekey.c
src/libcharon/sa/ikev2/tasks/child_rekey.h
src/libcharon/tests/suites/test_child_rekey.c