ikev2: Trigger make-before-break reauthentication instead of reauth task

This commit is contained in:
Martin Willi
2015-02-20 13:34:57 +01:00
parent c8e7dbcb56
commit 349f7f2412
3 changed files with 89 additions and 2 deletions
+10
View File
@@ -196,6 +196,16 @@ charon.load_modular = no
charon.max_packet = 10000 charon.max_packet = 10000
Maximum packet size accepted by charon. Maximum packet size accepted by charon.
charon.make_before_break = no
Initiate IKEv2 reauthentication with a make-before-break scheme.
Initiate IKEv2 reauthentication with a make-before-break instead of a
break-before-make scheme. Make-before-break uses overlapping IKE and
CHILD_SA during reauthentication by first recreating all new SAs before
deleting the old ones. This behavior can be beneficial to avoid connectivity
gaps during reauthentication, but requires support for overlapping SAs by
the peer. strongSwan can handle such overlapping SAs since version 5.3.0.
charon.mem-pool.reassign_online = no charon.mem-pool.reassign_online = no
Reassign an online IP address lease from an in-memory address pool if a Reassign an online IP address lease from an in-memory address pool if a
client with the same identity requests it explicitly. client with the same identity requests it explicitly.
+3 -2
View File
@@ -936,8 +936,9 @@ struct ike_sa_t {
/** /**
* Reauthenticate the IKE_SA. * Reauthenticate the IKE_SA.
* *
* Create a completely new IKE_SA with authentication, recreates all children * Triggers a new IKE_SA that replaces this one. IKEv1 implicitly inherits
* within the IKE_SA, closes this IKE_SA. * all Quick Modes, while IKEv2 recreates all active and queued CHILD_SAs
* in the new IKE_SA.
* *
* @return DESTROY_ME to destroy the IKE_SA * @return DESTROY_ME to destroy the IKE_SA
*/ */
+76
View File
@@ -171,6 +171,11 @@ struct private_task_manager_t {
* Base to calculate retransmission timeout * Base to calculate retransmission timeout
*/ */
double retransmit_base; double retransmit_base;
/**
* Use make-before-break instead of break-before-make reauth?
*/
bool make_before_break;
}; };
/** /**
@@ -1505,9 +1510,78 @@ METHOD(task_manager_t, queue_ike_rekey, void,
queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE)); queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
} }
/**
* Start reauthentication using make-before-break
*/
static void trigger_mbb_reauth(private_task_manager_t *this)
{
enumerator_t *enumerator;
child_sa_t *child_sa;
child_cfg_t *cfg;
ike_sa_t *new;
host_t *host;
task_t *task;
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
this->ike_sa->get_version(this->ike_sa), TRUE);
if (!new)
{ /* shouldn't happen */
return;
}
new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
host = this->ike_sa->get_other_host(this->ike_sa);
new->set_other_host(new, host->clone(host));
host = this->ike_sa->get_my_host(this->ike_sa);
new->set_my_host(new, host->clone(host));
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
while (enumerator->enumerate(enumerator, &host))
{
new->add_virtual_ip(new, TRUE, host);
}
enumerator->destroy(enumerator);
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
while (enumerator->enumerate(enumerator, &child_sa))
{
cfg = child_sa->get_config(child_sa);
new->queue_task(new, &child_create_create(new, cfg->get_ref(cfg),
FALSE, NULL, NULL)->task);
}
enumerator->destroy(enumerator);
enumerator = array_create_enumerator(this->queued_tasks);
while (enumerator->enumerate(enumerator, &task))
{
if (task->get_type(task) == TASK_CHILD_CREATE)
{
task->migrate(task, new);
new->queue_task(new, task);
array_remove_at(this->queued_tasks, enumerator);
}
}
enumerator->destroy(enumerator);
if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
this->ike_sa->set_state(this->ike_sa, IKE_REKEYING);
}
else
{
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
}
charon->bus->set_sa(charon->bus, this->ike_sa);
}
METHOD(task_manager_t, queue_ike_reauth, void, METHOD(task_manager_t, queue_ike_reauth, void,
private_task_manager_t *this) private_task_manager_t *this)
{ {
if (this->make_before_break)
{
return trigger_mbb_reauth(this);
}
queue_task(this, (task_t*)ike_reauth_create(this->ike_sa)); queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
} }
@@ -1773,6 +1847,8 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns), "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
.retransmit_base = lib->settings->get_double(lib->settings, .retransmit_base = lib->settings->get_double(lib->settings,
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns), "%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
.make_before_break = lib->settings->get_bool(lib->settings,
"%s.make_before_break", FALSE, lib->ns),
); );
return &this->public; return &this->public;