ike: Delay actively initiated reauthentication when other exchanges in progress
If any other IKE or CHILD_SA operation takes places, we should not start initiating reauthentication to avoid any potential races.
This commit is contained in:
@@ -46,11 +46,47 @@ METHOD(job_t, destroy, void,
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we should delay a reauth, and by how many seconds
|
||||||
|
*/
|
||||||
|
static u_int32_t get_retry_delay(ike_sa_t *ike_sa)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
u_int32_t retry = 0;
|
||||||
|
|
||||||
|
/* avoid reauth collisions for certain IKE_SA/CHILD_SA states */
|
||||||
|
if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
|
||||||
|
{
|
||||||
|
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
||||||
|
DBG1(DBG_IKE, "unable to reauthenticate in %N state, delaying for %us",
|
||||||
|
ike_sa_state_names, ike_sa->get_state(ike_sa), retry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
|
||||||
|
while (enumerator->enumerate(enumerator, &child_sa))
|
||||||
|
{
|
||||||
|
if (child_sa->get_state(child_sa) != CHILD_INSTALLED)
|
||||||
|
{
|
||||||
|
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
||||||
|
DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, "
|
||||||
|
"delaying for %us", child_sa_state_names,
|
||||||
|
child_sa->get_state(child_sa), retry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
return retry;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(job_t, execute, job_requeue_t,
|
METHOD(job_t, execute, job_requeue_t,
|
||||||
private_rekey_ike_sa_job_t *this)
|
private_rekey_ike_sa_job_t *this)
|
||||||
{
|
{
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
status_t status = SUCCESS;
|
status_t status = SUCCESS;
|
||||||
|
u_int32_t retry = 0;
|
||||||
|
|
||||||
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
||||||
this->ike_sa_id);
|
this->ike_sa_id);
|
||||||
@@ -62,7 +98,11 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
{
|
{
|
||||||
if (this->reauth)
|
if (this->reauth)
|
||||||
{
|
{
|
||||||
status = ike_sa->reauth(ike_sa);
|
retry = get_retry_delay(ike_sa);
|
||||||
|
if (!retry)
|
||||||
|
{
|
||||||
|
status = ike_sa->reauth(ike_sa);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -71,13 +111,18 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
|
|
||||||
if (status == DESTROY_ME)
|
if (status == DESTROY_ME)
|
||||||
{
|
{
|
||||||
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
||||||
|
ike_sa);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (retry)
|
||||||
|
{
|
||||||
|
return JOB_RESCHEDULE(retry);
|
||||||
|
}
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user