ikev1: When a reauth is detected explicitly delete the old IKE_SA
authorTobias Brunner <tobias@strongswan.org>
Tue, 12 May 2015 14:59:20 +0000 (16:59 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 21 May 2015 14:00:39 +0000 (16:00 +0200)
Instead of just implicitly destroying the old SA we properly delete it to
notify the other peer (if the other peer keeps the SA up after the
reauthentication and sends DPDs it might consider us dead even though the
new SA is up, that seems to be the case with racoon).  We delay the DELETE
a bit to give the other peer time to get the new SA fully established.

Since DELETE messages are not retransmitted it is still possible that
the other peer misses that we deleted the SA.

src/libcharon/processing/jobs/adopt_children_job.c

index 9ad4b73..b4f135a 100644 (file)
@@ -21,6 +21,7 @@
 #include <daemon.h>
 #include <hydra.h>
 #include <collections/array.h>
+#include <processing/jobs/delete_ike_sa_job.h>
 
 typedef struct private_adopt_children_job_t private_adopt_children_job_t;
 
@@ -133,10 +134,19 @@ METHOD(job_t, execute, job_requeue_t,
                                                         "adopting %d children and %d virtual IPs",
                                                         children->get_count(children), vips->get_count(vips));
                                        }
-                                       ike_sa->set_state(ike_sa, IKE_DELETING);
-                                       charon->bus->ike_updown(charon->bus, ike_sa, FALSE);
-                                       charon->ike_sa_manager->checkin_and_destroy(
+                                       if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
+                                       {
+                                               charon->ike_sa_manager->checkin_and_destroy(
+                                                                                       charon->ike_sa_manager, ike_sa);
+                                       }
+                                       else
+                                       {
+                                               lib->scheduler->schedule_job(lib->scheduler, (job_t*)
+                                                               delete_ike_sa_job_create(ike_sa->get_id(ike_sa),
+                                                                                                                TRUE), 10);
+                                               charon->ike_sa_manager->checkin(
                                                                                        charon->ike_sa_manager, ike_sa);
+                                       }
                                }
                                else
                                {