600, 600, /* jitter, over 10min */
TRUE, FALSE, /* mobike, aggressive */
0, 0, /* DPD delay, timeout */
- virtual ? host_create_from_string("0.0.0.0", 0) : NULL,
NULL, FALSE, NULL, NULL); /* pool, mediation */
+ if (virtual)
+ {
+ peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
+ }
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_class);
auth->add(auth, AUTH_RULE_IDENTITY, user);
ike_cfg = load_ike_config(this, settings, config);
peer_cfg = peer_cfg_create(config, IKEV2, ike_cfg, CERT_ALWAYS_SEND,
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, FALSE, 0, 0,
- NULL, NULL, FALSE, NULL, NULL);
+ NULL, FALSE, NULL, NULL);
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
ike_sa_t *ike_sa, child_sa_t *child_sa)
{
vpnservice_builder_t *builder;
+ enumerator_t *enumerator;
+ bool vip_found = FALSE;
host_t *vip;
int tunfd;
DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
- vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
- if (!vip || vip->is_anyaddr(vip))
+
+ builder = charonservice->get_vpnservice_builder(charonservice);
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ if (!vip->is_anyaddr(vip))
+ {
+ if (!builder->add_address(builder, vip))
+ {
+ break;
+ }
+ vip_found = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!vip_found)
{
DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
return FALSE;
}
-
- builder = charonservice->get_vpnservice_builder(charonservice);
- if (!builder->add_address(builder, vip) ||
- !add_routes(builder, child_sa) ||
+ if (!add_routes(builder, child_sa) ||
!builder->set_mtu(builder, TUN_DEFAULT_MTU))
{
return FALSE;
600, 600, /* jitter, over 10min */
TRUE, FALSE, /* mobike, aggressive */
0, 0, /* DPD delay, timeout */
- host_create_from_string("0.0.0.0", 0) /* virt */,
NULL, FALSE, NULL, NULL); /* pool, mediation */
-
+ peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
u_int32_t dpd_timeout;
/**
- * virtual IP to use locally
+ * List of virtual IPs (host_t*) to request
*/
- host_t *virtual_ip;
+ linked_list_t *vips;
/**
* pool to acquire configuration attributes from
return this->dpd_timeout;
}
-METHOD(peer_cfg_t, get_virtual_ip, host_t*,
+METHOD(peer_cfg_t, add_virtual_ip, void,
+ private_peer_cfg_t *this, host_t *vip)
+{
+ this->vips->insert_last(this->vips, vip);
+}
+
+METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
private_peer_cfg_t *this)
{
- return this->virtual_ip;
+ return this->vips->create_enumerator(this->vips);
}
METHOD(peer_cfg_t, get_pool, char*,
METHOD(peer_cfg_t, equals, bool,
private_peer_cfg_t *this, private_peer_cfg_t *other)
{
+ enumerator_t *e1, *e2;
+ host_t *vip1, *vip2;
+
if (this == other)
{
return TRUE;
return FALSE;
}
+ if (this->vips->get_count(this->vips) != other->vips->get_count(other->vips))
+ {
+ return FALSE;
+ }
+ e1 = create_virtual_ip_enumerator(this);
+ e2 = create_virtual_ip_enumerator(other);
+ if (e1->enumerate(e1, &vip1) && e2->enumerate(e2, &vip2))
+ {
+ if (!vip1->ip_equals(vip1, vip2))
+ {
+ e1->destroy(e1);
+ e2->destroy(e2);
+ return FALSE;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+
return (
this->ike_version == other->ike_version &&
this->cert_policy == other->cert_policy &&
this->jitter_time == other->jitter_time &&
this->over_time == other->over_time &&
this->dpd == other->dpd &&
- (this->virtual_ip == other->virtual_ip ||
- (this->virtual_ip && other->virtual_ip &&
- this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
(this->pool == other->pool ||
(this->pool && other->pool && streq(this->pool, other->pool))) &&
auth_cfg_equal(this, other)
this->ike_cfg->destroy(this->ike_cfg);
this->child_cfgs->destroy_offset(this->child_cfgs,
offsetof(child_cfg_t, destroy));
- DESTROY_IF(this->virtual_ip);
this->local_auth->destroy_offset(this->local_auth,
offsetof(auth_cfg_t, destroy));
this->remote_auth->destroy_offset(this->remote_auth,
offsetof(auth_cfg_t, destroy));
+ this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
#ifdef ME
DESTROY_IF(this->mediated_by);
DESTROY_IF(this->peer_id);
u_int32_t rekey_time, u_int32_t reauth_time,
u_int32_t jitter_time, u_int32_t over_time,
bool mobike, bool aggressive, u_int32_t dpd,
- u_int32_t dpd_timeout, host_t *virtual_ip,
- char *pool, bool mediation, peer_cfg_t *mediated_by,
+ u_int32_t dpd_timeout, char *pool,
+ bool mediation, peer_cfg_t *mediated_by,
identification_t *peer_id)
{
private_peer_cfg_t *this;
.use_aggressive = _use_aggressive,
.get_dpd = _get_dpd,
.get_dpd_timeout = _get_dpd_timeout,
- .get_virtual_ip = _get_virtual_ip,
+ .add_virtual_ip = _add_virtual_ip,
+ .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
.get_pool = _get_pool,
.add_auth_cfg = _add_auth_cfg,
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
.aggressive = aggressive,
.dpd = dpd,
.dpd_timeout = dpd_timeout,
- .virtual_ip = virtual_ip,
+ .vips = linked_list_create(),
.pool = strdupnull(pool),
.local_auth = linked_list_create(),
.remote_auth = linked_list_create(),
u_int32_t (*get_dpd_timeout) (peer_cfg_t *this);
/**
- * Get a virtual IP for the local peer.
+ * Add a virtual IP to request as initiator.
*
- * If no virtual IP should be used, NULL is returned. %any means to request
- * a virtual IP using configuration payloads. A specific address is also
- * used for a request and may be changed by the server.
+ * @param vip virtual IP to request, may be %any or %any6
+ */
+ void (*add_virtual_ip)(peer_cfg_t *this, host_t *vip);
+
+ /**
+ * Create an enumerator over virtual IPs to request.
+ *
+ * The returned enumerator enumerates over IPs added with add_virtual_ip().
*
- * @param suggestion NULL, %any or specific
- * @return virtual IP, %any or NULL
+ * @return enumerator over host_t*
*/
- host_t* (*get_virtual_ip) (peer_cfg_t *this);
+ enumerator_t* (*create_virtual_ip_enumerator)(peer_cfg_t *this);
/**
* Get the name of the pool to acquire configuration attributes from.
* @param aggressive use/accept aggressive mode with IKEv1
* @param dpd DPD check interval, 0 to disable
* @param dpd_timeout DPD timeout interval (IKEv1 only), if 0 default applies
- * @param virtual_ip virtual IP for local host, or NULL
* @param pool pool name to get configuration attributes from, or NULL
* @param mediation TRUE if this is a mediation connection
* @param mediated_by peer_cfg_t of the mediation connection to mediate through
u_int32_t rekey_time, u_int32_t reauth_time,
u_int32_t jitter_time, u_int32_t over_time,
bool mobike, bool aggressive, u_int32_t dpd,
- u_int32_t dpd_timeout, host_t *virtual_ip,
- char *pool, bool mediation, peer_cfg_t *mediated_by,
+ u_int32_t dpd_timeout, char *pool,
+ bool mediation, peer_cfg_t *mediated_by,
identification_t *peer_id);
#endif /** PEER_CFG_H_ @}*/
600, 600, /* jitter, over 10min */
TRUE, FALSE, /* mobike, aggressive */
0, 0, /* DPD delay, timeout */
- host_create_from_string("0.0.0.0", 0) /* virt */,
NULL, FALSE, NULL, NULL); /* pool, mediation */
+ peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
*/
static void add_ike_sa_parameters(radius_message_t *message, ike_sa_t *ike_sa)
{
+ enumerator_t *enumerator;
host_t *vip;
char buf[64];
chunk_t data;
message->add(message, RAT_USER_NAME, chunk_create(buf, strlen(buf)));
snprintf(buf, sizeof(buf), "%#H", ike_sa->get_other_host(ike_sa));
message->add(message, RAT_CALLING_STATION_ID, chunk_create(buf, strlen(buf)));
- vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (vip && vip->get_family(vip) == AF_INET)
- {
- message->add(message, RAT_FRAMED_IP_ADDRESS, vip->get_address(vip));
- }
- if (vip && vip->get_family(vip) == AF_INET6)
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
+ while (enumerator->enumerate(enumerator, &vip))
{
- /* we currently assign /128 prefixes, only (reserved, length) */
- data = chunk_from_chars(0, 128);
- data = chunk_cata("cc", data, vip->get_address(vip));
- message->add(message, RAT_FRAMED_IPV6_PREFIX, data);
+ switch (vip->get_family(vip))
+ {
+ case AF_INET:
+ message->add(message, RAT_FRAMED_IP_ADDRESS,
+ vip->get_address(vip));
+ break;
+ case AF_INET6:
+ /* we currently assign /128 prefixes, only (reserved, length) */
+ data = chunk_from_chars(0, 128);
+ data = chunk_cata("cc", data, vip->get_address(vip));
+ message->add(message, RAT_FRAMED_IPV6_PREFIX, data);
+ break;
+ default:
+ break;
+ }
}
}
ike_sa->set_other_host(ike_sa, value.host->clone(value.host));
break;
case HA_LOCAL_VIP:
- ike_sa->set_virtual_ip(ike_sa, TRUE, value.host);
+ ike_sa->add_virtual_ip(ike_sa, TRUE, value.host);
break;
case HA_REMOTE_VIP:
- ike_sa->set_virtual_ip(ike_sa, FALSE, value.host);
+ ike_sa->add_virtual_ip(ike_sa, FALSE, value.host);
received_vip = TRUE;
break;
case HA_PEER_ADDR:
char *pool;
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
- vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (peer_cfg && vip)
+ if (peer_cfg)
{
pool = peer_cfg->get_pool(peer_cfg);
if (pool)
{
- this->attr->reserve(this->attr, pool, vip);
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa,
+ FALSE);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ this->attr->reserve(this->attr, pool, vip);
+ }
+ enumerator->destroy(enumerator);
}
}
}
return TRUE;
}
+/**
+ * Send a virtual IP sync message for remote VIPs
+ */
+static void sync_vips(private_ha_ike_t *this, ike_sa_t *ike_sa)
+{
+ ha_message_t *m = NULL;
+ enumerator_t *enumerator;
+ host_t *vip;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ if (!m)
+ {
+ m = ha_message_create(HA_IKE_UPDATE);
+ m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
+ }
+ m->add_attribute(m, HA_REMOTE_VIP, vip);
+ }
+ enumerator->destroy(enumerator);
+
+ if (m)
+ {
+ this->socket->push(this->socket, m);
+ this->cache->cache(this->cache, ike_sa, m);
+ }
+}
+
METHOD(listener_t, message_hook, bool,
private_ha_ike_t *this, ike_sa_t *ike_sa, message_t *message,
bool incoming, bool plain)
{ /* After IKE_SA has been established, sync peers virtual IP.
* We cannot sync it in the state_change hook, it is installed later.
* TODO: where to sync local VIP? */
- ha_message_t *m;
- host_t *vip;
-
- vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (vip)
- {
- m = ha_message_create(HA_IKE_UPDATE);
- m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
- m->add_attribute(m, HA_REMOTE_VIP, vip);
- this->socket->push(this->socket, m);
- this->cache->cache(this->cache, ike_sa, m);
- }
+ sync_vips(this, ike_sa);
}
}
if (!plain && ike_sa->get_version(ike_sa) == IKEV1)
keymat_v1_t *keymat;
u_int32_t mid;
chunk_t iv;
- host_t *vip;
mid = message->get_message_id(message);
if (mid == 0)
}
if (!incoming && message->get_exchange_type(message) == TRANSACTION)
{
- vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (vip)
- {
- m = ha_message_create(HA_IKE_UPDATE);
- m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
- m->add_attribute(m, HA_REMOTE_VIP, vip);
- this->socket->push(this->socket, m);
- this->cache->cache(this->cache, ike_sa, m);
- }
+ sync_vips(this, ike_sa);
}
}
if (plain && ike_sa->get_version(ike_sa) == IKEV1 &&
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create("ha", IKEV2, ike_cfg, CERT_NEVER_SEND,
UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, 30,
- 0, NULL, NULL, FALSE, NULL, NULL);
+ 0, NULL, FALSE, NULL, NULL);
auth_cfg = auth_cfg_create();
auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
FALSE, FALSE, /* mobike, aggressive mode */
this->dpd_delay, /* dpd_delay */
this->dpd_timeout, /* dpd_timeout */
- this->vip ? this->vip->clone(this->vip) : NULL,
this->pool, FALSE, NULL, NULL);
+ if (this->vip)
+ {
+ peer_cfg->add_virtual_ip(peer_cfg, this->vip->clone(this->vip));
+ }
if (num)
{ /* initiator */
generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
600, 600, /* jitter, over 10min */
TRUE, FALSE, /* mobike, aggressive */
0, 0, /* DPD delay, timeout */
- host_create_from_string("0.0.0.0", 0) /* virt */,
NULL, FALSE, NULL, NULL); /* pool, mediation */
+ peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
this->rekey*5, this->rekey*3, /* jitter, overtime */
TRUE, FALSE, /* mobike, aggressive */
this->dpd, 0, /* DPD delay, timeout */
- NULL, NULL, /* vip, pool */
+ NULL, /* pool */
TRUE, NULL, NULL); /* mediation, med by, peer id */
e->destroy(e);
this->rekey*5, this->rekey*3, /* jitter, overtime */
TRUE, FALSE, /* mobike, aggressive */
this->dpd, 0, /* DPD delay, timeout */
- NULL, NULL, /* vip, pool */
+ NULL, /* pool */
FALSE, med_cfg, /* mediation, med by */
identification_create_from_encoding(ID_KEY_ID, other));
this->rekey*5, this->rekey*3, /* jitter, overtime */
TRUE, FALSE, /* mobike, aggressive */
this->dpd, 0, /* DPD delay, timeout */
- NULL, NULL, /* vip, pool */
+ NULL, /* pool */
FALSE, NULL, NULL); /* mediation, med by, peer id */
auth = auth_cfg_create();
this->rekey*5, this->rekey*3, /* jitter, overtime */
TRUE, FALSE, /* mobike, aggressiv */
this->dpd, 0, /* DPD delay, timeout */
- NULL, NULL, /* vip, pool */
+ NULL, /* pool */
TRUE, NULL, NULL); /* mediation, med by, peer id */
e->destroy(e);
peer_cfg = peer_cfg_create(
name, IKEV2, ike, cert_policy, uniqueid,
keyingtries, rekeytime, reauthtime, jitter, overtime,
- mobike, FALSE, dpd_delay, 0, vip, pool,
+ mobike, FALSE, dpd_delay, 0, pool,
mediation, mediated_cfg, peer_id);
+ if (vip)
+ {
+ peer_cfg->add_virtual_ip(peer_cfg, vip);
+ }
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
auth->add(auth, AUTH_RULE_IDENTITY, local_id);
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
msg->add_conn.mobike, msg->add_conn.aggressive,
msg->add_conn.dpd.delay, msg->add_conn.dpd.timeout,
- vip, msg->add_conn.other.sourceip_mask ?
+ msg->add_conn.other.sourceip_mask ?
msg->add_conn.name : msg->add_conn.other.sourceip,
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
+ if (vip)
+ {
+ peer_cfg->add_virtual_ip(peer_cfg, vip);
+ }
/* build leftauth= */
auth_cfg = build_auth_cfg(this, msg, TRUE, TRUE);
METHOD(stroke_control_t, terminate_srcip, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
- enumerator_t *enumerator;
+ enumerator_t *enumerator, *vips;
ike_sa_t *ike_sa;
host_t *start = NULL, *end = NULL, *vip;
- chunk_t chunk_start, chunk_end = chunk_empty, chunk_vip;
+ chunk_t chunk_start, chunk_end = chunk_empty, chunk;
if (msg->terminate_srcip.start)
{
charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
- vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (!vip)
- {
- continue;
- }
- if (!end)
+ bool match = FALSE;
+
+ vips = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
+ while (vips->enumerate(vips, &vip))
{
- if (!vip->ip_equals(vip, start))
+ if (!end)
{
- continue;
+ if (vip->ip_equals(vip, start))
+ {
+ match = TRUE;
+ break;
+ }
}
- }
- else
- {
- chunk_vip = vip->get_address(vip);
- if (chunk_vip.len != chunk_start.len ||
- chunk_vip.len != chunk_end.len ||
- memcmp(chunk_vip.ptr, chunk_start.ptr, chunk_vip.len) < 0 ||
- memcmp(chunk_vip.ptr, chunk_end.ptr, chunk_vip.len) > 0)
+ else
{
- continue;
+ chunk = vip->get_address(vip);
+ if (chunk.len == chunk_start.len &&
+ chunk.len == chunk_end.len &&
+ memcmp(chunk.ptr, chunk_start.ptr, chunk.len) >= 0 &&
+ memcmp(chunk.ptr, chunk_end.ptr, chunk.len) <= 0)
+ {
+ match = TRUE;
+ break;
+ }
}
}
+ vips->destroy(vips);
- /* schedule delete asynchronously */
- lib->processor->queue_job(lib->processor, (job_t*)
+ if (match)
+ {
+ /* schedule delete asynchronously */
+ lib->processor->queue_job(lib->processor, (job_t*)
delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE));
+ }
}
enumerator->destroy(enumerator);
start->destroy(start);
1800, 900, /* jitter, overtime */
TRUE, FALSE, /* mobike, aggressive */
60, 0, /* DPD delay, timeout */
- NULL, NULL, /* vip, pool */
+ NULL, /* pool */
FALSE, NULL, NULL); /* mediation, med by, peer id */
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
return strdup(total);
}
+/**
+ * Create variables for local virtual IPs
+ */
+static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+ int v4 = 0, v6 = 0;
+ char total[512] = "", current[64];
+ bool first = TRUE;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ if (first)
+ { /* legacy variable for first VIP */
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP='%H' ", host);
+ strncat(total, current, sizeof(total) - strlen(total) - 1);
+ }
+ switch (host->get_family(host))
+ {
+ case AF_INET:
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP4_%d='%H' ", ++v4, host);
+ break;
+ case AF_INET6:
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP6_%d='%H' ", ++v6, host);
+ break;
+ default:
+ continue;
+ }
+ strncat(total, current, sizeof(total) - strlen(total) - 1);
+ }
+ enumerator->destroy(enumerator);
+
+ return strdup(total);
+}
+
METHOD(listener_t, child_updown, bool,
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
bool up)
traffic_selector_t *my_ts, *other_ts;
enumerator_t *enumerator;
child_cfg_t *config;
- host_t *vip, *me, *other;
+ host_t *me, *other;
char *script;
config = child_sa->get_config(child_sa);
- vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
script = config->get_updown(config);
me = ike_sa->get_my_host(ike_sa);
other = ike_sa->get_other_host(ike_sa);
my_ts->to_subnet(my_ts, &my_client, &my_client_mask);
other_ts->to_subnet(other_ts, &other_client, &other_client_mask);
- if (vip)
- {
- if (asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip) < 0)
- {
- virtual_ip = NULL;
- }
- }
- else
- {
- if (asprintf(&virtual_ip, "") < 0)
- {
- virtual_ip = NULL;
- }
- }
+ virtual_ip = make_vip_vars(this, ike_sa);
/* check for the presence of an inbound mark */
mark = config->get_mark(config, TRUE);
}
if (ike_sa)
{
- enumerator_t *children;
+ enumerator_t *children, *enumerator;
child_sa_t *child_sa;
host_t *host;
+ linked_list_t *vips;
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, (void**)&child_sa))
host->set_port(host, IKEV2_UDP_PORT);
ike_sa->set_other_host(ike_sa, host);
- if (child_sa->update(child_sa, this->local, this->remote,
- ike_sa->get_virtual_ip(ike_sa, TRUE),
+ vips = linked_list_create();
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ vips->insert_last(vips, host);
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_sa->update(child_sa, this->local, this->remote, vips,
ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
{
ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
child_sa->get_spi(child_sa, TRUE));
}
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ vips->destroy(vips);
}
else
{
return status;
}
+/**
+ * Callback to reinstall a virtual IP
+ */
+static void reinstall_vip(host_t *vip, host_t *me)
+{
+ hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+ hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me);
+}
+
METHOD(child_sa_t, update, status_t,
- private_child_sa_t *this, host_t *me, host_t *other, host_t *vip,
- bool encap)
+ private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
+ bool encap)
{
child_sa_state_t old;
bool transport_proxy_mode;
/* we reinstall the virtual IP to handle interface roaming
* correctly */
- if (vip)
- {
- hydra->kernel_interface->del_ip(hydra->kernel_interface,
- vip);
- hydra->kernel_interface->add_ip(hydra->kernel_interface,
- vip, me);
- }
+ vips->invoke_function(vips, (void*)reinstall_vip, me);
/* reinstall updated policies */
install_policies_internal(this, me, other, my_ts, other_ts,
*
* @param me the new local host
* @param other the new remote host
- * @param vip virtual IP, if any
+ * @param vips list of local virtual IPs
* @param TRUE to use UDP encapsulation for NAT traversal
* @return SUCCESS or FAILED
*/
status_t (*update)(child_sa_t *this, host_t *me, host_t *other,
- host_t *vip, bool encap);
+ linked_list_t *vips, bool encap);
/**
* Destroys a child_sa.
*/
keymat_t *keymat;
/**
- * Virtual IP on local host, if any
+ * Virtual IPs on local host
*/
- host_t *my_virtual_ip;
+ linked_list_t *my_vips;
/**
- * Virtual IP on remote host, if any
+ * Virtual IPs on remote host
*/
- host_t *other_virtual_ip;
+ linked_list_t *other_vips;
/**
* List of configuration attributes (attribute_entry_t)
return this->keymat;
}
-METHOD(ike_sa_t, set_virtual_ip, void,
+METHOD(ike_sa_t, add_virtual_ip, void,
private_ike_sa_t *this, bool local, host_t *ip)
{
if (local)
if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip,
this->my_host) == SUCCESS)
{
- if (this->my_virtual_ip)
- {
- DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
- hydra->kernel_interface->del_ip(hydra->kernel_interface,
- this->my_virtual_ip);
- }
- DESTROY_IF(this->my_virtual_ip);
- this->my_virtual_ip = ip->clone(ip);
+ this->my_vips->insert_last(this->my_vips, 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);
+ this->other_vips->insert_last(this->other_vips, ip->clone(ip));
}
}
-METHOD(ike_sa_t, get_virtual_ip, host_t*,
+METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
private_ike_sa_t *this, bool local)
{
if (local)
{
- return this->my_virtual_ip;
- }
- else
- {
- return this->other_virtual_ip;
+ return this->my_vips->create_enumerator(this->my_vips);
}
+ return this->other_vips->create_enumerator(this->other_vips);
}
METHOD(ike_sa_t, add_peer_address, void,
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->update(child_sa, this->my_host,
- this->other_host, this->my_virtual_ip,
+ this->other_host, this->my_vips,
has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
{
this->public.rekey_child_sa(&this->public,
if (!has_condition(this, COND_ORIGINAL_INITIATOR))
{
DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
- if (this->other_virtual_ip != NULL ||
+ if (this->other_vips->get_count(this->other_vips) != 0 ||
has_condition(this, COND_XAUTH_AUTHENTICATED) ||
has_condition(this, COND_EAP_AUTHENTICATED)
#ifdef ME
/* check if we are able to reestablish this IKE_SA */
if (!has_condition(this, COND_ORIGINAL_INITIATOR) &&
- (this->other_virtual_ip != NULL ||
+ (this->other_vips->get_count(this->other_vips) != 0 ||
has_condition(this, COND_EAP_AUTHENTICATED)
#ifdef ME
|| this->is_mediation_server
host = this->my_host;
new->set_my_host(new, host->clone(host));
/* if we already have a virtual IP, we reuse it */
- host = this->my_virtual_ip;
- if (host)
+ enumerator = this->my_vips->create_enumerator(this->my_vips);
+ while (enumerator->enumerate(enumerator, &host))
{
- new->set_virtual_ip(new, TRUE, host);
+ new->add_virtual_ip(new, TRUE, host);
}
+ enumerator->destroy(enumerator);
#ifdef ME
if (this->peer_cfg->is_mediation(this->peer_cfg))
* We send the notify in IKE_AUTH if not yet ESTABLISHED. */
send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
!has_condition(this, COND_ORIGINAL_INITIATOR) &&
- (this->other_virtual_ip != NULL ||
+ (this->other_vips->get_count(this->other_vips) != 0 ||
has_condition(this, COND_EAP_AUTHENTICATED));
if (lifetime < diff)
attribute_entry_t *entry;
enumerator_t *enumerator;
auth_cfg_t *cfg;
+ host_t *vip;
/* apply hosts and ids */
this->my_host->destroy(this->my_host);
this->my_id = other->my_id->clone(other->my_id);
this->other_id = other->other_id->clone(other->other_id);
- /* apply virtual assigned IPs... */
- if (other->my_virtual_ip)
+ /* apply assigned virtual IPs... */
+ while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS)
{
- this->my_virtual_ip = other->my_virtual_ip;
- other->my_virtual_ip = NULL;
+ other->my_vips->insert_first(other->my_vips, vip);
}
- if (other->other_virtual_ip)
+ while (this->other_vips->remove_last(this->other_vips,
+ (void**)&vip) == SUCCESS)
{
- this->other_virtual_ip = other->other_virtual_ip;
- other->other_virtual_ip = NULL;
+ other->other_vips->insert_first(other->other_vips, vip);
}
/* authentication information */
private_ike_sa_t *this)
{
attribute_entry_t *entry;
+ host_t *vip;
charon->bus->set_sa(charon->bus, &this->public);
DESTROY_IF(this->keymat);
- if (this->my_virtual_ip)
+ while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS)
{
- hydra->kernel_interface->del_ip(hydra->kernel_interface,
- this->my_virtual_ip);
- this->my_virtual_ip->destroy(this->my_virtual_ip);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+ vip->destroy(vip);
}
- if (this->other_virtual_ip)
+ this->my_vips->destroy(this->my_vips);
+ while (this->other_vips->remove_last(this->other_vips,
+ (void**)&vip) == SUCCESS)
{
if (this->peer_cfg && this->peer_cfg->get_pool(this->peer_cfg))
{
hydra->attributes->release_address(hydra->attributes,
this->peer_cfg->get_pool(this->peer_cfg),
- this->other_virtual_ip, get_other_eap_id(this));
+ vip, get_other_eap_id(this));
}
- this->other_virtual_ip->destroy(this->other_virtual_ip);
+ vip->destroy(vip);
}
+ this->other_vips->destroy(this->other_vips);
this->peer_addresses->destroy_offset(this->peer_addresses,
offsetof(host_t, destroy));
#ifdef ME
.generate_message = _generate_message,
.reset = _reset,
.get_unique_id = _get_unique_id,
- .set_virtual_ip = _set_virtual_ip,
- .get_virtual_ip = _get_virtual_ip,
+ .add_virtual_ip = _add_virtual_ip,
+ .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
.add_configuration_attribute = _add_configuration_attribute,
.set_kmaddress = _set_kmaddress,
.create_task_enumerator = _create_task_enumerator,
.other_auths = linked_list_create(),
.unique_id = ++unique_id,
.peer_addresses = linked_list_create(),
+ .my_vips = linked_list_create(),
+ .other_vips = linked_list_create(),
.attributes = linked_list_create(),
.keepalive_interval = lib->settings->get_time(lib->settings,
"%s.keep_alive", KEEPALIVE_INTERVAL, charon->name),
status_t (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
/**
- * Set the virtual IP to use for this IKE_SA and its children.
+ * Add a virtual IP to use for this IKE_SA and its children.
*
* The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
* lifetime as the IKE_SA.
* @param local TRUE to set local address, FALSE for remote
* @param ip IP to set as virtual IP
*/
- void (*set_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
+ void (*add_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
/**
- * Get the virtual IP configured.
+ * Create an enumerator over virtual IPs.
*
* @param local TRUE to get local virtual IP, FALSE for remote
- * @return host_t *virtual IP
+ * @return enumerator over host_t*
*/
- host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
+ enumerator_t* (*create_virtual_ip_enumerator) (ike_sa_t *this, bool local);
/**
* Register a configuration attribute to the IKE_SA.
return NULL;
}
+METHOD(phase1_t, has_virtual_ip, bool,
+ private_phase1_t *this, peer_cfg_t *peer_cfg)
+{
+ enumerator_t *enumerator;
+ bool found = FALSE;
+ host_t *host;
+
+ enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
+ found = enumerator->enumerate(enumerator, &host);
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
METHOD(phase1_t, save_sa_payload, bool,
private_phase1_t *this, message_t *message)
{
.get_auth_method = _get_auth_method,
.get_id = _get_id,
.select_config = _select_config,
+ .has_virtual_ip = _has_virtual_ip,
.verify_auth = _verify_auth,
.build_auth = _build_auth,
.save_sa_payload = _save_sa_payload,
*/
identification_t* (*get_id)(phase1_t *this, peer_cfg_t *peer_cfg, bool local);
+ /**
+ * Check if peer config has virtual IPs to request
+ *
+ * @param peer_cfg peer_config to check
+ * @return TRUE if peer config contains at least one virtual IP
+ */
+ bool (*has_virtual_ip)(phase1_t *this, peer_cfg_t *peer_cfg);
+
/**
* Extract and store SA payload bytes from encoded message.
*
*/
static bool mode_config_expected(private_task_manager_t *this)
{
+ enumerator_t *enumerator;
peer_cfg_t *peer_cfg;
+ host_t *host;
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg && peer_cfg->get_pool(peer_cfg))
{
- if (!this->ike_sa->get_virtual_ip(this->ike_sa, FALSE))
- {
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ FALSE);
+ if (!enumerator->enumerate(enumerator, &host))
+ { /* have a pool, but no VIP assigned yet */
+ enumerator->destroy(enumerator);
return TRUE;
}
+ enumerator->destroy(enumerator);
}
return FALSE;
}
new->set_other_host(new, host->clone(host));
host = this->ike_sa->get_my_host(this->ike_sa);
new->set_my_host(new, host->clone(host));
- host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (host)
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
{
- new->set_virtual_ip(new, TRUE, host);
+ new->add_virtual_ip(new, TRUE, host);
}
+ enumerator->destroy(enumerator);
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
while (enumerator->enumerate(enumerator, &child_sa))
}
break;
}
- if (this->peer_cfg->get_virtual_ip(this->peer_cfg))
+ if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
{
this->ike_sa->queue_task(this->ike_sa,
(task_t*)mode_config_create(this->ike_sa, TRUE));
break;
}
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
- this->peer_cfg->get_virtual_ip(this->peer_cfg))
+ this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
{
this->ike_sa->queue_task(this->ike_sa,
(task_t*)mode_config_create(this->ike_sa, TRUE));
break;
}
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
- this->peer_cfg->get_virtual_ip(this->peer_cfg))
+ this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
{
this->ike_sa->queue_task(this->ike_sa,
(task_t*)mode_config_create(this->ike_sa, TRUE));
}
break;
}
- if (this->peer_cfg->get_virtual_ip(this->peer_cfg))
+ if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
{
this->ike_sa->queue_task(this->ike_sa,
(task_t*)mode_config_create(this->ike_sa, TRUE));
host_t *vip;
/* reuse virtual IP if we already have one */
- vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (!vip)
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
+ if (!enumerator->enumerate(enumerator, &vip))
{
+ enumerator->destroy(enumerator);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- vip = config->get_virtual_ip(config);
+ enumerator = config->create_virtual_ip_enumerator(config);
+ if (!enumerator->enumerate(enumerator, &vip))
+ {
+ vip = NULL;
+ }
}
+ enumerator->destroy(enumerator);
+
if (vip)
{
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
if (vip)
{
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
- this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
+ this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, vip);
cp->add_attribute(cp, build_vip(vip));
}
else
if (this->virtual_ip)
{
- this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
+ this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
}
return SUCCESS;
}
linked_list_t *supplied)
{
traffic_selector_t *ts;
+ enumerator_t *enumerator;
linked_list_t *list;
host_t *host;
- host = this->ike_sa->get_virtual_ip(this->ike_sa, local);
- if (!host)
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, local);
+ if (!enumerator->enumerate(enumerator, &host))
{
if (local)
{
host = this->ike_sa->get_other_host(this->ike_sa);
}
}
+ enumerator->destroy(enumerator);
list = this->config->get_traffic_selectors(this->config, local,
supplied, host);
if (list->get_first(list, (void**)&ts) == SUCCESS)
enumerator->destroy(enumerator);
}
+/**
+ * Get host to use for dynamic traffic selectors
+ */
+static host_t *get_dynamic_host(ike_sa_t *ike_sa, bool local)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
+ if (!enumerator->enumerate(enumerator, &host))
+ {
+ if (local)
+ {
+ host = ike_sa->get_my_host(ike_sa);
+ }
+ else
+ {
+ host = ike_sa->get_other_host(ike_sa);
+ }
+ }
+ enumerator->destroy(enumerator);
+ return host;
+}
+
METHOD(task_t, process_r, status_t,
private_quick_mode_t *this, message_t *message)
{
sa_payload_t *sa_payload;
linked_list_t *tsi, *tsr, *list = NULL;
peer_cfg_t *peer_cfg;
- host_t *me, *other;
u_int16_t group;
bool private;
{
return FAILED;
}
- me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (!me)
- {
- me = this->ike_sa->get_my_host(this->ike_sa);
- }
- other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
- if (!other)
- {
- other = this->ike_sa->get_other_host(this->ike_sa);
- }
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
tsi = linked_list_create();
tsr = linked_list_create();
tsr->insert_last(tsr, this->tsr);
this->tsi = this->tsr = NULL;
this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
- me, other);
+ get_dynamic_host(this->ike_sa, TRUE),
+ get_dynamic_host(this->ike_sa, FALSE));
if (this->config)
{
this->tsi = select_ts(this, FALSE, tsi);
}
}
+/**
+ * Get host to use for dynamic traffic selectors
+ */
+static host_t *get_dynamic_host(ike_sa_t *ike_sa, bool local)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
+ if (!enumerator->enumerate(enumerator, &host))
+ {
+ if (local)
+ {
+ host = ike_sa->get_my_host(ike_sa);
+ }
+ else
+ {
+ host = ike_sa->get_other_host(ike_sa);
+ }
+ }
+ enumerator->destroy(enumerator);
+ return host;
+}
+
/**
* Install a CHILD_SA for usage, return value:
* - FAILED: no acceptable proposal
chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
linked_list_t *my_ts, *other_ts;
- host_t *me, *other, *other_vip, *my_vip;
+ host_t *me, *other;
bool private;
if (this->proposals == NULL)
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
- my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
this->proposal = this->config->select_proposal(this->config,
this->dh_group = MODP_NONE;
}
- if (my_vip == NULL)
- {
- my_vip = me;
- }
- if (other_vip == NULL)
- {
- other_vip = other;
- }
-
if (this->initiator)
{
nonce_i = this->my_nonce;
other_ts = this->tsi;
}
my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts,
- my_vip);
+ get_dynamic_host(this->ike_sa, TRUE));
other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts,
- other_vip);
+ get_dynamic_host(this->ike_sa, FALSE));
if (this->initiator)
{
METHOD(task_t, build_i, status_t,
private_child_create_t *this, message_t *message)
{
- host_t *me, *other, *vip;
+ enumerator_t *enumerator;
+ host_t *vip;
peer_cfg_t *peer_cfg;
switch (message->get_exchange_type(message))
this->config->get_name(this->config));
}
- /* reuse virtual IP if we already have one */
- me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (me == NULL)
- {
- me = this->ike_sa->get_my_host(this->ike_sa);
- }
- other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
- if (other == NULL)
- {
- other = this->ike_sa->get_other_host(this->ike_sa);
- }
-
/* check if we want a virtual IP, but don't have one */
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- vip = peer_cfg->get_virtual_ip(peer_cfg);
- if (!this->reqid && vip)
+ enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
+ if (!this->reqid && enumerator->enumerate(enumerator, &vip))
{
/* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
vip = host_create_any(vip->get_family(vip));
}
else
{ /* but narrow it for host2host / if we already have a vip */
- this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
- NULL, me);
+ this->tsi = this->config->get_traffic_selectors(this->config, TRUE, NULL,
+ get_dynamic_host(this->ike_sa, TRUE));
}
- this->tsr = this->config->get_traffic_selectors(this->config, FALSE,
- NULL, other);
+ enumerator->destroy(enumerator);
+ this->tsr = this->config->get_traffic_selectors(this->config, FALSE, NULL,
+ get_dynamic_host(this->ike_sa, FALSE));
if (this->packet_tsi)
{
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (!this->config && peer_cfg && this->tsi && this->tsr)
{
- host_t *me, *other;
-
- me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (me == NULL)
- {
- me = this->ike_sa->get_my_host(this->ike_sa);
- }
- other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
- if (other == NULL)
- {
- other = this->ike_sa->get_other_host(this->ike_sa);
- }
- this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
- this->tsi, me, other);
+ this->config = peer_cfg->select_child_cfg(peer_cfg,
+ this->tsr, this->tsi,
+ get_dynamic_host(this->ike_sa, TRUE),
+ get_dynamic_host(this->ike_sa, FALSE));
}
if (this->config == NULL)
host_t *vip;
/* reuse virtual IP if we already have one */
- vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (!vip)
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ TRUE);
+ if (!enumerator->enumerate(enumerator, &vip))
{
+ enumerator->destroy(enumerator);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- vip = config->get_virtual_ip(config);
+ enumerator = config->create_virtual_ip_enumerator(config);
+ if (!enumerator->enumerate(enumerator, &vip))
+ {
+ vip = NULL;
+ }
}
+ enumerator->destroy(enumerator);
if (vip)
{
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
return SUCCESS;
}
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
- this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
+ this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, vip);
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
cp->add_attribute(cp, build_vip(vip));
if (this->virtual_ip &&
!this->virtual_ip->is_anyaddr(this->virtual_ip))
{
- this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
+ this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
}
return SUCCESS;
}
{
enumerator_t *enumerator;
child_sa_t *child_sa;
+ linked_list_t *vips;
+ host_t *host;
+
+ vips = linked_list_create();
+
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ vips->insert_last(vips, host);
+ }
+ enumerator->destroy(enumerator);
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->update(child_sa,
this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
- this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
+ this->ike_sa->get_other_host(this->ike_sa), vips,
+ this->ike_sa->has_condition(this->ike_sa,
+ COND_NAT_ANY)) == NOT_SUPPORTED)
{
this->ike_sa->rekey_child_sa(this->ike_sa,
child_sa->get_protocol(child_sa),
}
}
enumerator->destroy(enumerator);
+
+ vips->destroy(vips);
}
/**