As responder, try to reuse the reqid of the CHILD_SA the initiator is rekeying
authorMartin Willi <martin@revosec.ch>
Mon, 2 Jan 2012 15:36:39 +0000 (16:36 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 20 Mar 2012 16:31:31 +0000 (17:31 +0100)
src/libcharon/sa/ikev1/tasks/quick_mode.c

index ff52204..0e8eea9 100644 (file)
@@ -661,6 +661,42 @@ static bool has_notify_errors(private_quick_mode_t *this, message_t *message)
        return err;
 }
 
+/**
+ * Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
+ */
+static void check_for_rekeyed_child(private_quick_mode_t *this)
+{
+       enumerator_t *enumerator, *policies;
+       traffic_selector_t *local, *remote;
+       child_sa_t *child_sa;
+
+       enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
+       while (this->reqid == 0 && enumerator->enumerate(enumerator, &child_sa))
+       {
+               if (child_sa->get_state(child_sa) == CHILD_INSTALLED &&
+                       streq(child_sa->get_name(child_sa),
+                                 this->config->get_name(this->config)))
+               {
+                       policies = child_sa->create_policy_enumerator(child_sa);
+                       if (policies->enumerate(policies, &local, &remote))
+                       {
+                               if (local->equals(local, this->tsr) &&
+                                       remote->equals(remote, this->tsi) &&
+                                       this->proposal->equals(this->proposal,
+                                                                                  child_sa->get_proposal(child_sa)))
+                               {
+                                       this->reqid = child_sa->get_reqid(child_sa);
+                                       child_sa->set_state(child_sa, CHILD_REKEYING);
+                                       DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}",
+                                                child_sa->get_name(child_sa), this->reqid);
+                               }
+                       }
+                       policies->destroy(policies);
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
 METHOD(task_t, process_r, status_t,
        private_quick_mode_t *this, message_t *message)
 {
@@ -755,6 +791,8 @@ METHOD(task_t, process_r, status_t,
                                }
                        }
 
+                       check_for_rekeyed_child(this);
+
                        this->child_sa = child_sa_create(
                                                                        this->ike_sa->get_my_host(this->ike_sa),
                                                                        this->ike_sa->get_other_host(this->ike_sa),