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).
This commit is contained in: