further fixed for mobike roaming
This commit is contained in:
+21
-12
@@ -1681,7 +1681,13 @@ static status_t roam(private_ike_sa_t *this)
|
||||
}
|
||||
|
||||
me = charon->kernel_interface->get_source_addr(charon->kernel_interface,
|
||||
this->other_host);
|
||||
this->other_host);
|
||||
if (me && me->ip_equals(me, this->my_virtual_ip))
|
||||
{ /* do not roam to the virtual IP of this IKE_SA */
|
||||
me->destroy(me);
|
||||
me = NULL;
|
||||
}
|
||||
|
||||
if (me)
|
||||
{
|
||||
set_condition(this, COND_STALE, FALSE);
|
||||
@@ -1695,12 +1701,8 @@ static status_t roam(private_ike_sa_t *this)
|
||||
}
|
||||
me->set_port(me, this->my_host->get_port(this->my_host));
|
||||
|
||||
#ifndef MOBIKE
|
||||
set_my_host(this, me);
|
||||
return reestablish(this);
|
||||
#endif
|
||||
/* our attachement changed, update if we have mobike */
|
||||
if (this->extensions & EXT_MOBIKE)
|
||||
if (supports_extension(this, EXT_MOBIKE))
|
||||
{
|
||||
mobike = ike_mobike_create(&this->public, TRUE);
|
||||
mobike->roam(mobike, me, NULL);
|
||||
@@ -1713,15 +1715,11 @@ static status_t roam(private_ike_sa_t *this)
|
||||
}
|
||||
|
||||
/* there is nothing we can do without mobike */
|
||||
if (!(this->extensions & EXT_MOBIKE))
|
||||
if (!supports_extension(this, EXT_MOBIKE))
|
||||
{
|
||||
set_condition(this, COND_STALE, TRUE);
|
||||
return FAILED;
|
||||
}
|
||||
#ifndef MOBIKE
|
||||
set_condition(this, COND_STALE, TRUE);
|
||||
return FAILED;
|
||||
#endif
|
||||
|
||||
/* we are unable to reach the peer. Try an alternative address */
|
||||
iterator = create_additional_address_iterator(this);
|
||||
@@ -1729,10 +1727,18 @@ static status_t roam(private_ike_sa_t *this)
|
||||
{
|
||||
me = charon->kernel_interface->get_source_addr(charon->kernel_interface,
|
||||
other);
|
||||
if (me && me->ip_equals(me, this->my_virtual_ip))
|
||||
{ /* do not roam to the virtual IP of this IKE_SA */
|
||||
me->destroy(me);
|
||||
me = NULL;
|
||||
}
|
||||
|
||||
if (me)
|
||||
{
|
||||
/* good, we have a new route. Use MOBIKE to update */
|
||||
iterator->destroy(iterator);
|
||||
me->set_port(me, this->my_host->get_port(this->my_host));
|
||||
other->set_port(other, this->other_host->get_port(this->other_host));
|
||||
mobike = ike_mobike_create(&this->public, TRUE);
|
||||
mobike->roam(mobike, me, other);
|
||||
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
|
||||
@@ -1740,7 +1746,10 @@ static status_t roam(private_ike_sa_t *this)
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return SUCCESS;
|
||||
|
||||
/* no route found to host, give up (temporary) */
|
||||
set_condition(this, COND_STALE, TRUE);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -701,6 +701,7 @@ static iterator_t *create_iterator(private_ike_sa_manager_t* this)
|
||||
{
|
||||
iterator_t *iterator = this->ike_sa_list->create_iterator_locked(
|
||||
this->ike_sa_list, &this->mutex);
|
||||
|
||||
/* register hook to iterator over ike_sas, not entries */
|
||||
iterator->set_iterator_hook(iterator, (iterator_hook_t*)iterator_hook, this);
|
||||
return iterator;
|
||||
|
||||
@@ -314,6 +314,11 @@ static status_t build_request(private_task_manager_t *this)
|
||||
exchange = INFORMATIONAL;
|
||||
break;
|
||||
}
|
||||
if (activate_task(this, IKE_MOBIKE))
|
||||
{
|
||||
exchange = INFORMATIONAL;
|
||||
break;
|
||||
}
|
||||
if (activate_task(this, IKE_DPD))
|
||||
{
|
||||
exchange = INFORMATIONAL;
|
||||
@@ -592,6 +597,7 @@ static status_t process_request(private_task_manager_t *this,
|
||||
exchange_type_t exchange;
|
||||
payload_t *payload;
|
||||
notify_payload_t *notify;
|
||||
delete_payload_t *delete;
|
||||
|
||||
exchange = message->get_exchange_type(message);
|
||||
|
||||
@@ -669,27 +675,56 @@ static status_t process_request(private_task_manager_t *this,
|
||||
}
|
||||
case INFORMATIONAL:
|
||||
{
|
||||
delete_payload_t *delete;
|
||||
|
||||
delete = (delete_payload_t*)message->get_payload(message, DELETE);
|
||||
if (delete)
|
||||
iterator = message->get_payload_iterator(message);
|
||||
while (iterator->iterate(iterator, (void**)&payload))
|
||||
{
|
||||
if (delete->get_protocol_id(delete) == PROTO_IKE)
|
||||
switch (payload->get_type(payload))
|
||||
{
|
||||
task = (task_t*)ike_delete_create(this->ike_sa, FALSE);
|
||||
this->passive_tasks->insert_last(this->passive_tasks, task);
|
||||
}
|
||||
else
|
||||
{
|
||||
task = (task_t*)child_delete_create(this->ike_sa, NULL);
|
||||
this->passive_tasks->insert_last(this->passive_tasks, task);
|
||||
case NOTIFY:
|
||||
{
|
||||
notify = (notify_payload_t*)payload;
|
||||
switch (notify->get_notify_type(notify))
|
||||
{
|
||||
case ADDITIONAL_IP4_ADDRESS:
|
||||
case ADDITIONAL_IP6_ADDRESS:
|
||||
case NO_ADDITIONAL_ADDRESSES:
|
||||
case UPDATE_SA_ADDRESSES:
|
||||
case NO_NATS_ALLOWED:
|
||||
case UNACCEPTABLE_ADDRESSES:
|
||||
case UNEXPECTED_NAT_DETECTED:
|
||||
case COOKIE2:
|
||||
task = (task_t*)ike_mobike_create(this->ike_sa,
|
||||
FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DELETE:
|
||||
{
|
||||
delete = (delete_payload_t*)payload;
|
||||
if (delete->get_protocol_id(delete) == PROTO_IKE)
|
||||
{
|
||||
task = (task_t*)ike_delete_create(this->ike_sa, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
task = (task_t*)child_delete_create(this->ike_sa, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (task == NULL)
|
||||
{
|
||||
task = (task_t*)ike_dpd_create(FALSE);
|
||||
this->passive_tasks->insert_last(this->passive_tasks, task);
|
||||
}
|
||||
this->passive_tasks->insert_last(this->passive_tasks, task);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <daemon.h>
|
||||
#include <sa/tasks/ike_natd.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
|
||||
|
||||
@@ -59,6 +60,16 @@ struct private_ike_mobike_t {
|
||||
* remote host to roam to
|
||||
*/
|
||||
host_t *other;
|
||||
|
||||
/**
|
||||
* cookie2 value to verify new addresses
|
||||
*/
|
||||
chunk_t cookie2;
|
||||
|
||||
/**
|
||||
* NAT discovery reusing the IKE_NATD task
|
||||
*/
|
||||
ike_natd_t *natd;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -119,6 +130,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
|
||||
if (first)
|
||||
{ /* an ADDITIONAL_*_ADDRESS means replace, so flush once */
|
||||
flush_additional_addresses(this);
|
||||
first = FALSE;
|
||||
}
|
||||
data = notify->get_notification_data(notify);
|
||||
host = host_create_from_chunk(family, data, 0);
|
||||
@@ -185,10 +197,26 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
|
||||
{
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_payload(message, SECURITY_ASSOCIATION))
|
||||
{
|
||||
{
|
||||
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
|
||||
build_address_list(this, message);
|
||||
}
|
||||
else if (this->me || this->other)
|
||||
{ /* address change */
|
||||
message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
|
||||
build_address_list(this, message);
|
||||
/* TODO: NAT discovery */
|
||||
|
||||
/* set new addresses */
|
||||
if (this->me)
|
||||
{
|
||||
this->ike_sa->set_my_host(this->ike_sa, this->me->clone(this->me));
|
||||
}
|
||||
if (this->other)
|
||||
{
|
||||
this->ike_sa->set_other_host(this->ike_sa, this->other->clone(this->other));
|
||||
}
|
||||
}
|
||||
|
||||
return NEED_MORE;
|
||||
}
|
||||
@@ -197,8 +225,13 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
|
||||
* Implementation of task_t.process for responder
|
||||
*/
|
||||
static status_t process_r(private_ike_mobike_t *this, message_t *message)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
{
|
||||
if ((message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_payload(message, SECURITY_ASSOCIATION)) ||
|
||||
message->get_exchange_type(message) == INFORMATIONAL)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
}
|
||||
|
||||
return NEED_MORE;
|
||||
}
|
||||
@@ -259,9 +292,14 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
DESTROY_IF(this->me);
|
||||
DESTROY_IF(this->other);
|
||||
chunk_free(&this->cookie2);
|
||||
this->ike_sa = ike_sa;
|
||||
this->me = NULL;
|
||||
this->other = NULL;
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.migrate(&this->natd->task, ike_sa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,6 +309,11 @@ static void destroy(private_ike_mobike_t *this)
|
||||
{
|
||||
DESTROY_IF(this->me);
|
||||
DESTROY_IF(this->other);
|
||||
chunk_free(&this->cookie2);
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.destroy(&this->natd->task);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -301,6 +344,8 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
|
||||
this->initiator = initiator;
|
||||
this->me = NULL;
|
||||
this->other = NULL;
|
||||
this->cookie2 = chunk_empty;
|
||||
this->natd = NULL;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user