summaryrefslogtreecommitdiff
path: root/src/charon/sa/tasks
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-10-21 11:14:02 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-10-21 11:14:02 +0000
commit7410d3c6d6a9a1cd7aa55083c938946af6ff9498 (patch)
tree3291beffa55649f9be28b4a98a7d503d334fbcf2 /src/charon/sa/tasks
parent41787e147279ff0695e9d759487266a60b80867b (diff)
downloadvyos-strongswan-7410d3c6d6a9a1cd7aa55083c938946af6ff9498.tar.gz
vyos-strongswan-7410d3c6d6a9a1cd7aa55083c938946af6ff9498.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.3.4)
Diffstat (limited to 'src/charon/sa/tasks')
-rw-r--r--src/charon/sa/tasks/child_create.c39
-rw-r--r--src/charon/sa/tasks/child_create.h4
-rw-r--r--src/charon/sa/tasks/child_delete.c29
-rw-r--r--src/charon/sa/tasks/child_rekey.c15
-rw-r--r--src/charon/sa/tasks/ike_auth.c2
-rw-r--r--src/charon/sa/tasks/ike_delete.c36
-rw-r--r--src/charon/sa/tasks/ike_rekey.c2
-rw-r--r--src/charon/sa/tasks/task.h4
8 files changed, 105 insertions, 26 deletions
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index f51443738..558938f2e 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -158,6 +158,11 @@ struct private_child_create_t {
* successfully established the CHILD?
*/
bool established;
+
+ /**
+ * whether the CHILD_SA rekeys an existing one
+ */
+ bool rekey;
};
/**
@@ -249,7 +254,7 @@ static bool allocate_spi(private_child_create_t *this)
*/
static status_t select_and_install(private_child_create_t *this, bool no_dh)
{
- status_t status;
+ status_t status, status_i, status_o;
chunk_t nonce_i, nonce_r;
chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
@@ -401,22 +406,22 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
this->my_cpi = this->other_cpi = 0;
this->ipcomp = IPCOMP_NONE;
}
- status = FAILED;
+ status_i = status_o = FAILED;
if (this->keymat->derive_child_keys(this->keymat, this->proposal,
this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
{
if (this->initiator)
{
- status = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
this->my_spi, this->my_cpi, TRUE);
- status = this->child_sa->install(this->child_sa, encr_i, integ_i,
+ status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
this->other_spi, this->other_cpi, FALSE);
}
else
{
- status = this->child_sa->install(this->child_sa, encr_i, integ_i,
+ status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
this->my_spi, this->my_cpi, TRUE);
- status = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
this->other_spi, this->other_cpi, FALSE);
}
}
@@ -425,9 +430,12 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
chunk_clear(&encr_i);
chunk_clear(&encr_r);
- if (status != SUCCESS)
+ if (status_i != SUCCESS || status_o != SUCCESS)
{
- DBG1(DBG_IKE, "unable to install IPsec SA (SAD) in kernel");
+ DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
+ (status_i != SUCCESS) ? "inbound " : "",
+ (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
+ (status_o != SUCCESS) ? "outbound " : "");
return FAILED;
}
@@ -939,7 +947,11 @@ static status_t build_r(private_child_create_t *this, message_t *message)
ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
-
+
+ if (!this->rekey)
+ { /* invoke the child_up() hook if we are not rekeying */
+ charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
+ }
return SUCCESS;
}
@@ -1052,6 +1064,11 @@ static status_t process_i(private_child_create_t *this, message_t *message)
ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
+
+ if (!this->rekey)
+ { /* invoke the child_up() hook if we are not rekeying */
+ charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
+ }
}
else
{
@@ -1174,7 +1191,8 @@ static void destroy(private_child_create_t *this)
/*
* Described in header.
*/
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+child_create_t *child_create_create(ike_sa_t *ike_sa,
+ child_cfg_t *config, bool rekey,
traffic_selector_t *tsi, traffic_selector_t *tsr)
{
private_child_create_t *this = malloc_thing(private_child_create_t);
@@ -1222,6 +1240,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
this->other_cpi = 0;
this->reqid = 0;
this->established = FALSE;
+ this->rekey = rekey;
return &this->public;
}
diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h
index ce2829a9a..41f4fe2c8 100644
--- a/src/charon/sa/tasks/child_create.h
+++ b/src/charon/sa/tasks/child_create.h
@@ -71,11 +71,13 @@ struct child_create_t {
*
* @param ike_sa IKE_SA this task works for
* @param config child_cfg if task initiator, NULL if responder
+ * @param rekey whether we do a rekey or not
* @param tsi source of triggering packet, or NULL
* @param tsr destination of triggering packet, or NULL
* @return child_create task to handle by the task_manager
*/
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+child_create_t *child_create_create(ike_sa_t *ike_sa,
+ child_cfg_t *config, bool rekey,
traffic_selector_t *tsi, traffic_selector_t *tsr);
#endif /** CHILD_CREATE_H_ @}*/
diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c
index 0d89c148e..7abb07a84 100644
--- a/src/charon/sa/tasks/child_delete.c
+++ b/src/charon/sa/tasks/child_delete.c
@@ -52,11 +52,16 @@ struct private_child_delete_t {
u_int32_t spi;
/**
- * wheter to enforce delete action policy
+ * whether to enforce delete action policy
*/
bool check_delete_action;
/**
+ * is this delete exchange following a rekey?
+ */
+ bool rekeyed;
+
+ /**
* CHILD_SAs which get deleted
*/
linked_list_t *child_sas;
@@ -148,6 +153,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
switch (child_sa->get_state(child_sa))
{
case CHILD_REKEYING:
+ this->rekeyed = TRUE;
/* we reply as usual, rekeying will fail */
break;
case CHILD_DELETING:
@@ -190,6 +196,11 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (void**)&child_sa))
{
+ /* signal child down event if we are not rekeying */
+ if (!this->rekeyed)
+ {
+ charon->bus->child_updown(charon->bus, child_sa, FALSE);
+ }
spi = child_sa->get_spi(child_sa, TRUE);
protocol = child_sa->get_protocol(child_sa);
child_cfg = child_sa->get_config(child_sa);
@@ -229,15 +240,19 @@ static void log_children(private_child_delete_t *this)
{
iterator_t *iterator;
child_sa_t *child_sa;
+ u_int64_t bytes_in, bytes_out;
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (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 %.8x_o and TS %#R=== %#R",
+ "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)),
- ntohl(child_sa->get_spi(child_sa, FALSE)),
+ 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));
}
@@ -258,7 +273,10 @@ static status_t build_i(private_child_delete_t *this, message_t *message)
return SUCCESS;
}
this->child_sas->insert_last(this->child_sas, child_sa);
-
+ if (child_sa->get_state(child_sa) == CHILD_REKEYING)
+ {
+ this->rekeyed = TRUE;
+ }
log_children(this);
build_payloads(this, message);
return NEED_MORE;
@@ -359,6 +377,7 @@ child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
this->child_sas = linked_list_create();
this->protocol = protocol;
this->spi = spi;
+ this->rekeyed = FALSE;
if (protocol != PROTO_NONE)
{
diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c
index 6ab00dc5b..601e054ea 100644
--- a/src/charon/sa/tasks/child_rekey.c
+++ b/src/charon/sa/tasks/child_rekey.c
@@ -157,7 +157,8 @@ static status_t build_i(private_child_rekey_t *this, message_t *message)
/* ... our CHILD_CREATE task does the hard work for us. */
reqid = this->child_sa->get_reqid(this->child_sa);
- this->child_create = child_create_create(this->ike_sa, config, NULL, NULL);
+ this->child_create = child_create_create(this->ike_sa, config, TRUE,
+ NULL, NULL);
this->child_create->use_reqid(this->child_create, reqid);
this->child_create->task.build(&this->child_create->task, message);
@@ -207,6 +208,10 @@ static status_t build_r(private_child_rekey_t *this, message_t *message)
}
this->child_sa->set_state(this->child_sa, CHILD_REKEYING);
+
+ /* invoke rekey hook */
+ charon->bus->child_rekey(charon->bus, this->child_sa,
+ this->child_create->get_child(this->child_create));
return SUCCESS;
}
@@ -303,6 +308,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
}
}
+ 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));
+ }
+
spi = to_delete->get_spi(to_delete, TRUE);
protocol = to_delete->get_protocol(to_delete);
@@ -416,7 +427,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
this->initiator = FALSE;
- this->child_create = child_create_create(ike_sa, NULL, NULL, NULL);
+ this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL);
}
this->ike_sa = ike_sa;
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index 8d6cd56bd..d0b2a7e91 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -738,6 +738,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
+ charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
return SUCCESS;
}
return NEED_MORE;
@@ -916,6 +917,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
+ charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
return SUCCESS;
}
return NEED_MORE;
diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c
index f308a6358..cde117934 100644
--- a/src/charon/sa/tasks/ike_delete.c
+++ b/src/charon/sa/tasks/ike_delete.c
@@ -21,7 +21,7 @@
typedef struct private_ike_delete_t private_ike_delete_t;
-/**file
+/**
* Private members of a ike_delete_t task.
*/
struct private_ike_delete_t {
@@ -42,6 +42,11 @@ struct private_ike_delete_t {
bool initiator;
/**
+ * are we deleting a rekeyed SA?
+ */
+ bool rekeyed;
+
+ /**
* are we responding to a delete, but have initated our own?
*/
bool simultaneous;
@@ -64,6 +69,11 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
delete_payload = delete_payload_create(PROTO_IKE);
message->add_payload(message, (payload_t*)delete_payload);
+
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
+ {
+ this->rekeyed = TRUE;
+ }
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
DBG1(DBG_IKE, "sending DELETE for IKE_SA %s[%d]",
@@ -79,8 +89,12 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
static status_t process_i(private_ike_delete_t *this, message_t *message)
{
DBG0(DBG_IKE, "IKE_SA deleted");
- /* completed, delete IKE_SA by returning FAILED */
- return FAILED;
+ if (!this->rekeyed)
+ { /* invoke ike_down() hook if SA has not been rekeyed */
+ charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
+ }
+ /* completed, delete IKE_SA by returning DESTROY_ME */
+ return DESTROY_ME;
}
/**
@@ -106,14 +120,17 @@ static status_t process_r(private_ike_delete_t *this, message_t *message)
case IKE_ESTABLISHED:
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
this->ike_sa->reestablish(this->ike_sa);
+ return NEED_MORE;
+ case IKE_REKEYING:
+ this->rekeyed = TRUE;
break;
case IKE_DELETING:
this->simultaneous = TRUE;
- /* FALL */
+ break;
default:
- this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
break;
}
+ this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
return NEED_MORE;
}
@@ -129,8 +146,12 @@ static status_t build_r(private_ike_delete_t *this, message_t *message)
/* wait for peer's response for our delete request, but set a timeout */
return SUCCESS;
}
- /* completed, delete IKE_SA by returning FAILED */
- return FAILED;
+ if (!this->rekeyed)
+ { /* invoke ike_down() hook if SA has not been rekeyed */
+ charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
+ }
+ /* completed, delete IKE_SA by returning DESTROY_ME */
+ return DESTROY_ME;
}
/**
@@ -182,6 +203,7 @@ ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator)
this->ike_sa = ike_sa;
this->initiator = initiator;
+ this->rekeyed = FALSE;
this->simultaneous = FALSE;
return &this->public;
diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c
index bead408a6..3a049b566 100644
--- a/src/charon/sa/tasks/ike_rekey.c
+++ b/src/charon/sa/tasks/ike_rekey.c
@@ -367,6 +367,8 @@ static void destroy(private_ike_rekey_t *this)
if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED &&
this->new_sa->inherit(this->new_sa, this->ike_sa) != DESTROY_ME)
{
+ /* invoke hook if rekeying was successful */
+ charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa);
}
else
diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h
index f9b409f35..3d2014599 100644
--- a/src/charon/sa/tasks/task.h
+++ b/src/charon/sa/tasks/task.h
@@ -100,7 +100,8 @@ struct task_t {
*
* @param message message to add payloads to
* @return
- * - FAILED if a critical error occured
+ * - FAILED if a critical error occured
+ * - DESTROY_ME if IKE_SA has been properly deleted
* - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed
*/
@@ -112,6 +113,7 @@ struct task_t {
* @param message message to read payloads from
* @return
* - FAILED if a critical error occured
+ * - DESTROY_ME if IKE_SA has been properly deleted
* - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed
*/