linked-list: Change return value of find_first() and signature of its callback

This avoids the unportable five pointer hack.
This commit is contained in:
Tobias Brunner 2017-05-16 12:11:24 +02:00
parent 8a2e4d4a8b
commit 2e4d110d1e
29 changed files with 526 additions and 398 deletions

View File

@ -101,61 +101,63 @@ static void sad_entry_destroy(sad_entry_t *entry)
} }
} }
/** CALLBACK(sad_entry_match, bool,
* Find a list entry with given src, dst, (remote) spi and proto values. sad_entry_t * const entry, va_list args)
*/
static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
const host_t * const dst, const uint32_t * const spi,
const uint8_t * const proto)
{ {
const host_t *src, *dst;
const uint32_t *spi;
const uint8_t *proto;
VA_ARGS_VGET(args, src, dst, spi, proto);
if (entry->src == NULL || entry->dst == NULL) if (entry->src == NULL || entry->dst == NULL)
{ {
return FALSE; return FALSE;
} }
return src->ip_equals(entry->src, (host_t *)src) && return src->ip_equals(entry->src, (host_t *)src) &&
dst->ip_equals(entry->dst, (host_t *)dst) && dst->ip_equals(entry->dst, (host_t *)dst) &&
entry->spi_rem == *spi && entry->proto == *proto; entry->spi_rem == *spi && entry->proto == *proto;
} }
/** CALLBACK(sad_entry_match_dst, bool,
* Find a list entry with given reqid, spi and proto values. sad_entry_t * const entry, va_list args)
*/
static bool sad_entry_match_dst(sad_entry_t * const entry,
const uint32_t * const reqid,
const uint32_t * const spi,
const uint8_t * const proto)
{ {
const uint32_t *reqid, *spi;
const uint8_t *proto;
VA_ARGS_VGET(args, reqid, spi, proto);
return entry->reqid == *reqid && return entry->reqid == *reqid &&
entry->spi_rem == *spi && entry->spi_rem == *spi &&
entry->proto == *proto; entry->proto == *proto;
} }
/** CALLBACK(sad_entry_match_esa_id, bool,
* Find a list entry with given esa id. sad_entry_t * const entry, va_list args)
*/
static bool sad_entry_match_esa_id(sad_entry_t * const entry,
const esa_id_type * const esa_id)
{ {
const esa_id_type *esa_id;
VA_ARGS_VGET(args, esa_id);
return entry->esa_id == *esa_id; return entry->esa_id == *esa_id;
} }
/** CALLBACK(sad_entry_match_other_esa, bool,
* Find a list entry with given reqid and different esa id. sad_entry_t * const entry, va_list args)
*/
static bool sad_entry_match_other_esa(sad_entry_t * const entry,
const esa_id_type * const esa_id,
const uint32_t * const reqid)
{ {
const esa_id_type *esa_id;
const uint32_t *reqid;
VA_ARGS_VGET(args, esa_id, reqid);
return entry->reqid == *reqid && return entry->reqid == *reqid &&
entry->esa_id != *esa_id; entry->esa_id != *esa_id;
} }
/** CALLBACK(sad_entry_equal, bool,
* Compare two SAD entries for equality. sad_entry_t * const left, va_list args)
*/
static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
{ {
sad_entry_t *right;
VA_ARGS_VGET(args, right);
if (left->src == NULL || left->dst == NULL || right->src == NULL || if (left->src == NULL || left->dst == NULL || right->src == NULL ||
right->dst == NULL) right->dst == NULL)
{ {
@ -175,8 +177,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
const uint32_t reqid, const host_t * const src, const host_t * const dst, const uint32_t reqid, const host_t * const src, const host_t * const dst,
const uint32_t spi_loc, const uint32_t spi_rem, const uint8_t proto) const uint32_t spi_loc, const uint32_t spi_rem, const uint8_t proto)
{ {
status_t result;
sad_entry_t *new_entry; sad_entry_t *new_entry;
bool found;
INIT(new_entry, INIT(new_entry,
.esa_id = esa_id, .esa_id = esa_id,
@ -189,10 +191,9 @@ METHOD(tkm_kernel_sad_t, insert, bool,
); );
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
result = this->data->find_first(this->data, found = this->data->find_first(this->data, sad_entry_equal, NULL,
(linked_list_match_t)sad_entry_equal, NULL,
new_entry); new_entry);
if (result == NOT_FOUND) if (!found)
{ {
DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, " DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
"dst: %H, spi_loc: %x, spi_rem: %x,proto: %u)", esa_id, reqid, src, "dst: %H, spi_loc: %x, spi_rem: %x,proto: %u)", esa_id, reqid, src,
@ -207,7 +208,7 @@ METHOD(tkm_kernel_sad_t, insert, bool,
free(new_entry); free(new_entry);
} }
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
return result == NOT_FOUND; return !found;
} }
METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type, METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
@ -218,11 +219,10 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
sad_entry_t *entry = NULL; sad_entry_t *entry = NULL;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
const status_t res = this->data->find_first(this->data, const bool res = this->data->find_first(this->data, sad_entry_match,
(linked_list_match_t)sad_entry_match, (void**)&entry, src, dst, &spi,
(void**)&entry, src, dst, &spi, &proto);
&proto); if (res && entry)
if (res == SUCCESS && entry)
{ {
id = entry->esa_id; id = entry->esa_id;
DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, " DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, "
@ -243,13 +243,12 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
esa_id_type id = 0; esa_id_type id = 0;
sad_entry_t *entry = NULL; sad_entry_t *entry = NULL;
uint32_t reqid; uint32_t reqid;
status_t res; bool res;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
res = this->data->find_first(this->data, res = this->data->find_first(this->data, sad_entry_match_esa_id,
(linked_list_match_t)sad_entry_match_esa_id,
(void**)&entry, &esa_id); (void**)&entry, &esa_id);
if (res == SUCCESS && entry) if (res && entry)
{ {
reqid = entry->reqid; reqid = entry->reqid;
} }
@ -260,10 +259,9 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
return id; return id;
} }
res = this->data->find_first(this->data, res = this->data->find_first(this->data, sad_entry_match_other_esa,
(linked_list_match_t)sad_entry_match_other_esa,
(void**)&entry, &esa_id, &reqid); (void**)&entry, &esa_id, &reqid);
if (res == SUCCESS && entry) if (res && entry)
{ {
id = entry->esa_id; id = entry->esa_id;
DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u", DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u",
@ -281,10 +279,9 @@ METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
sad_entry_t *entry = NULL; sad_entry_t *entry = NULL;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
const status_t res = this->data->find_first(this->data, const bool res = this->data->find_first(this->data, sad_entry_match_dst,
(linked_list_match_t)sad_entry_match_dst, (void**)&entry, &reqid, &spi, &proto);
(void**)&entry, &reqid, &spi, &proto); if (res && entry)
if (res == SUCCESS && entry)
{ {
dst = entry->dst; dst = entry->dst;
DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u," DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"

View File

@ -92,11 +92,12 @@ static void overlay_destroy(overlay_t *this)
free(this); free(this);
} }
/** CALLBACK(overlay_equals, bool,
* compare two overlays by path overlay_t *this, va_list args)
*/
static bool overlay_equals(overlay_t *this, overlay_t *other)
{ {
overlay_t *other;
VA_ARGS_VGET(args, other);
return streq(this->path, other->path); return streq(this->path, other->path);
} }
@ -108,8 +109,8 @@ static bool overlay_remove(private_cowfs_t *this, char *path)
{ {
overlay_t over, *current; overlay_t over, *current;
over.path = path; over.path = path;
if (this->overlays->find_first(this->overlays, if (!this->overlays->find_first(this->overlays, overlay_equals,
(linked_list_match_t)overlay_equals, (void**)&current, &over) != SUCCESS) (void**)&current, &over))
{ {
return FALSE; return FALSE;
} }

View File

@ -167,6 +167,15 @@ METHOD(kernel_net_t, get_source_addr, host_t*,
return host_create_from_sockaddr((sockaddr_t*)&addr); return host_create_from_sockaddr((sockaddr_t*)&addr);
} }
CALLBACK(vip_equals, bool,
host_t *vip, va_list args)
{
host_t *host;
VA_ARGS_VGET(args, host);
return host->ip_equals(host, vip);
}
METHOD(kernel_net_t, get_source_addr_old, host_t*, METHOD(kernel_net_t, get_source_addr_old, host_t*,
private_android_net_t *this, host_t *dest, host_t *src) private_android_net_t *this, host_t *dest, host_t *src)
{ {
@ -179,8 +188,7 @@ METHOD(kernel_net_t, get_source_addr_old, host_t*,
if (host) if (host)
{ {
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->vips->find_first(this->vips, (void*)host->ip_equals, if (this->vips->find_first(this->vips, vip_equals, NULL, host))
NULL, host) == SUCCESS)
{ {
host->destroy(host); host->destroy(host);
host = NULL; host = NULL;
@ -236,8 +244,8 @@ METHOD(kernel_net_t, del_ip, status_t,
host_t *vip; host_t *vip;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->vips->find_first(this->vips, (void*)virtual_ip->ip_equals, if (this->vips->find_first(this->vips, vip_equals, (void**)&vip,
(void**)&vip, virtual_ip) == SUCCESS) virtual_ip))
{ {
this->vips->remove(this->vips, vip, NULL); this->vips->remove(this->vips, vip, NULL);
vip->destroy(vip); vip->destroy(vip);

View File

@ -207,20 +207,20 @@ static inline void register_logger(private_bus_t *this, debug_t group,
} }
} }
/** CALLBACK(find_max_levels, bool,
* Find the log level of the first registered logger that implements log or log_entry_t *entry, va_list args)
* vlog (or both).
*/
static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level,
level_t *vlevel)
{ {
level_t *level, *vlevel;
debug_t group;
VA_ARGS_VGET(args, group, level, vlevel);
if (entry->logger->log && *level == LEVEL_SILENT) if (entry->logger->log && *level == LEVEL_SILENT)
{ {
*level = entry->levels[*group]; *level = entry->levels[group];
} }
if (entry->logger->vlog && *vlevel == LEVEL_SILENT) if (entry->logger->vlog && *vlevel == LEVEL_SILENT)
{ {
*vlevel = entry->levels[*group]; *vlevel = entry->levels[group];
} }
return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT; return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT;
} }
@ -258,8 +258,8 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger)
loggers = this->loggers[group]; loggers = this->loggers[group];
loggers->remove(loggers, found, NULL); loggers->remove(loggers, found, NULL);
loggers->find_first(loggers, (linked_list_match_t)find_max_levels, loggers->find_first(loggers, find_max_levels, NULL, group,
NULL, &group, &level, &vlevel); &level, &vlevel);
set_level(&this->max_level[group], level); set_level(&this->max_level[group], level);
set_level(&this->max_vlevel[group], vlevel); set_level(&this->max_vlevel[group], vlevel);
} }

View File

@ -165,8 +165,12 @@ METHOD(child_cfg_t, add_proposal, void,
} }
} }
static bool match_proposal(proposal_t *item, proposal_t *proposal) CALLBACK(match_proposal, bool,
proposal_t *item, va_list args)
{ {
proposal_t *proposal;
VA_ARGS_VGET(args, proposal);
return item->equals(item, proposal); return item->equals(item, proposal);
} }
@ -185,8 +189,7 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*,
{ {
current->strip_dh(current, MODP_NONE); current->strip_dh(current, MODP_NONE);
} }
if (proposals->find_first(proposals, (linked_list_match_t)match_proposal, if (proposals->find_first(proposals, match_proposal, NULL, current))
NULL, current) == SUCCESS)
{ {
current->destroy(current); current->destroy(current);
continue; continue;

View File

@ -282,13 +282,14 @@ static void logger_entry_unregister_destroy(logger_entry_t *this)
logger_entry_destroy(this); logger_entry_destroy(this);
} }
/** CALLBACK(logger_entry_match, bool,
* Match a logger entry by target and whether it is a file or syslog logger logger_entry_t *this, va_list args)
*/
static bool logger_entry_match(logger_entry_t *this, char *target,
logger_type_t *type)
{ {
return this->type == *type && streq(this->target, target); logger_type_t type;
char *target;
VA_ARGS_VGET(args, target, type);
return this->type == type && streq(this->target, target);
} }
/** /**
@ -350,8 +351,8 @@ static logger_entry_t *get_logger_entry(char *target, logger_type_t type,
{ {
logger_entry_t *entry; logger_entry_t *entry;
if (existing->find_first(existing, (void*)logger_entry_match, if (!existing->find_first(existing, logger_entry_match, (void**)&entry,
(void**)&entry, target, &type) != SUCCESS) target, type))
{ {
INIT(entry, INIT(entry,
.target = strdup(target), .target = strdup(target),

View File

@ -632,21 +632,18 @@ METHOD(kernel_interface_t, enable_udp_decap, bool,
METHOD(kernel_interface_t, is_interface_usable, bool, METHOD(kernel_interface_t, is_interface_usable, bool,
private_kernel_interface_t *this, const char *iface) private_kernel_interface_t *this, const char *iface)
{ {
status_t expected;
if (!this->ifaces_filter) if (!this->ifaces_filter)
{ {
return TRUE; return TRUE;
} }
expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; return this->ifaces_filter->find_first(this->ifaces_filter,
return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, linked_list_match_str, NULL, iface) != this->ifaces_exclude;
NULL, iface) == expected;
} }
METHOD(kernel_interface_t, all_interfaces_usable, bool, METHOD(kernel_interface_t, all_interfaces_usable, bool,
private_kernel_interface_t *this) private_kernel_interface_t *this)
{ {
return this->ifaces_filter == NULL; return !this->ifaces_filter;
} }
METHOD(kernel_interface_t, get_address_by_ts, status_t, METHOD(kernel_interface_t, get_address_by_ts, status_t,

View File

@ -110,15 +110,12 @@ static bool policy_equals(bypass_policy_t *a, bypass_policy_t *b)
*/ */
static bool consider_interface(private_bypass_lan_listener_t *this, char *iface) static bool consider_interface(private_bypass_lan_listener_t *this, char *iface)
{ {
status_t expected;
if (!iface || !this->ifaces_filter) if (!iface || !this->ifaces_filter)
{ {
return TRUE; return TRUE;
} }
expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; return this->ifaces_filter->find_first(this->ifaces_filter,
return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, linked_list_match_str, NULL, iface) != this->ifaces_exclude;
NULL, iface) == expected;
} }
/** /**

View File

@ -151,8 +151,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
identification_t *id; identification_t *id;
host_t *vip; host_t *vip;
if (pools->find_first(pools, (linked_list_match_t)streq, if (!pools->find_first(pools, linked_list_match_str, NULL, "dhcp"))
NULL, "dhcp") != SUCCESS)
{ {
return NULL; return NULL;
} }

View File

@ -382,8 +382,7 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*,
while (try <= DHCP_TRIES && discover(this, transaction)) while (try <= DHCP_TRIES && discover(this, transaction))
{ {
if (!this->condvar->timed_wait(this->condvar, this->mutex, 1000 * try) && if (!this->condvar->timed_wait(this->condvar, this->mutex, 1000 * try) &&
this->request->find_first(this->request, NULL, this->request->find_first(this->request, NULL, (void**)&transaction))
(void**)&transaction) == SUCCESS)
{ {
break; break;
} }

View File

@ -69,6 +69,15 @@ static bool entry_matches(eap_vendor_type_t *item, eap_vendor_type_t *other)
return item->type == other->type && item->vendor == other->vendor; return item->type == other->type && item->vendor == other->vendor;
} }
CALLBACK(entry_matches_cb, bool,
eap_vendor_type_t *item, va_list args)
{
eap_vendor_type_t *other;
VA_ARGS_VGET(args, other);
return entry_matches(item, other);
}
/** /**
* Load the given EAP method * Load the given EAP method
*/ */
@ -121,8 +130,7 @@ static void select_method(private_eap_dynamic_t *this)
{ {
if (inner) if (inner)
{ {
if (inner->find_first(inner, (void*)entry_matches, if (!inner->find_first(inner, entry_matches_cb, NULL, entry))
NULL, entry) != SUCCESS)
{ {
if (entry->vendor) if (entry->vendor)
{ {

View File

@ -84,12 +84,12 @@ static void exclude_route_destroy(exclude_route_t *this)
free(this); free(this);
} }
/** CALLBACK(exclude_route_match, bool,
* Find an exclude route entry by destination address exclude_route_t *current, va_list args)
*/
static bool exclude_route_match(exclude_route_t *current,
host_t *dst)
{ {
host_t *dst;
VA_ARGS_VGET(args, dst);
return dst->ip_equals(dst, current->dst); return dst->ip_equals(dst, current->dst);
} }
@ -204,12 +204,12 @@ static void policy_entry_destroy(policy_entry_t *this)
free(this); free(this);
} }
/** CALLBACK(policy_entry_equals, bool,
* Compare two policy_entry_t objects policy_entry_t *a, va_list args)
*/
static inline bool policy_entry_equals(policy_entry_t *a,
policy_entry_t *b)
{ {
policy_entry_t *b;
VA_ARGS_VGET(args, b);
return a->direction == b->direction && return a->direction == b->direction &&
a->src.proto == b->src.proto && a->src.proto == b->src.proto &&
a->dst.proto == b->dst.proto && a->dst.proto == b->dst.proto &&
@ -297,9 +297,8 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this,
exclude_route_t *exclude; exclude_route_t *exclude;
host_t *gtw; host_t *gtw;
if (this->excludes->find_first(this->excludes, if (this->excludes->find_first(this->excludes, exclude_route_match,
(linked_list_match_t)exclude_route_match, (void**)&exclude, dst))
(void**)&exclude, dst) == SUCCESS)
{ {
route->exclude = exclude; route->exclude = exclude;
exclude->refs++; exclude->refs++;
@ -524,9 +523,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir); policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir);
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (this->policies->find_first(this->policies, policy_entry_equals,
(linked_list_match_t)policy_entry_equals, (void**)&found, policy))
(void**)&found, policy) == SUCCESS)
{ {
policy_entry_destroy(policy); policy_entry_destroy(policy);
policy = found; policy = found;
@ -567,9 +565,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir); policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir);
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (!this->policies->find_first(this->policies, policy_entry_equals,
(linked_list_match_t)policy_entry_equals, (void**)&found, policy))
(void**)&found, policy) != SUCCESS)
{ {
policy_entry_destroy(policy); policy_entry_destroy(policy);
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);

View File

@ -163,19 +163,21 @@ static void iface_entry_destroy(iface_entry_t *this)
free(this); free(this);
} }
/** CALLBACK(iface_entry_by_index, bool,
* find an interface entry by index iface_entry_t *this, va_list args)
*/
static bool iface_entry_by_index(iface_entry_t *this, int *ifindex)
{ {
return this->ifindex == *ifindex; int ifindex;
VA_ARGS_VGET(args, ifindex);
return this->ifindex == ifindex;
} }
/** CALLBACK(iface_entry_by_name, bool,
* find an interface entry by name iface_entry_t *this, va_list args)
*/
static bool iface_entry_by_name(iface_entry_t *this, char *ifname)
{ {
char *ifname;
VA_ARGS_VGET(args, ifname);
return streq(this->ifname, ifname); return streq(this->ifname, ifname);
} }
@ -1112,8 +1114,8 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this,
{ {
iface_entry_t *iface; iface_entry_t *iface;
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
(void**)&iface, &index) == SUCCESS) (void**)&iface, index))
{ {
return iface_entry_up_and_usable(iface); return iface_entry_up_and_usable(iface);
} }
@ -1175,9 +1177,8 @@ static void process_link(private_kernel_netlink_net_t *this,
{ {
case RTM_NEWLINK: case RTM_NEWLINK:
{ {
if (this->ifaces->find_first(this->ifaces, if (!this->ifaces->find_first(this->ifaces, iface_entry_by_index,
(void*)iface_entry_by_index, (void**)&entry, (void**)&entry, msg->ifi_index))
&msg->ifi_index) != SUCCESS)
{ {
INIT(entry, INIT(entry,
.ifindex = msg->ifi_index, .ifindex = msg->ifi_index,
@ -1292,8 +1293,8 @@ static void process_addr(private_kernel_netlink_net_t *this,
} }
this->lock->write_lock(this->lock); this->lock->write_lock(this->lock);
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
(void**)&iface, &msg->ifa_index) == SUCCESS) (void**)&iface, msg->ifa_index))
{ {
addr_map_entry_t *entry, lookup = { addr_map_entry_t *entry, lookup = {
.ip = host, .ip = host,
@ -1674,8 +1675,8 @@ static int get_interface_index(private_kernel_netlink_net_t *this, char* name)
DBG2(DBG_KNL, "getting iface index for %s", name); DBG2(DBG_KNL, "getting iface index for %s", name);
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, if (this->ifaces->find_first(this->ifaces, iface_entry_by_name,
(void**)&iface, name) == SUCCESS) (void**)&iface, name))
{ {
ifindex = iface->ifindex; ifindex = iface->ifindex;
} }
@ -1700,8 +1701,8 @@ static char *get_interface_name_by_index(private_kernel_netlink_net_t *this,
DBG2(DBG_KNL, "getting iface name for index %d", index); DBG2(DBG_KNL, "getting iface name for index %d", index);
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
(void**)&iface, &index) == SUCCESS) (void**)&iface, index))
{ {
name = strdup(iface->ifname); name = strdup(iface->ifname);
} }
@ -1941,7 +1942,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
table = (uintptr_t)route->table; table = (uintptr_t)route->table;
if (this->rt_exclude->find_first(this->rt_exclude, NULL, if (this->rt_exclude->find_first(this->rt_exclude, NULL,
(void**)&table) == SUCCESS) (void**)&table))
{ /* route is from an excluded routing table */ { /* route is from an excluded routing table */
continue; continue;
} }
@ -2400,11 +2401,11 @@ METHOD(kernel_net_t, add_ip, status_t,
} }
/* try to find the target interface, either by config or via src ip */ /* try to find the target interface, either by config or via src ip */
if (!this->install_virtual_ip_on || if (!this->install_virtual_ip_on ||
this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, !this->ifaces->find_first(this->ifaces, iface_entry_by_name,
(void**)&iface, this->install_virtual_ip_on) != SUCCESS) (void**)&iface, this->install_virtual_ip_on))
{ {
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, if (!this->ifaces->find_first(this->ifaces, iface_entry_by_name,
(void**)&iface, iface_name) != SUCCESS) (void**)&iface, iface_name))
{ /* if we don't find the requested interface we just use the first */ { /* if we don't find the requested interface we just use the first */
this->ifaces->get_first(this->ifaces, (void**)&iface); this->ifaces->get_first(this->ifaces, (void**)&iface);
} }

View File

@ -585,12 +585,12 @@ CALLBACK(policy_entry_destroy_cb, void,
policy_entry_destroy(policy, this); policy_entry_destroy(policy, this);
} }
/** CALLBACK(policy_entry_equals, bool,
* compares two policy_entry_t policy_entry_t *current, va_list args)
*/
static inline bool policy_entry_equals(policy_entry_t *current,
policy_entry_t *policy)
{ {
policy_entry_t *policy;
VA_ARGS_VGET(args, policy);
return current->direction == policy->direction && return current->direction == policy->direction &&
current->src.proto == policy->src.proto && current->src.proto == policy->src.proto &&
current->dst.proto == policy->dst.proto && current->dst.proto == policy->dst.proto &&
@ -600,13 +600,13 @@ static inline bool policy_entry_equals(policy_entry_t *current,
current->dst.net->equals(current->dst.net, policy->dst.net); current->dst.net->equals(current->dst.net, policy->dst.net);
} }
/** CALLBACK(policy_entry_match_byindex, bool,
* compare the given kernel index with that of a policy policy_entry_t *current, va_list args)
*/
static inline bool policy_entry_match_byindex(policy_entry_t *current,
uint32_t *index)
{ {
return current->index == *index; uint32_t index;
VA_ARGS_VGET(args, index);
return current->index == index;
} }
/** /**
@ -1279,9 +1279,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this,
index = response.x_policy->sadb_x_policy_id; index = response.x_policy->sadb_x_policy_id;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (this->policies->find_first(this->policies, policy_entry_match_byindex,
(linked_list_match_t)policy_entry_match_byindex, (void**)&policy, index) &&
(void**)&policy, &index) == SUCCESS &&
policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS) policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS)
{ {
reqid = sa->sa->cfg.reqid; reqid = sa->sa->cfg.reqid;
@ -2572,8 +2571,7 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
/* we try to find the policy again and update the kernel index */ /* we try to find the policy again and update the kernel index */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, NULL, if (!this->policies->find_first(this->policies, NULL, (void**)&policy))
(void**)&policy) != SUCCESS)
{ {
DBG2(DBG_KNL, "unable to update index, the policy is already gone, " DBG2(DBG_KNL, "unable to update index, the policy is already gone, "
"ignoring"); "ignoring");
@ -2624,9 +2622,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
/* find a matching policy */ /* find a matching policy */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (this->policies->find_first(this->policies, policy_entry_equals,
(linked_list_match_t)policy_entry_equals, (void**)&found, policy))
(void**)&found, policy) == SUCCESS)
{ /* use existing policy */ { /* use existing policy */
DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing " DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
"refcount", id->src_ts, id->dst_ts, policy_dir_names, id->dir); "refcount", id->src_ts, id->dst_ts, policy_dir_names, id->dir);
@ -2719,9 +2716,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
/* find a matching policy */ /* find a matching policy */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (!this->policies->find_first(this->policies, policy_entry_equals,
(linked_list_match_t)policy_entry_equals, (void**)&found, policy))
(void**)&found, policy) != SUCCESS)
{ {
DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found",
id->src_ts, id->dst_ts, policy_dir_names, id->dir); id->src_ts, id->dst_ts, policy_dir_names, id->dir);
@ -2832,9 +2828,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
/* find a matching policy */ /* find a matching policy */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->policies->find_first(this->policies, if (!this->policies->find_first(this->policies, policy_entry_equals,
(linked_list_match_t)policy_entry_equals, (void**)&found, policy))
(void**)&found, policy) != SUCCESS)
{ {
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
id->src_ts, id->dst_ts, policy_dir_names, id->dir); id->src_ts, id->dst_ts, policy_dir_names, id->dir);

View File

@ -106,12 +106,13 @@ METHOD(enumerator_t, enumerate_attrs, bool,
return FALSE; return FALSE;
} }
/** CALLBACK(is_family, bool,
* Check if the given host has a matching address family host_t *host, va_list args)
*/
static bool is_family(host_t *host, int *family)
{ {
return host->get_family(host) == *family; int family;
VA_ARGS_VGET(args, family);
return host->get_family(host) == family;
} }
/** /**
@ -119,7 +120,7 @@ static bool is_family(host_t *host, int *family)
*/ */
static bool has_host_family(linked_list_t *list, int family) static bool has_host_family(linked_list_t *list, int family)
{ {
return list->find_first(list, (void*)is_family, NULL, &family) == SUCCESS; return list->find_first(list, is_family, NULL, family);
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,

View File

@ -358,11 +358,12 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
data, (void*)cdp_data_destroy); data, (void*)cdp_data_destroy);
} }
/** CALLBACK(match_cert, bool,
* Compare the given certificate to the ca_cert_t items in the list ca_cert_t *item, va_list args)
*/
static bool match_cert(ca_cert_t *item, certificate_t *cert)
{ {
certificate_t *cert;
VA_ARGS_VGET(args, cert);
return cert->equals(cert, item->cert); return cert->equals(cert, item->cert);
} }
@ -409,8 +410,7 @@ static certificate_t *add_cert_internal(private_stroke_ca_t *this,
{ {
ca_cert_t *found; ca_cert_t *found;
if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert))
(void**)&found, cert) == SUCCESS)
{ {
cert->destroy(cert); cert->destroy(cert);
cert = found->cert->get_ref(found->cert); cert = found->cert->get_ref(found->cert);
@ -515,8 +515,7 @@ METHOD(stroke_ca_t, get_cert_ref, certificate_t*,
ca_cert_t *found; ca_cert_t *found;
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert))
(void**)&found, cert) == SUCCESS)
{ {
cert->destroy(cert); cert->destroy(cert);
cert = found->cert->get_ref(found->cert); cert = found->cert->get_ref(found->cert);

View File

@ -958,8 +958,7 @@ static void list_plugins(FILE *out)
{ {
case FEATURE_PROVIDE: case FEATURE_PROVIDE:
fp = &features[i]; fp = &features[i];
loaded = list->find_first(list, NULL, loaded = list->find_first(list, NULL, (void**)&fp);
(void**)&fp) == SUCCESS;
fprintf(out, " %s%s\n", fprintf(out, " %s%s\n",
str, loaded ? "" : " (not loaded)"); str, loaded ? "" : " (not loaded)");
break; break;

View File

@ -151,8 +151,10 @@ static entry_t *entry_create()
/** /**
* Function that matches entry_t objects by ike_sa_id_t. * Function that matches entry_t objects by ike_sa_id_t.
*/ */
static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id) static bool entry_match_by_id(entry_t *entry, void *arg)
{ {
ike_sa_id_t *id = arg;
if (id->equals(id, entry->ike_sa_id)) if (id->equals(id, entry->ike_sa_id))
{ {
return TRUE; return TRUE;
@ -172,7 +174,7 @@ static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id)
/** /**
* Function that matches entry_t objects by ike_sa_t pointers. * Function that matches entry_t objects by ike_sa_t pointers.
*/ */
static bool entry_match_by_sa(entry_t *entry, ike_sa_t *ike_sa) static bool entry_match_by_sa(entry_t *entry, void *ike_sa)
{ {
return entry->ike_sa == ike_sa; return entry->ike_sa == ike_sa;
} }
@ -677,7 +679,7 @@ static void remove_entry_at(private_enumerator_t *this)
*/ */
static status_t get_entry_by_match_function(private_ike_sa_manager_t *this, static status_t get_entry_by_match_function(private_ike_sa_manager_t *this,
ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment, ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment,
linked_list_match_t match, void *param) bool (*match)(entry_t*,void*), void *param)
{ {
table_item_t *item; table_item_t *item;
u_int row, seg; u_int row, seg;
@ -710,7 +712,7 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this,
ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment) ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment)
{ {
return get_entry_by_match_function(this, ike_sa_id, entry, segment, return get_entry_by_match_function(this, ike_sa_id, entry, segment,
(linked_list_match_t)entry_match_by_id, ike_sa_id); entry_match_by_id, ike_sa_id);
} }
/** /**
@ -721,7 +723,7 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this,
ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment) ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment)
{ {
return get_entry_by_match_function(this, ike_sa_id, entry, segment, return get_entry_by_match_function(this, ike_sa_id, entry, segment,
(linked_list_match_t)entry_match_by_sa, ike_sa); entry_match_by_sa, ike_sa);
} }
/** /**
@ -858,6 +860,15 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
lock->unlock(lock); lock->unlock(lock);
} }
CALLBACK(id_matches, bool,
ike_sa_id_t *a, va_list args)
{
ike_sa_id_t *b;
VA_ARGS_VGET(args, b);
return a->equals(a, b);
}
/** /**
* Put an SA between two peers into the hash table. * Put an SA between two peers into the hash table.
*/ */
@ -886,8 +897,7 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
entry->other_id, family)) entry->other_id, family))
{ {
if (connected_peers->sas->find_first(connected_peers->sas, if (connected_peers->sas->find_first(connected_peers->sas,
(linked_list_match_t)entry->ike_sa_id->equals, id_matches, NULL, entry->ike_sa_id))
NULL, entry->ike_sa_id) == SUCCESS)
{ {
lock->unlock(lock); lock->unlock(lock);
return; return;

View File

@ -450,22 +450,21 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist,
return this; return this;
} }
/** CALLBACK(match_initiated_by_ids, bool,
* Find an initiated connection by the peers' ids initiated_t *current, va_list args)
*/
static bool match_initiated_by_ids(initiated_t *current, identification_t *id,
identification_t *peer_id)
{ {
identification_t *id, *peer_id;
VA_ARGS_VGET(args, id, peer_id);
return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id); return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id);
} }
static status_t get_initiated_by_ids(private_connect_manager_t *this, static bool get_initiated_by_ids(private_connect_manager_t *this,
identification_t *id, identification_t *id,
identification_t *peer_id, identification_t *peer_id,
initiated_t **initiated) initiated_t **initiated)
{ {
return this->initiated->find_first(this->initiated, return this->initiated->find_first(this->initiated, match_initiated_by_ids,
(linked_list_match_t)match_initiated_by_ids,
(void**)initiated, id, peer_id); (void**)initiated, id, peer_id);
} }
@ -490,21 +489,20 @@ static void remove_initiated(private_connect_manager_t *this,
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
/** CALLBACK(match_checklist_by_id, bool,
* Find the checklist with a specific connect ID check_list_t *current, va_list args)
*/
static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id)
{ {
return chunk_equals(*connect_id, current->connect_id); chunk_t connect_id;
VA_ARGS_VGET(args, connect_id);
return chunk_equals(connect_id, current->connect_id);
} }
static status_t get_checklist_by_id(private_connect_manager_t *this, static bool get_checklist_by_id(private_connect_manager_t *this,
chunk_t connect_id, chunk_t connect_id, check_list_t **check_list)
check_list_t **check_list)
{ {
return this->checklists->find_first(this->checklists, return this->checklists->find_first(this->checklists, match_checklist_by_id,
(linked_list_match_t)match_checklist_by_id, (void**)check_list, connect_id);
(void**)check_list, &connect_id);
} }
/** /**
@ -528,19 +526,19 @@ static void remove_checklist(private_connect_manager_t *this,
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
/** CALLBACK(match_endpoint_by_host, bool,
* Checks if a list of endpoint_notify_t contains a certain host_t endpoint_notify_t *current, va_list args)
*/
static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host)
{ {
host_t *host;
VA_ARGS_VGET(args, host);
return host->equals(host, current->get_host(current)); return host->equals(host, current->get_host(current));
} }
static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, static bool endpoints_contain(linked_list_t *endpoints, host_t *host,
endpoint_notify_t **endpoint) endpoint_notify_t **endpoint)
{ {
return endpoints->find_first(endpoints, return endpoints->find_first(endpoints, match_endpoint_by_host,
(linked_list_match_t)match_endpoint_by_host,
(void**)endpoint, host); (void**)endpoint, host);
} }
@ -560,39 +558,44 @@ static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair)
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
/** CALLBACK(match_pair_by_hosts, bool,
* Searches a list of endpoint_pair_t for a pair with specific host_ts endpoint_pair_t *current, va_list args)
*/
static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local,
host_t *remote)
{ {
return local->equals(local, current->local) && remote->equals(remote, current->remote); host_t *local, *remote;
VA_ARGS_VGET(args, local, remote);
return local->equals(local, current->local) &&
remote->equals(remote, current->remote);
} }
static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local, static bool get_pair_by_hosts(linked_list_t *pairs, host_t *local,
host_t *remote, endpoint_pair_t **pair) host_t *remote, endpoint_pair_t **pair)
{ {
return pairs->find_first(pairs, (linked_list_match_t)match_pair_by_hosts, return pairs->find_first(pairs, match_pair_by_hosts, (void**)pair, local,
(void**)pair, local, remote); remote);
} }
static bool match_pair_by_id(endpoint_pair_t *current, uint32_t *id) CALLBACK(match_pair_by_id, bool,
endpoint_pair_t *current, va_list args)
{ {
return current->id == *id; uint32_t id;
VA_ARGS_VGET(args, id);
return current->id == id;
} }
/** /**
* Searches for a pair with a specific id * Searches for a pair with a specific id
*/ */
static status_t get_pair_by_id(check_list_t *checklist, uint32_t id, static bool get_pair_by_id(check_list_t *checklist, uint32_t id,
endpoint_pair_t **pair) endpoint_pair_t **pair)
{ {
return checklist->pairs->find_first(checklist->pairs, return checklist->pairs->find_first(checklist->pairs, match_pair_by_id,
(linked_list_match_t)match_pair_by_id, (void**)pair, id);
(void**)pair, &id);
} }
static bool match_succeeded_pair(endpoint_pair_t *current) CALLBACK(match_succeeded_pair, bool,
endpoint_pair_t *current, va_list args)
{ {
return current->state == CHECK_SUCCEEDED; return current->state == CHECK_SUCCEEDED;
} }
@ -600,15 +603,14 @@ static bool match_succeeded_pair(endpoint_pair_t *current)
/** /**
* Returns the best pair of state CHECK_SUCCEEDED from a checklist. * Returns the best pair of state CHECK_SUCCEEDED from a checklist.
*/ */
static status_t get_best_valid_pair(check_list_t *checklist, static bool get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair)
endpoint_pair_t **pair)
{ {
return checklist->pairs->find_first(checklist->pairs, return checklist->pairs->find_first(checklist->pairs, match_succeeded_pair,
(linked_list_match_t)match_succeeded_pair, (void**)pair);
(void**)pair);
} }
static bool match_waiting_pair(endpoint_pair_t *current) CALLBACK(match_waiting_pair, bool,
endpoint_pair_t *current, va_list args)
{ {
return current->state == CHECK_WAITING; return current->state == CHECK_WAITING;
} }
@ -865,7 +867,7 @@ static job_requeue_t initiator_finish(callback_data_t *data)
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
check_list_t *checklist; check_list_t *checklist;
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, data->connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't finish " DBG1(DBG_IKE, "checklist with id '%#B' not found, can't finish "
"connectivity checks", &data->connect_id); "connectivity checks", &data->connect_id);
@ -953,7 +955,7 @@ static job_requeue_t retransmit(callback_data_t *data)
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
check_list_t *checklist; check_list_t *checklist;
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, data->connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't retransmit " DBG1(DBG_IKE, "checklist with id '%#B' not found, can't retransmit "
"connectivity check", &data->connect_id); "connectivity check", &data->connect_id);
@ -962,7 +964,7 @@ static job_requeue_t retransmit(callback_data_t *data)
} }
endpoint_pair_t *pair; endpoint_pair_t *pair;
if (get_pair_by_id(checklist, data->mid, &pair) != SUCCESS) if (!get_pair_by_id(checklist, data->mid, &pair))
{ {
DBG1(DBG_IKE, "pair with id '%d' not found, can't retransmit " DBG1(DBG_IKE, "pair with id '%d' not found, can't retransmit "
"connectivity check", data->mid); "connectivity check", data->mid);
@ -1108,7 +1110,7 @@ static job_requeue_t sender(callback_data_t *data)
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
check_list_t *checklist; check_list_t *checklist;
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, data->connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't send " DBG1(DBG_IKE, "checklist with id '%#B' not found, can't send "
"connectivity check", &data->connect_id); "connectivity check", &data->connect_id);
@ -1124,9 +1126,8 @@ static job_requeue_t sender(callback_data_t *data)
{ {
DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check"); DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check");
if (checklist->pairs->find_first(checklist->pairs, if (!checklist->pairs->find_first(checklist->pairs, match_waiting_pair,
(linked_list_match_t)match_waiting_pair, (void**)&pair))
(void**)&pair) != SUCCESS)
{ {
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
DBG1(DBG_IKE, "no pairs in waiting state, aborting"); DBG1(DBG_IKE, "no pairs in waiting state, aborting");
@ -1182,7 +1183,7 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
initiated_t *initiated = data->initiated; initiated_t *initiated = data->initiated;
endpoint_pair_t *pair; endpoint_pair_t *pair;
if (get_best_valid_pair(checklist, &pair) == SUCCESS) if (get_best_valid_pair(checklist, &pair))
{ {
ike_sa_id_t *waiting_sa; ike_sa_id_t *waiting_sa;
enumerator_t *enumerator = initiated->mediated->create_enumerator( enumerator_t *enumerator = initiated->mediated->create_enumerator(
@ -1219,7 +1220,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
{ {
initiated_t *initiated; initiated_t *initiated;
if (get_initiated_by_ids(this, checklist->initiator.id, if (get_initiated_by_ids(this, checklist->initiator.id,
checklist->responder.id, &initiated) == SUCCESS) checklist->responder.id, &initiated))
{ {
callback_job_t *job; callback_job_t *job;
@ -1247,7 +1248,7 @@ static void process_response(private_connect_manager_t *this, check_t *check,
check_list_t *checklist) check_list_t *checklist)
{ {
endpoint_pair_t *pair; endpoint_pair_t *pair;
if (get_pair_by_id(checklist, check->mid, &pair) == SUCCESS) if (get_pair_by_id(checklist, check->mid, &pair))
{ {
if (pair->local->equals(pair->local, check->dst) && if (pair->local->equals(pair->local, check->dst) &&
pair->remote->equals(pair->remote, check->src)) pair->remote->equals(pair->remote, check->src))
@ -1261,9 +1262,9 @@ static void process_response(private_connect_manager_t *this, check_t *check,
checklist->initiator.endpoints : checklist->responder.endpoints; checklist->initiator.endpoints : checklist->responder.endpoints;
endpoint_notify_t *local_endpoint; endpoint_notify_t *local_endpoint;
if (endpoints_contain(local_endpoints, if (!endpoints_contain(local_endpoints,
check->endpoint->get_host(check->endpoint), check->endpoint->get_host(check->endpoint),
&local_endpoint) != SUCCESS) &local_endpoint))
{ {
local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE, local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE,
check->endpoint->get_host(check->endpoint), pair->local); check->endpoint->get_host(check->endpoint), pair->local);
@ -1302,15 +1303,14 @@ static void process_request(private_connect_manager_t *this, check_t *check,
peer_reflexive->set_priority(peer_reflexive, peer_reflexive->set_priority(peer_reflexive,
check->endpoint->get_priority(check->endpoint)); check->endpoint->get_priority(check->endpoint));
if (endpoints_contain(remote_endpoints, check->src, &remote_endpoint) != SUCCESS) if (!endpoints_contain(remote_endpoints, check->src, &remote_endpoint))
{ {
remote_endpoint = peer_reflexive->clone(peer_reflexive); remote_endpoint = peer_reflexive->clone(peer_reflexive);
remote_endpoints->insert_last(remote_endpoints, remote_endpoint); remote_endpoints->insert_last(remote_endpoints, remote_endpoint);
} }
endpoint_pair_t *pair; endpoint_pair_t *pair;
if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, &pair))
&pair) == SUCCESS)
{ {
switch(pair->state) switch(pair->state)
{ {
@ -1389,7 +1389,7 @@ METHOD(connect_manager_t, process_check, void,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
check_list_t *checklist; check_list_t *checklist;
if (get_checklist_by_id(this, check->connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, check->connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found", DBG1(DBG_IKE, "checklist with id '%#B' not found",
&check->connect_id); &check->connect_id);
@ -1423,6 +1423,15 @@ METHOD(connect_manager_t, process_check, void,
check_destroy(check); check_destroy(check);
} }
CALLBACK(id_matches, bool,
ike_sa_id_t *a, va_list args)
{
ike_sa_id_t *b;
VA_ARGS_VGET(args, b);
return a->equals(a, b);
}
METHOD(connect_manager_t, check_and_register, bool, METHOD(connect_manager_t, check_and_register, bool,
private_connect_manager_t *this, identification_t *id, private_connect_manager_t *this, identification_t *id,
identification_t *peer_id, ike_sa_id_t *mediated_sa) identification_t *peer_id, ike_sa_id_t *mediated_sa)
@ -1432,7 +1441,7 @@ METHOD(connect_manager_t, check_and_register, bool,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS) if (!get_initiated_by_ids(this, id, peer_id, &initiated))
{ {
DBG2(DBG_IKE, "registered waiting mediated connection with '%Y'", DBG2(DBG_IKE, "registered waiting mediated connection with '%Y'",
peer_id); peer_id);
@ -1441,9 +1450,8 @@ METHOD(connect_manager_t, check_and_register, bool,
already_there = FALSE; already_there = FALSE;
} }
if (initiated->mediated->find_first(initiated->mediated, if (!initiated->mediated->find_first(initiated->mediated, id_matches,
(linked_list_match_t)mediated_sa->equals, NULL, mediated_sa))
NULL, mediated_sa) != SUCCESS)
{ {
initiated->mediated->insert_last(initiated->mediated, initiated->mediated->insert_last(initiated->mediated,
mediated_sa->clone(mediated_sa)); mediated_sa->clone(mediated_sa));
@ -1462,7 +1470,7 @@ METHOD(connect_manager_t, check_and_initiate, void,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS) if (!get_initiated_by_ids(this, id, peer_id, &initiated))
{ {
DBG2(DBG_IKE, "no waiting mediated connections with '%Y'", peer_id); DBG2(DBG_IKE, "no waiting mediated connections with '%Y'", peer_id);
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
@ -1492,7 +1500,7 @@ METHOD(connect_manager_t, set_initiator_data, status_t,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (get_checklist_by_id(this, connect_id, NULL) == SUCCESS) if (get_checklist_by_id(this, connect_id, NULL))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' already exists, aborting", DBG1(DBG_IKE, "checklist with id '%#B' already exists, aborting",
&connect_id); &connect_id);
@ -1517,7 +1525,7 @@ METHOD(connect_manager_t, set_responder_data, status_t,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found", DBG1(DBG_IKE, "checklist with id '%#B' not found",
&connect_id); &connect_id);
@ -1547,7 +1555,7 @@ METHOD(connect_manager_t, stop_checks, status_t,
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS) if (!get_checklist_by_id(this, connect_id, &checklist))
{ {
DBG1(DBG_IKE, "checklist with id '%#B' not found", DBG1(DBG_IKE, "checklist with id '%#B' not found",
&connect_id); &connect_id);

View File

@ -81,11 +81,12 @@ typedef struct {
bool check_delete_action; bool check_delete_action;
} entry_t; } entry_t;
/** CALLBACK(match_child, bool,
* Check if the given entry is for the same CHILD_SA entry_t *entry, va_list args)
*/
static bool match_child(entry_t *entry, child_sa_t *child_sa)
{ {
child_sa_t *child_sa;
VA_ARGS_VGET(args, child_sa);
return entry->child_sa == child_sa; return entry->child_sa == child_sa;
} }
@ -252,8 +253,8 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x", DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
protocol_id_names, protocol, ntohl(spi)); protocol_id_names, protocol, ntohl(spi));
if (this->child_sas->find_first(this->child_sas, if (this->child_sas->find_first(this->child_sas, match_child,
(void*)match_child, NULL, child_sa) == SUCCESS) NULL, child_sa))
{ {
continue; continue;
} }

View File

@ -140,19 +140,21 @@ static void destroy_acquire(acquire_t *this)
free(this); free(this);
} }
/** CALLBACK(acquire_by_reqid, bool,
* match an acquire entry by reqid acquire_t *this, va_list args)
*/
static bool acquire_by_reqid(acquire_t *this, uint32_t *reqid)
{ {
return this->reqid == *reqid; uint32_t reqid;
VA_ARGS_VGET(args, reqid);
return this->reqid == reqid;
} }
/** CALLBACK(acquire_by_dst, bool,
* match an acquire entry by destination address acquire_t *this, va_list args)
*/
static bool acquire_by_dst(acquire_t *this, host_t *dst)
{ {
host_t *dst;
VA_ARGS_VGET(args, dst);
return this->dst && this->dst->ip_equals(this->dst, dst); return this->dst && this->dst->ip_equals(this->dst, dst);
} }
@ -439,8 +441,8 @@ METHOD(trap_manager_t, acquire, void,
uint8_t mask; uint8_t mask;
dst->to_subnet(dst, &host, &mask); dst->to_subnet(dst, &host, &mask);
if (this->acquires->find_first(this->acquires, (void*)acquire_by_dst, if (this->acquires->find_first(this->acquires, acquire_by_dst,
(void**)&acquire, host) == SUCCESS) (void**)&acquire, host))
{ {
host->destroy(host); host->destroy(host);
ignore = TRUE; ignore = TRUE;
@ -456,8 +458,8 @@ METHOD(trap_manager_t, acquire, void,
} }
else else
{ {
if (this->acquires->find_first(this->acquires, (void*)acquire_by_reqid, if (this->acquires->find_first(this->acquires, acquire_by_reqid,
(void**)&acquire, &reqid) == SUCCESS) (void**)&acquire, reqid))
{ {
ignore = TRUE; ignore = TRUE;
} }

View File

@ -224,42 +224,60 @@ static void flush_entries(private_ipsec_sa_mgr_t *this)
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
/* CALLBACK(match_entry_by_sa_ptr, bool,
* Different match functions to find SAs in the linked list ipsec_sa_entry_t *item, va_list args)
*/
static bool match_entry_by_ptr(ipsec_sa_entry_t *item, ipsec_sa_entry_t *entry)
{ {
return item == entry; ipsec_sa_t *sa;
}
static bool match_entry_by_sa_ptr(ipsec_sa_entry_t *item, ipsec_sa_t *sa) VA_ARGS_VGET(args, sa);
{
return item->sa == sa; return item->sa == sa;
} }
static bool match_entry_by_spi_inbound(ipsec_sa_entry_t *item, uint32_t *spi, CALLBACK(match_entry_by_spi_inbound, bool,
bool *inbound) ipsec_sa_entry_t *item, va_list args)
{ {
return item->sa->get_spi(item->sa) == *spi && uint32_t spi;
item->sa->is_inbound(item->sa) == *inbound; int inbound;
VA_ARGS_VGET(args, spi, inbound);
return item->sa->get_spi(item->sa) == spi &&
item->sa->is_inbound(item->sa) == inbound;
} }
static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t *spi, static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t spi,
host_t *src, host_t *dst) host_t *src, host_t *dst)
{ {
return item->sa->match_by_spi_src_dst(item->sa, *spi, src, dst); return item->sa->match_by_spi_src_dst(item->sa, spi, src, dst);
} }
static bool match_entry_by_reqid_inbound(ipsec_sa_entry_t *item, CALLBACK(match_entry_by_spi_src_dst_cb, bool,
uint32_t *reqid, bool *inbound) ipsec_sa_entry_t *item, va_list args)
{ {
return item->sa->match_by_reqid(item->sa, *reqid, *inbound); host_t *src, *dst;
uint32_t spi;
VA_ARGS_VGET(args, spi, src, dst);
return match_entry_by_spi_src_dst(item, spi, src, dst);
} }
static bool match_entry_by_spi_dst(ipsec_sa_entry_t *item, uint32_t *spi, CALLBACK(match_entry_by_reqid_inbound, bool,
host_t *dst) ipsec_sa_entry_t *item, va_list args)
{ {
return item->sa->match_by_spi_dst(item->sa, *spi, dst); uint32_t reqid;
int inbound;
VA_ARGS_VGET(args, reqid, inbound);
return item->sa->match_by_reqid(item->sa, reqid, inbound);
}
CALLBACK(match_entry_by_spi_dst, bool,
ipsec_sa_entry_t *item, va_list args)
{
host_t *dst;
uint32_t spi;
VA_ARGS_VGET(args, spi, dst);
return item->sa->match_by_spi_dst(item->sa, spi, dst);
} }
/** /**
@ -296,8 +314,7 @@ static job_requeue_t sa_expired(ipsec_sa_expired_t *expired)
private_ipsec_sa_mgr_t *this = expired->manager; private_ipsec_sa_mgr_t *this = expired->manager;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_ptr, if (this->sas->find_first(this->sas, NULL, (void**)&expired->entry))
NULL, expired->entry) == SUCCESS)
{ {
uint32_t hard_offset; uint32_t hard_offset;
@ -383,8 +400,8 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, uint32_t spi)
uint32_t *spi_alloc; uint32_t *spi_alloc;
if (this->allocated_spis->get(this->allocated_spis, &spi) || if (this->allocated_spis->get(this->allocated_spis, &spi) ||
this->sas->find_first(this->sas, (void*)match_entry_by_spi_inbound, this->sas->find_first(this->sas, match_entry_by_spi_inbound,
NULL, &spi, TRUE) == SUCCESS) NULL, spi, TRUE))
{ {
return FALSE; return FALSE;
} }
@ -484,8 +501,8 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
free(spi_alloc); free(spi_alloc);
} }
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, NULL,
NULL, &spi, src, dst) == SUCCESS) spi, src, dst))
{ {
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
DBG1(DBG_ESP, "failed to install SAD entry: already installed"); DBG1(DBG_ESP, "failed to install SAD entry: already installed");
@ -519,8 +536,8 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t,
} }
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb,
(void**)&entry, &spi, src, dst) == SUCCESS && (void**)&entry, spi, src, dst) &&
wait_for_entry(this, entry)) wait_for_entry(this, entry))
{ {
entry->sa->set_source(entry->sa, new_src); entry->sa->set_source(entry->sa, new_src);
@ -547,8 +564,8 @@ METHOD(ipsec_sa_mgr_t, query_sa, status_t,
ipsec_sa_entry_t *entry = NULL; ipsec_sa_entry_t *entry = NULL;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb,
(void**)&entry, &spi, src, dst) == SUCCESS && (void**)&entry, spi, src, dst) &&
wait_for_entry(this, entry)) wait_for_entry(this, entry))
{ {
entry->sa->get_usestats(entry->sa, bytes, packets, time); entry->sa->get_usestats(entry->sa, bytes, packets, time);
@ -572,7 +589,7 @@ METHOD(ipsec_sa_mgr_t, del_sa, status_t,
enumerator = this->sas->create_enumerator(this->sas); enumerator = this->sas->create_enumerator(this->sas);
while (enumerator->enumerate(enumerator, (void**)&current)) while (enumerator->enumerate(enumerator, (void**)&current))
{ {
if (match_entry_by_spi_src_dst(current, &spi, src, dst)) if (match_entry_by_spi_src_dst(current, spi, src, dst))
{ {
if (wait_remove_entry(this, current)) if (wait_remove_entry(this, current))
{ {
@ -602,8 +619,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_reqid, ipsec_sa_t*,
ipsec_sa_t *sa = NULL; ipsec_sa_t *sa = NULL;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_reqid_inbound, if (this->sas->find_first(this->sas, match_entry_by_reqid_inbound,
(void**)&entry, &reqid, &inbound) == SUCCESS && (void**)&entry, reqid, inbound) &&
wait_for_entry(this, entry)) wait_for_entry(this, entry))
{ {
sa = entry->sa; sa = entry->sa;
@ -619,8 +636,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_spi, ipsec_sa_t*,
ipsec_sa_t *sa = NULL; ipsec_sa_t *sa = NULL;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_dst, if (this->sas->find_first(this->sas, match_entry_by_spi_dst,
(void**)&entry, &spi, dst) == SUCCESS && (void**)&entry, spi, dst) &&
wait_for_entry(this, entry)) wait_for_entry(this, entry))
{ {
sa = entry->sa; sa = entry->sa;
@ -635,8 +652,8 @@ METHOD(ipsec_sa_mgr_t, checkin, void,
ipsec_sa_entry_t *entry; ipsec_sa_entry_t *entry;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
if (this->sas->find_first(this->sas, (void*)match_entry_by_sa_ptr, if (this->sas->find_first(this->sas, match_entry_by_sa_ptr,
(void**)&entry, sa) == SUCCESS) (void**)&entry, sa))
{ {
if (entry->locked) if (entry->locked)
{ {

View File

@ -47,6 +47,17 @@ struct element_t {
element_t *next; element_t *next;
}; };
/*
* Described in header
*/
bool linked_list_match_str(void *item, va_list args)
{
char *a = item, *b;
VA_ARGS_VGET(args, b);
return streq(a, b);
}
/** /**
* Creates an empty linked list object. * Creates an empty linked list object.
*/ */
@ -371,26 +382,41 @@ METHOD(linked_list_t, remove_at, void,
} }
} }
METHOD(linked_list_t, find_first, status_t, METHOD(linked_list_t, find_first, bool,
private_linked_list_t *this, linked_list_match_t match, private_linked_list_t *this, linked_list_match_t match, void **item, ...)
void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
{ {
element_t *current = this->first; element_t *current = this->first;
va_list args;
bool matched = FALSE;
if (!match && !item)
{
return FALSE;
}
while (current) while (current)
{ {
if ((match && match(current->value, d1, d2, d3, d4, d5)) || if (match)
(!match && item && current->value == *item)) {
va_start(args, item);
matched = match(current->value, args);
va_end(args);
}
else
{
matched = current->value == *item;
}
if (matched)
{ {
if (item != NULL) if (item != NULL)
{ {
*item = current->value; *item = current->value;
} }
return SUCCESS; return TRUE;
} }
current = current->next; current = current->next;
} }
return NOT_FOUND; return FALSE;
} }
METHOD(linked_list_t, invoke_offset, void, METHOD(linked_list_t, invoke_offset, void,
@ -548,7 +574,7 @@ linked_list_t *linked_list_create()
.reset_enumerator = (void*)_reset_enumerator, .reset_enumerator = (void*)_reset_enumerator,
.get_first = _get_first, .get_first = _get_first,
.get_last = _get_last, .get_last = _get_last,
.find_first = (void*)_find_first, .find_first = _find_first,
.insert_first = _insert_first, .insert_first = _insert_first,
.insert_last = _insert_last, .insert_last = _insert_last,
.insert_before = (void*)_insert_before, .insert_before = (void*)_insert_before,

View File

@ -28,15 +28,22 @@ typedef struct linked_list_t linked_list_t;
#include <collections/enumerator.h> #include <collections/enumerator.h>
/** /**
* Method to match elements in a linked list (used in find_* functions) * Function to match elements in a linked list
* *
* @param item current list item * @param item current list item
* @param ... user supplied data (only pointers, at most 5) * @param args user supplied data
* @return * @return TRUE, if the item matched, FALSE otherwise
* - TRUE, if the item matched
* - FALSE, otherwise
*/ */
typedef bool (*linked_list_match_t)(void *item, ...); typedef bool (*linked_list_match_t)(void *item, va_list args);
/**
* Helper function to match a string in a linked list of strings
*
* @param item list item (char*)
* @param args user supplied data (char*)
* @return
*/
bool linked_list_match_str(void *item, va_list args);
/** /**
* Function to be invoked on elements in a linked list * Function to be invoked on elements in a linked list
@ -167,21 +174,20 @@ struct linked_list_t {
* *
* The first object passed to the match function is the current list item, * The first object passed to the match function is the current list item,
* followed by the user supplied data. * followed by the user supplied data.
* If the supplied function returns TRUE this function returns SUCCESS, and * If the supplied function returns TRUE so does this function, and the
* the current object is returned in the third parameter, otherwise, * current object is returned in the third parameter (if given), otherwise,
* the next item is checked. * the next item is checked.
* *
* If match is NULL, *item and the current object are compared. * If match is NULL, *item and the current object are compared.
* *
* @warning Only use pointers as user supplied data.
*
* @param match comparison function to call on each object, or NULL * @param match comparison function to call on each object, or NULL
* @param item the list item, if found * @param item the list item, if found, or NULL
* @param ... user data to supply to match function (limited to 5 arguments) * @param ... user data to supply to match function
* @return SUCCESS if found, NOT_FOUND otherwise * @return TRUE if found, FALSE otherwise (or if neither match,
* nor item is supplied)
*/ */
status_t (*find_first) (linked_list_t *this, linked_list_match_t match, bool (*find_first)(linked_list_t *this, linked_list_match_t match,
void **item, ...); void **item, ...);
/** /**
* Invoke a method on all of the contained objects. * Invoke a method on all of the contained objects.

View File

@ -812,11 +812,12 @@ static bool verify_trust_chain(private_credential_manager_t *this,
return trusted; return trusted;
} }
/** CALLBACK(cert_equals, bool,
* List find match function for certificates certificate_t *a, va_list args)
*/
static bool cert_equals(certificate_t *a, certificate_t *b)
{ {
certificate_t *b;
VA_ARGS_VGET(args, b);
return a->equals(a, b); return a->equals(a, b);
} }
@ -896,8 +897,7 @@ METHOD(enumerator_t, trusted_enumerate, bool,
continue; continue;
} }
if (this->failed->find_first(this->failed, (void*)cert_equals, if (this->failed->find_first(this->failed, cert_equals, NULL, current))
NULL, current) == SUCCESS)
{ /* check each candidate only once */ { /* check each candidate only once */
continue; continue;
} }

View File

@ -149,8 +149,12 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
cert_data_destroy); cert_data_destroy);
} }
static bool certificate_equals(certificate_t *item, certificate_t *cert) CALLBACK(certificate_equals, bool,
certificate_t *item, va_list args)
{ {
certificate_t *cert;
VA_ARGS_VGET(args, cert);
return item->equals(item, cert); return item->equals(item, cert);
} }
@ -163,9 +167,8 @@ static certificate_t *add_cert_internal(private_mem_cred_t *this, bool trusted,
{ {
certificate_t *cached; certificate_t *cached;
this->lock->write_lock(this->lock); this->lock->write_lock(this->lock);
if (this->untrusted->find_first(this->untrusted, if (this->untrusted->find_first(this->untrusted, certificate_equals,
(linked_list_match_t)certificate_equals, (void**)&cached, cert))
(void**)&cached, cert) == SUCCESS)
{ {
cert->destroy(cert); cert->destroy(cert);
cert = cached->get_ref(cached); cert = cached->get_ref(cached);
@ -201,9 +204,8 @@ METHOD(mem_cred_t, get_cert_ref, certificate_t*,
certificate_t *cached; certificate_t *cached;
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
if (this->untrusted->find_first(this->untrusted, if (this->untrusted->find_first(this->untrusted, certificate_equals,
(linked_list_match_t)certificate_equals, (void**)&cached, cert))
(void**)&cached, cert) == SUCCESS)
{ {
cert->destroy(cert); cert->destroy(cert);
cert = cached->get_ref(cached); cert = cached->get_ref(cached);

View File

@ -811,11 +811,12 @@ METHOD(crypto_factory_t, remove_dh, void,
this->lock->unlock(this->lock); this->lock->unlock(this->lock);
} }
/** CALLBACK(entry_match, bool,
* match algorithms of an entry? entry_t *a, va_list args)
*/
static bool entry_match(entry_t *a, entry_t *b)
{ {
entry_t *b;
VA_ARGS_VGET(args, b);
return a->algo == b->algo; return a->algo == b->algo;
} }
@ -828,7 +829,7 @@ CALLBACK(unique_check, bool,
while (orig->enumerate(orig, &entry)) while (orig->enumerate(orig, &entry))
{ {
if (list->find_first(list, (void*)entry_match, NULL, entry) == SUCCESS) if (list->find_first(list, entry_match, NULL, entry))
{ {
continue; continue;
} }

View File

@ -606,18 +606,14 @@ static void load_provided(private_plugin_loader_t *this,
provided_feature_t *provided, provided_feature_t *provided,
int level); int level);
/** CALLBACK(is_feature_loaded, bool,
* Used to find a loaded feature provided_feature_t *item, va_list args)
*/
static bool is_feature_loaded(provided_feature_t *item)
{ {
return item->loaded; return item->loaded;
} }
/** CALLBACK(is_feature_loadable, bool,
* Used to find a loadable feature provided_feature_t *item, va_list args)
*/
static bool is_feature_loadable(provided_feature_t *item)
{ {
return !item->loading && !item->loaded && !item->failed; return !item->loading && !item->loaded && !item->failed;
} }
@ -630,8 +626,7 @@ static bool loaded_feature_matches(registered_feature_t *a,
{ {
if (plugin_feature_matches(a->feature, b->feature)) if (plugin_feature_matches(a->feature, b->feature))
{ {
return b->plugins->find_first(b->plugins, (void*)is_feature_loaded, return b->plugins->find_first(b->plugins, is_feature_loaded, NULL);
NULL) == SUCCESS;
} }
return FALSE; return FALSE;
} }
@ -644,8 +639,7 @@ static bool loadable_feature_equals(registered_feature_t *a,
{ {
if (plugin_feature_equals(a->feature, b->feature)) if (plugin_feature_equals(a->feature, b->feature))
{ {
return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, return b->plugins->find_first(b->plugins, is_feature_loadable, NULL);
NULL) == SUCCESS;
} }
return FALSE; return FALSE;
} }
@ -658,8 +652,7 @@ static bool loadable_feature_matches(registered_feature_t *a,
{ {
if (plugin_feature_matches(a->feature, b->feature)) if (plugin_feature_matches(a->feature, b->feature))
{ {
return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, return b->plugins->find_first(b->plugins, is_feature_loadable, NULL);
NULL) == SUCCESS;
} }
return FALSE; return FALSE;
} }
@ -1011,8 +1004,8 @@ static void purge_plugins(private_plugin_loader_t *this)
{ /* feature interface not supported */ { /* feature interface not supported */
continue; continue;
} }
if (entry->features->find_first(entry->features, if (!entry->features->find_first(entry->features, is_feature_loaded,
(void*)is_feature_loaded, NULL) != SUCCESS) NULL))
{ {
DBG2(DBG_LIB, "unloading plugin '%s' without loaded features", DBG2(DBG_LIB, "unloading plugin '%s' without loaded features",
entry->plugin->get_name(entry->plugin)); entry->plugin->get_name(entry->plugin));
@ -1062,6 +1055,15 @@ static bool find_plugin(char *path, char *name, char *buf, char **file)
return FALSE; return FALSE;
} }
CALLBACK(find_plugin_cb, bool,
char *path, va_list args)
{
char *name, *buf, **file;
VA_ARGS_VGET(args, name, buf, file);
return find_plugin(path, name, buf, file);
}
/** /**
* Used to sort plugins by priority * Used to sort plugins by priority
*/ */
@ -1244,8 +1246,8 @@ METHOD(plugin_loader_t, load_plugins, bool,
} }
if (this->paths) if (this->paths)
{ {
this->paths->find_first(this->paths, (void*)find_plugin, NULL, this->paths->find_first(this->paths, find_plugin_cb, NULL, token,
token, buf, &file); buf, &file);
} }
if (!file) if (!file)
{ {

View File

@ -183,26 +183,48 @@ END_TEST
* find * find
*/ */
static bool match_a_b(void *item, void *a, void *b) CALLBACK(find_a_b, bool,
void *item, va_list args)
{ {
void *a, *b;
VA_ARGS_VGET(args, a, b);
ck_assert(a == (void*)1); ck_assert(a == (void*)1);
ck_assert(b == (void*)2); ck_assert(b == (void*)2);
return item == a || item == b; return item == a || item == b;
} }
CALLBACK(find_a, bool,
void *item, va_list args)
{
void *a;
VA_ARGS_VGET(args, a);
return match_a(item, a);
}
CALLBACK(find_b, bool,
void *item, va_list args)
{
void *b;
VA_ARGS_VGET(args, b);
return match_b(item, b);
}
START_TEST(test_find) START_TEST(test_find)
{ {
void *a = (void*)1, *b = (void*)2; void *a = (void*)1, *b = (void*)2;
ck_assert(list->find_first(list, NULL, &a) == NOT_FOUND); ck_assert(!list->find_first(list, NULL, &a));
list->insert_last(list, a); list->insert_last(list, a);
ck_assert(list->find_first(list, NULL, &a) == SUCCESS); ck_assert(list->find_first(list, NULL, &a));
ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND); ck_assert(!list->find_first(list, NULL, &b));
list->insert_last(list, b); list->insert_last(list, b);
ck_assert(list->find_first(list, NULL, &a) == SUCCESS); ck_assert(list->find_first(list, NULL, &a));
ck_assert(list->find_first(list, NULL, &b) == SUCCESS); ck_assert(list->find_first(list, NULL, &b));
ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND); ck_assert(!list->find_first(list, NULL, NULL));
} }
END_TEST END_TEST
@ -210,29 +232,57 @@ START_TEST(test_find_callback)
{ {
void *a = (void*)1, *b = (void*)2, *x = NULL; void *a = (void*)1, *b = (void*)2, *x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND); ck_assert(!list->find_first(list, find_a_b, &x, a, b));
list->insert_last(list, a); list->insert_last(list, a);
ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS); ck_assert(list->find_first(list, find_a, NULL, a));
x = NULL; x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS); ck_assert(list->find_first(list, find_a, &x, a));
ck_assert(a == x); ck_assert(a == x);
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND); ck_assert(!list->find_first(list, find_b, &x, b));
ck_assert(a == x); ck_assert(a == x);
x = NULL; x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS); ck_assert(list->find_first(list, find_a_b, &x, a, b));
ck_assert(a == x); ck_assert(a == x);
list->insert_last(list, b); list->insert_last(list, b);
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS); ck_assert(list->find_first(list, find_a, &x, a));
ck_assert(a == x); ck_assert(a == x);
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS); ck_assert(list->find_first(list, find_b, &x, b));
ck_assert(b == x); ck_assert(b == x);
x = NULL; x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS); ck_assert(list->find_first(list, find_a_b, &x, a, b));
ck_assert(a == x); ck_assert(a == x);
} }
END_TEST END_TEST
CALLBACK(find_args, bool,
void *item, va_list args)
{
uint64_t d, e;
level_t c;
int *a, b;
VA_ARGS_VGET(args, a, b, c, d, e);
ck_assert_int_eq(*a, 1);
ck_assert_int_eq(b, 2);
ck_assert_int_eq(c, LEVEL_PRIVATE);
ck_assert_int_eq(d, UINT64_MAX);
ck_assert_int_eq(e, UINT64_MAX-1);
return item == a;
}
START_TEST(test_find_callback_args)
{
int a = 1, b = 2, *x;
uint64_t d = UINT64_MAX;
list->insert_last(list, &a);
ck_assert(list->find_first(list, find_args, (void**)&x, &a, b,
LEVEL_PRIVATE, d, UINT64_MAX-1));
ck_assert_int_eq(a, *x);
}
END_TEST
/******************************************************************************* /*******************************************************************************
* invoke * invoke
*/ */
@ -464,6 +514,7 @@ Suite *linked_list_suite_create()
tcase_add_checked_fixture(tc, setup_list, teardown_list); tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_find); tcase_add_test(tc, test_find);
tcase_add_test(tc, test_find_callback); tcase_add_test(tc, test_find_callback);
tcase_add_test(tc, test_find_callback_args);
suite_add_tcase(s, tc); suite_add_tcase(s, tc);
tc = tcase_create("invoke"); tc = tcase_create("invoke");