]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
child-create: Update CHILD_SA IP addresses before installation
authorTobias Brunner <tobias@strongswan.org>
Thu, 15 Oct 2020 11:45:53 +0000 (13:45 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 27 Oct 2020 15:45:10 +0000 (16:45 +0100)
We create the child_sa_t object when initiating the CREATE_CHILD_SA
request, however, the IP addresses/ports might have changed once we
eventually receive the response (potentially to a retransmit sent to
a different address).  So update them before installing the SA and
policies.

If the local address changed too and depending on the kernel
implementation, the temporary SA created to allocate the inbound SPI
might remain as it can't be updated.  This could cause issues if e.g.
the address switches back before that SA expired (the updated inbound
SA conflicts with the temporary one), or if that happens close together
and the expire (having to wait for the address update) causes the
updated SA to get deleted.

Fixes #3164.

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

index 2b9e68d3bf6ea0fd57a2e9832e06165380c648d0..64dd55167bf4873a6fc1327f5cf14d2970805c64 100644 (file)
@@ -707,6 +707,17 @@ static status_t select_and_install(private_child_create_t *this,
                }
        }
 
+       this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
+       this->child_sa->set_mode(this->child_sa, this->mode);
+       this->child_sa->set_protocol(this->child_sa,
+                                                                this->proposal->get_protocol(this->proposal));
+       this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
+
+       /* addresses might have changed since we originally sent the request, update
+        * them before we configure any policies and install the SAs */
+       this->child_sa->update(this->child_sa, me, other, NULL,
+                                                  this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+
        this->child_sa->set_policies(this->child_sa, my_ts, other_ts);
        if (!this->initiator)
        {
@@ -716,12 +727,6 @@ static status_t select_and_install(private_child_create_t *this,
                                                          offsetof(traffic_selector_t, destroy));
        }
 
-       this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
-       this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
-       this->child_sa->set_mode(this->child_sa, this->mode);
-       this->child_sa->set_protocol(this->child_sa,
-                                                                this->proposal->get_protocol(this->proposal));
-
        if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
        {
                this->my_cpi = this->other_cpi = 0;