Defer CHILD_SA rekeying if allocating an SPI fails

This commit is contained in:
Martin Willi 2013-04-03 12:16:27 +02:00
parent 3f4300ed1e
commit bee6515a28
2 changed files with 26 additions and 12 deletions

View File

@ -475,6 +475,7 @@ METHOD(task_manager_t, initiate, status_t,
break; break;
case FAILED: case FAILED:
default: default:
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING) if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
{ {
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);

View File

@ -86,6 +86,24 @@ struct private_child_rekey_t {
bool other_child_destroyed; bool other_child_destroyed;
}; };
/**
* Schedule a retry if rekeying temporary failed
*/
static void schedule_delayed_rekey(private_child_rekey_t *this)
{
u_int32_t retry;
job_t *job;
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
job = (job_t*)rekey_child_sa_job_create(
this->child_sa->get_reqid(this->child_sa),
this->child_sa->get_protocol(this->child_sa),
this->child_sa->get_spi(this->child_sa, TRUE));
DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
lib->scheduler->schedule_job(lib->scheduler, job, retry);
}
/** /**
* Implementation of task_t.build for initiator, after rekeying * Implementation of task_t.build for initiator, after rekeying
*/ */
@ -166,8 +184,13 @@ METHOD(task_t, build_i, status_t,
} }
reqid = this->child_sa->get_reqid(this->child_sa); reqid = this->child_sa->get_reqid(this->child_sa);
this->child_create->use_reqid(this->child_create, reqid); this->child_create->use_reqid(this->child_create, reqid);
this->child_create->task.build(&this->child_create->task, message);
if (this->child_create->task.build(&this->child_create->task,
message) != NEED_MORE)
{
schedule_delayed_rekey(this);
return FAILED;
}
this->child_sa->set_state(this->child_sa, CHILD_REKEYING); this->child_sa->set_state(this->child_sa, CHILD_REKEYING);
return NEED_MORE; return NEED_MORE;
@ -316,17 +339,7 @@ METHOD(task_t, process_i, status_t,
if (!(this->collision && if (!(this->collision &&
this->collision->get_type(this->collision) == TASK_CHILD_DELETE)) this->collision->get_type(this->collision) == TASK_CHILD_DELETE))
{ {
job_t *job; schedule_delayed_rekey(this);
u_int32_t retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
job = (job_t*)rekey_child_sa_job_create(
this->child_sa->get_reqid(this->child_sa),
this->child_sa->get_protocol(this->child_sa),
this->child_sa->get_spi(this->child_sa, TRUE));
DBG1(DBG_IKE, "CHILD_SA rekeying failed, "
"trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
lib->scheduler->schedule_job(lib->scheduler, job, retry);
} }
return SUCCESS; return SUCCESS;
} }