From: Tobias Brunner Date: Fri, 10 Jun 2016 14:00:25 +0000 (+0200) Subject: child-rekey: Only rekey installed CHILD_SAs X-Git-Tag: 5.5.0dr1~4^2~1 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=15cea08adc6a2700c401a23ce1838d33f31e26f5;p=thirdparty%2Fstrongswan.git child-rekey: Only rekey installed CHILD_SAs Depending on the lifetimes a CHILD_SA we rekeyed as responder might expire shortly afterwards. We don't want to rekey it again. When retrying due to an INVALID_KE_PAYLOAD notify the expected state is CHILD_REKEYING if it is anything else (e.g. due to a collision) we ignore it. We also abort the exchange properly if we don't find the CHILD_SA, no need for an empty INFORMATIONAL exchange anymore. --- diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index 95e4a3daec..c04ec141fd 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -160,14 +160,21 @@ METHOD(task_t, build_i, status_t, { /* check if it is an outbound CHILD_SA */ this->child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol, this->spi, FALSE); - if (!this->child_sa) - { /* CHILD_SA is gone, unable to rekey. As an empty CREATE_CHILD_SA - * exchange is invalid, we fall back to an INFORMATIONAL exchange.*/ - message->set_exchange_type(message, INFORMATIONAL); - return SUCCESS; + if (this->child_sa) + { + /* we work only with the inbound SPI */ + this->spi = this->child_sa->get_spi(this->child_sa, TRUE); } - /* we work only with the inbound SPI */ - this->spi = this->child_sa->get_spi(this->child_sa, TRUE); + } + if (!this->child_sa || + (!this->child_create && + this->child_sa->get_state(this->child_sa) != CHILD_INSTALLED) || + (this->child_create && + this->child_sa->get_state(this->child_sa) != CHILD_REKEYING)) + { + /* CHILD_SA is gone or in the wrong state, unable to rekey */ + message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED); + return SUCCESS; } config = this->child_sa->get_config(this->child_sa);