ikev2: Schedule a timeout for the delete message following passive IKE rekeying
authorMartin Willi <martin@revosec.ch>
Tue, 25 Nov 2014 13:21:34 +0000 (14:21 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 3 Mar 2015 12:45:39 +0000 (13:45 +0100)
Under some conditions it can happen that the CREATE_CHILD_SA exchange for
rekeying the IKE_SA initiated by the peer is successful, but the delete message
does not follow. For example if processing takes just too long locally, the
peer might consider us dead, but we won't notice that.

As this leaves the old IKE_SA in IKE_REKEYING state, we currently avoid actively
initiating any tasks, such as rekeying or scheduled DPD. This leaves the IKE_SA
in a dead and unusable state. To avoid that situation, we schedule a timeout
to wait for the DELETE message to follow the CREATE_CHILD_SA, before we
actively start to delete the IKE_SA.

Alternatively we could start a liveness check on the SA after a timeout to see
if the peer still has that state and we can expect the delete to follow. But
it is unclear if all peers can handle such messages in this very special state,
so we currently don't go for that approach.

While we could calculate the timeout based on the local retransmission timeout,
the peer might use a different scheme, so a fixed timeout works as well.

Fixes #742.

src/libcharon/sa/ikev2/tasks/ike_rekey.c

index ba7a101..4dcc84c 100644 (file)
@@ -210,6 +210,12 @@ METHOD(task_t, build_r, status_t,
        this->public.task.build = _build_r_delete;
        this->public.task.process = _process_r_delete;
 
+       /* the peer does have to delete the IKE_SA. If it does not, we get a
+        * unusable IKE_SA in REKEYING state without a replacement. We consider
+        * this a timeout condition by the peer, and trigger a delete actively. */
+       lib->scheduler->schedule_job(lib->scheduler, (job_t*)
+               delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 90);
+
        return NEED_MORE;
 }