/*
- * Copyright (C) 2010-2018 Tobias Brunner
+ * Copyright (C) 2010-2020 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
return TRUE;
}
-/**
- * update addresses of associated CHILD_SAs
- */
-static void update_children(private_ike_mobike_t *this)
-{
- enumerator_t *enumerator;
- child_sa_t *child_sa;
- linked_list_t *vips;
- status_t status;
- host_t *host;
-
- vips = linked_list_create();
-
- enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
- while (enumerator->enumerate(enumerator, &host))
- {
- vips->insert_last(vips, host);
- }
- enumerator->destroy(enumerator);
-
- enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
- while (enumerator->enumerate(enumerator, (void**)&child_sa))
- {
- status = child_sa->update(child_sa,
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa), vips,
- this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
- switch (status)
- {
- case NOT_SUPPORTED:
- this->ike_sa->rekey_child_sa(this->ike_sa,
- child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
- break;
- case SUCCESS:
- charon->child_sa_manager->remove(charon->child_sa_manager,
- child_sa);
- charon->child_sa_manager->add(charon->child_sa_manager,
- child_sa, this->ike_sa);
- break;
- default:
- break;
- }
- }
- enumerator->destroy(enumerator);
-
- vips->destroy(vips);
-}
-
/**
* Apply the port of the old host, if its ip equals the new, use port otherwise.
*/
{
return FAILED;
}
- update_children(this);
}
if (this->address && !this->check)
{
}
else if (message->get_exchange_type(message) == INFORMATIONAL)
{
- process_payloads(this, message);
- if (this->update)
- {
- host_t *me, *other;
+ host_t *me_new = NULL, *other, *other_old, *other_new = NULL;
- me = message->get_destination(message);
- other = message->get_source(message);
- this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
- this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
- }
+ process_payloads(this, message);
if (this->natd)
{
this->natd->task.process(&this->natd->task, message);
}
- if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa,
- COND_ORIGINAL_INITIATOR))
+
+ if (this->update)
+ {
+ me_new = message->get_destination(message);
+ other_new = message->get_source(message);
+ }
+ else if (this->addresses_updated &&
+ this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
{
- host_t *other = message->get_source(message);
- host_t *other_old = this->ike_sa->get_other_host(this->ike_sa);
+ other = message->get_source(message);
+ other_old = this->ike_sa->get_other_host(this->ike_sa);
if (!other->equals(other, other_old))
{
DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
other);
- this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
- this->update = TRUE;
+ other_new = other;
+ /* our address might have changed too if the responder used
+ * a different address from our list to reach us */
+ me_new = message->get_destination(message);
}
}
+
+ if (me_new || other_new)
+ {
+ this->ike_sa->update_hosts(this->ike_sa, me_new,
+ other_new, UPDATE_HOSTS_FORCE_ALL);
+ }
}
return NEED_MORE;
}
message->add_notify(message, FALSE, COOKIE2, this->cookie2);
chunk_free(&this->cookie2);
}
- if (this->update)
- {
- update_children(this);
- }
return SUCCESS;
}
return NEED_MORE;
if (this->natd)
{
this->natd->task.process(&this->natd->task, message);
- if (!this->update && this->natd->has_mapping_changed(this->natd))
- {
- /* force an update if mappings have changed */
- this->update = this->check = TRUE;
+
+ if (this->update)
+ { /* update children again, as NAT state may have changed */
+ this->ike_sa->update_hosts(this->ike_sa, NULL, NULL,
+ UPDATE_HOSTS_FORCE_CHILDREN);
+ }
+ else if (this->natd->has_mapping_changed(this->natd))
+ { /* force a check/update if mappings have changed during a DPD */
+ this->check = TRUE;
DBG1(DBG_IKE, "detected changes in NAT mappings, "
"initiating MOBIKE update");
}
}
- if (this->update)
- {
- /* update again, as NAT state may have changed */
- update_children(this);
- }
if (this->check)
{
- host_t *me_new, *me_old, *other_new, *other_old;
+ host_t *me, *me_new = NULL, *other, *other_new = NULL;
- me_new = message->get_destination(message);
- other_new = message->get_source(message);
- me_old = this->ike_sa->get_my_host(this->ike_sa);
- other_old = this->ike_sa->get_other_host(this->ike_sa);
+ me = message->get_destination(message);
+ other = message->get_source(message);
- if (!me_new->equals(me_new, me_old))
+ if (!me->equals(me, this->ike_sa->get_my_host(this->ike_sa)))
{
- this->update = TRUE;
- this->ike_sa->set_my_host(this->ike_sa, me_new->clone(me_new));
+ me_new = me;
}
- if (!other_new->equals(other_new, other_old))
+ if (!other->equals(other, this->ike_sa->get_other_host(this->ike_sa)))
{
- this->update = TRUE;
- this->ike_sa->set_other_host(this->ike_sa, other_new->clone(other_new));
+ other_new = other;
}
- if (this->update)
+ if (me_new || other_new)
{
+ this->ike_sa->update_hosts(this->ike_sa, me_new, other_new,
+ UPDATE_HOSTS_FORCE_ALL);
/* use the same task to ... */
if (!this->ike_sa->has_condition(this->ike_sa,
COND_ORIGINAL_INITIATOR))
{ /*... send an updated list of addresses as responder */
- update_children(this);
- this->update = FALSE;
+ this->address = TRUE;
}
else
{ /* ... send the update as original initiator */
+ this->update = TRUE;
if (this->natd)
{
this->natd->task.destroy(&this->natd->task);