ike: Keep track of send keepalive jobs to avoid scheduling more than one per IKE_SA
authorTobias Brunner <tobias@strongswan.org>
Mon, 16 Nov 2015 16:14:18 +0000 (17:14 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 3 Mar 2016 16:15:37 +0000 (17:15 +0100)
src/libcharon/processing/jobs/send_keepalive_job.c
src/libcharon/sa/ike_sa.c
src/libcharon/sa/ike_sa.h

index 3e34776..e06eae3 100644 (file)
@@ -54,7 +54,7 @@ METHOD(job_t, execute, job_requeue_t,
                                                                                          this->ike_sa_id);
        if (ike_sa)
        {
-               ike_sa->send_keepalive(ike_sa);
+               ike_sa->send_keepalive(ike_sa, TRUE);
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        }
        return JOB_REQUEUE_NONE;
index 3632d62..afd6fdf 100644 (file)
@@ -239,6 +239,11 @@ struct private_ike_sa_t {
        u_int32_t keepalive_interval;
 
        /**
+        * The schedueld keep alive job, if any
+        */
+       send_keepalive_job_t *keepalive_job;
+
+       /**
         * interval for retries during initiation (e.g. if DNS resolution failed),
         * 0 to disable (default)
         */
@@ -482,11 +487,14 @@ METHOD(ike_sa_t, set_message_id, void,
 }
 
 METHOD(ike_sa_t, send_keepalive, void,
-       private_ike_sa_t *this)
+       private_ike_sa_t *this, bool scheduled)
 {
-       send_keepalive_job_t *job;
        time_t last_out, now, diff;
 
+       if (scheduled)
+       {
+               this->keepalive_job = NULL;
+       }
        if (!this->keepalive_interval || this->state == IKE_PASSIVE)
        {       /* keepalives disabled either by configuration or for passive IKE_SAs */
                return;
@@ -517,9 +525,12 @@ METHOD(ike_sa_t, send_keepalive, void,
                charon->sender->send_no_marker(charon->sender, packet);
                diff = 0;
        }
-       job = send_keepalive_job_create(this->ike_sa_id);
-       lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
-                                                                this->keepalive_interval - diff);
+       if (!this->keepalive_job)
+       {
+               this->keepalive_job = send_keepalive_job_create(this->ike_sa_id);
+               lib->scheduler->schedule_job(lib->scheduler, (job_t*)this->keepalive_job,
+                                                                        this->keepalive_interval - diff);
+       }
 }
 
 METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*,
@@ -566,7 +577,7 @@ METHOD(ike_sa_t, set_condition, void,
                                case COND_NAT_HERE:
                                        DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
                                        this->conditions |= COND_NAT_ANY;
-                                       send_keepalive(this);
+                                       send_keepalive(this, FALSE);
                                        break;
                                case COND_NAT_THERE:
                                        DBG1(DBG_IKE, "remote host is behind NAT");
@@ -594,7 +605,7 @@ METHOD(ike_sa_t, set_condition, void,
                                                                  has_condition(this, COND_NAT_FAKE));
                                        break;
                                case COND_STALE:
-                                       send_keepalive(this);
+                                       send_keepalive(this, FALSE);
                                        break;
                                default:
                                        break;
@@ -755,7 +766,7 @@ METHOD(ike_sa_t, set_state, void,
        }
        if (keepalives)
        {
-               send_keepalive(this);
+               send_keepalive(this, FALSE);
        }
 }
 
@@ -2329,7 +2340,7 @@ METHOD(ike_sa_t, inherit_post, void,
        this->conditions = other->conditions;
        if (this->conditions & COND_NAT_HERE)
        {
-               send_keepalive(this);
+               send_keepalive(this, FALSE);
        }
 
 #ifdef ME
index 9dbc805..e15ac2e 100644 (file)
@@ -837,8 +837,10 @@ struct ike_sa_t {
         *
         * To refresh NAT tables in a NAT router between the peers, periodic empty
         * UDP packets are sent if no other traffic was sent.
+        *
+        * @param scheduled             if this is a scheduled keepalive
         */
-       void (*send_keepalive) (ike_sa_t *this);
+       void (*send_keepalive) (ike_sa_t *this, bool scheduled);
 
        /**
         * Get the keying material of this IKE_SA.