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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
private_rekey_ike_sa_job_t *this)
|
||||
{
|
||||
ike_sa_t *ike_sa;
|
||||
status_t status = SUCCESS;
|
||||
u_int32_t retry = 0;
|
||||
|
||||
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
||||
this->ike_sa_id);
|
||||
@@ -62,7 +98,11 @@ METHOD(job_t, execute, job_requeue_t,
|
||||
{
|
||||
if (this->reauth)
|
||||
{
|
||||
status = ike_sa->reauth(ike_sa);
|
||||
retry = get_retry_delay(ike_sa);
|
||||
if (!retry)
|
||||
{
|
||||
status = ike_sa->reauth(ike_sa);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -71,13 +111,18 @@ METHOD(job_t, execute, job_requeue_t,
|
||||
|
||||
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
|
||||
{
|
||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||
}
|
||||
}
|
||||
if (retry)
|
||||
{
|
||||
return JOB_RESCHEDULE(retry);
|
||||
}
|
||||
return JOB_REQUEUE_NONE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user