ikev1: Defer Mode Config push after CHILD adoption and reauth detection

When an initiator starts reauthentication on a connection that uses push
mode to assign a virtual IP, we can't execute the Mode Config before releasing
the virtual IP. Otherwise we would request a new and different lease, which
the client probably can't handle. Defer Mode Config execution, so the same IP
gets first released then reassigned during reauthentication.
This commit is contained in:
Martin Willi
2014-08-25 09:55:44 +02:00
parent 898c8b12f9
commit 891bbbd4bb
2 changed files with 35 additions and 10 deletions
+18 -5
View File
@@ -475,6 +475,8 @@ METHOD(task_t, process_r, status_t,
} }
case AM_AUTH: case AM_AUTH:
{ {
adopt_children_job_t *job = NULL;
while (TRUE) while (TRUE)
{ {
if (this->ph1->verify_auth(this->ph1, this->method, message, if (this->ph1->verify_auth(this->ph1, this->method, message,
@@ -524,9 +526,8 @@ METHOD(task_t, process_r, status_t,
{ {
return send_delete(this); return send_delete(this);
} }
lib->processor->queue_job(lib->processor, (job_t*) job = adopt_children_job_create(
adopt_children_job_create( this->ike_sa->get_id(this->ike_sa));
this->ike_sa->get_id(this->ike_sa)));
break; break;
} }
/* check for and prepare mode config push/pull */ /* check for and prepare mode config push/pull */
@@ -542,10 +543,22 @@ METHOD(task_t, process_r, status_t,
{ {
if (!this->peer_cfg->use_pull_mode(this->peer_cfg)) if (!this->peer_cfg->use_pull_mode(this->peer_cfg))
{ {
this->ike_sa->queue_task(this->ike_sa, if (job)
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE)); {
job->queue_task(job, (task_t*)
mode_config_create(this->ike_sa, TRUE, FALSE));
}
else
{
this->ike_sa->queue_task(this->ike_sa, (task_t*)
mode_config_create(this->ike_sa, TRUE, FALSE));
}
} }
} }
if (job)
{
lib->processor->queue_job(lib->processor, (job_t*)job);
}
return SUCCESS; return SUCCESS;
} }
default: default:
+17 -5
View File
@@ -479,6 +479,7 @@ METHOD(task_t, build_r, status_t,
{ {
id_payload_t *id_payload; id_payload_t *id_payload;
identification_t *id; identification_t *id;
adopt_children_job_t *job = NULL;
id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE); id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE);
if (!id) if (!id)
@@ -522,9 +523,8 @@ METHOD(task_t, build_r, status_t,
{ {
return send_notify(this, AUTHENTICATION_FAILED); return send_notify(this, AUTHENTICATION_FAILED);
} }
lib->processor->queue_job(lib->processor, (job_t*) job = adopt_children_job_create(
adopt_children_job_create( this->ike_sa->get_id(this->ike_sa));
this->ike_sa->get_id(this->ike_sa)));
break; break;
} }
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg)) if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
@@ -539,10 +539,22 @@ METHOD(task_t, build_r, status_t,
{ {
if (!this->peer_cfg->use_pull_mode(this->peer_cfg)) if (!this->peer_cfg->use_pull_mode(this->peer_cfg))
{ {
this->ike_sa->queue_task(this->ike_sa, if (job)
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE)); {
job->queue_task(job, (task_t*)
mode_config_create(this->ike_sa, TRUE, FALSE));
}
else
{
this->ike_sa->queue_task(this->ike_sa, (task_t*)
mode_config_create(this->ike_sa, TRUE, FALSE));
}
} }
} }
if (job)
{
lib->processor->queue_job(lib->processor, (job_t*)job);
}
return SUCCESS; return SUCCESS;
} }
default: default: