/*
- * Copyright (C) 2006-2011 Tobias Brunner
+ * Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
#include <processing/jobs/send_dpd_job.h>
#include <processing/jobs/send_keepalive_job.h>
#include <processing/jobs/rekey_ike_sa_job.h>
+#include <sa/ikev2/tasks/ike_auth_lifetime.h>
#ifdef ME
#include <sa/ikev2/tasks/ike_me.h>
linked_list_t *attributes;
/**
- * list of peers additional addresses, transmitted via MOBIKE
+ * list of peer's addresses, additional ones transmitted via MOBIKE
*/
- linked_list_t *additional_addresses;
+ linked_list_t *peer_addresses;
/**
* previously value of received DESTINATION_IP hash
lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
-
trigger_dpd = this->peer_cfg->get_dpd(this->peer_cfg);
}
break;
}
}
-METHOD(ike_sa_t, add_additional_address, void,
+METHOD(ike_sa_t, add_peer_address, void,
private_ike_sa_t *this, host_t *host)
{
- this->additional_addresses->insert_last(this->additional_addresses, host);
+ this->peer_addresses->insert_last(this->peer_addresses, host);
}
-METHOD(ike_sa_t, create_additional_address_enumerator, enumerator_t*,
+METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
private_ike_sa_t *this)
{
- return this->additional_addresses->create_enumerator(
- this->additional_addresses);
+ return this->peer_addresses->create_enumerator(this->peer_addresses);
}
-METHOD(ike_sa_t, remove_additional_addresses, void,
+METHOD(ike_sa_t, clear_peer_addresses, void,
private_ike_sa_t *this)
{
- enumerator_t *enumerator = create_additional_address_enumerator(this);
+ enumerator_t *enumerator = create_peer_address_enumerator(this);
host_t *host;
+
while (enumerator->enumerate(enumerator, (void**)&host))
{
- this->additional_addresses->remove_at(this->additional_addresses,
- enumerator);
+ this->peer_addresses->remove_at(this->peer_addresses,
+ enumerator);
host->destroy(host);
}
enumerator->destroy(enumerator);
#endif /* ME */
)
{
- time_t now = time_monotonic(NULL);
+ time_t del, now;
- DBG1(DBG_IKE, "IKE_SA will timeout in %V",
- &now, &this->stats[STAT_DELETE]);
+ del = this->stats[STAT_DELETE];
+ now = time_monotonic(NULL);
+ DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V",
+ get_name(this), this->unique_id, &now, &del);
return FAILED;
}
else
{
- DBG1(DBG_IKE, "reauthenticating actively");
+ DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively",
+ get_name(this), this->unique_id);
}
}
+ else
+ {
+ DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]",
+ get_name(this), this->unique_id);
+ }
this->task_manager->queue_ike_reauth(this->task_manager);
return this->task_manager->initiate(this->task_manager);
}
DBG1(DBG_IKE, "peer not responding, trying again (%d/%d)",
this->keyingtry + 1, tries);
reset(this);
+ resolve_hosts(this);
this->task_manager->queue_ike(this->task_manager);
return this->task_manager->initiate(this->task_manager);
}
return SUCCESS;
}
-METHOD(ike_sa_t, set_auth_lifetime, void,
+METHOD(ike_sa_t, set_auth_lifetime, status_t,
private_ike_sa_t *this, u_int32_t lifetime)
{
- u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg);
- u_int32_t reauth_time = time_monotonic(NULL) + lifetime - reduction;
+ u_int32_t diff, hard, soft, now;
+ ike_auth_lifetime_t *task;
+ bool send_update;
+
+ diff = this->peer_cfg->get_over_time(this->peer_cfg);
+ now = time_monotonic(NULL);
+ hard = now + lifetime;
+ soft = hard - diff;
- if (lifetime < reduction)
+ /* check if we have to send an AUTH_LIFETIME to enforce the new lifetime.
+ * We send the notify in IKE_AUTH if not yet ESTABLISHED. */
+ send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
+ !has_condition(this, COND_ORIGINAL_INITIATOR) &&
+ (this->other_virtual_ip != NULL ||
+ has_condition(this, COND_EAP_AUTHENTICATED));
+
+ if (lifetime < diff)
{
- DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
- lifetime);
- lib->processor->queue_job(lib->processor,
+ this->stats[STAT_REAUTH] = now;
+
+ if (!send_update)
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
+ "starting reauthentication", lifetime);
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE));
+ }
}
else if (this->stats[STAT_REAUTH] == 0 ||
- this->stats[STAT_REAUTH] > reauth_time)
+ this->stats[STAT_REAUTH] > soft)
{
- this->stats[STAT_REAUTH] = reauth_time;
- DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
- " in %ds", lifetime, lifetime - reduction);
- lib->scheduler->schedule_job(lib->scheduler,
+ this->stats[STAT_REAUTH] = soft;
+ if (!send_update)
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling "
+ "reauthentication in %ds", lifetime, lifetime - diff);
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
- lifetime - reduction);
+ lifetime - diff);
+ }
}
else
{
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
"reauthentication already scheduled in %ds", lifetime,
this->stats[STAT_REAUTH] - time_monotonic(NULL));
+ send_update = FALSE;
}
+ /* give at least some seconds to reauthenticate */
+ this->stats[STAT_DELETE] = max(hard, now + 10);
+
+ if (send_update)
+ {
+ task = ike_auth_lifetime_create(&this->public, TRUE);
+ this->task_manager->queue_task(this->task_manager, &task->task);
+ return this->task_manager->initiate(this->task_manager);
+ }
+ return SUCCESS;
}
/**
bool valid = FALSE;
enumerator_t *enumerator;
host_t *src, *addr;
+
DBG1(DBG_IKE, "old path is not available anymore, try to find another");
- src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
- this->other_host, NULL);
- if (!src)
+ enumerator = this->peer_addresses->create_enumerator(this->peer_addresses);
+ while (enumerator->enumerate(enumerator, &addr))
{
- enumerator = this->additional_addresses->create_enumerator(
- this->additional_addresses);
- while (enumerator->enumerate(enumerator, &addr))
+ DBG1(DBG_IKE, "looking for a route to %H ...", addr);
+ src = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, addr, NULL);
+ if (src)
{
- DBG1(DBG_IKE, "looking for a route to %H ...", addr);
- src = hydra->kernel_interface->get_source_addr(
- hydra->kernel_interface, addr, NULL);
- if (src)
- {
- break;
- }
+ break;
}
- enumerator->destroy(enumerator);
}
+ enumerator->destroy(enumerator);
if (src)
{
valid = TRUE;
}
this->other_virtual_ip->destroy(this->other_virtual_ip);
}
- this->additional_addresses->destroy_offset(this->additional_addresses,
- offsetof(host_t, destroy));
+ this->peer_addresses->destroy_offset(this->peer_addresses,
+ offsetof(host_t, destroy));
#ifdef ME
if (this->is_mediation_server)
{
.has_condition = _has_condition,
.set_pending_updates = _set_pending_updates,
.get_pending_updates = _get_pending_updates,
- .create_additional_address_enumerator = _create_additional_address_enumerator,
- .add_additional_address = _add_additional_address,
- .remove_additional_addresses = _remove_additional_addresses,
+ .create_peer_address_enumerator = _create_peer_address_enumerator,
+ .add_peer_address = _add_peer_address,
+ .clear_peer_addresses = _clear_peer_addresses,
.has_mapping_changed = _has_mapping_changed,
.retransmit = _retransmit,
.delete = _delete_,
.my_auths = linked_list_create(),
.other_auths = linked_list_create(),
.unique_id = ++unique_id,
- .additional_addresses = linked_list_create(),
+ .peer_addresses = linked_list_create(),
.attributes = linked_list_create(),
.keepalive_interval = lib->settings->get_time(lib->settings,
"charon.keep_alive", KEEPALIVE_INTERVAL),