diff options
| author | Tobias Brunner <tobias@strongswan.org> | 2017-05-26 13:57:57 +0200 |
|---|---|---|
| committer | Tobias Brunner <tobias@strongswan.org> | 2017-05-26 14:24:13 +0200 |
| commit | b668bf3f9ec1e6e44cb31c727ac928105e383b32 (patch) | |
| tree | db62e4fcd1a955b5179c6f172a9403500bb24e50 /src/libcharon/plugins | |
| parent | 0da10b73addd8c181bed0772c7eac32d28d8af77 (diff) | |
| parent | 2e4d110d1e94a3be9da06894832492ff469eec37 (diff) | |
| download | strongswan-b668bf3f9ec1.tar.bz2 strongswan-b668bf3f9ec1.tar.xz | |
Merge branch 'variadic-enumerators'
This adds several changes to enumerator_t and linked_list_t to improve
portability. In particular to Apple's ARM64 iOS platform, whose calling
convention for variadic and regular functions are different. This means
that assigning a non-variadic function to a variadic function pointer,
as we did with our enumerator_t::enumerate() implementations and several
callbacks, will result in crashes as the called function will access the
arguments differently than the caller provided them.
To avoid this issue the enumerator_t interface is now fully variadic.
A new mandatory method is added, venumerate(), that takes a va_list with
the arguments provided while enumerating. enumerate() is replaced with
a generic implementation that prepares a va_list and calls the
enumerator's venumerate() implementation. As this allows passing the
arguments of one enumerator to another it avoids the five pointer hack
used by enumerator_create_nested() and enumerator_create_cleaner().
To simplify the implementation of venumerate() a helper macro is provided
that assigns values from a given va_list to local variables.
The signature of the callback passed to enumerator_create_filter() has
also changed significantly. It's now required to enumerate over the
original enumerator in the callback as this avoids the previous in/out
pointer hack. The arguments to the outer enumerator are provided in a
va_list.
Similar changes to avoid such five pointer hacks affect the signatures
of the callbacks for linked_list_t's invoke_function() and find_first()
methods. For the latter the return type also changed from status_t to
bool, which is important as SUCCESS is defined as 0, so checks for ==
SUCCESS will now fail.
Diffstat (limited to 'src/libcharon/plugins')
44 files changed, 738 insertions, 503 deletions
diff --git a/src/libcharon/plugins/android_dns/android_dns_handler.c b/src/libcharon/plugins/android_dns/android_dns_handler.c index 160a145d3..68bbaecb2 100644 --- a/src/libcharon/plugins/android_dns/android_dns_handler.c +++ b/src/libcharon/plugins/android_dns/android_dns_handler.c @@ -182,12 +182,15 @@ METHOD(attribute_handler_t, release, void, } METHOD(enumerator_t, enumerate_dns, bool, - enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data) + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_DNS; *data = chunk_empty; - /* stop enumeration */ - this->enumerate = (void*)return_false; + this->venumerate = return_false; return TRUE; } @@ -198,7 +201,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, enumerator_t *enumerator; INIT(enumerator, - .enumerate = (void*)_enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c index f4c143641..3310f79fd 100644 --- a/src/libcharon/plugins/attr/attr_provider.c +++ b/src/libcharon/plugins/attr/attr_provider.c @@ -75,17 +75,23 @@ typedef struct { ike_version_t ike; } enumerator_data_t; -/** - * convert enumerator value from attribute_entry - */ -static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in, - configuration_attribute_type_t *type, void* none, chunk_t *value) +CALLBACK(attr_enum_filter, bool, + enumerator_data_t *data, enumerator_t *orig, va_list args) { - if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike) + configuration_attribute_type_t *type; + attribute_entry_t *entry; + chunk_t *value; + + VA_ARGS_VGET(args, type, value); + + while (orig->enumerate(orig, &entry)) { - *type = (*in)->type; - *value = (*in)->value; - return TRUE; + if (entry->ike == IKE_ANY || entry->ike == data->ike) + { + *type = entry->type; + *value = entry->value; + return TRUE; + } } return FALSE; } @@ -112,7 +118,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attr_enum_filter, data, attr_enum_destroy); + attr_enum_filter, data, attr_enum_destroy); } return enumerator_create_empty(); } diff --git a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c index e690028f2..644cff029 100644 --- a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c +++ b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c @@ -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) { - status_t expected; - if (!iface || !this->ifaces_filter) { return TRUE; } - expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; - return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, - NULL, iface) == expected; + return this->ifaces_filter->find_first(this->ifaces_filter, + linked_list_match_str, NULL, iface) != this->ifaces_exclude; } /** diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c index f0681b1da..50ffbab9d 100644 --- a/src/libcharon/plugins/dhcp/dhcp_provider.c +++ b/src/libcharon/plugins/dhcp/dhcp_provider.c @@ -151,8 +151,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, identification_t *id; host_t *vip; - if (pools->find_first(pools, (linked_list_match_t)streq, - NULL, "dhcp") != SUCCESS) + if (!pools->find_first(pools, linked_list_match_str, NULL, "dhcp")) { return NULL; } diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index 807c68274..42f8f1ef9 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -382,8 +382,7 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*, while (try <= DHCP_TRIES && discover(this, transaction)) { if (!this->condvar->timed_wait(this->condvar, this->mutex, 1000 * try) && - this->request->find_first(this->request, NULL, - (void**)&transaction) == SUCCESS) + this->request->find_first(this->request, NULL, (void**)&transaction)) { break; } diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.c b/src/libcharon/plugins/dhcp/dhcp_transaction.c index 3ee88a698..87711799c 100644 --- a/src/libcharon/plugins/dhcp/dhcp_transaction.c +++ b/src/libcharon/plugins/dhcp/dhcp_transaction.c @@ -114,16 +114,22 @@ METHOD(dhcp_transaction_t, add_attribute, void, this->attributes->insert_last(this->attributes, entry); } -/** - * Filter function to map entries to type/data - */ -static bool attribute_filter(void *null, attribute_entry_t **entry, - configuration_attribute_type_t *type, - void **dummy, chunk_t *data) +CALLBACK(attribute_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *type = (*entry)->type; - *data = (*entry)->data; - return TRUE; + configuration_attribute_type_t *type; + attribute_entry_t *entry; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); + + if (orig->enumerate(orig, &entry)) + { + *type = entry->type; + *data = entry->data; + return TRUE; + } + return FALSE; } METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*, @@ -131,7 +137,7 @@ METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*, { return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attribute_filter, NULL, NULL); + attribute_filter, NULL, NULL); } /** diff --git a/src/libcharon/plugins/dnscert/dnscert_cred.c b/src/libcharon/plugins/dnscert/dnscert_cred.c index d32794c99..533bd5be4 100644 --- a/src/libcharon/plugins/dnscert/dnscert_cred.c +++ b/src/libcharon/plugins/dnscert/dnscert_cred.c @@ -75,12 +75,15 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; dnscert_t *cur_crt; rr_t *cur_rr; chunk_t certificate; + VA_ARGS_VGET(args, cert); + /* Get the next supported CERT using the inner enumerator. */ while (this->inner->enumerate(this->inner, &cur_rr)) { @@ -175,7 +178,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .inner = response->get_rr_set(response)->create_rr_enumerator( diff --git a/src/libcharon/plugins/eap_dynamic/eap_dynamic.c b/src/libcharon/plugins/eap_dynamic/eap_dynamic.c index 83ccd3a8a..204fb317d 100644 --- a/src/libcharon/plugins/eap_dynamic/eap_dynamic.c +++ b/src/libcharon/plugins/eap_dynamic/eap_dynamic.c @@ -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; } +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 */ @@ -121,8 +130,7 @@ static void select_method(private_eap_dynamic_t *this) { if (inner) { - if (inner->find_first(inner, (void*)entry_matches, - NULL, entry) != SUCCESS) + if (!inner->find_first(inner, entry_matches_cb, NULL, entry)) { if (entry->vendor) { diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c index 9a87ad38d..58bbc2edd 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c @@ -404,11 +404,13 @@ typedef struct { attr_t *current; } attribute_enumerator_t; - METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->current) { destroy_attr(this->current); @@ -446,7 +448,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _attribute_destroy, }, .list = linked_list_create(), diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c index ec1686910..e11e0e5ea 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c @@ -79,10 +79,8 @@ typedef struct { private_eap_sim_file_triplets_t *this; } triplet_enumerator_t; -/** - * destroy a triplet enumerator - */ -static void enumerator_destroy(triplet_enumerator_t *e) +METHOD(enumerator_t, enumerator_destroy, void, + triplet_enumerator_t *e) { if (e->current) { @@ -97,13 +95,14 @@ static void enumerator_destroy(triplet_enumerator_t *e) free(e); } -/** - * enumerate through triplets - */ -static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **imsi, - char **rand, char **sres, char **kc) +METHOD(enumerator_t, enumerator_enumerate, bool, + triplet_enumerator_t *e, va_list args) { + identification_t **imsi; triplet_t *triplet; + char **rand, **sres, **kc; + + VA_ARGS_VGET(args, imsi, rand, sres, kc); if (e->inner->enumerate(e->inner, &triplet)) { @@ -124,12 +123,15 @@ METHOD(eap_sim_file_triplets_t, create_enumerator, enumerator_t*, triplet_enumerator_t *enumerator = malloc_thing(triplet_enumerator_t); this->mutex->lock(this->mutex); - enumerator->public.enumerate = (void*)enumerator_enumerate; - enumerator->public.destroy = (void*)enumerator_destroy; - enumerator->inner = this->triplets->create_enumerator(this->triplets); - enumerator->current = NULL; - enumerator->this = this; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerator_enumerate, + .destroy = _enumerator_destroy, + }, + .inner = this->triplets->create_enumerator(this->triplets), + .this = this, + ); return &enumerator->public; } diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c index 2024c2682..4585731de 100644 --- a/src/libcharon/plugins/forecast/forecast_listener.c +++ b/src/libcharon/plugins/forecast/forecast_listener.c @@ -613,17 +613,23 @@ METHOD(listener_t, ike_update, bool, return TRUE; } -/** - * Filter to map entries to ts/mark - */ -static bool ts_filter(entry_t *entry, traffic_selector_t **ts, - traffic_selector_t **out, void *dummy, uint32_t *mark, - void *dummy2, bool *reinject) +CALLBACK(ts_filter, bool, + entry_t *entry, enumerator_t *orig, va_list args) { - *out = *ts; - *mark = entry->mark; - *reinject = entry->reinject; - return TRUE; + traffic_selector_t *ts, **out; + uint32_t *mark; + bool *reinject; + + VA_ARGS_VGET(args, out, mark, reinject); + + if (orig->enumerate(orig, &ts)) + { + *out = ts; + *mark = entry->mark; + *reinject = entry->reinject; + return TRUE; + } + return FALSE; } /** @@ -632,7 +638,7 @@ static bool ts_filter(entry_t *entry, traffic_selector_t **ts, static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock) { return enumerator_create_filter(array_create_enumerator(entry->lts), - (void*)ts_filter, entry, NULL); + ts_filter, entry, NULL); } /** @@ -641,7 +647,7 @@ static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock) static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock) { return enumerator_create_filter(array_create_enumerator(entry->rts), - (void*)ts_filter, entry, NULL); + ts_filter, entry, NULL); } METHOD(forecast_listener_t, create_enumerator, enumerator_t*, diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c index 42dfaf0e2..5f73b7156 100644 --- a/src/libcharon/plugins/ha/ha_message.c +++ b/src/libcharon/plugins/ha/ha_message.c @@ -331,10 +331,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, ha_message_attribute_t *attr_out, - ha_message_value_t *value) + attribute_enumerator_t *this, va_list args) { - ha_message_attribute_t attr; + ha_message_attribute_t attr, *attr_out; + ha_message_value_t *value; + + VA_ARGS_VGET(args, attr_out, value); if (this->cleanup) { @@ -602,7 +604,8 @@ METHOD(ha_message_t, create_attribute_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _enum_destroy, }, .buf = chunk_skip(this->buf, 2), diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c index a0e514614..1a6108ed9 100644 --- a/src/libcharon/plugins/ha/ha_tunnel.c +++ b/src/libcharon/plugins/ha/ha_tunnel.c @@ -111,8 +111,12 @@ typedef struct { } shared_enum_t; METHOD(enumerator_t, shared_enumerate, bool, - shared_enum_t *this, shared_key_t **key, id_match_t *me, id_match_t *other) + shared_enum_t *this, va_list args) { + shared_key_t **key; + id_match_t *me, *other; + + VA_ARGS_VGET(args, key, me, other); if (this->key) { if (me) @@ -151,7 +155,8 @@ METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = (void*)free, }, .key = this->key, diff --git a/src/libcharon/plugins/ipseckey/ipseckey_cred.c b/src/libcharon/plugins/ipseckey/ipseckey_cred.c index ff50d8a17..b3ac2b328 100644 --- a/src/libcharon/plugins/ipseckey/ipseckey_cred.c +++ b/src/libcharon/plugins/ipseckey/ipseckey_cred.c @@ -62,13 +62,16 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; ipseckey_t *cur_ipseckey; public_key_t *public; rr_t *cur_rr; chunk_t key; + VA_ARGS_VGET(args, cert); + /* Get the next supported IPSECKEY using the inner enumerator. */ while (this->inner->enumerate(this->inner, &cur_rr)) { @@ -211,7 +214,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .inner = rrset->create_rr_enumerator(rrset), diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c index efeb98045..18a87b707 100644 --- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c +++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c @@ -466,9 +466,12 @@ typedef struct { } addr_enumerator_t; METHOD(enumerator_t, addr_enumerate, bool, - addr_enumerator_t *this, host_t **host) + addr_enumerator_t *this, va_list args) { iface_t *entry; + host_t **host; + + VA_ARGS_VGET(args, host); while (TRUE) { @@ -523,7 +526,8 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_addr_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _addr_enumerate, .destroy = _addr_destroy, }, .which = which, diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 77e37e249..d4832e233 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -84,12 +84,12 @@ static void exclude_route_destroy(exclude_route_t *this) free(this); } -/** - * Find an exclude route entry by destination address - */ -static bool exclude_route_match(exclude_route_t *current, - host_t *dst) +CALLBACK(exclude_route_match, bool, + exclude_route_t *current, va_list args) { + host_t *dst; + + VA_ARGS_VGET(args, dst); return dst->ip_equals(dst, current->dst); } @@ -204,12 +204,12 @@ static void policy_entry_destroy(policy_entry_t *this) free(this); } -/** - * Compare two policy_entry_t objects - */ -static inline bool policy_entry_equals(policy_entry_t *a, - policy_entry_t *b) +CALLBACK(policy_entry_equals, bool, + policy_entry_t *a, va_list args) { + policy_entry_t *b; + + VA_ARGS_VGET(args, b); return a->direction == b->direction && a->src.proto == b->src.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; host_t *gtw; - if (this->excludes->find_first(this->excludes, - (linked_list_match_t)exclude_route_match, - (void**)&exclude, dst) == SUCCESS) + if (this->excludes->find_first(this->excludes, exclude_route_match, + (void**)&exclude, dst)) { route->exclude = exclude; 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); this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) == SUCCESS) + if (this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { policy_entry_destroy(policy); 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); this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { policy_entry_destroy(policy); this->mutex->unlock(this->mutex); diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index da05de304..c411b829d 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -542,10 +542,10 @@ static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this, /** * Destroy a policy_sa(_in)_t object */ -static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir, private_kernel_netlink_ipsec_t *this) { - if (*dir == POLICY_OUT) + if (dir == POLICY_OUT) { policy_sa_out_t *out = (policy_sa_out_t*)policy; out->src_ts->destroy(out->src_ts); @@ -555,6 +555,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, free(policy); } +CALLBACK(policy_sa_destroy_cb, void, + policy_sa_t *policy, va_list args) +{ + private_kernel_netlink_ipsec_t *this; + policy_dir_t dir; + + VA_ARGS_VGET(args, dir, this); + policy_sa_destroy(policy, dir, this); +} + typedef struct policy_entry_t policy_entry_t; /** @@ -599,9 +609,8 @@ static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this, } if (policy->used_by) { - policy->used_by->invoke_function(policy->used_by, - (linked_list_invoke_t)policy_sa_destroy, - &policy->direction, this); + policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb, + policy->direction, this); policy->used_by->destroy(policy->used_by); } free(policy); @@ -2768,7 +2777,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, ipsec_sa_equals(mapping->sa, &assigned_sa)) { current->used_by->remove_at(current->used_by, enumerator); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); break; } if (is_installed) diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index 2dc76d941..0dd3e30cb 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -163,19 +163,21 @@ static void iface_entry_destroy(iface_entry_t *this) free(this); } -/** - * find an interface entry by index - */ -static bool iface_entry_by_index(iface_entry_t *this, int *ifindex) +CALLBACK(iface_entry_by_index, bool, + iface_entry_t *this, va_list args) { - return this->ifindex == *ifindex; + int ifindex; + + VA_ARGS_VGET(args, ifindex); + return this->ifindex == ifindex; } -/** - * find an interface entry by name - */ -static bool iface_entry_by_name(iface_entry_t *this, char *ifname) +CALLBACK(iface_entry_by_name, bool, + iface_entry_t *this, va_list args) { + char *ifname; + + VA_ARGS_VGET(args, 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; - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, index)) { return iface_entry_up_and_usable(iface); } @@ -1125,9 +1127,13 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this, * * this->lock must be locked when calling this function */ -static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface, - private_kernel_netlink_net_t *this) +CALLBACK(addr_entry_unregister, void, + addr_entry_t *addr, va_list args) { + private_kernel_netlink_net_t *this; + iface_entry_t *iface; + + VA_ARGS_VGET(args, iface, this); if (addr->refcount) { addr_map_entry_remove(this->vips, addr, iface); @@ -1171,9 +1177,8 @@ static void process_link(private_kernel_netlink_net_t *this, { case RTM_NEWLINK: { - if (this->ifaces->find_first(this->ifaces, - (void*)iface_entry_by_index, (void**)&entry, - &msg->ifi_index) != SUCCESS) + if (!this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&entry, msg->ifi_index)) { INIT(entry, .ifindex = msg->ifi_index, @@ -1217,7 +1222,7 @@ static void process_link(private_kernel_netlink_net_t *this, * another interface? */ this->ifaces->remove_at(this->ifaces, enumerator); current->addrs->invoke_function(current->addrs, - (void*)addr_entry_unregister, current, this); + addr_entry_unregister, current, this); iface_entry_destroy(current); break; } @@ -1288,8 +1293,8 @@ static void process_addr(private_kernel_netlink_net_t *this, } this->lock->write_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &msg->ifa_index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, msg->ifa_index)) { addr_map_entry_t *entry, lookup = { .ip = host, @@ -1518,35 +1523,39 @@ typedef struct { kernel_address_type_t which; } address_enumerator_t; -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) +CALLBACK(address_enumerator_destroy, void, + address_enumerator_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, - addr_entry_t** in, host_t** out) +CALLBACK(filter_addresses, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->refcount) - { /* skip virtual interfaces added by us */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->refcount) - { /* address is regular, but not requested */ - return FALSE; - } - if ((*in)->scope >= RT_SCOPE_LINK) - { /* skip addresses with a unusable scope */ - return FALSE; + addr_entry_t *addr; + host_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &addr)) + { + if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->refcount) + { /* skip virtual interfaces added by us */ + continue; + } + if (!(data->which & ADDR_TYPE_REGULAR) && !addr->refcount) + { /* address is regular, but not requested */ + continue; + } + if (addr->scope >= RT_SCOPE_LINK) + { /* skip addresses with a unusable scope */ + continue; + } + *out = addr->ip; + return TRUE; } - *out = (*in)->ip; - return TRUE; + return FALSE; } /** @@ -1556,30 +1565,35 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) { return enumerator_create_filter( - iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); + iface->addrs->create_enumerator(iface->addrs), + filter_addresses, data, NULL); } -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, - iface_entry_t** out) +CALLBACK(filter_interfaces, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) - { /* skip interfaces excluded by config */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) - { /* ignore loopback devices */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; + iface_entry_t *iface, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &iface)) + { + if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable) + { /* skip interfaces excluded by config */ + continue; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + continue; + } + if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP)) + { /* skip interfaces not up */ + continue; + } + *out = iface; + return TRUE; } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1596,9 +1610,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, return enumerator_create_nested( enumerator_create_filter( this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), + filter_interfaces, data, NULL), (void*)create_iface_enumerator, data, - (void*)address_enumerator_destroy); + address_enumerator_destroy); } METHOD(kernel_net_t, get_interface_name, bool, @@ -1661,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); this->lock->read_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, name) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, name)) { ifindex = iface->ifindex; } @@ -1687,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); this->lock->read_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, index)) { name = strdup(iface->ifname); } @@ -1928,7 +1942,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, table = (uintptr_t)route->table; if (this->rt_exclude->find_first(this->rt_exclude, NULL, - (void**)&table) == SUCCESS) + (void**)&table)) { /* route is from an excluded routing table */ continue; } @@ -2165,8 +2179,14 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void, } METHOD(enumerator_t, enumerate_subnets, bool, - subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname) + subnet_enumerator_t *this, va_list args) { + host_t **net; + uint8_t *mask; + char **ifname; + + VA_ARGS_VGET(args, net, mask, ifname); + if (!this->current) { this->current = this->msg; @@ -2270,7 +2290,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_subnets, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_subnets, .destroy = _destroy_subnet_enumerator, }, .private = this, @@ -2380,11 +2401,11 @@ METHOD(kernel_net_t, add_ip, status_t, } /* try to find the target interface, either by config or via src ip */ if (!this->install_virtual_ip_on || - this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, this->install_virtual_ip_on) != SUCCESS) + !this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, this->install_virtual_ip_on)) { - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, iface_name) != SUCCESS) + if (!this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, iface_name)) { /* if we don't find the requested interface we just use the first */ this->ifaces->get_first(this->ifaces, (void**)&iface); } diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index fd427ebbb..fd1adb2ae 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -464,10 +464,10 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, /** * Destroy a policy_sa(_in)_t object */ -static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir, private_kernel_pfkey_ipsec_t *this) { - if (*dir == POLICY_OUT) + if (dir == POLICY_OUT) { policy_sa_out_t *out = (policy_sa_out_t*)policy; out->src_ts->destroy(out->src_ts); @@ -477,6 +477,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, free(policy); } +CALLBACK(policy_sa_destroy_cb, void, + policy_sa_t *policy, va_list args) +{ + private_kernel_pfkey_ipsec_t *this; + policy_dir_t dir; + + VA_ARGS_VGET(args, dir, this); + policy_sa_destroy(policy, dir, this); +} + typedef struct policy_entry_t policy_entry_t; /** @@ -557,9 +567,8 @@ static void policy_entry_destroy(policy_entry_t *policy, } if (policy->used_by) { - policy->used_by->invoke_function(policy->used_by, - (linked_list_invoke_t)policy_sa_destroy, - &policy->direction, this); + policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb, + policy->direction, this); policy->used_by->destroy(policy->used_by); } DESTROY_IF(policy->src.net); @@ -567,12 +576,21 @@ static void policy_entry_destroy(policy_entry_t *policy, free(policy); } -/** - * compares two policy_entry_t - */ -static inline bool policy_entry_equals(policy_entry_t *current, - policy_entry_t *policy) +CALLBACK(policy_entry_destroy_cb, void, + policy_entry_t *policy, va_list args) { + private_kernel_pfkey_ipsec_t *this; + + VA_ARGS_VGET(args, this); + policy_entry_destroy(policy, this); +} + +CALLBACK(policy_entry_equals, bool, + policy_entry_t *current, va_list args) +{ + policy_entry_t *policy; + + VA_ARGS_VGET(args, policy); return current->direction == policy->direction && current->src.proto == policy->src.proto && current->dst.proto == policy->dst.proto && @@ -582,13 +600,13 @@ static inline bool policy_entry_equals(policy_entry_t *current, current->dst.net->equals(current->dst.net, policy->dst.net); } -/** - * compare the given kernel index with that of a policy - */ -static inline bool policy_entry_match_byindex(policy_entry_t *current, - uint32_t *index) +CALLBACK(policy_entry_match_byindex, bool, + policy_entry_t *current, va_list args) { - return current->index == *index; + uint32_t index; + + VA_ARGS_VGET(args, index); + return current->index == index; } /** @@ -1261,9 +1279,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, index = response.x_policy->sadb_x_policy_id; this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_match_byindex, - (void**)&policy, &index) == SUCCESS && + if (this->policies->find_first(this->policies, policy_entry_match_byindex, + (void**)&policy, index) && policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS) { reqid = sa->sa->cfg.reqid; @@ -2554,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 */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, NULL, - (void**)&policy) != SUCCESS) + if (!this->policies->find_first(this->policies, NULL, (void**)&policy)) { DBG2(DBG_KNL, "unable to update index, the policy is already gone, " "ignoring"); @@ -2606,9 +2622,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) == SUCCESS) + if (this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { /* use existing policy */ DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing " "refcount", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2701,9 +2716,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2814,9 +2828,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2860,7 +2873,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, if (policy->used_by->get_count(policy->used_by) > 0) { /* policy is used by more SAs, keep in kernel */ DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); if (!is_installed) { /* no need to update as the policy was not installed for this SA */ @@ -2915,7 +2928,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, } this->policies->remove(this->policies, found, NULL); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); policy_entry_destroy(policy, this); this->mutex->unlock(this->mutex); @@ -3088,8 +3101,7 @@ METHOD(kernel_ipsec_t, destroy, void, lib->watcher->remove(lib->watcher, this->socket_events); close(this->socket_events); } - this->policies->invoke_function(this->policies, - (linked_list_invoke_t)policy_entry_destroy, + this->policies->invoke_function(this->policies, policy_entry_destroy_cb, this); this->policies->destroy(this->policies); this->excludes->destroy(this->excludes); diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index efcf1c2a7..6d06ee179 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -601,9 +601,12 @@ typedef struct { } rt_enumerator_t; METHOD(enumerator_t, rt_enumerate, bool, - rt_enumerator_t *this, int *xtype, struct sockaddr **addr) + rt_enumerator_t *this, va_list args) { - int i, type; + struct sockaddr **addr; + int i, type, *xtype; + + VA_ARGS_VGET(args, xtype, addr); if (this->remaining < sizeof(this->addr->sa_len) || this->remaining < this->addr->sa_len) @@ -637,7 +640,8 @@ static enumerator_t *create_rt_enumerator(int types, int remaining, INIT(this, .public = { - .enumerate = (void*)_rt_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rt_enumerate, .destroy = (void*)free, }, .types = types, @@ -1050,41 +1054,45 @@ typedef struct { kernel_address_type_t which; } address_enumerator_t; -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) +CALLBACK(address_enumerator_destroy, void, + address_enumerator_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, - addr_entry_t** in, host_t** out) +CALLBACK(filter_addresses, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - host_t *ip; - if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->virtual) - { /* skip virtual interfaces added by us */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->virtual) - { /* address is regular, but not requested */ - return FALSE; - } - ip = (*in)->ip; - if (ip->get_family(ip) == AF_INET6) + addr_entry_t *addr; + host_t *ip, **out; + struct sockaddr_in6 *sin6; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &addr)) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - { /* skip addresses with a unusable scope */ - return FALSE; + if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->virtual) + { /* skip virtual interfaces added by us */ + continue; } + if (!(data->which & ADDR_TYPE_REGULAR) && !addr->virtual) + { /* address is regular, but not requested */ + continue; + } + ip = addr->ip; + if (ip->get_family(ip) == AF_INET6) + { + sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + { /* skip addresses with a unusable scope */ + continue; + } + } + *out = ip; + return TRUE; } - *out = ip; - return TRUE; + return FALSE; } /** @@ -1094,29 +1102,34 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) { return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); + filter_addresses, data, NULL); } -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, - iface_entry_t** out) +CALLBACK(filter_interfaces, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) - { /* skip interfaces excluded by config */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) - { /* ignore loopback devices */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; + iface_entry_t *iface, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &iface)) + { + if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable) + { /* skip interfaces excluded by config */ + continue; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + continue; + } + if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP)) + { /* skip interfaces not up */ + continue; + } + *out = iface; + return TRUE; } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1133,9 +1146,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, return enumerator_create_nested( enumerator_create_filter( this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), + filter_interfaces, data, NULL), (void*)create_iface_enumerator, data, - (void*)address_enumerator_destroy); + address_enumerator_destroy); } METHOD(kernel_net_t, get_features, kernel_feature_t, @@ -1789,13 +1802,18 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void, } METHOD(enumerator_t, enumerate_subnets, bool, - subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname) + subnet_enumerator_t *this, va_list args) { enumerator_t *enumerator; + host_t **net; struct rt_msghdr *rtm; struct sockaddr *addr; + uint8_t *mask; + char **ifname; int type; + VA_ARGS_VGET(args, net, mask, ifname); + if (!this->current) { this->current = this->buf; @@ -1888,7 +1906,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_subnets, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_subnets, .destroy = _destroy_subnet_enumerator, }, .buf = buf, diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c index 2f482962a..2cedd130e 100644 --- a/src/libcharon/plugins/load_tester/load_tester_creds.c +++ b/src/libcharon/plugins/load_tester/load_tester_creds.c @@ -395,22 +395,28 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, return NULL; } -/** - * Filter function for shared keys, returning ID matches - */ -static bool shared_filter(void *null, shared_key_t **in, shared_key_t **out, - void **un1, id_match_t *me, void **un2, id_match_t *other) +CALLBACK(shared_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *out = *in; - if (me) - { - *me = ID_MATCH_ANY; - } - if (other) + shared_key_t *key, **out; + id_match_t *me, *other; + + VA_ARGS_VGET(args, out, me, other); + + if (orig->enumerate(orig, &key)) { - *other = ID_MATCH_ANY; + *out = key; + if (me) + { + *me = ID_MATCH_ANY; + } + if (other) + { + *other = ID_MATCH_ANY; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, @@ -431,7 +437,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, return NULL; } return enumerator_create_filter(enumerator_create_single(shared, NULL), - (void*)shared_filter, NULL, NULL); + shared_filter, NULL, NULL); } METHOD(load_tester_creds_t, destroy, void, diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index 78159c845..f34990176 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -223,10 +223,11 @@ typedef struct { } peer_enumerator_t; METHOD(enumerator_t, peer_enumerator_enumerate, bool, - peer_enumerator_t *this, peer_cfg_t **cfg) + peer_enumerator_t *this, va_list args) { char *name, *local_net, *remote_net; chunk_t me, other; + peer_cfg_t **cfg; child_cfg_t *child_cfg; auth_cfg_t *auth; peer_cfg_create_t peer = { @@ -249,6 +250,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, .mode = MODE_TUNNEL, }; + VA_ARGS_VGET(args, cfg); + DESTROY_IF(this->current); if (!this->inner->enumerate(this->inner, &name, &me, &other, &local_net, &remote_net)) @@ -295,7 +298,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_peer_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, .destroy = _peer_enumerator_destroy, }, .ike = this->ike, diff --git a/src/libcharon/plugins/medcli/medcli_creds.c b/src/libcharon/plugins/medcli/medcli_creds.c index 677229b9f..528fc004d 100644 --- a/src/libcharon/plugins/medcli/medcli_creds.c +++ b/src/libcharon/plugins/medcli/medcli_creds.c @@ -50,10 +50,13 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, private_enumerator_enumerate, bool, - private_enumerator_t *this, private_key_t **key) + private_enumerator_t *this, va_list args) { + private_key_t **key; chunk_t chunk; + VA_ARGS_VGET(args, key); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -92,7 +95,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_private_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _private_enumerator_enumerate, .destroy = _private_enumerator_destroy, }, ); @@ -123,11 +127,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; public_key_t *public; chunk_t chunk; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -180,7 +187,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .type = key, diff --git a/src/libcharon/plugins/medsrv/medsrv_creds.c b/src/libcharon/plugins/medsrv/medsrv_creds.c index 0d99c4f77..16d4bd7f3 100644 --- a/src/libcharon/plugins/medsrv/medsrv_creds.c +++ b/src/libcharon/plugins/medsrv/medsrv_creds.c @@ -52,12 +52,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { - certificate_t *trusted; + certificate_t *trusted, **cert; public_key_t *public; chunk_t chunk; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -110,7 +112,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .type = key, diff --git a/src/libcharon/plugins/osx_attr/osx_attr_handler.c b/src/libcharon/plugins/osx_attr/osx_attr_handler.c index 6baf76d35..e7a627b93 100644 --- a/src/libcharon/plugins/osx_attr/osx_attr_handler.c +++ b/src/libcharon/plugins/osx_attr/osx_attr_handler.c @@ -218,12 +218,15 @@ METHOD(attribute_handler_t, release, void, } METHOD(enumerator_t, enumerate_dns, bool, - enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data) + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_DNS; *data = chunk_empty; - /* stop enumeration */ - this->enumerate = (void*)return_false; + this->venumerate = (void*)return_false; return TRUE; } @@ -234,7 +237,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, enumerator_t *enumerator; INIT(enumerator, - .enumerate = (void*)_enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.c b/src/libcharon/plugins/p_cscf/p_cscf_handler.c index 76633845e..cdf266054 100644 --- a/src/libcharon/plugins/p_cscf/p_cscf_handler.c +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.c @@ -83,9 +83,12 @@ typedef struct { } attr_enumerator_t; METHOD(enumerator_t, enumerate_attrs, bool, - attr_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attr_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->request_ipv4) { *type = P_CSCF_IP4_ADDRESS; @@ -103,12 +106,13 @@ METHOD(enumerator_t, enumerate_attrs, bool, return FALSE; } -/** - * Check if the given host has a matching address family - */ -static bool is_family(host_t *host, int *family) +CALLBACK(is_family, bool, + host_t *host, va_list args) { - return host->get_family(host) == *family; + int family; + + VA_ARGS_VGET(args, family); + return host->get_family(host) == family; } /** @@ -116,7 +120,7 @@ static bool is_family(host_t *host, 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 *, @@ -132,7 +136,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_attrs, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_attrs, .destroy = (void*)free, }, ); diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c index 9077b51d4..05b865464 100644 --- a/src/libcharon/plugins/resolve/resolve_handler.c +++ b/src/libcharon/plugins/resolve/resolve_handler.c @@ -391,10 +391,13 @@ typedef struct { bool v6; } attribute_enumerator_t; -static bool attribute_enumerate(attribute_enumerator_t *this, - configuration_attribute_type_t *type, - chunk_t *data) +METHOD(enumerator_t, attribute_enumerate, bool, + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->v4) { *type = INTERNAL_IP4_DNS; @@ -443,7 +446,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = (void*)free, }, .v4 = has_host_family(vips, AF_INET), diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c index cf7c3b814..55e818122 100644 --- a/src/libcharon/plugins/sql/sql_config.c +++ b/src/libcharon/plugins/sql/sql_config.c @@ -504,11 +504,12 @@ typedef struct { ike_cfg_t *current; } ike_enumerator_t; -/** - * Implementation of ike_enumerator_t.public.enumerate - */ -static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) +METHOD(enumerator_t, ike_enumerator_enumerate, bool, + ike_enumerator_t *this, va_list args) { + ike_cfg_t **cfg; + + VA_ARGS_VGET(args, cfg); DESTROY_IF(this->current); this->current = build_ike_cfg(this->this, this->inner, this->me, this->other); if (this->current) @@ -519,10 +520,8 @@ static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) return FALSE; } -/** - * Implementation of ike_enumerator_t.public.destroy - */ -static void ike_enumerator_destroy(ike_enumerator_t *this) +METHOD(enumerator_t, ike_enumerator_destroy, void, + ike_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); @@ -532,19 +531,22 @@ static void ike_enumerator_destroy(ike_enumerator_t *this) METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, private_sql_config_t *this, host_t *me, host_t *other) { - ike_enumerator_t *e = malloc_thing(ike_enumerator_t); - - e->this = this; - e->me = me; - e->other = other; - e->current = NULL; - e->public.enumerate = (void*)ike_enumerator_enumerate; - e->public.destroy = (void*)ike_enumerator_destroy; + ike_enumerator_t *e; + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _ike_enumerator_enumerate, + .destroy = _ike_enumerator_destroy, + }, + .this = this, + .me = me, + .other = other, + ); e->inner = this->db->query(this->db, - "SELECT id, certreq, force_encap, local, remote " - "FROM ike_configs", - DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT); + "SELECT id, certreq, force_encap, local, remote " + "FROM ike_configs", + DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT); if (!e->inner) { free(e); @@ -569,11 +571,12 @@ typedef struct { peer_cfg_t *current; } peer_enumerator_t; -/** - * Implementation of peer_enumerator_t.public.enumerate - */ -static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) +METHOD(enumerator_t, peer_enumerator_enumerate, bool, + peer_enumerator_t *this, va_list args) { + peer_cfg_t **cfg; + + VA_ARGS_VGET(args, cfg); DESTROY_IF(this->current); this->current = build_peer_cfg(this->this, this->inner, this->me, this->other); if (this->current) @@ -584,10 +587,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) return FALSE; } -/** - * Implementation of peer_enumerator_t.public.destroy - */ -static void peer_enumerator_destroy(peer_enumerator_t *this) +METHOD(enumerator_t, peer_enumerator_destroy, void, + peer_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); @@ -599,12 +600,16 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, { peer_enumerator_t *e = malloc_thing(peer_enumerator_t); - e->this = this; - e->me = me; - e->other = other; - e->current = NULL; - e->public.enumerate = (void*)peer_enumerator_enumerate; - e->public.destroy = (void*)peer_enumerator_destroy; + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, + .destroy = _peer_enumerator_destroy, + }, + .this = this, + .me = me, + .other = other, + ); /* TODO: only get configs whose IDs match exactly or contain wildcards */ e->inner = this->db->query(this->db, diff --git a/src/libcharon/plugins/sql/sql_cred.c b/src/libcharon/plugins/sql/sql_cred.c index 117eec921..3317de6c8 100644 --- a/src/libcharon/plugins/sql/sql_cred.c +++ b/src/libcharon/plugins/sql/sql_cred.c @@ -52,11 +52,14 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, private_enumerator_enumerate, bool, - private_enumerator_t *this, private_key_t **key) + private_enumerator_t *this, va_list args) { + private_key_t **key; chunk_t blob; int type; + VA_ARGS_VGET(args, key); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -88,7 +91,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_private_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _private_enumerator_enumerate, .destroy = _private_enumerator_destroy, }, ); @@ -132,11 +136,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; chunk_t blob; int type; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -169,7 +176,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, ); @@ -221,12 +229,15 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerator_enumerate, bool, - shared_enumerator_t *this, shared_key_t **shared, - id_match_t *me, id_match_t *other) + shared_enumerator_t *this, va_list args) { + shared_key_t **shared; + id_match_t *me, *other; chunk_t blob; int type; + VA_ARGS_VGET(args, shared, me, other); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -265,7 +276,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_shared_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerator_enumerate, .destroy = _shared_enumerator_destroy, }, .me = me, @@ -340,9 +352,11 @@ typedef enum { } cdp_type_t; METHOD(enumerator_t, cdp_enumerator_enumerate, bool, - cdp_enumerator_t *this, char **uri) + cdp_enumerator_t *this, va_list args) { - char *text; + char *text, **uri; + + VA_ARGS_VGET(args, uri); free(this->current); while (this->inner->enumerate(this->inner, &text)) @@ -384,7 +398,8 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_cdp_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cdp_enumerator_enumerate, .destroy = _cdp_enumerator_destroy, }, ); diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index cd1b4d093..7835031c2 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -178,28 +178,32 @@ METHOD(attribute_provider_t, release_address, bool, return found; } -/** - * Filter function to convert host to DNS configuration attributes - */ -static bool attr_filter(void *lock, host_t **in, - configuration_attribute_type_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - host_t *host = *in; + configuration_attribute_type_t *type; + chunk_t *data; + host_t *host; - switch (host->get_family(host)) + VA_ARGS_VGET(args, type, data); + + while (orig->enumerate(orig, &host)) { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + continue; + } + *data = host->get_address(host); + return TRUE; } - *data = host->get_address(host); - return TRUE; + return FALSE; } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, @@ -223,7 +227,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, enumerator->destroy(enumerator); return enumerator_create_filter( attr->dns->create_enumerator(attr->dns), - (void*)attr_filter, this->lock, + attr_filter, this->lock, (void*)this->lock->unlock); } } @@ -338,24 +342,28 @@ METHOD(stroke_attribute_t, del_dns, void, this->lock->unlock(this->lock); } -/** - * Pool enumerator filter function, converts pool_t to name, size, ... - */ -static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name, - void *d1, u_int *size, void *d2, u_int *online, - void *d3, u_int *offline) +CALLBACK(pool_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - mem_pool_t *pool = *poolp; + mem_pool_t *pool; + const char **name; + u_int *size, *online, *offline; - if (pool->get_size(pool) == 0) + VA_ARGS_VGET(args, name, size, online, offline); + + while (orig->enumerate(orig, &pool)) { - return FALSE; + if (pool->get_size(pool) == 0) + { + continue; + } + *name = pool->get_name(pool); + *size = pool->get_size(pool); + *online = pool->get_online(pool); + *offline = pool->get_offline(pool); + return TRUE; } - *name = pool->get_name(pool); - *size = pool->get_size(pool); - *online = pool->get_online(pool); - *offline = pool->get_offline(pool); - return TRUE; + return FALSE; } METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, @@ -363,7 +371,7 @@ METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->pools->create_enumerator(this->pools), - (void*)pool_filter, + pool_filter, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index 13ed41e0e..4593e9bdc 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -171,26 +171,30 @@ typedef struct { identification_t *id; } cert_data_t; -/** - * destroy cert_data - */ -static void cert_data_destroy(cert_data_t *data) +CALLBACK(cert_data_destroy, void, + cert_data_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter function for certs enumerator - */ -static bool certs_filter(cert_data_t *data, ca_cert_t **in, - certificate_t **out) +CALLBACK(certs_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { + ca_cert_t *cacert; public_key_t *public; - certificate_t *cert = (*in)->cert; + certificate_t **out; + + VA_ARGS_VGET(args, out); - if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + while (orig->enumerate(orig, &cacert)) { + certificate_t *cert = cacert->cert; + + if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) + { + continue; + } public = cert->get_public_key(cert); if (public) { @@ -208,9 +212,9 @@ static bool certs_filter(cert_data_t *data, ca_cert_t **in, } else if (data->key != KEY_ANY) { - return FALSE; + continue; } - if (data->id == NULL || cert->has_subject(cert, data->id)) + if (!data->id || cert->has_subject(cert, data->id)) { *out = cert; return TRUE; @@ -235,8 +239,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, this->lock->read_lock(this->lock); enumerator = this->certs->create_enumerator(this->certs); - return enumerator_create_filter(enumerator, (void*)certs_filter, data, - (void*)cert_data_destroy); + return enumerator_create_filter(enumerator, certs_filter, data, + cert_data_destroy); } /** @@ -354,11 +358,12 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, data, (void*)cdp_data_destroy); } -/** - * Compare the given certificate to the ca_cert_t items in the list - */ -static bool match_cert(ca_cert_t *item, certificate_t *cert) +CALLBACK(match_cert, bool, + ca_cert_t *item, va_list args) { + certificate_t *cert; + + VA_ARGS_VGET(args, cert); return cert->equals(cert, item->cert); } @@ -405,8 +410,7 @@ static certificate_t *add_cert_internal(private_stroke_ca_t *this, { ca_cert_t *found; - if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, - (void**)&found, cert) == SUCCESS) + if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert)) { cert->destroy(cert); cert = found->cert->get_ref(found->cert); @@ -511,8 +515,7 @@ METHOD(stroke_ca_t, get_cert_ref, certificate_t*, ca_cert_t *found; this->lock->read_lock(this->lock); - if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, - (void**)&found, cert) == SUCCESS) + if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert)) { cert->destroy(cert); cert = found->cert->get_ref(found->cert); diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index d47787d72..00f74831c 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -68,13 +68,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, (void*)this->mutex->unlock, this->mutex); } -/** - * filter function for ike configs - */ -static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out) +CALLBACK(ike_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = (*in)->get_ike_cfg(*in); - return TRUE; + peer_cfg_t *cfg; + ike_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &cfg)) + { + *out = cfg->get_ike_cfg(cfg); + return TRUE; + } + return FALSE; } METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, @@ -82,7 +89,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, { this->mutex->lock(this->mutex); return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)ike_filter, this->mutex, + ike_filter, this->mutex, (void*)this->mutex->unlock); } diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c index d0cc9afab..19d5a62a1 100644 --- a/src/libcharon/plugins/stroke/stroke_handler.c +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -62,35 +62,39 @@ static void attributes_destroy(attributes_t *this) free(this); } -/** - * Filter function to convert host to DNS configuration attributes - */ -static bool attr_filter(void *lock, host_t **in, - configuration_attribute_type_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - host_t *host = *in; + configuration_attribute_type_t *type; + chunk_t *data; + host_t *host; - switch (host->get_family(host)) - { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; - } - if (host->is_anyaddr(host)) - { - *data = chunk_empty; - } - else + VA_ARGS_VGET(args, type, data); + + while (orig->enumerate(orig, &host)) { - *data = host->get_address(host); + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + continue; + } + if (host->is_anyaddr(host)) + { + *data = chunk_empty; + } + else + { + *data = host->get_address(host); + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, @@ -114,7 +118,7 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, enumerator->destroy(enumerator); return enumerator_create_filter( attr->dns->create_enumerator(attr->dns), - (void*)attr_filter, this->lock, + attr_filter, this->lock, (void*)this->lock->unlock); } } diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index a33316658..22992599d 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -958,8 +958,7 @@ static void list_plugins(FILE *out) { case FEATURE_PROVIDE: fp = &features[i]; - loaded = list->find_first(list, NULL, - (void**)&fp) == SUCCESS; + loaded = list->find_first(list, NULL, (void**)&fp); fprintf(out, " %s%s\n", str, loaded ? "" : " (not loaded)"); break; diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c index e0578fe9b..dcd4ae348 100644 --- a/src/libcharon/plugins/uci/uci_config.c +++ b/src/libcharon/plugins/uci/uci_config.c @@ -118,11 +118,12 @@ static u_int create_rekey(char *string) } METHOD(enumerator_t, peer_enumerator_enumerate, bool, - peer_enumerator_t *this, peer_cfg_t **cfg) + peer_enumerator_t *this, va_list args) { char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey; char *local_id, *local_addr, *local_net; char *remote_id, *remote_addr, *remote_net; + peer_cfg_t **cfg; child_cfg_t *child_cfg; ike_cfg_t *ike_cfg; auth_cfg_t *auth; @@ -145,6 +146,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, .mode = MODE_TUNNEL, }; + VA_ARGS_VGET(args, cfg); + /* defaults */ name = "unnamed"; local_id = NULL; @@ -212,7 +215,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_peer_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, .destroy = _peer_enumerator_destroy, }, .inner = this->parser->create_section_enumerator(this->parser, @@ -241,10 +245,13 @@ typedef struct { } ike_enumerator_t; METHOD(enumerator_t, ike_enumerator_enumerate, bool, - ike_enumerator_t *this, ike_cfg_t **cfg) + ike_enumerator_t *this, va_list args) { + ike_cfg_t **cfg; char *local_addr, *remote_addr, *ike_proposal; + VA_ARGS_VGET(args, cfg); + /* defaults */ local_addr = "0.0.0.0"; remote_addr = "0.0.0.0"; @@ -282,7 +289,8 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_ike_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _ike_enumerator_enumerate, .destroy = _ike_enumerator_destroy, }, .inner = this->parser->create_section_enumerator(this->parser, diff --git a/src/libcharon/plugins/uci/uci_creds.c b/src/libcharon/plugins/uci/uci_creds.c index f5d5ace70..404a3e39f 100644 --- a/src/libcharon/plugins/uci/uci_creds.c +++ b/src/libcharon/plugins/uci/uci_creds.c @@ -52,12 +52,15 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerator_enumerate, bool, - shared_enumerator_t *this, shared_key_t **key, id_match_t *me, - id_match_t *other) + shared_enumerator_t *this, va_list args) { + shared_key_t **key; + id_match_t *me, *other; char *local_id, *remote_id, *psk; identification_t *local, *remote; + VA_ARGS_VGET(args, key, me, other); + while (TRUE) { /* defaults */ @@ -126,7 +129,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_shared_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerator_enumerate, .destroy = _shared_enumerator_destroy, }, .me = me, diff --git a/src/libcharon/plugins/uci/uci_parser.c b/src/libcharon/plugins/uci/uci_parser.c index 2429e9e44..e847dd393 100644 --- a/src/libcharon/plugins/uci/uci_parser.c +++ b/src/libcharon/plugins/uci/uci_parser.c @@ -58,11 +58,10 @@ typedef struct { } section_enumerator_t; METHOD(enumerator_t, section_enumerator_enumerate, bool, - section_enumerator_t *this, ...) + section_enumerator_t *this, va_list args) { struct uci_element *element; char **value; - va_list args; int i; if (&this->current->list == this->list) @@ -70,8 +69,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool, return FALSE; } - va_start(args, this); - value = va_arg(args, char**); if (value) { @@ -96,7 +93,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool, *value = uci_to_option(element)->value; } } - va_end(args); this->current = list_to_element(this->current->list.next); return TRUE; @@ -124,7 +120,13 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*, i++; } va_end(args); - e = malloc(sizeof(section_enumerator_t) + sizeof(char*) * i); + INIT_EXTRA(e, sizeof(char*) * i, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _section_enumerator_enumerate, + .destroy = _section_enumerator_destroy, + }, + ); i = 0; va_start(args, this); do @@ -134,9 +136,6 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*, while (e->keywords[i++]); va_end(args); - e->public.enumerate = (void*)_section_enumerator_enumerate; - e->public.destroy = _section_enumerator_destroy; - /* load uci context */ e->ctx = uci_alloc_context(); if (uci_load(e->ctx, this->package, &e->package) != UCI_OK) diff --git a/src/libcharon/plugins/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c index 25e0756b7..4a1478c6d 100644 --- a/src/libcharon/plugins/unity/unity_handler.c +++ b/src/libcharon/plugins/unity/unity_handler.c @@ -368,9 +368,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, enumerate_attributes, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->i < countof(attributes)) { *type = attributes[this->i++]; @@ -393,7 +396,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, } INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_attributes, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_attributes, .destroy = (void*)free, }, ); @@ -407,24 +411,27 @@ typedef struct { ike_sa_id_t *id; } include_filter_t; -/** - * Include enumerator filter function - */ -static bool include_filter(include_filter_t *data, - entry_t **entry, traffic_selector_t **ts) +CALLBACK(include_filter, bool, + include_filter_t *data, enumerator_t *orig, va_list args) { - if (data->id->equals(data->id, (*entry)->id)) + entry_t *entry; + traffic_selector_t **ts; + + VA_ARGS_VGET(args, ts); + + while (orig->enumerate(orig, &entry)) { - *ts = (*entry)->ts; - return TRUE; + if (data->id->equals(data->id, entry->id)) + { + *ts = entry->ts; + return TRUE; + } } return FALSE; } -/** - * Destroy include filter data, unlock mutex - */ -static void destroy_filter(include_filter_t *data) +CALLBACK(destroy_filter, void, + include_filter_t *data) { data->mutex->unlock(data->mutex); free(data); @@ -442,7 +449,7 @@ METHOD(unity_handler_t, create_include_enumerator, enumerator_t*, data->mutex->lock(data->mutex); return enumerator_create_filter( this->include->create_enumerator(this->include), - (void*)include_filter, data, (void*)destroy_filter); + include_filter, data, destroy_filter); } METHOD(unity_handler_t, destroy, void, diff --git a/src/libcharon/plugins/unity/unity_provider.c b/src/libcharon/plugins/unity/unity_provider.c index 07f5f9b61..b6a55648e 100644 --- a/src/libcharon/plugins/unity/unity_provider.c +++ b/src/libcharon/plugins/unity/unity_provider.c @@ -77,12 +77,15 @@ static void append_ts(bio_writer_t *writer, traffic_selector_t *ts) } METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *attr) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *attr; traffic_selector_t *ts; bio_writer_t *writer; + VA_ARGS_VGET(args, type, attr); + if (this->list->get_count(this->list) == 0) { return FALSE; @@ -183,7 +186,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, INIT(attr_enum, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _attribute_destroy, }, .list = list, diff --git a/src/libcharon/plugins/vici/suites/test_message.c b/src/libcharon/plugins/vici/suites/test_message.c index 045e34fff..73bba239b 100644 --- a/src/libcharon/plugins/vici/suites/test_message.c +++ b/src/libcharon/plugins/vici/suites/test_message.c @@ -122,9 +122,14 @@ typedef struct { endecode_test_t *next; } endecode_enum_t; -static bool endecode_enumerate(endecode_enum_t *this, vici_type_t *type, - char **name, chunk_t *data) +METHOD(enumerator_t, endecode_enumerate, bool, + endecode_enum_t *this, va_list args) { + vici_type_t *type; + chunk_t *data; + char **name; + + VA_ARGS_VGET(args, type, name, data); if (this->next) { *type = this->next->type; @@ -149,7 +154,8 @@ static enumerator_t *endecode_create_enumerator(endecode_test_t *test) INIT(enumerator, .public = { - .enumerate = (void*)endecode_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _endecode_enumerate, .destroy = (void*)free, }, .next = test, diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c index 4e1fa9708..ab765fa14 100644 --- a/src/libcharon/plugins/vici/vici_attribute.c +++ b/src/libcharon/plugins/vici/vici_attribute.c @@ -184,16 +184,22 @@ METHOD(attribute_provider_t, release_address, bool, return found; } -/** - * Filter mapping attribute_t to enumerated type/value arguments - */ -static bool attr_filter(void *data, attribute_t **attr, - configuration_attribute_type_t *type, - void *in, chunk_t *value) +CALLBACK(attr_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *type = (*attr)->type; - *value = (*attr)->value; - return TRUE; + attribute_t *attr; + configuration_attribute_type_t *type; + chunk_t *value; + + VA_ARGS_VGET(args, type, value); + + if (orig->enumerate(orig, &attr)) + { + *type = attr->type; + *value = attr->value; + return TRUE; + } + return FALSE; } /** @@ -203,7 +209,7 @@ CALLBACK(create_nested, enumerator_t*, pool_t *pool, void *this) { return enumerator_create_filter(array_create_enumerator(pool->attrs), - (void*)attr_filter, NULL, NULL); + attr_filter, NULL, NULL); } /** diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index 3af67df94..0c355e3a0 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -141,13 +141,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, (void*)this->lock->unlock, this->lock); } -/** - * Enumerator filter function for ike configs - */ -static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out) +CALLBACK(ike_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = (*in)->get_ike_cfg(*in); - return TRUE; + peer_cfg_t *cfg; + ike_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &cfg)) + { + *out = cfg->get_ike_cfg(cfg); + return TRUE; + } + return FALSE; } METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, @@ -155,7 +162,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->conns->create_enumerator(this->conns), - (void*)ike_filter, this->lock, + ike_filter, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/plugins/vici/vici_message.c b/src/libcharon/plugins/vici/vici_message.c index 58b896773..91d344994 100644 --- a/src/libcharon/plugins/vici/vici_message.c +++ b/src/libcharon/plugins/vici/vici_message.c @@ -135,11 +135,16 @@ typedef struct { } parse_enumerator_t; METHOD(enumerator_t, parse_enumerate, bool, - parse_enumerator_t *this, vici_type_t *out, char **name, chunk_t *value) + parse_enumerator_t *this, va_list args) { + vici_type_t *out; + chunk_t *value; + char **name; uint8_t type; chunk_t data; + VA_ARGS_VGET(args, out, name, value); + if (!this->reader->remaining(this->reader) || !this->reader->read_uint8(this->reader, &type)) { @@ -218,7 +223,8 @@ METHOD(vici_message_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_parse_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _parse_enumerate, .destroy = _parse_destroy, }, .reader = bio_reader_create(this->encoding), diff --git a/src/libcharon/plugins/whitelist/whitelist_listener.c b/src/libcharon/plugins/whitelist/whitelist_listener.c index 7e5b2f4e0..136554674 100644 --- a/src/libcharon/plugins/whitelist/whitelist_listener.c +++ b/src/libcharon/plugins/whitelist/whitelist_listener.c @@ -119,14 +119,19 @@ METHOD(whitelist_listener_t, remove_, void, DESTROY_IF(id); } -/** - * Enumerator filter, from hashtable (key, value) to single identity - */ -static bool whitelist_filter(rwlock_t *lock, identification_t **key, - identification_t **id, identification_t **value) +CALLBACK(whitelist_filter, bool, + rwlock_t *lock, enumerator_t *orig, va_list args) { - *id = *value; - return TRUE; + identification_t *key, *value, **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &key, &value)) + { + *out = value; + return TRUE; + } + return FALSE; } METHOD(whitelist_listener_t, create_enumerator, enumerator_t*, @@ -134,7 +139,7 @@ METHOD(whitelist_listener_t, create_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->ids->create_enumerator(this->ids), - (void*)whitelist_filter, this->lock, + whitelist_filter, this->lock, (void*)this->lock->unlock); } |
