summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev2/tasks/child_rekey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ikev2/tasks/child_rekey.c')
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_rekey.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index 761c860e7..b67e9b80f 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2016 Tobias Brunner
+ * Copyright (C) 2009-2017 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* HSR Hochschule fuer Technik Rapperswil
@@ -283,7 +283,8 @@ METHOD(task_t, build_r, status_t,
/**
* Handle a rekey collision
*/
-static child_sa_t *handle_collision(private_child_rekey_t *this)
+static child_sa_t *handle_collision(private_child_rekey_t *this,
+ child_sa_t **to_install)
{
child_sa_t *to_delete;
@@ -302,8 +303,11 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
{
child_sa_t *child_sa;
- DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child");
+ *to_install = this->child_create->get_child(this->child_create);
to_delete = this->child_sa;
+ DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child "
+ "%s{%d}", to_delete->get_name(to_delete),
+ to_delete->get_unique_id(to_delete));
/* don't touch child other created, it has already been deleted */
if (!this->other_child_destroyed)
{
@@ -321,9 +325,10 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
}
else
{
- DBG1(DBG_IKE, "CHILD_SA rekey collision lost, "
- "deleting rekeyed child");
to_delete = this->child_create->get_child(this->child_create);
+ DBG1(DBG_IKE, "CHILD_SA rekey collision lost, deleting redundant "
+ "child %s{%d}", to_delete->get_name(to_delete),
+ to_delete->get_unique_id(to_delete));
}
}
else
@@ -334,15 +339,17 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
* the CHILD_SA the other is not deleting. */
if (del->get_child(del) != this->child_sa)
{
- DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, "
- "deleting rekeyed child");
to_delete = this->child_sa;
+ DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, deleting old child "
+ "%s{%d}", to_delete->get_name(to_delete),
+ to_delete->get_unique_id(to_delete));
}
else
{
- DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, "
- "deleting redundant child");
to_delete = this->child_create->get_child(this->child_create);
+ DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, deleting redundant "
+ "child %s{%d}", to_delete->get_name(to_delete),
+ to_delete->get_unique_id(to_delete));
}
}
return to_delete;
@@ -353,7 +360,7 @@ METHOD(task_t, process_i, status_t,
{
protocol_id_t protocol;
uint32_t spi;
- child_sa_t *to_delete;
+ child_sa_t *to_delete, *to_install = NULL;
if (message->get_notify(message, NO_ADDITIONAL_SAS))
{
@@ -415,19 +422,48 @@ METHOD(task_t, process_i, status_t,
/* check for rekey collisions */
if (this->collision)
{
- to_delete = handle_collision(this);
+ to_delete = handle_collision(this, &to_install);
}
else
{
+ to_install = this->child_create->get_child(this->child_create);
to_delete = this->child_sa;
}
-
+ if (to_install)
+ {
+ if (to_install->install_outbound(to_install) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "unable to install outbound IPsec SA (SAD) in kernel");
+ charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
+ to_install);
+ /* FIXME: delete the child_sa? fail the task? */
+ }
+ else
+ {
+ linked_list_t *my_ts, *other_ts;
+
+ my_ts = linked_list_create_from_enumerator(
+ to_install->create_ts_enumerator(to_install, TRUE));
+ other_ts = linked_list_create_from_enumerator(
+ to_install->create_ts_enumerator(to_install, FALSE));
+
+ DBG0(DBG_IKE, "outbound CHILD_SA %s{%d} established "
+ "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
+ to_install->get_name(to_install),
+ to_install->get_unique_id(to_install),
+ ntohl(to_install->get_spi(to_install, TRUE)),
+ ntohl(to_install->get_spi(to_install, FALSE)),
+ my_ts, other_ts);
+
+ my_ts->destroy(my_ts);
+ other_ts->destroy(other_ts);
+ }
+ }
if (to_delete != this->child_create->get_child(this->child_create))
{ /* invoke rekey hook if rekeying successful */
charon->bus->child_rekey(charon->bus, this->child_sa,
this->child_create->get_child(this->child_create));
}
-
if (to_delete == NULL)
{
return SUCCESS;