quick-delete: Properly handle failures to restart CHILD_SA
If DESTROY_ME is returned from initiate(), we must not touch the IKE_SA anymore.
This commit is contained in:
@@ -86,13 +86,15 @@ struct private_quick_delete_t {
|
|||||||
/**
|
/**
|
||||||
* Delete the specified CHILD_SA, if found
|
* Delete the specified CHILD_SA, if found
|
||||||
*/
|
*/
|
||||||
static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
|
static status_t delete_child(private_quick_delete_t *this,
|
||||||
uint32_t spi, bool remote_close)
|
protocol_id_t protocol, uint32_t spi,
|
||||||
|
bool remote_close)
|
||||||
{
|
{
|
||||||
uint64_t bytes_in, bytes_out;
|
uint64_t bytes_in, bytes_out;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
linked_list_t *my_ts, *other_ts;
|
linked_list_t *my_ts, *other_ts;
|
||||||
child_cfg_t *child_cfg;
|
child_cfg_t *child_cfg;
|
||||||
|
status_t status = SUCCESS;
|
||||||
bool rekeyed;
|
bool rekeyed;
|
||||||
|
|
||||||
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, TRUE);
|
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, TRUE);
|
||||||
@@ -101,7 +103,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
|
|||||||
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE);
|
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE);
|
||||||
if (!child_sa)
|
if (!child_sa)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return NOT_FOUND;
|
||||||
}
|
}
|
||||||
this->spi = spi = child_sa->get_spi(child_sa, TRUE);
|
this->spi = spi = child_sa->get_spi(child_sa, TRUE);
|
||||||
}
|
}
|
||||||
@@ -154,7 +156,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
|
|||||||
{
|
{
|
||||||
case ACTION_RESTART:
|
case ACTION_RESTART:
|
||||||
child_cfg->get_ref(child_cfg);
|
child_cfg->get_ref(child_cfg);
|
||||||
this->ike_sa->initiate(this->ike_sa, child_cfg,
|
status = this->ike_sa->initiate(this->ike_sa, child_cfg,
|
||||||
child_sa->get_reqid(child_sa), NULL, NULL);
|
child_sa->get_reqid(child_sa), NULL, NULL);
|
||||||
break;
|
break;
|
||||||
case ACTION_ROUTE:
|
case ACTION_ROUTE:
|
||||||
@@ -168,15 +170,18 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
|
|||||||
child_cfg->destroy(child_cfg);
|
child_cfg->destroy(child_cfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi);
|
if (status == SUCCESS)
|
||||||
|
{
|
||||||
return TRUE;
|
this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_i, status_t,
|
METHOD(task_t, build_i, status_t,
|
||||||
private_quick_delete_t *this, message_t *message)
|
private_quick_delete_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
if (delete_child(this, this->protocol, this->spi, FALSE) || this->force)
|
if (delete_child(this, this->protocol, this->spi, FALSE) == SUCCESS ||
|
||||||
|
this->force)
|
||||||
{
|
{
|
||||||
delete_payload_t *delete_payload;
|
delete_payload_t *delete_payload;
|
||||||
|
|
||||||
@@ -206,6 +211,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
payload_t *payload;
|
payload_t *payload;
|
||||||
delete_payload_t *delete_payload;
|
delete_payload_t *delete_payload;
|
||||||
protocol_id_t protocol;
|
protocol_id_t protocol;
|
||||||
|
status_t status = SUCCESS;
|
||||||
uint32_t spi;
|
uint32_t spi;
|
||||||
|
|
||||||
payloads = message->create_payload_enumerator(message);
|
payloads = message->create_payload_enumerator(message);
|
||||||
@@ -224,18 +230,27 @@ METHOD(task_t, process_r, status_t,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
|
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
|
||||||
protocol_id_names, protocol, ntohl(spi));
|
protocol_id_names, protocol, ntohl(spi));
|
||||||
if (!delete_child(this, protocol, spi, TRUE))
|
status = delete_child(this, protocol, spi, TRUE);
|
||||||
|
if (status == NOT_FOUND)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "CHILD_SA not found, ignored");
|
DBG1(DBG_IKE, "CHILD_SA not found, ignored");
|
||||||
continue;
|
status = SUCCESS;
|
||||||
|
}
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spis->destroy(spis);
|
spis->destroy(spis);
|
||||||
}
|
}
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
payloads->destroy(payloads);
|
payloads->destroy(payloads);
|
||||||
|
|
||||||
return SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_r, status_t,
|
METHOD(task_t, build_r, status_t,
|
||||||
|
|||||||
Reference in New Issue
Block a user