]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike: Add an option to trigger a DPD instead of a NAT keepalive
authorTobias Brunner <tobias@strongswan.org>
Thu, 19 Mar 2020 12:39:48 +0000 (13:39 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 2 Jun 2020 12:07:06 +0000 (14:07 +0200)
This is useful on Android where the app might not be able to send
keep-alives if the device is asleep for a while.  If the NAT mapping
has been deleted in the mean time, the NAT-D payloads allow detecting
this and connectivity can be restored by doing a MOBIKE update or
recreating the SA if the peer already deleted it because the client
wasn't reachable.

conf/options/charon.opt
src/libcharon/sa/ike_sa.c

index fd2d36a0b7e68361cf7655d8ea00490bbae8cc95..b6e55e11253bf9503fde78f2e863e809a697d756 100644 (file)
@@ -220,6 +220,11 @@ charon.interfaces_use
 charon.keep_alive = 20s
        NAT keep alive interval.
 
+charon.keep_alive_dpd_margin = 0s
+       Number of seconds the keep alive interval may be exceeded before a DPD is
+       sent instead of a NAT keep alive (0 to disable).  This is only useful if a
+       clock is used that includes time spent suspended (e.g. CLOCK_BOOTTIME).
+
 charon.leak_detective.detailed = yes
        Includes source file names and line numbers in leak detective output.
 
index b44c157d94934df2d3c0ef5f224b254d37792510..5e54208ec046e0b566255f9b3c4fdb5c8b9cb6b0 100644 (file)
@@ -236,6 +236,12 @@ struct private_ike_sa_t {
         */
        uint32_t keepalive_interval;
 
+       /**
+        * Time the NAT keep alive interval may be exceeded before triggering a DPD
+        * instead of a NAT keep alive
+        */
+       uint32_t keepalive_dpd_margin;
+
        /**
         * The scheduled keep alive job, if any
         */
@@ -655,7 +661,19 @@ METHOD(ike_sa_t, send_keepalive, void,
 
        diff = now - last_out;
 
-       if (diff >= this->keepalive_interval)
+       if (this->keepalive_dpd_margin &&
+               diff > (this->keepalive_interval + this->keepalive_dpd_margin))
+       {
+               if (!this->task_manager->busy(this->task_manager))
+               {
+                       DBG1(DBG_IKE, "sending DPD instead of keep alive %ds after last "
+                                "outbound message", diff);
+                       this->task_manager->queue_dpd(this->task_manager);
+                       this->task_manager->initiate(this->task_manager);
+               }
+               diff = 0;
+       }
+       else if (diff >= this->keepalive_interval)
        {
                packet_t *packet;
                chunk_t data;
@@ -3183,6 +3201,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
                .unique_id = ref_get(&unique_id),
                .keepalive_interval = lib->settings->get_time(lib->settings,
                                                                "%s.keep_alive", KEEPALIVE_INTERVAL, lib->ns),
+               .keepalive_dpd_margin = lib->settings->get_time(lib->settings,
+                                                               "%s.keep_alive_dpd_margin", 0, lib->ns),
                .retry_initiate_interval = lib->settings->get_time(lib->settings,
                                                                "%s.retry_initiate_interval", 0, lib->ns),
                .flush_auth_cfg = lib->settings->get_bool(lib->settings,