summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev2
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ikev2')
-rw-r--r--src/libcharon/sa/ikev2/task_manager_v2.c20
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c18
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_delete.c7
3 files changed, 29 insertions, 16 deletions
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
index a6af744fc..8e6da1609 100644
--- a/src/libcharon/sa/ikev2/task_manager_v2.c
+++ b/src/libcharon/sa/ikev2/task_manager_v2.c
@@ -1145,14 +1145,9 @@ METHOD(task_manager_t, process_message, status_t,
return FAILED;
}
}
- if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
- this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
- msg->get_exchange_type(msg) != IKE_SA_INIT)
- { /* only do host updates based on verified messages */
- if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
- { /* with MOBIKE, we do no implicit updates */
- this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
- }
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
+ { /* with MOBIKE, we do no implicit updates */
+ this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
}
charon->bus->message(charon->bus, msg, TRUE, TRUE);
if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
@@ -1198,10 +1193,13 @@ METHOD(task_manager_t, process_message, status_t,
if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
msg->get_exchange_type(msg) != IKE_SA_INIT)
- { /* only do host updates based on verified messages */
+ { /* only do updates based on verified messages (or initial ones) */
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
- { /* with MOBIKE, we do no implicit updates */
- this->ike_sa->update_hosts(this->ike_sa, me, other, FALSE);
+ { /* with MOBIKE, we do no implicit updates. we force an
+ * update of the local address on IKE_SA_INIT, but never
+ * for the remote address */
+ this->ike_sa->update_hosts(this->ike_sa, me, NULL, mid == 0);
+ this->ike_sa->update_hosts(this->ike_sa, NULL, other, FALSE);
}
}
charon->bus->message(charon->bus, msg, TRUE, TRUE);
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index 8ae36af84..7cfa537a9 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -244,9 +244,23 @@ static bool allocate_spi(private_child_create_t *this)
{
enumerator_t *enumerator;
proposal_t *proposal;
+ protocol_id_t proto = PROTO_ESP;
- /* TODO: allocate additional SPI for AH if we have such proposals */
- this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
+ if (this->initiator)
+ {
+ /* we just get a SPI for the first protocol. TODO: If we ever support
+ * proposal lists with mixed protocols, we'd need multiple SPIs */
+ if (this->proposals->get_first(this->proposals,
+ (void**)&proposal) == SUCCESS)
+ {
+ proto = proposal->get_protocol(proposal);
+ }
+ }
+ else
+ {
+ proto = this->proposal->get_protocol(this->proposal);
+ }
+ this->my_spi = this->child_sa->alloc_spi(this->child_sa, proto);
if (this->my_spi)
{
if (this->initiator)
diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c
index eaaca2039..e898efc88 100644
--- a/src/libcharon/sa/ikev2/tasks/child_delete.c
+++ b/src/libcharon/sa/ikev2/tasks/child_delete.c
@@ -198,7 +198,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
child_sa_t *child_sa;
child_cfg_t *child_cfg;
protocol_id_t protocol;
- u_int32_t spi;
+ u_int32_t spi, reqid;
action_t action;
status_t status = SUCCESS;
@@ -211,6 +211,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
charon->bus->child_updown(charon->bus, child_sa, FALSE);
}
spi = child_sa->get_spi(child_sa, TRUE);
+ reqid = child_sa->get_reqid(child_sa);
protocol = child_sa->get_protocol(child_sa);
child_cfg = child_sa->get_config(child_sa);
child_cfg->get_ref(child_cfg);
@@ -223,12 +224,12 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
case ACTION_RESTART:
child_cfg->get_ref(child_cfg);
status = this->ike_sa->initiate(this->ike_sa, child_cfg,
- child_sa->get_reqid(child_sa), NULL, NULL);
+ reqid, NULL, NULL);
break;
case ACTION_ROUTE:
charon->traps->install(charon->traps,
this->ike_sa->get_peer_cfg(this->ike_sa), child_cfg,
- child_sa->get_reqid(child_sa));
+ reqid);
break;
default:
break;