summaryrefslogtreecommitdiff
path: root/src/libcharon/processing/jobs
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2014-07-11 07:23:31 +0200
committerYves-Alexis Perez <corsac@debian.org>2014-07-11 07:23:31 +0200
commit81c63b0eed39432878f78727f60a1e7499645199 (patch)
tree82387d8fecd1c20788fd8bd784a9b0bde091fb6b /src/libcharon/processing/jobs
parentc5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9 (diff)
downloadvyos-strongswan-81c63b0eed39432878f78727f60a1e7499645199.tar.gz
vyos-strongswan-81c63b0eed39432878f78727f60a1e7499645199.zip
Imported Upstream version 5.2.0
Diffstat (limited to 'src/libcharon/processing/jobs')
-rw-r--r--src/libcharon/processing/jobs/process_message_job.c2
-rw-r--r--src/libcharon/processing/jobs/rekey_ike_sa_job.c49
2 files changed, 48 insertions, 3 deletions
diff --git a/src/libcharon/processing/jobs/process_message_job.c b/src/libcharon/processing/jobs/process_message_job.c
index 606135b0b..a6795e766 100644
--- a/src/libcharon/processing/jobs/process_message_job.c
+++ b/src/libcharon/processing/jobs/process_message_job.c
@@ -51,7 +51,7 @@ METHOD(job_t, execute, job_requeue_t,
/* if this is an unencrypted INFORMATIONAL exchange it is likely a
* connectivity check. */
if (this->message->get_exchange_type(this->message) == INFORMATIONAL &&
- this->message->get_first_payload_type(this->message) != ENCRYPTED)
+ this->message->get_first_payload_type(this->message) != PLV2_ENCRYPTED)
{
/* theoretically this could also be an error message
* see RFC 4306, section 1.5. */
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
index 712c7c2c1..516dc5dd5 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
@@ -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;
}