aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/processing/jobs/retry_initiate_job.c2
-rw-r--r--src/libcharon/sa/ike_sa.c28
-rw-r--r--src/libcharon/sa/ike_sa.h9
3 files changed, 35 insertions, 4 deletions
diff --git a/src/libcharon/processing/jobs/retry_initiate_job.c b/src/libcharon/processing/jobs/retry_initiate_job.c
index 11e573992..e6da3e362 100644
--- a/src/libcharon/processing/jobs/retry_initiate_job.c
+++ b/src/libcharon/processing/jobs/retry_initiate_job.c
@@ -54,7 +54,7 @@ METHOD(job_t, execute, void,
}
else
{
- if (ike_sa->initiate(ike_sa, NULL, 0, NULL, NULL) == DESTROY_ME)
+ if (ike_sa->retry_initiate(ike_sa) == DESTROY_ME)
{
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
ike_sa);
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 93a8ad850..c104ff973 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -223,6 +223,11 @@ struct private_ike_sa_t {
u_int32_t retry_initiate_interval;
/**
+ * TRUE if a retry_initiate_job has been queued
+ */
+ bool retry_initiate_queued;
+
+ /**
* Timestamps for this IKE_SA
*/
u_int32_t stats[STAT_MAX];
@@ -1162,14 +1167,30 @@ METHOD(ike_sa_t, initiate, status_t,
if (defer_initiate)
{
- job_t *job = (job_t*)retry_initiate_job_create(this->ike_sa_id);
- lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
- this->retry_initiate_interval);
+ if (!this->retry_initiate_queued)
+ {
+ job_t *job = (job_t*)retry_initiate_job_create(this->ike_sa_id);
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
+ this->retry_initiate_interval);
+ this->retry_initiate_queued = TRUE;
+ }
return SUCCESS;
}
+ this->retry_initiate_queued = FALSE;
return this->task_manager->initiate(this->task_manager);
}
+METHOD(ike_sa_t, retry_initiate, status_t,
+ private_ike_sa_t *this)
+{
+ if (this->retry_initiate_queued)
+ {
+ this->retry_initiate_queued = FALSE;
+ return initiate(this, NULL, 0, NULL, NULL);
+ }
+ return SUCCESS;
+}
+
METHOD(ike_sa_t, process_message, status_t,
private_ike_sa_t *this, message_t *message)
{
@@ -2089,6 +2110,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
.set_statistic = _set_statistic,
.process_message = _process_message,
.initiate = _initiate,
+ .retry_initiate = _retry_initiate,
.get_ike_cfg = _get_ike_cfg,
.set_ike_cfg = _set_ike_cfg,
.get_peer_cfg = _get_peer_cfg,
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index a3c3de81c..5b2eb4ed1 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -695,6 +695,15 @@ struct ike_sa_t {
traffic_selector_t *tsr);
/**
+ * Retry initiation of this IKE_SA after it got deferred previously.
+ *
+ * @return
+ * - SUCCESS if initiation deferred or started
+ * - DESTROY_ME if initiation failed
+ */
+ status_t (*retry_initiate) (ike_sa_t *this);
+
+ /**
* Initiates the deletion of an IKE_SA.
*
* Sends a delete message to the remote peer and waits for