aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon/sa/ike_sa.c103
-rw-r--r--src/charon/sa/tasks/ike_config.c16
2 files changed, 68 insertions, 51 deletions
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index ec69f619d..0f7a5e36c 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -1152,6 +1152,55 @@ static void set_other_id(private_ike_sa_t *this, identification_t *other)
}
/**
+ * Implementation of ike_sa_t.set_virtual_ip
+ */
+static void set_virtual_ip(private_ike_sa_t *this, bool local, host_t *ip)
+{
+ if (local)
+ {
+ DBG1(DBG_IKE, "installing new virtual IP %H", ip);
+ if (this->my_virtual_ip)
+ {
+ DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
+ charon->kernel_interface->del_ip(charon->kernel_interface,
+ this->my_virtual_ip,
+ this->my_host);
+ this->my_virtual_ip->destroy(this->my_virtual_ip);
+ }
+ if (charon->kernel_interface->add_ip(charon->kernel_interface, ip,
+ this->my_host) == SUCCESS)
+ {
+ this->my_virtual_ip = ip->clone(ip);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "installing virtual IP %H failed", ip);
+ this->my_virtual_ip = NULL;
+ }
+ }
+ else
+ {
+ DESTROY_IF(this->other_virtual_ip);
+ this->other_virtual_ip = ip->clone(ip);
+ }
+}
+
+/**
+ * Implementation of ike_sa_t.get_virtual_ip
+ */
+static host_t* get_virtual_ip(private_ike_sa_t *this, bool local)
+{
+ if (local)
+ {
+ return this->my_virtual_ip;
+ }
+ else
+ {
+ return this->other_virtual_ip;
+ }
+}
+
+/**
* Implementation of ike_sa_t.derive_keys.
*/
static status_t derive_keys(private_ike_sa_t *this,
@@ -1494,6 +1543,11 @@ static void reestablish(private_ike_sa_t *this)
set_peer_cfg(other, this->peer_cfg);
other->other_host->destroy(other->other_host);
other->other_host = this->other_host->clone(this->other_host);
+ if (this->my_virtual_ip)
+ {
+ /* if we already have a virtual IP, we reuse it */
+ set_virtual_ip(other, TRUE, this->my_virtual_ip);
+ }
if (this->state == IKE_ESTABLISHED)
{
@@ -1620,55 +1674,6 @@ static void enable_natt(private_ike_sa_t *this, bool local)
}
/**
- * Implementation of ike_sa_t.set_virtual_ip
- */
-static void set_virtual_ip(private_ike_sa_t *this, bool local, host_t *ip)
-{
- if (local)
- {
- DBG1(DBG_IKE, "installing new virtual IP %H", ip);
- if (this->my_virtual_ip)
- {
- DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip,
- this->my_host);
- this->my_virtual_ip->destroy(this->my_virtual_ip);
- }
- if (charon->kernel_interface->add_ip(charon->kernel_interface, ip,
- this->my_host) == SUCCESS)
- {
- this->my_virtual_ip = ip->clone(ip);
- }
- else
- {
- DBG1(DBG_IKE, "installing virtual IP %H failed", ip);
- this->my_virtual_ip = NULL;
- }
- }
- else
- {
- DESTROY_IF(this->other_virtual_ip);
- this->other_virtual_ip = ip->clone(ip);
- }
-}
-
-/**
- * Implementation of ike_sa_t.get_virtual_ip
- */
-static host_t* get_virtual_ip(private_ike_sa_t *this, bool local)
-{
- if (local)
- {
- return this->my_virtual_ip;
- }
- else
- {
- return this->other_virtual_ip;
- }
-}
-
-/**
* Implementation of ike_sa_t.remove_dns_server
*/
static void remove_dns_servers(private_ike_sa_t *this)
diff --git a/src/charon/sa/tasks/ike_config.c b/src/charon/sa/tasks/ike_config.c
index 0fc35013b..4db6e2cc2 100644
--- a/src/charon/sa/tasks/ike_config.c
+++ b/src/charon/sa/tasks/ike_config.c
@@ -261,8 +261,20 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
if (message->get_exchange_type(message) == IKE_AUTH &&
message->get_payload(message, ID_INITIATOR))
{
- peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa);
- this->virtual_ip = config->get_virtual_ip(config, NULL);
+ peer_cfg_t *config;
+ host_t *vip;
+
+ /* reuse virtual IP if we already have one */
+ vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
+ if (vip)
+ {
+ this->virtual_ip = vip->clone(vip);
+ }
+ else
+ {
+ config = this->ike_sa->get_peer_cfg(this->ike_sa);
+ this->virtual_ip = config->get_virtual_ip(config, NULL);
+ }
build_payloads(this, message, CFG_REQUEST);
}