diff options
Diffstat (limited to 'src/libcharon/sa/ike_sa.c')
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 305 |
1 files changed, 174 insertions, 131 deletions
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 63c04d9c0..2f4e1123c 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Tobias Brunner + * Copyright (C) 2006-2013 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -26,7 +26,7 @@ #include <library.h> #include <hydra.h> #include <daemon.h> -#include <collections/linked_list.h> +#include <collections/array.h> #include <utils/lexparser.h> #include <processing/jobs/retransmit_job.h> #include <processing/jobs/delete_ike_sa_job.h> @@ -95,24 +95,24 @@ struct private_ike_sa_t { peer_cfg_t *peer_cfg; /** - * currently used authentication ruleset, local (as auth_cfg_t) + * currently used authentication ruleset, local */ auth_cfg_t *my_auth; /** - * list of completed local authentication rounds + * currently used authentication constraints, remote */ - linked_list_t *my_auths; + auth_cfg_t *other_auth; /** - * list of completed remote authentication rounds + * Array of completed local authentication rounds (as auth_cfg_t) */ - linked_list_t *other_auths; + array_t *my_auths; /** - * currently used authentication constraints, remote (as auth_cfg_t) + * Array of completed remote authentication rounds (as auth_cfg_t) */ - auth_cfg_t *other_auth; + array_t *other_auths; /** * Selected IKE proposal @@ -172,9 +172,9 @@ struct private_ike_sa_t { 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 @@ -184,22 +184,22 @@ struct private_ike_sa_t { /** * Virtual IPs on local host */ - linked_list_t *my_vips; + array_t *my_vips; /** * Virtual IPs on remote host */ - linked_list_t *other_vips; + array_t *other_vips; /** * List of configuration attributes (attribute_entry_t) */ - linked_list_t *attributes; + array_t *attributes; /** * 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 @@ -282,7 +282,8 @@ static time_t get_use_time(private_ike_sa_t* this, bool inbound) { 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)) { child_sa->get_usestats(child_sa, inbound, ¤t, NULL, NULL); @@ -389,11 +390,11 @@ METHOD(ike_sa_t, add_auth_cfg, void, { if (local) { - this->my_auths->insert_last(this->my_auths, cfg); + array_insert(this->my_auths, ARRAY_TAIL, cfg); } 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) { - 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->other_auth->purge(this->other_auth, FALSE); - while (this->my_auths->remove_last(this->my_auths, - (void**)&cfg) == SUCCESS) + while (array_remove(this->my_auths, ARRAY_TAIL, &cfg)) { cfg->destroy(cfg); } - while (this->other_auths->remove_last(this->other_auths, - (void**)&cfg) == SUCCESS) + while (array_remove(this->other_auths, ARRAY_TAIL, &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, 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 { @@ -765,7 +764,7 @@ METHOD(ike_sa_t, add_virtual_ip, void, } 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, private_ike_sa_t *this, bool local) { - linked_list_t *vips = local ? this->my_vips : this->other_vips; + array_t *vips; 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); } - while (vips->remove_first(vips, (void**)&vip) == SUCCESS) + while (array_remove(vips, ARRAY_HEAD, &vip)) { if (local) { @@ -796,23 +796,23 @@ METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*, { 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, 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*, 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 */ 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, private_ike_sa_t *this) { - enumerator_t *enumerator; - host_t *host; - - 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); + array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy)); + this->peer_addresses = NULL; } METHOD(ike_sa_t, has_mapping_changed, bool, @@ -927,13 +918,16 @@ METHOD(ike_sa_t, update_hosts, void, { enumerator_t *enumerator; child_sa_t *child_sa; + linked_list_t *vips; - enumerator = this->child_sas->create_enumerator(this->child_sas); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + vips = linked_list_create_from_enumerator( + 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, - this->other_host, this->my_vips, - has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED) + if (child_sa->update(child_sa, this->my_host, this->other_host, + vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED) { this->public.rekey_child_sa(&this->public, child_sa->get_protocol(child_sa), @@ -941,6 +935,8 @@ METHOD(ike_sa_t, update_hosts, void, } } enumerator->destroy(enumerator); + + vips->destroy(vips); } } @@ -1081,6 +1077,20 @@ METHOD(ike_sa_t, initiate_mediated, status_t, static void resolve_hosts(private_ike_sa_t *this) { host_t *host; + int family = 0; + + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } if (this->remote_host) { @@ -1094,7 +1104,7 @@ static void resolve_hosts(private_ike_sa_t *this) other_addr = this->ike_cfg->get_other_addr(this->ike_cfg, NULL); other_port = this->ike_cfg->get_other_port(this->ike_cfg); - host = host_create_from_dns(other_addr, 0, other_port); + host = host_create_from_dns(other_addr, family, other_port); } if (host) { @@ -1110,7 +1120,6 @@ static void resolve_hosts(private_ike_sa_t *this) { char *my_addr; u_int16_t my_port; - int family = 0; /* use same address family as for other */ if (!this->other_host->is_anyaddr(this->other_host)) @@ -1133,7 +1142,7 @@ static void resolve_hosts(private_ike_sa_t *this) } else { /* fallback to address family specific %any(6), if configured */ - host = host_create_from_dns(my_addr, 0, my_port); + host = host_create_from_dns(my_addr, family, my_port); } } } @@ -1313,7 +1322,7 @@ METHOD(ike_sa_t, get_other_eap_id, identification_t*, enumerator_t *enumerator; 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)) { /* prefer EAP-Identity of last round */ @@ -1350,7 +1359,7 @@ METHOD(ike_sa_t, set_other_id, void, METHOD(ike_sa_t, add_child_sa, void, 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*, @@ -1359,7 +1368,7 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*, enumerator_t *enumerator; 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**)¤t)) { if (current->get_spi(current, inbound) == spi && @@ -1375,19 +1384,19 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*, METHOD(ike_sa_t, get_child_count, int, 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*, 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, 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, @@ -1420,13 +1429,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t, child_sa_t *child_sa; 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)) { if (child_sa->get_protocol(child_sa) == protocol && 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); status = SUCCESS; break; @@ -1493,7 +1502,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_vips->get_count(this->other_vips) != 0 || + if (array_count(this->other_vips) != 0 || has_condition(this, COND_XAUTH_AUTHENTICATED) || has_condition(this, COND_EAP_AUTHENTICATED) #ifdef ME @@ -1526,6 +1535,30 @@ METHOD(ike_sa_t, reauth, status_t, return this->task_manager->initiate(this->task_manager); } +/** + * Check if tasks to create CHILD_SAs are queued in the given queue + */ +static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue) +{ + enumerator_t *enumerator; + task_t *task; + bool found = FALSE; + + enumerator = this->task_manager->create_task_enumerator(this->task_manager, + queue); + while (enumerator->enumerate(enumerator, &task)) + { + if (task->get_type(task) == TASK_CHILD_CREATE || + task->get_type(task) == TASK_QUICK_MODE) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + return found; +} + METHOD(ike_sa_t, reestablish, status_t, private_ike_sa_t *this) { @@ -1540,7 +1573,7 @@ METHOD(ike_sa_t, reestablish, status_t, if (has_condition(this, COND_REAUTHENTICATING)) { /* 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 /* allow reauth of mediation connections without CHILD_SAs */ && !this->peer_cfg->is_mediation(this->peer_cfg) @@ -1557,7 +1590,7 @@ METHOD(ike_sa_t, reestablish, status_t, } else { /* 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)) { if (this->state == IKE_DELETING) @@ -1575,13 +1608,20 @@ METHOD(ike_sa_t, reestablish, status_t, break; case ACTION_ROUTE: charon->traps->install(charon->traps, this->peer_cfg, - child_sa->get_config(child_sa)); + child_sa->get_config(child_sa), + child_sa->get_reqid(child_sa)); break; default: break; } } enumerator->destroy(enumerator); + /* check if we have tasks that recreate children */ + if (!restart) + { + restart = is_child_queued(this, TASK_QUEUE_ACTIVE) || + is_child_queued(this, TASK_QUEUE_QUEUED); + } #ifdef ME /* mediation connections have no children, keep them up anyway */ if (this->peer_cfg->is_mediation(this->peer_cfg)) @@ -1597,7 +1637,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_vips->get_count(this->other_vips) != 0 || + (array_count(this->other_vips) != 0 || has_condition(this, COND_EAP_AUTHENTICATED) #ifdef ME || this->is_mediation_server @@ -1620,7 +1660,7 @@ 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 */ - enumerator = this->my_vips->create_enumerator(this->my_vips); + enumerator = array_create_enumerator(this->my_vips); while (enumerator->enumerate(enumerator, &host)) { new->add_virtual_ip(new, TRUE, host); @@ -1635,7 +1675,8 @@ METHOD(ike_sa_t, reestablish, status_t, else #endif /* ME */ { - enumerator = this->child_sas->create_enumerator(this->child_sas); + /* handle existing CHILD_SAs */ + enumerator = array_create_enumerator(this->child_sas); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (has_condition(this, COND_REAUTHENTICATING)) @@ -1644,7 +1685,7 @@ METHOD(ike_sa_t, reestablish, status_t, { case CHILD_ROUTED: { /* 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); action = ACTION_NONE; break; @@ -1674,7 +1715,8 @@ METHOD(ike_sa_t, reestablish, status_t, DBG1(DBG_IKE, "restarting CHILD_SA %s", child_cfg->get_name(child_cfg)); child_cfg->get_ref(child_cfg); - status = new->initiate(new, child_cfg, 0, NULL, NULL); + status = new->initiate(new, child_cfg, + child_sa->get_reqid(child_sa), NULL, NULL); break; default: continue; @@ -1685,6 +1727,16 @@ METHOD(ike_sa_t, reestablish, status_t, } } enumerator->destroy(enumerator); + /* adopt any active or queued CHILD-creating tasks */ + if (status != DESTROY_ME) + { + task_manager_t *other_tasks = ((private_ike_sa_t*)new)->task_manager; + other_tasks->adopt_child_tasks(other_tasks, this->task_manager); + if (new->get_state(new) == IKE_CREATED) + { + status = new->initiate(new, NULL, 0, NULL, NULL); + } + } } if (status == DESTROY_ME) @@ -1774,7 +1826,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_vips->get_count(this->other_vips) != 0 || + (array_count(this->other_vips) != 0 || has_condition(this, COND_EAP_AUTHENTICATED)); if (lifetime < diff) @@ -1948,13 +2000,12 @@ METHOD(ike_sa_t, add_configuration_attribute, void, private_ike_sa_t *this, attribute_handler_t *handler, configuration_attribute_type_t type, chunk_t data) { - attribute_entry_t *entry = malloc_thing(attribute_entry_t); - - entry->handler = handler; - entry->type = type; - entry->data = chunk_clone(data); - - this->attributes->insert_last(this->attributes, entry); + attribute_entry_t entry = { + .handler = handler, + .type = type, + .data = chunk_clone(data), + }; + array_insert(this->attributes, ARRAY_TAIL, &entry); } METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, @@ -1980,8 +2031,8 @@ METHOD(ike_sa_t, inherit, void, { private_ike_sa_t *other = (private_ike_sa_t*)other_public; child_sa_t *child_sa; - attribute_entry_t *entry; enumerator_t *enumerator; + attribute_entry_t entry; auth_cfg_t *cfg; host_t *vip; @@ -1996,35 +2047,33 @@ METHOD(ike_sa_t, inherit, void, this->other_id = other->other_id->clone(other->other_id); /* 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, - (void**)&vip) == SUCCESS) + while (array_remove(other->other_vips, ARRAY_HEAD, &vip)) { - this->other_vips->insert_first(this->other_vips, vip); + array_insert_create(&this->other_vips, ARRAY_TAIL, vip); } /* authentication information */ - enumerator = other->my_auths->create_enumerator(other->my_auths); + enumerator = array_create_enumerator(other->my_auths); 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 = other->other_auths->create_enumerator(other->other_auths); + enumerator = array_create_enumerator(other->other_auths); 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); /* ... and configuration attributes */ - while (other->attributes->remove_last(other->attributes, - (void**)&entry) == SUCCESS) + while (array_remove(other->attributes, ARRAY_HEAD, &entry)) { - this->attributes->insert_first(this->attributes, entry); + array_insert(this->attributes, ARRAY_TAIL, &entry); } /* inherit all conditions */ @@ -2047,10 +2096,9 @@ METHOD(ike_sa_t, inherit, void, #endif /* ME */ /* adopt all children */ - while (other->child_sas->remove_last(other->child_sas, - (void**)&child_sa) == SUCCESS) + while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa)) { - 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 */ @@ -2077,7 +2125,8 @@ METHOD(ike_sa_t, inherit, void, METHOD(ike_sa_t, destroy, void, private_ike_sa_t *this) { - attribute_entry_t *entry; + attribute_entry_t entry; + child_sa_t *child_sa; host_t *vip; charon->bus->set_sa(charon->bus, &this->public); @@ -2086,35 +2135,28 @@ METHOD(ike_sa_t, destroy, void, DESTROY_IF(this->task_manager); /* remove attributes first, as we pass the IKE_SA to the handler */ - while (this->attributes->remove_last(this->attributes, - (void**)&entry) == SUCCESS) + while (array_remove(this->attributes, ARRAY_TAIL, &entry)) { - hydra->attributes->release(hydra->attributes, entry->handler, - this->other_id, entry->type, entry->data); - free(entry->data.ptr); - free(entry); + hydra->attributes->release(hydra->attributes, entry.handler, + this->other_id, entry.type, entry.data); + free(entry.data.ptr); } - this->attributes->destroy(this->attributes); - - this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy)); - - /* unset SA after here to avoid usage by the listeners */ - charon->bus->set_sa(charon->bus, NULL); - - DESTROY_IF(this->keymat); - - while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS) + /* uninstall CHILD_SAs before virtual IPs, otherwise we might kill + * routes that the CHILD_SA tries to uninstall. */ + while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa)) + { + child_sa->destroy(child_sa); + } + while (array_remove(this->my_vips, ARRAY_TAIL, &vip)) { hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE); vip->destroy(vip); } - this->my_vips->destroy(this->my_vips); - if (this->other_vips->get_count(this->other_vips)) + if (array_count(this->other_vips)) { charon->bus->assign_vips(charon->bus, &this->public, FALSE); } - while (this->other_vips->remove_last(this->other_vips, - (void**)&vip) == SUCCESS) + while (array_remove(this->other_vips, ARRAY_TAIL, &vip)) { if (this->peer_cfg) { @@ -2129,9 +2171,16 @@ METHOD(ike_sa_t, destroy, void, } vip->destroy(vip); } - this->other_vips->destroy(this->other_vips); - this->peer_addresses->destroy_offset(this->peer_addresses, - offsetof(host_t, destroy)); + + /* unset SA after here to avoid usage by the listeners */ + charon->bus->set_sa(charon->bus, NULL); + + array_destroy(this->child_sas); + DESTROY_IF(this->keymat); + array_destroy(this->attributes); + array_destroy(this->my_vips); + array_destroy(this->other_vips); + array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy)); #ifdef ME if (this->is_mediation_server) { @@ -2155,10 +2204,8 @@ METHOD(ike_sa_t, destroy, void, DESTROY_IF(this->proposal); this->my_auth->destroy(this->my_auth); this->other_auth->destroy(this->other_auth); - this->my_auths->destroy_offset(this->my_auths, - offsetof(auth_cfg_t, destroy)); - this->other_auths->destroy_offset(this->other_auths, - offsetof(auth_cfg_t, destroy)); + array_destroy_offset(this->my_auths, offsetof(auth_cfg_t, destroy)); + array_destroy_offset(this->other_auths, offsetof(auth_cfg_t, destroy)); this->ike_sa_id->destroy(this->ike_sa_id); free(this); @@ -2171,7 +2218,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, ike_version_t version) { private_ike_sa_t *this; - static u_int32_t unique_id = 0; + static refcount_t unique_id = 0; if (version == IKE_ANY) { /* prefer IKEv2 if protocol not specified */ @@ -2270,7 +2317,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), .version = version, - .child_sas = linked_list_create(), .my_host = host_create_any(AF_INET), .other_host = host_create_any(AF_INET), .my_id = identification_create_from_encoding(ID_ANY, chunk_empty), @@ -2281,13 +2327,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, .stats[STAT_OUTBOUND] = time_monotonic(NULL), .my_auth = auth_cfg_create(), .other_auth = auth_cfg_create(), - .my_auths = linked_list_create(), - .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(), + .my_auths = array_create(0, 0), + .other_auths = array_create(0, 0), + .attributes = array_create(sizeof(attribute_entry_t), 0), + .unique_id = ref_get(&unique_id), .keepalive_interval = lib->settings->get_time(lib->settings, "%s.keep_alive", KEEPALIVE_INTERVAL, charon->name), .retry_initiate_interval = lib->settings->get_time(lib->settings, |