Clear virtual IPs before storing assigned ones on the IKE_SA
authorTobias Brunner <tobias@strongswan.org>
Wed, 5 Sep 2012 11:16:31 +0000 (13:16 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 5 Sep 2012 12:35:57 +0000 (14:35 +0200)
Otherwise we'll end up with duplicate or invalid VIPs stored on the
IKE_SA.

src/libcharon/plugins/ha/ha_dispatcher.c
src/libcharon/sa/ike_sa.c
src/libcharon/sa/ike_sa.h
src/libcharon/sa/ikev1/tasks/mode_config.c
src/libcharon/sa/ikev2/tasks/ike_config.c

index f07b4ea..97ed131 100644 (file)
@@ -310,7 +310,7 @@ static void process_ike_update(private_ha_dispatcher_t *this,
        ike_sa_t *ike_sa = NULL;
        peer_cfg_t *peer_cfg = NULL;
        auth_cfg_t *auth;
-       bool received_vip = FALSE, first_peer_addr = TRUE;
+       bool received_vip = FALSE, first_local_vip = TRUE, first_peer_addr = TRUE;
 
        enumerator = message->create_attribute_enumerator(message);
        while (enumerator->enumerate(enumerator, &attribute, &value))
@@ -344,9 +344,18 @@ static void process_ike_update(private_ha_dispatcher_t *this,
                                ike_sa->set_other_host(ike_sa, value.host->clone(value.host));
                                break;
                        case HA_LOCAL_VIP:
+                               if (first_local_vip)
+                               {
+                                       ike_sa->clear_virtual_ips(ike_sa, TRUE);
+                                       first_local_vip = FALSE;
+                               }
                                ike_sa->add_virtual_ip(ike_sa, TRUE, value.host);
                                break;
                        case HA_REMOTE_VIP:
+                               if (!received_vip)
+                               {
+                                       ike_sa->clear_virtual_ips(ike_sa, FALSE);
+                               }
                                ike_sa->add_virtual_ip(ike_sa, FALSE, value.host);
                                received_vip = TRUE;
                                break;
index 7672acc..e3744b6 100644 (file)
@@ -757,6 +757,23 @@ METHOD(ike_sa_t, add_virtual_ip, void,
        }
 }
 
+
+METHOD(ike_sa_t, clear_virtual_ips, void,
+       private_ike_sa_t *this, bool local)
+{
+       linked_list_t *vips = local ? this->my_vips : this->other_vips;
+       host_t *vip;
+
+       while (vips->remove_first(vips, (void**)&vip) == SUCCESS)
+       {
+               if (local)
+               {
+                       hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+               }
+               vip->destroy(vip);
+       }
+}
+
 METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
        private_ike_sa_t *this, bool local)
 {
@@ -2193,6 +2210,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
                        .reset = _reset,
                        .get_unique_id = _get_unique_id,
                        .add_virtual_ip = _add_virtual_ip,
+                       .clear_virtual_ips = _clear_virtual_ips,
                        .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
                        .add_configuration_attribute = _add_configuration_attribute,
                        .set_kmaddress = _set_kmaddress,
index d2a394b..d9ee6b8 100644 (file)
@@ -942,6 +942,13 @@ struct ike_sa_t {
        void (*add_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
 
        /**
+        * Clear all virtual IPs stored on this IKE_SA.
+        *
+        * @param local                 TRUE to clear local addresses, FALSE for remote
+        */
+       void (*clear_virtual_ips) (ike_sa_t *this, bool local);
+
+       /**
         * Create an enumerator over virtual IPs.
         *
         * @param local                 TRUE to get local virtual IP, FALSE for remote
index 03072a2..a134ad5 100644 (file)
@@ -332,6 +332,8 @@ METHOD(task_t, build_r, status_t,
        vips = linked_list_create();
        pools = linked_list_create();
 
+       this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+
        enumerator = this->vips->create_enumerator(this->vips);
        while (enumerator->enumerate(enumerator, &requested))
        {
@@ -411,6 +413,8 @@ METHOD(task_t, process_i, status_t,
 
        process_payloads(this, message);
 
+       this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
+
        enumerator = this->vips->create_enumerator(this->vips);
        while (enumerator->enumerate(enumerator, &host))
        {
index e788bb5..fbfcb0e 100644 (file)
@@ -344,6 +344,8 @@ METHOD(task_t, build_r, status_t,
                vips = linked_list_create();
                pools = linked_list_create();
 
+               this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+
                enumerator = this->vips->create_enumerator(this->vips);
                while (enumerator->enumerate(enumerator, &requested))
                {
@@ -437,6 +439,8 @@ METHOD(task_t, process_i, status_t,
 
                process_payloads(this, message);
 
+               this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
+
                enumerator = this->vips->create_enumerator(this->vips);
                while (enumerator->enumerate(enumerator, &host))
                {