summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev1/tasks/mode_config.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-04-11 22:03:59 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-04-11 22:30:17 +0200
commit8404fb0212f9fb77bc53b23004b829b488430700 (patch)
tree23876c7540d138f58a6a7d90793ccf9004f6afd2 /src/libcharon/sa/ikev1/tasks/mode_config.c
parent1b7c683a32c62b6e08ad7bf5af39b9f4edd634f3 (diff)
downloadvyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.tar.gz
vyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.zip
Imported Upstream version 5.3.0
Diffstat (limited to 'src/libcharon/sa/ikev1/tasks/mode_config.c')
-rw-r--r--src/libcharon/sa/ikev1/tasks/mode_config.c137
1 files changed, 94 insertions, 43 deletions
diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c
index 94026b9af..d0994a961 100644
--- a/src/libcharon/sa/ikev1/tasks/mode_config.c
+++ b/src/libcharon/sa/ikev1/tasks/mode_config.c
@@ -16,7 +16,6 @@
#include "mode_config.h"
#include <daemon.h>
-#include <hydra.h>
#include <encoding/payloads/cp_payload.h>
typedef struct private_mode_config_t private_mode_config_t;
@@ -136,9 +135,8 @@ static void handle_attribute(private_mode_config_t *this,
enumerator->destroy(enumerator);
/* and pass it to the handle function */
- handler = hydra->attributes->handle(hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), handler,
- ca->get_type(ca), ca->get_chunk(ca));
+ handler = charon->attributes->handle(charon->attributes,
+ this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca));
this->ike_sa->add_configuration_attribute(this->ike_sa,
handler, ca->get_type(ca), ca->get_chunk(ca));
}
@@ -326,9 +324,8 @@ static status_t build_request(private_mode_config_t *this, message_t *message)
enumerator->destroy(enumerator);
}
- enumerator = hydra->attributes->create_initiator_enumerator(
- hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), vips);
+ enumerator = charon->attributes->create_initiator_enumerator(
+ charon->attributes, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &handler, &type, &data))
{
add_attribute(this, cp, type, data, handler);
@@ -353,7 +350,7 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
cp_payload_t *cp;
peer_cfg_t *config;
identification_t *id;
- linked_list_t *pools;
+ linked_list_t *pools, *migrated, *vips;
host_t *any4, *any6, *found;
char *name;
@@ -361,45 +358,62 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- any4 = host_create_any(AF_INET);
- any6 = host_create_any(AF_INET6);
+ /* if we migrated virtual IPs during reauthentication, reassign them */
+ migrated = linked_list_create_from_enumerator(
+ this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ FALSE));
+ vips = migrated->clone_offset(migrated, offsetof(host_t, clone));
+ migrated->destroy(migrated);
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
/* in push mode, we ask each configured pool for an address */
- enumerator = config->create_pool_enumerator(config);
- while (enumerator->enumerate(enumerator, &name))
+ if (!vips->get_count(vips))
{
- pools = linked_list_create_with_items(name, NULL);
- /* try IPv4, then IPv6 */
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, any4);
- if (!found)
- {
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, any6);
- }
- pools->destroy(pools);
- if (found)
+ any4 = host_create_any(AF_INET);
+ any6 = host_create_any(AF_INET6);
+ enumerator = config->create_pool_enumerator(config);
+ while (enumerator->enumerate(enumerator, &name))
{
- DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
- this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
- cp->add_attribute(cp, build_vip(found));
- this->vips->insert_last(this->vips, found);
+ pools = linked_list_create_with_items(name, NULL);
+ /* try IPv4, then IPv6 */
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, any4);
+ if (!found)
+ {
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, any6);
+ }
+ pools->destroy(pools);
+ if (found)
+ {
+ vips->insert_last(vips, found);
+ }
}
+ enumerator->destroy(enumerator);
+ any4->destroy(any4);
+ any6->destroy(any6);
}
- enumerator->destroy(enumerator);
- any4->destroy(any4);
- any6->destroy(any6);
+ enumerator = vips->create_enumerator(vips);
+ while (enumerator->enumerate(enumerator, &found))
+ {
+ DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
+ this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
+ cp->add_attribute(cp, build_vip(found));
+ this->vips->insert_last(this->vips, found);
+ vips->remove_at(vips, enumerator);
+ }
+ enumerator->destroy(enumerator);
+ vips->destroy(vips);
charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
/* query registered providers for additional attributes to include */
pools = linked_list_create_from_enumerator(
config->create_pool_enumerator(config));
- enumerator = hydra->attributes->create_responder_enumerator(
- hydra->attributes, pools, id, this->vips);
+ enumerator = charon->attributes->create_responder_enumerator(
+ charon->attributes, pools, this->ike_sa, this->vips);
while (enumerator->enumerate(enumerator, &type, &value))
{
add_attribute(this, cp, type, value, NULL);
@@ -458,6 +472,28 @@ METHOD(task_t, process_r, status_t,
}
/**
+ * Assign a migrated virtual IP
+ */
+static host_t *assign_migrated_vip(linked_list_t *migrated, host_t *requested)
+{
+ enumerator_t *enumerator;
+ host_t *found = NULL, *vip;
+
+ enumerator = migrated->create_enumerator(migrated);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ if (vip->ip_equals(vip, requested))
+ {
+ migrated->remove_at(migrated, enumerator);
+ found = vip;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
* Build CFG_REPLY message after receiving CFG_REQUEST
*/
static status_t build_reply(private_mode_config_t *this, message_t *message)
@@ -468,29 +504,35 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
cp_payload_t *cp;
peer_cfg_t *config;
identification_t *id;
- linked_list_t *vips, *pools;
- host_t *requested;
+ linked_list_t *vips, *pools, *migrated;
+ host_t *requested, *found;
cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- vips = linked_list_create();
pools = linked_list_create_from_enumerator(
config->create_pool_enumerator(config));
-
+ /* if we migrated virtual IPs during reauthentication, reassign them */
+ vips = linked_list_create_from_enumerator(
+ this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ FALSE));
+ migrated = vips->clone_offset(vips, offsetof(host_t, clone));
+ vips->destroy(vips);
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+ vips = linked_list_create();
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
- host_t *found = NULL;
-
- /* query all pools until we get an address */
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, requested);
+ found = assign_migrated_vip(migrated, requested);
+ if (!found)
+ {
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, requested);
+ }
if (found)
{
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
@@ -509,8 +551,8 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
/* query registered providers for additional attributes to include */
- enumerator = hydra->attributes->create_responder_enumerator(
- hydra->attributes, pools, id, vips);
+ enumerator = charon->attributes->create_responder_enumerator(
+ charon->attributes, pools, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &type, &value))
{
cp->add_attribute(cp,
@@ -518,6 +560,15 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
type, value));
}
enumerator->destroy(enumerator);
+ /* if a client did not re-request all adresses, release them */
+ enumerator = migrated->create_enumerator(migrated);
+ while (enumerator->enumerate(enumerator, &found))
+ {
+ charon->attributes->release_address(charon->attributes,
+ pools, found, this->ike_sa);
+ }
+ enumerator->destroy(enumerator);
+ migrated->destroy_offset(migrated, offsetof(host_t, destroy));
vips->destroy_offset(vips, offsetof(host_t, destroy));
pools->destroy(pools);