child-create: Promote selected DH group, demote proposals that don't contain it
authorTobias Brunner <tobias@strongswan.org>
Fri, 2 Feb 2018 11:04:18 +0000 (12:04 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 9 Feb 2018 09:20:05 +0000 (10:20 +0100)
src/libcharon/sa/ikev2/tasks/child_create.c

index 17c5573..5161ca1 100644 (file)
@@ -277,12 +277,13 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host)
 }
 
 /**
- * Allocate SPIs and update proposals
+ * Allocate SPIs and update proposals, we also promote the selected DH group
  */
 static bool allocate_spi(private_child_create_t *this)
 {
        enumerator_t *enumerator;
        proposal_t *proposal;
+       linked_list_t *other_dh_groups;
 
        if (this->initiator)
        {
@@ -304,12 +305,29 @@ static bool allocate_spi(private_child_create_t *this)
        {
                if (this->initiator)
                {
+                       other_dh_groups = linked_list_create();
                        enumerator = this->proposals->create_enumerator(this->proposals);
                        while (enumerator->enumerate(enumerator, &proposal))
                        {
                                proposal->set_spi(proposal, this->my_spi);
+
+                               /* move the selected DH group to the front, if any */
+                               if (this->dh_group != MODP_NONE &&
+                                       !proposal->promote_dh_group(proposal, this->dh_group))
+                               {       /* proposals that don't contain the selected group are
+                                        * moved to the back */
+                                       this->proposals->remove_at(this->proposals, enumerator);
+                                       other_dh_groups->insert_last(other_dh_groups, proposal);
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+                       enumerator = other_dh_groups->create_enumerator(other_dh_groups);
+                       while (enumerator->enumerate(enumerator, (void**)&proposal))
+                       {       /* no need to remove from the list as we destroy it anyway*/
+                               this->proposals->insert_last(this->proposals, proposal);
                        }
                        enumerator->destroy(enumerator);
+                       other_dh_groups->destroy(other_dh_groups);
                }
                else
                {