diff options
author | Martin Willi <martin@revosec.ch> | 2013-04-03 12:16:27 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-04-03 12:25:27 +0200 |
commit | bee6515a28c2aaa0a6e37a5eec0213be868492e0 (patch) | |
tree | a21a93db3c7bd623c635013d1bbf72df959d6a0c /src | |
parent | 3f4300ed1eb32ad685b6bd1007059221a3318cd4 (diff) | |
download | strongswan-bee6515a28c2aaa0a6e37a5eec0213be868492e0.tar.bz2 strongswan-bee6515a28c2aaa0a6e37a5eec0213be868492e0.tar.xz |
Defer CHILD_SA rekeying if allocating an SPI fails
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 1 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_rekey.c | 37 |
2 files changed, 26 insertions, 12 deletions
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index a53c06bf7..5298abf79 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -475,6 +475,7 @@ METHOD(task_manager_t, initiate, status_t, break; case FAILED: default: + this->initiating.type = EXCHANGE_TYPE_UNDEFINED; if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING) { charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index f8c2ed141..262cb10e0 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -87,6 +87,24 @@ struct private_child_rekey_t { }; /** + * 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 */ static status_t build_i_delete(private_child_rekey_t *this, message_t *message) @@ -166,8 +184,13 @@ METHOD(task_t, build_i, status_t, } reqid = this->child_sa->get_reqid(this->child_sa); 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); return NEED_MORE; @@ -316,17 +339,7 @@ METHOD(task_t, process_i, status_t, if (!(this->collision && this->collision->get_type(this->collision) == TASK_CHILD_DELETE)) { - job_t *job; - 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); + schedule_delayed_rekey(this); } return SUCCESS; } |