Merge branch 'multi-vip'
Brings support for multiple virtual IPs and multiple pools in left/rigthsourceip definitions. Also introduces the new left/rightdns options to configure requested DNS server address family and respond with multiple connection specific servers.
This commit is contained in:
@@ -819,9 +819,18 @@ METHOD(child_sa_t, add_policies, status_t,
|
||||
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;
|
||||
@@ -927,13 +936,7 @@ METHOD(child_sa_t, update, status_t,
|
||||
|
||||
/* 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,
|
||||
|
||||
@@ -346,12 +346,12 @@ struct child_sa_t {
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
||||
+52
-48
@@ -182,14 +182,14 @@ struct private_ike_sa_t {
|
||||
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)
|
||||
@@ -735,7 +735,7 @@ METHOD(ike_sa_t, get_keymat, keymat_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)
|
||||
@@ -744,39 +744,27 @@ METHOD(ike_sa_t, set_virtual_ip, void,
|
||||
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,
|
||||
@@ -909,7 +897,7 @@ METHOD(ike_sa_t, update_hosts, 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,
|
||||
@@ -1458,7 +1446,7 @@ METHOD(ike_sa_t, reauth, status_t,
|
||||
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
|
||||
@@ -1562,7 +1550,7 @@ METHOD(ike_sa_t, reestablish, status_t,
|
||||
|
||||
/* 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
|
||||
@@ -1585,11 +1573,12 @@ METHOD(ike_sa_t, reestablish, status_t,
|
||||
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))
|
||||
@@ -1732,7 +1721,7 @@ METHOD(ike_sa_t, set_auth_lifetime, status_t,
|
||||
* 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)
|
||||
@@ -1937,6 +1926,7 @@ METHOD(ike_sa_t, inherit, void,
|
||||
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);
|
||||
@@ -1948,16 +1938,15 @@ METHOD(ike_sa_t, inherit, void,
|
||||
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 */
|
||||
@@ -2032,6 +2021,7 @@ METHOD(ike_sa_t, destroy, void,
|
||||
private_ike_sa_t *this)
|
||||
{
|
||||
attribute_entry_t *entry;
|
||||
host_t *vip;
|
||||
|
||||
charon->bus->set_sa(charon->bus, &this->public);
|
||||
|
||||
@@ -2056,22 +2046,34 @@ METHOD(ike_sa_t, destroy, void,
|
||||
|
||||
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))
|
||||
if (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));
|
||||
enumerator_t *enumerator;
|
||||
char *pool;
|
||||
|
||||
enumerator = this->peer_cfg->create_pool_enumerator(this->peer_cfg);
|
||||
while (enumerator->enumerate(enumerator, &pool))
|
||||
{
|
||||
if (hydra->attributes->release_address(hydra->attributes, pool,
|
||||
vip, get_other_eap_id(this)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
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
|
||||
@@ -2190,8 +2192,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
||||
.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,
|
||||
@@ -2226,6 +2228,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
||||
.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),
|
||||
|
||||
@@ -931,7 +931,7 @@ struct ike_sa_t {
|
||||
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.
|
||||
@@ -939,15 +939,15 @@ struct ike_sa_t {
|
||||
* @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.
|
||||
|
||||
@@ -609,6 +609,34 @@ METHOD(phase1_t, get_id, identification_t*,
|
||||
return id;
|
||||
}
|
||||
|
||||
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, has_pool, bool,
|
||||
private_phase1_t *this, peer_cfg_t *peer_cfg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool found = FALSE;
|
||||
char *pool;
|
||||
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
found = enumerator->enumerate(enumerator, &pool);
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(phase1_t, save_sa_payload, bool,
|
||||
private_phase1_t *this, message_t *message)
|
||||
{
|
||||
@@ -748,6 +776,8 @@ phase1_t *phase1_create(ike_sa_t *ike_sa, bool initiator)
|
||||
.get_auth_method = _get_auth_method,
|
||||
.get_id = _get_id,
|
||||
.select_config = _select_config,
|
||||
.has_virtual_ip = _has_virtual_ip,
|
||||
.has_pool = _has_pool,
|
||||
.verify_auth = _verify_auth,
|
||||
.build_auth = _build_auth,
|
||||
.save_sa_payload = _save_sa_payload,
|
||||
|
||||
@@ -108,6 +108,22 @@ struct phase1_t {
|
||||
*/
|
||||
identification_t* (*get_id)(phase1_t *this, peer_cfg_t *peer_cfg, bool local);
|
||||
|
||||
/**
|
||||
* Check if peer config has virtual IPs pool assigned.
|
||||
*
|
||||
* @param peer_cfg peer_config to check
|
||||
* @return TRUE if peer config contains at least one pool
|
||||
*/
|
||||
bool (*has_pool)(phase1_t *this, peer_cfg_t *peer_cfg);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -346,15 +346,30 @@ METHOD(task_manager_t, retransmit, status_t,
|
||||
*/
|
||||
static bool mode_config_expected(private_task_manager_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
peer_cfg_t *peer_cfg;
|
||||
char *pool;
|
||||
host_t *host;
|
||||
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (peer_cfg && peer_cfg->get_pool(peer_cfg))
|
||||
if (peer_cfg)
|
||||
{
|
||||
if (!this->ike_sa->get_virtual_ip(this->ike_sa, FALSE))
|
||||
{
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
if (!enumerator->enumerate(enumerator, &pool))
|
||||
{ /* no pool configured */
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1309,11 +1324,12 @@ METHOD(task_manager_t, queue_ike_reauth, void,
|
||||
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))
|
||||
|
||||
@@ -320,7 +320,7 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
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));
|
||||
@@ -497,8 +497,8 @@ METHOD(task_t, process_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
|
||||
this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (!this->ph1->has_pool(this->ph1, 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));
|
||||
|
||||
@@ -524,8 +524,8 @@ METHOD(task_t, build_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
|
||||
this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (!this->ph1->has_pool(this->ph1, 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));
|
||||
@@ -658,7 +658,7 @@ METHOD(task_t, process_i, status_t,
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -42,9 +42,9 @@ struct private_mode_config_t {
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* virtual ip
|
||||
* Received list of virtual IPs, host_t*
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
@@ -174,8 +174,7 @@ static void process_attribute(private_mode_config_t *this,
|
||||
}
|
||||
if (ip)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->virtual_ip = ip;
|
||||
this->vips->insert_last(this->vips, ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -239,23 +238,44 @@ METHOD(task_t, build_i, status_t,
|
||||
peer_cfg_t *config;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t data;
|
||||
host_t *vip;
|
||||
linked_list_t *vips;
|
||||
host_t *host;
|
||||
|
||||
vips = linked_list_create();
|
||||
|
||||
/* 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);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (vips->get_count(vips) == 0)
|
||||
{
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
vip = config->get_virtual_ip(config);
|
||||
}
|
||||
if (vip)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = config->create_virtual_ip_enumerator(config);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
|
||||
enumerator = vips->create_enumerator(vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
cp->add_attribute(cp, build_vip(host));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(
|
||||
hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vips);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
@@ -279,6 +299,8 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
@@ -299,37 +321,64 @@ METHOD(task_t, build_r, status_t,
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
host_t *vip = NULL;
|
||||
cp_payload_t *cp = NULL;
|
||||
peer_cfg_t *config;
|
||||
identification_t *id;
|
||||
linked_list_t *vips, *pools;
|
||||
host_t *requested;
|
||||
|
||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (this->virtual_ip)
|
||||
vips = linked_list_create();
|
||||
pools = linked_list_create();
|
||||
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &requested))
|
||||
{
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||
if (config->get_pool(config))
|
||||
enumerator_t *poolenum;
|
||||
char *pool;
|
||||
host_t *found = NULL;
|
||||
|
||||
/* query all pools until we get an address */
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
|
||||
|
||||
poolenum = config->create_pool_enumerator(config);
|
||||
while (poolenum->enumerate(poolenum, &pool))
|
||||
{
|
||||
vip = hydra->attributes->acquire_address(hydra->attributes,
|
||||
config->get_pool(config), id, this->virtual_ip);
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pool, id, requested);
|
||||
if (!found)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
|
||||
if (!cp)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
|
||||
}
|
||||
cp->add_attribute(cp, build_vip(found));
|
||||
/* use pool to request other attributes */
|
||||
if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
|
||||
{
|
||||
pools->insert_last(pools, pool);
|
||||
}
|
||||
vips->insert_last(vips, found);
|
||||
break;
|
||||
}
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
|
||||
if (vip)
|
||||
poolenum->destroy(poolenum);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending empty config payload");
|
||||
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
|
||||
requested, id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* query registered providers for additional attributes to include */
|
||||
enumerator = hydra->attributes->create_responder_enumerator(
|
||||
hydra->attributes, config->get_pool(config), id, vip);
|
||||
hydra->attributes, pools, id, vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (!cp)
|
||||
@@ -343,25 +392,35 @@ METHOD(task_t, build_r, status_t,
|
||||
type, value));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
cp->set_identifier(cp, this->identifier);
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
DESTROY_IF(vip);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(task_t, process_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->virtual_ip)
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
||||
if (!host->is_anyaddr(host))
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -374,10 +433,9 @@ METHOD(task_t, get_type, task_type_t,
|
||||
METHOD(task_t, migrate, void,
|
||||
private_mode_config_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->vips = linked_list_create();
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
}
|
||||
@@ -385,7 +443,7 @@ METHOD(task_t, migrate, void,
|
||||
METHOD(task_t, destroy, void,
|
||||
private_mode_config_t *this)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
free(this);
|
||||
}
|
||||
@@ -408,6 +466,7 @@ mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
.initiator = initiator,
|
||||
.ike_sa = ike_sa,
|
||||
.requested = linked_list_create(),
|
||||
.vips = linked_list_create(),
|
||||
);
|
||||
|
||||
if (initiator)
|
||||
|
||||
@@ -398,11 +398,12 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
|
||||
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)
|
||||
{
|
||||
@@ -413,6 +414,7 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool 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)
|
||||
@@ -831,6 +833,30 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
|
||||
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)
|
||||
{
|
||||
@@ -841,7 +867,6 @@ METHOD(task_t, process_r, status_t,
|
||||
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;
|
||||
|
||||
@@ -849,16 +874,6 @@ METHOD(task_t, process_r, status_t,
|
||||
{
|
||||
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();
|
||||
@@ -866,7 +881,8 @@ METHOD(task_t, process_r, status_t,
|
||||
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);
|
||||
|
||||
@@ -284,6 +284,30 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -298,7 +322,7 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
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)
|
||||
@@ -314,8 +338,6 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
|
||||
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,
|
||||
@@ -354,15 +376,6 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
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;
|
||||
@@ -378,9 +391,9 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
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)
|
||||
{
|
||||
@@ -723,7 +736,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
|
||||
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))
|
||||
@@ -763,22 +777,10 @@ METHOD(task_t, build_i, status_t,
|
||||
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));
|
||||
@@ -788,11 +790,12 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -948,20 +951,10 @@ METHOD(task_t, build_r, status_t,
|
||||
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)
|
||||
|
||||
@@ -43,9 +43,9 @@ struct private_ike_config_t {
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* virtual ip
|
||||
* Received list of virtual IPs, host_t*
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
@@ -170,8 +170,7 @@ static void process_attribute(private_ike_config_t *this,
|
||||
}
|
||||
if (ip)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->virtual_ip = ip;
|
||||
this->vips->insert_last(this->vips, ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -242,23 +241,45 @@ METHOD(task_t, build_i, status_t,
|
||||
peer_cfg_t *config;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t data;
|
||||
host_t *vip;
|
||||
linked_list_t *vips;
|
||||
host_t *host;
|
||||
|
||||
vips = linked_list_create();
|
||||
|
||||
/* 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);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (vips->get_count(vips) == 0)
|
||||
{
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
vip = config->get_virtual_ip(config);
|
||||
}
|
||||
if (vip)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = config->create_virtual_ip_enumerator(config);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
|
||||
enumerator = vips->create_enumerator(vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
cp->add_attribute(cp, build_vip(host));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(
|
||||
hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vips);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
@@ -284,6 +305,8 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
@@ -310,40 +333,75 @@ METHOD(task_t, build_r, status_t,
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
host_t *vip = NULL;
|
||||
cp_payload_t *cp = NULL;
|
||||
peer_cfg_t *config;
|
||||
identification_t *id;
|
||||
linked_list_t *vips, *pools;
|
||||
host_t *requested;
|
||||
|
||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (this->virtual_ip)
|
||||
{
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||
if (config->get_pool(config))
|
||||
{
|
||||
vip = hydra->attributes->acquire_address(hydra->attributes,
|
||||
config->get_pool(config), id, this->virtual_ip);
|
||||
}
|
||||
if (vip == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending %N",
|
||||
notify_type_names, INTERNAL_ADDRESS_FAILURE);
|
||||
message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
|
||||
chunk_empty);
|
||||
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);
|
||||
vips = linked_list_create();
|
||||
pools = linked_list_create();
|
||||
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &requested))
|
||||
{
|
||||
enumerator_t *poolenum;
|
||||
char *pool;
|
||||
host_t *found = NULL;
|
||||
|
||||
/* query all pools until we get an address */
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
|
||||
|
||||
poolenum = config->create_pool_enumerator(config);
|
||||
while (poolenum->enumerate(poolenum, &pool))
|
||||
{
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pool, id, requested);
|
||||
if (!found)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
|
||||
if (!cp)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
|
||||
}
|
||||
cp->add_attribute(cp, build_vip(found));
|
||||
/* use pool to request other attributes */
|
||||
if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
|
||||
{
|
||||
pools->insert_last(pools, pool);
|
||||
}
|
||||
vips->insert_last(vips, found);
|
||||
break;
|
||||
}
|
||||
poolenum->destroy(poolenum);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
|
||||
requested, id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (this->vips->get_count(this->vips) && !vips->get_count(vips))
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending %N",
|
||||
notify_type_names, INTERNAL_ADDRESS_FAILURE);
|
||||
message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
|
||||
chunk_empty);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
pools->destroy(pools);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* query registered providers for additional attributes to include */
|
||||
enumerator = hydra->attributes->create_responder_enumerator(
|
||||
hydra->attributes, config->get_pool(config), id, vip);
|
||||
hydra->attributes, pools, id, vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (!cp)
|
||||
@@ -357,12 +415,13 @@ METHOD(task_t, build_r, status_t,
|
||||
type, value));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
pools->destroy(pools);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
DESTROY_IF(vip);
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -373,14 +432,20 @@ METHOD(task_t, process_i, status_t,
|
||||
{
|
||||
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
|
||||
{ /* in last IKE_AUTH exchange */
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->virtual_ip &&
|
||||
!this->virtual_ip->is_anyaddr(this->virtual_ip))
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
||||
if (!host->is_anyaddr(host))
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -395,10 +460,9 @@ METHOD(task_t, get_type, task_type_t,
|
||||
METHOD(task_t, migrate, void,
|
||||
private_ike_config_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->vips = linked_list_create();
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
}
|
||||
@@ -406,7 +470,7 @@ METHOD(task_t, migrate, void,
|
||||
METHOD(task_t, destroy, void,
|
||||
private_ike_config_t *this)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
free(this);
|
||||
}
|
||||
@@ -428,6 +492,7 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
},
|
||||
.initiator = initiator,
|
||||
.ike_sa = ike_sa,
|
||||
.vips = linked_list_create(),
|
||||
.requested = linked_list_create(),
|
||||
);
|
||||
|
||||
|
||||
@@ -250,15 +250,26 @@ static void update_children(private_ike_mobike_t *this)
|
||||
{
|
||||
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),
|
||||
@@ -266,6 +277,8 @@ static void update_children(private_ike_mobike_t *this)
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user