From: Tobias Brunner Date: Thu, 15 Oct 2020 11:45:53 +0000 (+0200) Subject: child-create: Update CHILD_SA IP addresses before installation X-Git-Tag: 5.9.1rc1~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bce0c5fd74a0;p=thirdparty%2Fstrongswan.git child-create: Update CHILD_SA IP addresses before installation 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. --- diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 2b9e68d3bf..64dd55167b 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -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;