]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike-sa: Add flags to force updating hosts/CHILD_SAs
authorTobias Brunner <tobias@strongswan.org>
Tue, 27 Oct 2020 18:06:21 +0000 (19:06 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 18 Jan 2021 10:34:40 +0000 (11:34 +0100)
This allows more fine grained control over what's updated and does not
require multiple calls of the method. Plus we'll be able to use it in
the ike-mobike task.

src/libcharon/processing/jobs/update_sa_job.c
src/libcharon/sa/ike_sa.c
src/libcharon/sa/ike_sa.h
src/libcharon/sa/ikev1/task_manager_v1.c
src/libcharon/sa/ikev1/tasks/aggressive_mode.c
src/libcharon/sa/ikev1/tasks/main_mode.c
src/libcharon/sa/ikev2/task_manager_v2.c

index dfb85f69053b485f875f835104ce96321e32da8e..6fe211357a531d128fdcfabed1b0d87c00aa25a6 100644 (file)
@@ -76,7 +76,7 @@ METHOD(job_t, execute, job_requeue_t,
        }
        else
        {
-               ike_sa->update_hosts(ike_sa, NULL, this->new, FALSE);
+               ike_sa->update_hosts(ike_sa, NULL, this->new, 0);
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        }
        return JOB_REQUEUE_NONE;
index b8fdcbb07d21f71a75bfbb43508fe01b5ec45ed4..24fb4cd23b674522f0a2f6684e4e71d945e92022 100644 (file)
@@ -1114,7 +1114,7 @@ METHOD(ike_sa_t, float_ports, void,
 }
 
 METHOD(ike_sa_t, update_hosts, void,
-       private_ike_sa_t *this, host_t *me, host_t *other, bool force)
+       private_ike_sa_t *this, host_t *me, host_t *other, update_hosts_flag_t flags)
 {
        host_t *new_me = NULL, *new_other = NULL;
        bool silent = FALSE;
@@ -1138,18 +1138,18 @@ METHOD(ike_sa_t, update_hosts, void,
        }
        else
        {
-               /* update our address in any case */
-               if (force && !me->equals(me, this->my_host))
+               /* update our address only if forced */
+               if ((flags & UPDATE_HOSTS_FORCE_LOCAL) && !me->equals(me, this->my_host))
                {
                        new_me = me;
                }
 
                if (!other->equals(other, this->other_host) &&
-                       (force || has_condition(this, COND_NAT_THERE)))
+                       ((flags & UPDATE_HOSTS_FORCE_REMOTE) || has_condition(this, COND_NAT_THERE)))
                {
                        /* only update other's address if we are behind a static NAT,
                         * which we assume is the case if we are not initiator */
-                       if (force ||
+                       if ((flags & UPDATE_HOSTS_FORCE_REMOTE) ||
                                (!has_condition(this, COND_NAT_HERE) ||
                                 !has_condition(this, COND_ORIGINAL_INITIATOR)))
                        {
@@ -1158,13 +1158,13 @@ METHOD(ike_sa_t, update_hosts, void,
                }
        }
 
-       if (new_me || new_other)
+       if (new_me || new_other || (flags & UPDATE_HOSTS_FORCE_CHILDREN))
        {
                enumerator_t *enumerator;
                child_sa_t *child_sa;
                linked_list_t *vips;
 
-               if (!silent)
+               if ((new_me || new_other) && !silent)
                {
                        charon->bus->ike_update(charon->bus, &this->public,
                                                                        new_me ?: this->my_host,
index b965a49c97981eedfc09911537a8f5e0cad6383e..f15455930a85928e5462131b3f911d8e125bb84b 100644 (file)
@@ -28,6 +28,7 @@ typedef enum ike_extension_t ike_extension_t;
 typedef enum ike_condition_t ike_condition_t;
 typedef enum ike_sa_state_t ike_sa_state_t;
 typedef enum statistic_t statistic_t;
+typedef enum update_hosts_flag_t update_hosts_flag_t;
 typedef struct ike_sa_t ike_sa_t;
 
 #include <library.h>
@@ -264,6 +265,25 @@ enum statistic_t {
        STAT_MAX
 };
 
+/**
+ * Flags used when updating addresses
+ */
+enum update_hosts_flag_t {
+       /** Force updating the local address (otherwise not updated if an address
+        * is already set). */
+       UPDATE_HOSTS_FORCE_LOCAL = (1<<0),
+       /** Force updating the remote address (otherwise only updated if peer is
+        * behind a NAT). */
+       UPDATE_HOSTS_FORCE_REMOTE = (1<<1),
+       /** Force updating both addresses. */
+       UPDATE_HOSTS_FORCE_ADDRS = UPDATE_HOSTS_FORCE_LOCAL|UPDATE_HOSTS_FORCE_REMOTE,
+       /** Force updating the CHILD_SAs even if no addresses changed, useful if
+        * NAT state may have changed. */
+       UPDATE_HOSTS_FORCE_CHILDREN = (1<<2),
+       /** Force updating everything. */
+       UPDATE_HOSTS_FORCE_ALL = UPDATE_HOSTS_FORCE_ADDRS|UPDATE_HOSTS_FORCE_CHILDREN,
+};
+
 /**
  * State of an IKE_SA.
  *
@@ -454,15 +474,16 @@ struct ike_sa_t {
        void (*float_ports)(ike_sa_t *this);
 
        /**
-        * Update the IKE_SAs host.
+        * Update the IKE_SAs host and CHILD_SAs.
         *
         * Hosts may be NULL to use current host.
         *
         * @param me                    new local host address, or NULL
         * @param other                 new remote host address, or NULL
-        * @param force                 force update
+        * @param flags                 flags to force certain updates
         */
-       void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other, bool force);
+       void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other,
+                                                update_hosts_flag_t flags);
 
        /**
         * Get the own identification.
index 2a8bcfae7f5f6f09046463e84bf0c82c20a3f40e..f49a8eb8ed871804ba44a3838f98ca1e77e18d3d 100644 (file)
@@ -1408,7 +1408,7 @@ METHOD(task_manager_t, process_message, status_t,
                }
                this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                                                                        time_monotonic(NULL));
-               this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
+               this->ike_sa->update_hosts(this->ike_sa, me, other, UPDATE_HOSTS_FORCE_ADDRS);
                charon->bus->message(charon->bus, msg, TRUE, TRUE);
                if (process_response(this, msg) != SUCCESS)
                {
@@ -1528,7 +1528,7 @@ METHOD(task_manager_t, process_message, status_t,
                                                        "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
                                                        lib->ns));
                }
-               this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
+               this->ike_sa->update_hosts(this->ike_sa, me, other, UPDATE_HOSTS_FORCE_ADDRS);
                charon->bus->message(charon->bus, msg, TRUE, TRUE);
                if (process_request(this, msg) != SUCCESS)
                {
index 7314f8872e53be85b6dda549c6abcb5c01356a27..c38276c9c9633b224a66c6eee6314b9cd0b34881 100644 (file)
@@ -384,7 +384,8 @@ METHOD(task_t, process_r, status_t,
 
                        this->ike_sa->update_hosts(this->ike_sa,
                                                                           message->get_destination(message),
-                                                                          message->get_source(message), TRUE);
+                                                                          message->get_source(message),
+                                                                          UPDATE_HOSTS_FORCE_ADDRS);
 
                        sa_payload = (sa_payload_t*)message->get_payload(message,
                                                                                                        PLV1_SECURITY_ASSOCIATION);
index c1d12046fe21a805467348ea8d34d4c1e2ffddf7..35e860f090881853286fef0a2c7713ed4d821670 100644 (file)
@@ -376,7 +376,8 @@ METHOD(task_t, process_r, status_t,
 
                        this->ike_sa->update_hosts(this->ike_sa,
                                                                           message->get_destination(message),
-                                                                          message->get_source(message), TRUE);
+                                                                          message->get_source(message),
+                                                                          UPDATE_HOSTS_FORCE_ADDRS);
 
                        sa_payload = (sa_payload_t*)message->get_payload(message,
                                                                                                        PLV1_SECURITY_ASSOCIATION);
index 64d95f58199f2cb409c5257133ea2ab53d143151..9a3c1cae3e8f9cb9763360580c30bc89376e72ce 100644 (file)
@@ -1649,8 +1649,10 @@ METHOD(task_manager_t, process_message, status_t,
                                return FAILED;
                        }
                        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
-                       {       /* with MOBIKE, we do no implicit updates */
-                               this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
+                       {       /* only do implicit updates without MOBIKE, and only force
+                                * updates for IKE_AUTH (ports might change due to NAT-T) */
+                               this->ike_sa->update_hosts(this->ike_sa, me, other,
+                                                                                  mid == 1 ? UPDATE_HOSTS_FORCE_ADDRS : 0);
                        }
                        status = handle_fragment(this, &this->responding.defrag, msg);
                        if (status != SUCCESS)
@@ -1718,11 +1720,11 @@ METHOD(task_manager_t, process_message, status_t,
                                msg->get_exchange_type(msg) != IKE_SA_INIT)
                        {       /* only do updates based on verified messages (or initial ones) */
                                if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
-                               {       /* with MOBIKE, we do no implicit updates.  we force an
-                                        * update of the local address on IKE_SA_INIT, but never
-                                        * for the remote address */
-                                       this->ike_sa->update_hosts(this->ike_sa, me, NULL, mid == 0);
-                                       this->ike_sa->update_hosts(this->ike_sa, NULL, other, FALSE);
+                               {       /* only do implicit updates without MOBIKE, we force an
+                                        * update of the local address on IKE_SA_INIT as we might
+                                        * not know it yet, but never for the remote address */
+                                       this->ike_sa->update_hosts(this->ike_sa, me, other,
+                                                                                          mid == 0 ? UPDATE_HOSTS_FORCE_LOCAL : 0);
                                }
                        }
                        status = handle_fragment(this, &this->initiating.defrag, msg);