ike-sa: use arrays instead of linked lists in long lived collections

This saves about 1.5KB of memory per IKE_SA.
This commit is contained in:
Martin Willi 2013-07-11 15:58:15 +02:00
parent 4730c4b32b
commit 893da0411f
1 changed files with 103 additions and 121 deletions

View File

@ -26,7 +26,7 @@
#include <library.h> #include <library.h>
#include <hydra.h> #include <hydra.h>
#include <daemon.h> #include <daemon.h>
#include <collections/linked_list.h> #include <collections/array.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <processing/jobs/retransmit_job.h> #include <processing/jobs/retransmit_job.h>
#include <processing/jobs/delete_ike_sa_job.h> #include <processing/jobs/delete_ike_sa_job.h>
@ -95,25 +95,25 @@ struct private_ike_sa_t {
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
/** /**
* currently used authentication ruleset, local (as auth_cfg_t) * currently used authentication ruleset, local
*/ */
auth_cfg_t *my_auth; auth_cfg_t *my_auth;
/** /**
* list of completed local authentication rounds * currently used authentication constraints, remote
*/
linked_list_t *my_auths;
/**
* list of completed remote authentication rounds
*/
linked_list_t *other_auths;
/**
* currently used authentication constraints, remote (as auth_cfg_t)
*/ */
auth_cfg_t *other_auth; auth_cfg_t *other_auth;
/**
* Array of completed local authentication rounds (as auth_cfg_t)
*/
array_t *my_auths;
/**
* Array of completed remote authentication rounds (as auth_cfg_t)
*/
array_t *other_auths;
/** /**
* Selected IKE proposal * Selected IKE proposal
*/ */
@ -172,9 +172,9 @@ struct private_ike_sa_t {
ike_condition_t conditions; ike_condition_t conditions;
/** /**
* Linked List containing the child sa's of the current IKE_SA. * Array containing the child sa's of the current IKE_SA.
*/ */
linked_list_t *child_sas; array_t *child_sas;
/** /**
* keymat of this IKE_SA * keymat of this IKE_SA
@ -184,22 +184,22 @@ struct private_ike_sa_t {
/** /**
* Virtual IPs on local host * Virtual IPs on local host
*/ */
linked_list_t *my_vips; array_t *my_vips;
/** /**
* Virtual IPs on remote host * Virtual IPs on remote host
*/ */
linked_list_t *other_vips; array_t *other_vips;
/** /**
* List of configuration attributes (attribute_entry_t) * List of configuration attributes (attribute_entry_t)
*/ */
linked_list_t *attributes; array_t *attributes;
/** /**
* list of peer's addresses, additional ones transmitted via MOBIKE * list of peer's addresses, additional ones transmitted via MOBIKE
*/ */
linked_list_t *peer_addresses; array_t *peer_addresses;
/** /**
* previously value of received DESTINATION_IP hash * previously value of received DESTINATION_IP hash
@ -282,7 +282,8 @@ static time_t get_use_time(private_ike_sa_t* this, bool inbound)
{ {
use_time = this->stats[STAT_OUTBOUND]; use_time = this->stats[STAT_OUTBOUND];
} }
enumerator = this->child_sas->create_enumerator(this->child_sas);
enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, &child_sa)) while (enumerator->enumerate(enumerator, &child_sa))
{ {
child_sa->get_usestats(child_sa, inbound, &current, NULL, NULL); child_sa->get_usestats(child_sa, inbound, &current, NULL, NULL);
@ -389,11 +390,11 @@ METHOD(ike_sa_t, add_auth_cfg, void,
{ {
if (local) if (local)
{ {
this->my_auths->insert_last(this->my_auths, cfg); array_insert(this->my_auths, ARRAY_TAIL, cfg);
} }
else else
{ {
this->other_auths->insert_last(this->other_auths, cfg); array_insert(this->other_auths, ARRAY_TAIL, cfg);
} }
} }
@ -402,9 +403,9 @@ METHOD(ike_sa_t, create_auth_cfg_enumerator, enumerator_t*,
{ {
if (local) if (local)
{ {
return this->my_auths->create_enumerator(this->my_auths); return array_create_enumerator(this->my_auths);
} }
return this->other_auths->create_enumerator(this->other_auths); return array_create_enumerator(this->other_auths);
} }
/** /**
@ -417,13 +418,11 @@ static void flush_auth_cfgs(private_ike_sa_t *this)
this->my_auth->purge(this->my_auth, FALSE); this->my_auth->purge(this->my_auth, FALSE);
this->other_auth->purge(this->other_auth, FALSE); this->other_auth->purge(this->other_auth, FALSE);
while (this->my_auths->remove_last(this->my_auths, while (array_remove(this->my_auths, ARRAY_TAIL, &cfg))
(void**)&cfg) == SUCCESS)
{ {
cfg->destroy(cfg); cfg->destroy(cfg);
} }
while (this->other_auths->remove_last(this->other_auths, while (array_remove(this->other_auths, ARRAY_TAIL, &cfg))
(void**)&cfg) == SUCCESS)
{ {
cfg->destroy(cfg); cfg->destroy(cfg);
} }
@ -750,7 +749,7 @@ METHOD(ike_sa_t, add_virtual_ip, void,
if (hydra->kernel_interface->add_ip(hydra->kernel_interface, if (hydra->kernel_interface->add_ip(hydra->kernel_interface,
ip, -1, iface) == SUCCESS) ip, -1, iface) == SUCCESS)
{ {
this->my_vips->insert_last(this->my_vips, ip->clone(ip)); array_insert_create(&this->my_vips, ARRAY_TAIL, ip->clone(ip));
} }
else else
{ {
@ -765,7 +764,7 @@ METHOD(ike_sa_t, add_virtual_ip, void,
} }
else else
{ {
this->other_vips->insert_last(this->other_vips, ip->clone(ip)); array_insert_create(&this->other_vips, ARRAY_TAIL, ip->clone(ip));
} }
} }
@ -773,14 +772,15 @@ METHOD(ike_sa_t, add_virtual_ip, void,
METHOD(ike_sa_t, clear_virtual_ips, void, METHOD(ike_sa_t, clear_virtual_ips, void,
private_ike_sa_t *this, bool local) private_ike_sa_t *this, bool local)
{ {
linked_list_t *vips = local ? this->my_vips : this->other_vips; array_t *vips;
host_t *vip; host_t *vip;
if (!local && vips->get_count(vips)) vips = local ? this->my_vips : this->other_vips;
if (!local && array_count(vips))
{ {
charon->bus->assign_vips(charon->bus, &this->public, FALSE); charon->bus->assign_vips(charon->bus, &this->public, FALSE);
} }
while (vips->remove_first(vips, (void**)&vip) == SUCCESS) while (array_remove(vips, ARRAY_HEAD, &vip))
{ {
if (local) if (local)
{ {
@ -796,23 +796,23 @@ METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
{ {
if (local) if (local)
{ {
return this->my_vips->create_enumerator(this->my_vips); return array_create_enumerator(this->my_vips);
} }
return this->other_vips->create_enumerator(this->other_vips); return array_create_enumerator(this->other_vips);
} }
METHOD(ike_sa_t, add_peer_address, void, METHOD(ike_sa_t, add_peer_address, void,
private_ike_sa_t *this, host_t *host) private_ike_sa_t *this, host_t *host)
{ {
this->peer_addresses->insert_last(this->peer_addresses, host); array_insert_create(&this->peer_addresses, ARRAY_TAIL, host);
} }
METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*, METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
private_ike_sa_t *this) private_ike_sa_t *this)
{ {
if (this->peer_addresses->get_count(this->peer_addresses)) if (this->peer_addresses)
{ {
return this->peer_addresses->create_enumerator(this->peer_addresses); return array_create_enumerator(this->peer_addresses);
} }
/* in case we don't have MOBIKE */ /* in case we don't have MOBIKE */
return enumerator_create_single(this->other_host, NULL); return enumerator_create_single(this->other_host, NULL);
@ -821,17 +821,8 @@ METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
METHOD(ike_sa_t, clear_peer_addresses, void, METHOD(ike_sa_t, clear_peer_addresses, void,
private_ike_sa_t *this) private_ike_sa_t *this)
{ {
enumerator_t *enumerator; array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
host_t *host; this->peer_addresses = NULL;
enumerator = this->peer_addresses->create_enumerator(this->peer_addresses);
while (enumerator->enumerate(enumerator, (void**)&host))
{
this->peer_addresses->remove_at(this->peer_addresses,
enumerator);
host->destroy(host);
}
enumerator->destroy(enumerator);
} }
METHOD(ike_sa_t, has_mapping_changed, bool, METHOD(ike_sa_t, has_mapping_changed, bool,
@ -927,13 +918,16 @@ METHOD(ike_sa_t, update_hosts, void,
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
child_sa_t *child_sa; child_sa_t *child_sa;
linked_list_t *vips;
enumerator = this->child_sas->create_enumerator(this->child_sas); vips = linked_list_create_from_enumerator(
while (enumerator->enumerate(enumerator, (void**)&child_sa)) array_create_enumerator(this->my_vips));
enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, &child_sa))
{ {
if (child_sa->update(child_sa, this->my_host, if (child_sa->update(child_sa, this->my_host, this->other_host,
this->other_host, this->my_vips, vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
{ {
this->public.rekey_child_sa(&this->public, this->public.rekey_child_sa(&this->public,
child_sa->get_protocol(child_sa), child_sa->get_protocol(child_sa),
@ -941,6 +935,8 @@ METHOD(ike_sa_t, update_hosts, void,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
vips->destroy(vips);
} }
} }
@ -1326,7 +1322,7 @@ METHOD(ike_sa_t, get_other_eap_id, identification_t*,
enumerator_t *enumerator; enumerator_t *enumerator;
auth_cfg_t *cfg; auth_cfg_t *cfg;
enumerator = this->other_auths->create_enumerator(this->other_auths); enumerator = array_create_enumerator(this->other_auths);
while (enumerator->enumerate(enumerator, &cfg)) while (enumerator->enumerate(enumerator, &cfg))
{ {
/* prefer EAP-Identity of last round */ /* prefer EAP-Identity of last round */
@ -1363,7 +1359,7 @@ METHOD(ike_sa_t, set_other_id, void,
METHOD(ike_sa_t, add_child_sa, void, METHOD(ike_sa_t, add_child_sa, void,
private_ike_sa_t *this, child_sa_t *child_sa) private_ike_sa_t *this, child_sa_t *child_sa)
{ {
this->child_sas->insert_last(this->child_sas, child_sa); array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
} }
METHOD(ike_sa_t, get_child_sa, child_sa_t*, METHOD(ike_sa_t, get_child_sa, child_sa_t*,
@ -1372,7 +1368,7 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*,
enumerator_t *enumerator; enumerator_t *enumerator;
child_sa_t *current, *found = NULL; child_sa_t *current, *found = NULL;
enumerator = this->child_sas->create_enumerator(this->child_sas); enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, (void**)&current)) while (enumerator->enumerate(enumerator, (void**)&current))
{ {
if (current->get_spi(current, inbound) == spi && if (current->get_spi(current, inbound) == spi &&
@ -1388,19 +1384,19 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*,
METHOD(ike_sa_t, get_child_count, int, METHOD(ike_sa_t, get_child_count, int,
private_ike_sa_t *this) private_ike_sa_t *this)
{ {
return this->child_sas->get_count(this->child_sas); return array_count(this->child_sas);
} }
METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
private_ike_sa_t *this) private_ike_sa_t *this)
{ {
return this->child_sas->create_enumerator(this->child_sas); return array_create_enumerator(this->child_sas);
} }
METHOD(ike_sa_t, remove_child_sa, void, METHOD(ike_sa_t, remove_child_sa, void,
private_ike_sa_t *this, enumerator_t *enumerator) private_ike_sa_t *this, enumerator_t *enumerator)
{ {
this->child_sas->remove_at(this->child_sas, enumerator); array_remove_at(this->child_sas, enumerator);
} }
METHOD(ike_sa_t, rekey_child_sa, status_t, METHOD(ike_sa_t, rekey_child_sa, status_t,
@ -1433,13 +1429,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t,
child_sa_t *child_sa; child_sa_t *child_sa;
status_t status = NOT_FOUND; status_t status = NOT_FOUND;
enumerator = this->child_sas->create_enumerator(this->child_sas); enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, (void**)&child_sa)) while (enumerator->enumerate(enumerator, (void**)&child_sa))
{ {
if (child_sa->get_protocol(child_sa) == protocol && if (child_sa->get_protocol(child_sa) == protocol &&
child_sa->get_spi(child_sa, TRUE) == spi) child_sa->get_spi(child_sa, TRUE) == spi)
{ {
this->child_sas->remove_at(this->child_sas, enumerator); array_remove_at(this->child_sas, enumerator);
child_sa->destroy(child_sa); child_sa->destroy(child_sa);
status = SUCCESS; status = SUCCESS;
break; break;
@ -1506,7 +1502,7 @@ METHOD(ike_sa_t, reauth, status_t,
if (!has_condition(this, COND_ORIGINAL_INITIATOR)) if (!has_condition(this, COND_ORIGINAL_INITIATOR))
{ {
DBG1(DBG_IKE, "initiator did not reauthenticate as requested"); DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
if (this->other_vips->get_count(this->other_vips) != 0 || if (array_count(this->other_vips) != 0 ||
has_condition(this, COND_XAUTH_AUTHENTICATED) || has_condition(this, COND_XAUTH_AUTHENTICATED) ||
has_condition(this, COND_EAP_AUTHENTICATED) has_condition(this, COND_EAP_AUTHENTICATED)
#ifdef ME #ifdef ME
@ -1553,7 +1549,7 @@ METHOD(ike_sa_t, reestablish, status_t,
if (has_condition(this, COND_REAUTHENTICATING)) if (has_condition(this, COND_REAUTHENTICATING))
{ /* only reauthenticate if we have children */ { /* only reauthenticate if we have children */
if (this->child_sas->get_count(this->child_sas) == 0 if (array_count(this->child_sas) == 0
#ifdef ME #ifdef ME
/* allow reauth of mediation connections without CHILD_SAs */ /* allow reauth of mediation connections without CHILD_SAs */
&& !this->peer_cfg->is_mediation(this->peer_cfg) && !this->peer_cfg->is_mediation(this->peer_cfg)
@ -1570,7 +1566,7 @@ METHOD(ike_sa_t, reestablish, status_t,
} }
else else
{ /* check if we have children to keep up at all */ { /* check if we have children to keep up at all */
enumerator = this->child_sas->create_enumerator(this->child_sas); enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, (void**)&child_sa)) while (enumerator->enumerate(enumerator, (void**)&child_sa))
{ {
if (this->state == IKE_DELETING) if (this->state == IKE_DELETING)
@ -1611,7 +1607,7 @@ METHOD(ike_sa_t, reestablish, status_t,
/* check if we are able to reestablish this IKE_SA */ /* check if we are able to reestablish this IKE_SA */
if (!has_condition(this, COND_ORIGINAL_INITIATOR) && if (!has_condition(this, COND_ORIGINAL_INITIATOR) &&
(this->other_vips->get_count(this->other_vips) != 0 || (array_count(this->other_vips) != 0 ||
has_condition(this, COND_EAP_AUTHENTICATED) has_condition(this, COND_EAP_AUTHENTICATED)
#ifdef ME #ifdef ME
|| this->is_mediation_server || this->is_mediation_server
@ -1634,7 +1630,7 @@ METHOD(ike_sa_t, reestablish, status_t,
host = this->my_host; host = this->my_host;
new->set_my_host(new, host->clone(host)); new->set_my_host(new, host->clone(host));
/* if we already have a virtual IP, we reuse it */ /* if we already have a virtual IP, we reuse it */
enumerator = this->my_vips->create_enumerator(this->my_vips); enumerator = array_create_enumerator(this->my_vips);
while (enumerator->enumerate(enumerator, &host)) while (enumerator->enumerate(enumerator, &host))
{ {
new->add_virtual_ip(new, TRUE, host); new->add_virtual_ip(new, TRUE, host);
@ -1649,7 +1645,7 @@ METHOD(ike_sa_t, reestablish, status_t,
else else
#endif /* ME */ #endif /* ME */
{ {
enumerator = this->child_sas->create_enumerator(this->child_sas); enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, (void**)&child_sa)) while (enumerator->enumerate(enumerator, (void**)&child_sa))
{ {
if (has_condition(this, COND_REAUTHENTICATING)) if (has_condition(this, COND_REAUTHENTICATING))
@ -1658,7 +1654,7 @@ METHOD(ike_sa_t, reestablish, status_t,
{ {
case CHILD_ROUTED: case CHILD_ROUTED:
{ /* move routed child directly */ { /* move routed child directly */
this->child_sas->remove_at(this->child_sas, enumerator); array_remove_at(this->child_sas, enumerator);
new->add_child_sa(new, child_sa); new->add_child_sa(new, child_sa);
action = ACTION_NONE; action = ACTION_NONE;
break; break;
@ -1789,7 +1785,7 @@ METHOD(ike_sa_t, set_auth_lifetime, status_t,
* We send the notify in IKE_AUTH if not yet ESTABLISHED. */ * We send the notify in IKE_AUTH if not yet ESTABLISHED. */
send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 && send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
!has_condition(this, COND_ORIGINAL_INITIATOR) && !has_condition(this, COND_ORIGINAL_INITIATOR) &&
(this->other_vips->get_count(this->other_vips) != 0 || (array_count(this->other_vips) != 0 ||
has_condition(this, COND_EAP_AUTHENTICATED)); has_condition(this, COND_EAP_AUTHENTICATED));
if (lifetime < diff) if (lifetime < diff)
@ -1963,13 +1959,12 @@ METHOD(ike_sa_t, add_configuration_attribute, void,
private_ike_sa_t *this, attribute_handler_t *handler, private_ike_sa_t *this, attribute_handler_t *handler,
configuration_attribute_type_t type, chunk_t data) configuration_attribute_type_t type, chunk_t data)
{ {
attribute_entry_t *entry = malloc_thing(attribute_entry_t); attribute_entry_t entry = {
.handler = handler,
entry->handler = handler; .type = type,
entry->type = type; .data = chunk_clone(data),
entry->data = chunk_clone(data); };
array_insert(this->attributes, ARRAY_TAIL, &entry);
this->attributes->insert_last(this->attributes, entry);
} }
METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
@ -1995,8 +1990,8 @@ METHOD(ike_sa_t, inherit, void,
{ {
private_ike_sa_t *other = (private_ike_sa_t*)other_public; private_ike_sa_t *other = (private_ike_sa_t*)other_public;
child_sa_t *child_sa; child_sa_t *child_sa;
attribute_entry_t *entry;
enumerator_t *enumerator; enumerator_t *enumerator;
attribute_entry_t entry;
auth_cfg_t *cfg; auth_cfg_t *cfg;
host_t *vip; host_t *vip;
@ -2011,35 +2006,33 @@ METHOD(ike_sa_t, inherit, void,
this->other_id = other->other_id->clone(other->other_id); this->other_id = other->other_id->clone(other->other_id);
/* apply assigned virtual IPs... */ /* apply assigned virtual IPs... */
while (other->my_vips->remove_last(other->my_vips, (void**)&vip) == SUCCESS) while (array_remove(other->my_vips, ARRAY_HEAD, &vip))
{ {
this->my_vips->insert_first(this->my_vips, vip); array_insert_create(&this->my_vips, ARRAY_TAIL, vip);
} }
while (other->other_vips->remove_last(other->other_vips, while (array_remove(other->other_vips, ARRAY_HEAD, &vip))
(void**)&vip) == SUCCESS)
{ {
this->other_vips->insert_first(this->other_vips, vip); array_insert_create(&this->other_vips, ARRAY_TAIL, vip);
} }
/* authentication information */ /* authentication information */
enumerator = other->my_auths->create_enumerator(other->my_auths); enumerator = array_create_enumerator(other->my_auths);
while (enumerator->enumerate(enumerator, &cfg)) while (enumerator->enumerate(enumerator, &cfg))
{ {
this->my_auths->insert_last(this->my_auths, cfg->clone(cfg)); array_insert(this->my_auths, ARRAY_TAIL, cfg->clone(cfg));
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
enumerator = other->other_auths->create_enumerator(other->other_auths); enumerator = array_create_enumerator(other->other_auths);
while (enumerator->enumerate(enumerator, &cfg)) while (enumerator->enumerate(enumerator, &cfg))
{ {
this->other_auths->insert_last(this->other_auths, cfg->clone(cfg)); array_insert(this->other_auths, ARRAY_TAIL, cfg->clone(cfg));
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
/* ... and configuration attributes */ /* ... and configuration attributes */
while (other->attributes->remove_last(other->attributes, while (array_remove(other->attributes, ARRAY_HEAD, &entry))
(void**)&entry) == SUCCESS)
{ {
this->attributes->insert_first(this->attributes, entry); array_insert(this->attributes, ARRAY_TAIL, &entry);
} }
/* inherit all conditions */ /* inherit all conditions */
@ -2062,10 +2055,9 @@ METHOD(ike_sa_t, inherit, void,
#endif /* ME */ #endif /* ME */
/* adopt all children */ /* adopt all children */
while (other->child_sas->remove_last(other->child_sas, while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
(void**)&child_sa) == SUCCESS)
{ {
this->child_sas->insert_first(this->child_sas, (void*)child_sa); array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
} }
/* move pending tasks to the new IKE_SA */ /* move pending tasks to the new IKE_SA */
@ -2092,7 +2084,7 @@ METHOD(ike_sa_t, inherit, void,
METHOD(ike_sa_t, destroy, void, METHOD(ike_sa_t, destroy, void,
private_ike_sa_t *this) private_ike_sa_t *this)
{ {
attribute_entry_t *entry; attribute_entry_t entry;
host_t *vip; host_t *vip;
charon->bus->set_sa(charon->bus, &this->public); charon->bus->set_sa(charon->bus, &this->public);
@ -2101,25 +2093,22 @@ METHOD(ike_sa_t, destroy, void,
DESTROY_IF(this->task_manager); DESTROY_IF(this->task_manager);
/* remove attributes first, as we pass the IKE_SA to the handler */ /* remove attributes first, as we pass the IKE_SA to the handler */
while (this->attributes->remove_last(this->attributes, while (array_remove(this->attributes, ARRAY_TAIL, &entry))
(void**)&entry) == SUCCESS)
{ {
hydra->attributes->release(hydra->attributes, entry->handler, hydra->attributes->release(hydra->attributes, entry.handler,
this->other_id, entry->type, entry->data); this->other_id, entry.type, entry.data);
free(entry->data.ptr); free(entry.data.ptr);
free(entry);
} }
while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS) while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
{ {
hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE); hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE);
vip->destroy(vip); vip->destroy(vip);
} }
if (this->other_vips->get_count(this->other_vips)) if (array_count(this->other_vips))
{ {
charon->bus->assign_vips(charon->bus, &this->public, FALSE); charon->bus->assign_vips(charon->bus, &this->public, FALSE);
} }
while (this->other_vips->remove_last(this->other_vips, while (array_remove(this->other_vips, ARRAY_TAIL, &vip))
(void**)&vip) == SUCCESS)
{ {
if (this->peer_cfg) if (this->peer_cfg)
{ {
@ -2138,13 +2127,12 @@ METHOD(ike_sa_t, destroy, void,
/* unset SA after here to avoid usage by the listeners */ /* unset SA after here to avoid usage by the listeners */
charon->bus->set_sa(charon->bus, NULL); charon->bus->set_sa(charon->bus, NULL);
this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy)); array_destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
DESTROY_IF(this->keymat); DESTROY_IF(this->keymat);
this->attributes->destroy(this->attributes); array_destroy(this->attributes);
this->my_vips->destroy(this->my_vips); array_destroy(this->my_vips);
this->other_vips->destroy(this->other_vips); array_destroy(this->other_vips);
this->peer_addresses->destroy_offset(this->peer_addresses, array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
offsetof(host_t, destroy));
#ifdef ME #ifdef ME
if (this->is_mediation_server) if (this->is_mediation_server)
{ {
@ -2168,10 +2156,8 @@ METHOD(ike_sa_t, destroy, void,
DESTROY_IF(this->proposal); DESTROY_IF(this->proposal);
this->my_auth->destroy(this->my_auth); this->my_auth->destroy(this->my_auth);
this->other_auth->destroy(this->other_auth); this->other_auth->destroy(this->other_auth);
this->my_auths->destroy_offset(this->my_auths, array_destroy_offset(this->my_auths, offsetof(auth_cfg_t, destroy));
offsetof(auth_cfg_t, destroy)); array_destroy_offset(this->other_auths, offsetof(auth_cfg_t, destroy));
this->other_auths->destroy_offset(this->other_auths,
offsetof(auth_cfg_t, destroy));
this->ike_sa_id->destroy(this->ike_sa_id); this->ike_sa_id->destroy(this->ike_sa_id);
free(this); free(this);
@ -2283,7 +2269,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
}, },
.ike_sa_id = ike_sa_id->clone(ike_sa_id), .ike_sa_id = ike_sa_id->clone(ike_sa_id),
.version = version, .version = version,
.child_sas = linked_list_create(),
.my_host = host_create_any(AF_INET), .my_host = host_create_any(AF_INET),
.other_host = host_create_any(AF_INET), .other_host = host_create_any(AF_INET),
.my_id = identification_create_from_encoding(ID_ANY, chunk_empty), .my_id = identification_create_from_encoding(ID_ANY, chunk_empty),
@ -2294,13 +2279,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
.stats[STAT_OUTBOUND] = time_monotonic(NULL), .stats[STAT_OUTBOUND] = time_monotonic(NULL),
.my_auth = auth_cfg_create(), .my_auth = auth_cfg_create(),
.other_auth = auth_cfg_create(), .other_auth = auth_cfg_create(),
.my_auths = linked_list_create(), .my_auths = array_create(0, 0),
.other_auths = linked_list_create(), .other_auths = array_create(0, 0),
.attributes = array_create(sizeof(attribute_entry_t), 0),
.unique_id = ref_get(&unique_id), .unique_id = ref_get(&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, .keepalive_interval = lib->settings->get_time(lib->settings,
"%s.keep_alive", KEEPALIVE_INTERVAL, charon->name), "%s.keep_alive", KEEPALIVE_INTERVAL, charon->name),
.retry_initiate_interval = lib->settings->get_time(lib->settings, .retry_initiate_interval = lib->settings->get_time(lib->settings,