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:
Tobias Brunner
2020-10-27 16:35:45 +01:00
parent c5baa4cbd6
commit 12a3f3ca52
+26 -11
View File
@@ -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,