charon->bus->set_sa(charon->bus, ike_sa);
if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME)
+ child_sa->get_spi(child_sa, TRUE), FALSE) != DESTROY_ME)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
listener->status = SUCCESS;
protocol_id_names, proto, ntohl(spi), reqid);
if (hard)
{
- job = (job_t*)delete_child_sa_job_create(reqid, proto, spi);
+ job = (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard);
}
else
{
DBG1(DBG_CFG, "resyncing CHILD_SA using a delete");
status = ike_sa->delete_child_sa(ike_sa,
child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ child_sa->get_spi(child_sa, TRUE),
+ FALSE);
}
else
{
* inbound SPI of the CHILD_SA
*/
u_int32_t spi;
+
+ /**
+ * Delete for an expired CHILD_SA
+ */
+ bool expired;
};
METHOD(job_t, destroy, void,
}
else
{
- ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi);
+ ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi, this->expired);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
* Described in header
*/
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi)
+ protocol_id_t protocol, u_int32_t spi, bool expired)
{
private_delete_child_sa_job_t *this;
.reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .expired = expired,
);
return &this->public;
* @param reqid reqid of the CHILD_SA, as used in kernel
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param expired TRUE if CHILD_SA already expired
* @return delete_child_sa_job_t object
*/
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi);
+ protocol_id_t protocol, u_int32_t spi, bool expired);
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
{
DBG1(DBG_JOB, "deleting CHILD_SA after %d seconds "
"of inactivity", this->timeout);
- status = ike_sa->delete_child_sa(ike_sa, proto, delete);
+ status = ike_sa->delete_child_sa(ike_sa, proto, delete, FALSE);
}
}
if (status == DESTROY_ME)
}
METHOD(ike_sa_t, delete_child_sa, status_t,
- private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
+ private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi, bool expired)
{
- this->task_manager->queue_child_delete(this->task_manager, protocol, spi);
+ this->task_manager->queue_child_delete(this->task_manager,
+ protocol, spi, expired);
return this->task_manager->initiate(this->task_manager);
}
*
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
+ * @param expired TRUE if CHILD_SA is expired
* @return
* - NOT_FOUND, if IKE_SA has no such CHILD_SA
* - SUCCESS, if delete message sent
*/
- status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
+ status_t (*delete_child_sa)(ike_sa_t *this, protocol_id_t protocol,
+ u_int32_t spi, bool expired);
/**
* Destroy a CHILD SA with the specified protocol/SPI.
{
queue_task(this, (task_t*)
quick_delete_create(this->ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE), FALSE));
+ child_sa->get_spi(child_sa, TRUE), FALSE, FALSE));
}
enumerator->destroy(enumerator);
}
METHOD(task_manager_t, queue_child_delete, void,
- private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi)
+ private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi,
+ bool expired)
{
queue_task(this, (task_t*)quick_delete_create(this->ike_sa, protocol,
- spi, FALSE));
+ spi, FALSE, expired));
}
METHOD(task_manager_t, queue_dpd, void,
else
{
this->del = (task_t*)quick_delete_create(this->ike_sa,
- PROTO_NONE, 0, FALSE);
+ PROTO_NONE, 0, FALSE, FALSE);
}
}
break;
* Send delete even if SA does not exist
*/
bool force;
+
+ /**
+ * SA already expired?
+ */
+ bool expired;
};
/**
child_sa->set_state(child_sa, CHILD_DELETING);
- child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in);
- child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out);
-
- DBG0(DBG_IKE, "closing CHILD_SA %s{%d} "
- "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
- ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
- ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
- child_sa->get_traffic_selectors(child_sa, TRUE),
- child_sa->get_traffic_selectors(child_sa, FALSE));
+ if (this->expired)
+ {
+ DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
+ "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ ntohl(child_sa->get_spi(child_sa, TRUE)),
+ ntohl(child_sa->get_spi(child_sa, FALSE)),
+ child_sa->get_traffic_selectors(child_sa, TRUE),
+ child_sa->get_traffic_selectors(child_sa, FALSE));
+ }
+ else
+ {
+ child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in);
+ child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out);
+
+ DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs "
+ "%.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
+ ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
+ child_sa->get_traffic_selectors(child_sa, TRUE),
+ child_sa->get_traffic_selectors(child_sa, FALSE));
+ }
charon->bus->child_updown(charon->bus, child_sa, FALSE);
* Described in header.
*/
quick_delete_t *quick_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
- u_int32_t spi, bool force)
+ u_int32_t spi, bool force, bool expired)
{
private_quick_delete_t *this;
.protocol = protocol,
.spi = spi,
.force = force,
+ .expired = expired,
);
if (protocol != PROTO_NONE)
* @param protocol protocol of CHILD_SA to delete, PROTO_NONE as responder
* @param spi inbound SPI of CHILD_SA to delete
* @param force send delete even if SA does not exist
+ * @param expired TRUE if SA already expired
* @return quick_delete task to handle by the task_manager
*/
quick_delete_t *quick_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
- u_int32_t spi, bool force);
+ u_int32_t spi, bool force, bool expired);
#endif /** QUICK_DELETE_H_ @}*/
this->ike_sa->queue_task(this->ike_sa,
(task_t*)quick_delete_create(this->ike_sa,
this->proposal->get_protocol(this->proposal),
- this->spi_i, TRUE));
+ this->spi_i, TRUE, TRUE));
return ALREADY_DONE;
}
return SUCCESS;
else
{
task = (task_t*)child_delete_create(this->ike_sa,
- PROTO_NONE, 0);
+ PROTO_NONE, 0, FALSE);
}
break;
}
}
METHOD(task_manager_t, queue_child_delete, void,
- private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi)
+ private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi,
+ bool expired)
{
- queue_task(this, (task_t*)child_delete_create(this->ike_sa, protocol, spi));
+ queue_task(this, (task_t*)child_delete_create(this->ike_sa,
+ protocol, spi, expired));
}
METHOD(task_manager_t, queue_dpd, void,
bool rekeyed;
/**
+ * CHILD_SA already expired?
+ */
+ bool expired;
+
+ /**
* CHILD_SAs which get deleted
*/
linked_list_t *child_sas;
enumerator = this->child_sas->create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in);
- child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out);
-
- DBG0(DBG_IKE, "closing CHILD_SA %s{%d} "
- "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
- ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
- ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
- child_sa->get_traffic_selectors(child_sa, TRUE),
- child_sa->get_traffic_selectors(child_sa, FALSE));
+ if (this->expired)
+ {
+ DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
+ "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ ntohl(child_sa->get_spi(child_sa, TRUE)),
+ ntohl(child_sa->get_spi(child_sa, FALSE)),
+ child_sa->get_traffic_selectors(child_sa, TRUE),
+ child_sa->get_traffic_selectors(child_sa, FALSE));
+ }
+ else
+ {
+ child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in);
+ child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out);
+
+ DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs %.8x_i "
+ "(%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
+ ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
+ child_sa->get_traffic_selectors(child_sa, TRUE),
+ child_sa->get_traffic_selectors(child_sa, FALSE));
+ }
}
enumerator->destroy(enumerator);
}
* Described in header.
*/
child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
- u_int32_t spi)
+ u_int32_t spi, bool expired)
{
private_child_delete_t *this;
.child_sas = linked_list_create(),
.protocol = protocol,
.spi = spi,
+ .expired = expired,
);
if (protocol != PROTO_NONE)
* @param ike_sa IKE_SA this task works for
* @param protocol protocol of CHILD_SA to delete, PROTO_NONE as responder
* @param spi inbound SPI of CHILD_SA to delete
+ * @param expired TRUE if CHILD_SA already expired
* @return child_delete task to handle by the task_manager
*/
child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
- u_int32_t spi);
+ u_int32_t spi, bool expired);
#endif /** CHILD_DELETE_H_ @}*/
protocol = to_delete->get_protocol(to_delete);
/* rekeying done, delete the obsolete CHILD_SA using a subtask */
- this->child_delete = child_delete_create(this->ike_sa, protocol, spi);
+ this->child_delete = child_delete_create(this->ike_sa, protocol, spi, FALSE);
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete;
*
* @param protocol CHILD_SA protocol, AH|ESP
* @param spi CHILD_SA SPI to rekey
+ * @param expired TRUE if SA already expired
*/
void (*queue_child_delete)(task_manager_t *this, protocol_id_t protocol,
- u_int32_t spi);
+ u_int32_t spi, bool expired);
/**
* Queue liveness checking tasks.