child-sa: Add a new state to track rekeyed IKEv1 CHILD_SAs
authorTobias Brunner <tobias@strongswan.org>
Tue, 24 Mar 2015 17:36:49 +0000 (18:36 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 25 Mar 2015 11:00:20 +0000 (12:00 +0100)
This is needed to handle DELETEs properly, which was previously done via
CHILD_REKEYING, which we don't use anymore since 5c6a62ceb6 as it prevents
reauthentication.

src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/vici/vici_query.c
src/libcharon/processing/jobs/rekey_ike_sa_job.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/child_sa.h
src/libcharon/sa/ikev1/tasks/quick_delete.c
src/libcharon/sa/ikev1/tasks/quick_mode.c

index 8afd7db..68b8232 100644 (file)
@@ -323,7 +323,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 
                }
        }
-       else if (child_sa->get_state(child_sa) == CHILD_REKEYING)
+       else if (child_sa->get_state(child_sa) == CHILD_REKEYING ||
+                        child_sa->get_state(child_sa) == CHILD_REKEYED)
        {
                rekey = child_sa->get_lifetime(child_sa, TRUE);
                fprintf(out, ", expires in %V", &now, &rekey);
index 84fc23c..3e0d73c 100644 (file)
@@ -68,7 +68,8 @@ static void list_child(private_vici_query_t *this, vici_builder_t *b,
        b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child));
        b->add_kv(b, "mode", "%N", ipsec_mode_names, child->get_mode(child));
        if (child->get_state(child) == CHILD_INSTALLED ||
-               child->get_state(child) == CHILD_REKEYING)
+               child->get_state(child) == CHILD_REKEYING ||
+               child->get_state(child) == CHILD_REKEYED)
        {
                b->add_kv(b, "protocol", "%N", protocol_id_names,
                                  child->get_protocol(child));
index 516dc5d..403d826 100644 (file)
@@ -67,7 +67,8 @@ static u_int32_t get_retry_delay(ike_sa_t *ike_sa)
                enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
                while (enumerator->enumerate(enumerator, &child_sa))
                {
-                       if (child_sa->get_state(child_sa) != CHILD_INSTALLED)
+                       if (child_sa->get_state(child_sa) != CHILD_INSTALLED &&
+                               child_sa->get_state(child_sa) != CHILD_REKEYED)
                        {
                                retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
                                DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, "
index 068092d..9ea384e 100644 (file)
@@ -34,6 +34,7 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
        "INSTALLED",
        "UPDATING",
        "REKEYING",
+       "REKEYED",
        "RETRYING",
        "DELETING",
        "DESTROYING",
index 83b8c09..debe8eb 100644 (file)
@@ -68,6 +68,11 @@ enum child_sa_state_t {
        CHILD_REKEYING,
 
        /**
+        * CHILD_SA that was rekeyed, but stays installed
+        */
+       CHILD_REKEYED,
+
+       /**
         * CHILD_SA negotiation failed, but gets retried
         */
        CHILD_RETRYING,
index 4206182..1b95a8b 100644 (file)
@@ -105,7 +105,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
                this->spi = spi = child_sa->get_spi(child_sa, TRUE);
        }
 
-       rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYING;
+       rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED;
        child_sa->set_state(child_sa, CHILD_DELETING);
 
        my_ts = linked_list_create_from_enumerator(
index 982c128..96edfd8 100644 (file)
@@ -402,7 +402,7 @@ static bool install(private_quick_mode_t *this)
        {
                charon->bus->child_rekey(charon->bus, old, this->child_sa);
                /* rekeyed CHILD_SAs stay installed until they expire */
-               old->set_state(old, CHILD_INSTALLED);
+               old->set_state(old, CHILD_REKEYED);
        }
        else
        {
@@ -988,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
                        {
                                case CHILD_INSTALLED:
                                case CHILD_REKEYING:
+                               case CHILD_REKEYED:
                                        policies = child_sa->create_policy_enumerator(child_sa);
                                        if (policies->enumerate(policies, &local, &remote) &&
                                                local->equals(local, this->tsr) &&