From 5297c65398b683503d389cc5a0bc2aa06225d786 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 3 May 2017 13:58:02 +0200 Subject: [PATCH 1/7] utils: Add helper macros to read variadic arguments into local variables --- src/libstrongswan/utils/utils.h | 48 +++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index 0aed842b1..33b8d1956 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef HAVE_SYS_PARAM_H #include @@ -140,6 +141,49 @@ void utils_deinit(); #define _VA_ARGS_DISPATCH(func, num) __VA_ARGS_DISPATCH(func, num) #define __VA_ARGS_DISPATCH(func, num) func ## num +/** + * Assign variadic arguments to the given variables. + * + * @note The order and types of the variables are significant and must match the + * variadic arguments passed to the function that calls this macro exactly. + * + * @param last the last argument before ... in the function that calls this + * @param ... variable names + */ +#define VA_ARGS_GET(last, ...) ({ \ + va_list _va_args_get_ap; \ + va_start(_va_args_get_ap, last); \ + _VA_ARGS_GET_ASGN(__VA_ARGS__) \ + va_end(_va_args_get_ap); \ +}) + +/** + * Assign variadic arguments from a va_list to the given variables. + * + * @note The order and types of the variables are significant and must match the + * variadic arguments passed to the function that calls this macro exactly. + * + * @param list the va_list variable in the function that calls this + * @param ... variable names + */ +#define VA_ARGS_VGET(list, ...) ({ \ + va_list _va_args_get_ap; \ + va_copy(_va_args_get_ap, list); \ + _VA_ARGS_GET_ASGN(__VA_ARGS__) \ + va_end(_va_args_get_ap); \ +}) + +#define _VA_ARGS_GET_ASGN(...) VA_ARGS_DISPATCH(_VA_ARGS_GET_ASGN, __VA_ARGS__)(__VA_ARGS__) +#define _VA_ARGS_GET_ASGN1(v1) __VA_ARGS_GET_ASGN(v1) +#define _VA_ARGS_GET_ASGN2(v1,v2) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) +#define _VA_ARGS_GET_ASGN3(v1,v2,v3) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) +#define _VA_ARGS_GET_ASGN4(v1,v2,v3,v4) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) +#define _VA_ARGS_GET_ASGN5(v1,v2,v3,v4,v5) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) __VA_ARGS_GET_ASGN(v5) +#define __VA_ARGS_GET_ASGN(v) v = va_arg(_va_args_get_ap, typeof(v)); + /** * Macro to allocate a sized type. */ From 16bffa8b55542ba7c29fa8b856b26cdcdf2de869 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 9 May 2017 16:59:37 +0200 Subject: [PATCH 2/7] enumerator: Add venumerate() method to enumerator_t that takes a va_list This will allow us to implement e.g. enumerator_cleaner without having to use that unportable 5 pointer forwarding or having to define a callback for each instance. A generic implementation for enumerate() is provided so only venumerate() has to be implemented, which may be simplified by using the VA_ARGS_VGET() macro. --- src/libstrongswan/collections/enumerator.c | 24 +++++++++++++-- src/libstrongswan/collections/enumerator.h | 35 ++++++++++++++++++---- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index fa277e7c8..e96b235e3 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2013 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -31,6 +31,25 @@ #include +/* + * Described in header. + */ +bool enumerator_enumerate_default(enumerator_t *enumerator, ...) +{ + va_list args; + bool result; + + if (!enumerator->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE DEFAULT: venumerate() missing !!!"); + return FALSE; + } + va_start(args, enumerator); + result = enumerator->venumerate(enumerator, args); + va_end(args); + return result; +} + /** * Implementation of enumerator_create_empty().enumerate */ @@ -646,4 +665,3 @@ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)) return &this->public; } - diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index 55f8d83e6..224fe7ea8 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -34,8 +34,11 @@ struct enumerator_t { /** * Enumerate collection. * - * The enumerate function takes a variable argument list containing - * pointers where the enumerated values get written. + * The enumerate() method takes a variable number of pointer arguments + * where the enumerated values get written to. + * + * @note Just assigning the generic enumerator_enumerate_default() function + * that calls the enumerator's venumerate() method is usually enough. * * @param ... variable list of enumerated items, implementation dependent * @return TRUE if pointers returned @@ -43,11 +46,33 @@ struct enumerator_t { bool (*enumerate)(enumerator_t *this, ...); /** - * Destroy a enumerator instance. + * Enumerate collection. + * + * The venumerate() method takes a variable argument list containing + * pointers where the enumerated values get written to. + * + * To simplify the implementation the VA_ARGS_VGET() macro may be used. + * + * @param args variable list of enumerated items, implementation dependent + * @return TRUE if pointers returned + */ + bool (*venumerate)(enumerator_t *this, va_list args); + + /** + * Destroy an enumerator_t instance. */ void (*destroy)(enumerator_t *this); }; +/** + * Generic implementation of enumerator_t::enumerate() that simply calls + * the enumerator's venumerate() method. + * + * @param enumerator the enumerator + * @param ... arguments passed to enumerate() + */ +bool enumerator_enumerate_default(enumerator_t *enumerator, ...); + /** * Create an enumerator which enumerates over nothing * From 95a63bf2813cd6ecad912237688526bbcc3481ee Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2017 09:17:02 +0200 Subject: [PATCH 3/7] Migrate all enumerators to venumerate() interface change --- src/charon-nm/nm/nm_creds.c | 11 +- src/charon-nm/nm/nm_handler.c | 27 +- src/dumm/dumm.c | 9 +- .../libandroidbridge/backend/android_attr.c | 19 +- src/libcharon/attributes/attribute_manager.c | 25 +- src/libcharon/attributes/mem_pool.c | 12 +- src/libcharon/config/peer_cfg.c | 22 +- .../encoding/payloads/certreq_payload.c | 9 +- .../encoding/payloads/delete_payload.c | 9 +- src/libcharon/encoding/payloads/eap_payload.c | 9 +- .../plugins/android_dns/android_dns_handler.c | 12 +- src/libcharon/plugins/dnscert/dnscert_cred.c | 8 +- .../plugins/eap_radius/eap_radius_provider.c | 11 +- .../eap_sim_file/eap_sim_file_triplets.c | 32 +- src/libcharon/plugins/ha/ha_message.c | 11 +- src/libcharon/plugins/ha/ha_tunnel.c | 9 +- .../plugins/ipseckey/ipseckey_cred.c | 8 +- .../plugins/kernel_iph/kernel_iph_net.c | 8 +- .../kernel_netlink/kernel_netlink_net.c | 11 +- .../kernel_pfroute/kernel_pfroute_net.c | 20 +- src/libcharon/plugins/medcli/medcli_config.c | 8 +- src/libcharon/plugins/medcli/medcli_creds.c | 16 +- src/libcharon/plugins/medsrv/medsrv_creds.c | 9 +- .../plugins/osx_attr/osx_attr_handler.c | 12 +- src/libcharon/plugins/p_cscf/p_cscf_handler.c | 10 +- .../plugins/resolve/resolve_handler.c | 12 +- src/libcharon/plugins/sql/sql_config.c | 71 ++-- src/libcharon/plugins/sql/sql_cred.c | 35 +- src/libcharon/plugins/uci/uci_config.c | 16 +- src/libcharon/plugins/uci/uci_creds.c | 10 +- src/libcharon/plugins/uci/uci_parser.c | 17 +- src/libcharon/plugins/unity/unity_handler.c | 10 +- src/libcharon/plugins/unity/unity_provider.c | 10 +- .../plugins/vici/suites/test_message.c | 12 +- src/libcharon/plugins/vici/vici_message.c | 10 +- src/libcharon/sa/child_sa.c | 10 +- src/libcharon/sa/ike_sa.c | 8 +- src/libcharon/sa/ike_sa_manager.c | 10 +- src/libimcv/imc/imc_os_info.c | 36 +- src/libimcv/imv/imv_agent.c | 32 +- src/libimcv/pts/pts_pcr.c | 16 +- src/libpttls/sasl/sasl_mechanism.c | 8 +- src/libradius/radius_message.c | 20 +- src/libstrongswan/collections/array.c | 9 +- src/libstrongswan/collections/enumerator.c | 327 +++++++++--------- src/libstrongswan/collections/enumerator.h | 12 +- src/libstrongswan/collections/hashtable.c | 10 +- src/libstrongswan/collections/linked_list.c | 9 +- src/libstrongswan/credentials/auth_cfg.c | 21 +- .../credentials/credential_manager.c | 28 +- .../credentials/keys/public_key.c | 9 +- .../credentials/sets/auth_cfg_wrapper.c | 36 +- .../credentials/sets/callback_cred.c | 10 +- .../credentials/sets/cert_cache.c | 38 +- .../credentials/sets/ocsp_response_wrapper.c | 35 +- src/libstrongswan/crypto/crypto_factory.c | 10 +- .../plugins/mysql/mysql_database.c | 21 +- .../plugins/openssl/openssl_crl.c | 11 +- .../plugins/openssl/openssl_pkcs7.c | 18 +- .../plugins/pkcs11/pkcs11_library.c | 22 +- .../plugins/pkcs11/pkcs11_manager.c | 10 +- .../plugins/pkcs7/pkcs7_signed_data.c | 9 +- .../plugins/sqlite/sqlite_database.c | 33 +- src/libstrongswan/settings/settings.c | 6 +- src/libstrongswan/utils/backtrace.c | 9 +- src/libstrongswan/utils/identification.c | 20 +- src/manager/xml.c | 10 +- src/starter/parser/conf_parser.c | 8 +- 68 files changed, 851 insertions(+), 560 deletions(-) diff --git a/src/charon-nm/nm/nm_creds.c b/src/charon-nm/nm/nm_creds.c index f8fae9504..c191ffde5 100644 --- a/src/charon-nm/nm/nm_creds.c +++ b/src/charon-nm/nm/nm_creds.c @@ -235,9 +235,13 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_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; + + VA_ARGS_VGET(args, key, me, other); + if (this->done) { return FALSE; @@ -307,7 +311,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = _shared_destroy, }, .this = this, diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index bdc0667cf..6c81afa0e 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -65,29 +65,33 @@ METHOD(attribute_handler_t, handle, bool, return TRUE; } -/** - * Implementation of create_attribute_enumerator().enumerate() for WINS - */ -static bool enumerate_nbns(enumerator_t *this, - configuration_attribute_type_t *type, chunk_t *data) +METHOD(enumerator_t, enumerate_nbns, bool, + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_NBNS; *data = chunk_empty; - /* done */ - this->enumerate = (void*)return_false; + this->venumerate = (void*)return_false; return TRUE; } /** * Implementation of create_attribute_enumerator().enumerate() for DNS */ -static bool enumerate_dns(enumerator_t *this, - configuration_attribute_type_t *type, chunk_t *data) +METHOD(enumerator_t, enumerate_dns, bool, + 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; /* enumerate WINS server as next attribute ... */ - this->enumerate = (void*)enumerate_nbns; + this->venumerate = _enumerate_nbns; return TRUE; } @@ -100,7 +104,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, /* enumerate DNS attribute first ... */ - .enumerate = (void*)enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c index cc4f5a16b..d147b2df0 100644 --- a/src/dumm/dumm.c +++ b/src/dumm/dumm.c @@ -267,10 +267,12 @@ typedef struct { } template_enumerator_t; METHOD(enumerator_t, template_enumerate, bool, - template_enumerator_t *this, char **template) + template_enumerator_t *this, va_list args) { struct stat st; - char *rel; + char *rel, **template; + + VA_ARGS_VGET(args, template); while (this->inner->enumerate(this->inner, &rel, NULL, &st)) { @@ -296,7 +298,8 @@ METHOD(dumm_t, create_template_enumerator, enumerator_t*, template_enumerator_t *enumerator; INIT(enumerator, .public = { - .enumerate = (void*)_template_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _template_enumerate, .destroy = (void*)_template_enumerator_destroy, }, .inner = enumerator_create_directory(TEMPLATE_DIR), diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c index 47933d1f2..5e4898fc3 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c @@ -73,20 +73,28 @@ METHOD(attribute_handler_t, release, void, } METHOD(enumerator_t, enumerate_dns6, 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_IP6_DNS; *data = chunk_empty; - this->enumerate = (void*)return_false; + this->venumerate = (void*)return_false; return TRUE; } METHOD(enumerator_t, enumerate_dns4, 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; - this->enumerate = (void*)_enumerate_dns6; + this->venumerate = _enumerate_dns6; return TRUE; } @@ -96,7 +104,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, enumerator_t *enumerator; INIT(enumerator, - .enumerate = (void*)_enumerate_dns4, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns4, .destroy = (void*)free, ); return enumerator; diff --git a/src/libcharon/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c index 2ab7ed118..3a4a21a02 100644 --- a/src/libcharon/attributes/attribute_manager.c +++ b/src/libcharon/attributes/attribute_manager.c @@ -237,14 +237,14 @@ typedef struct { linked_list_t *vips; } initiator_enumerator_t; -/** - * Enumerator implementation for initiator attributes - */ -static bool initiator_enumerate(initiator_enumerator_t *this, - attribute_handler_t **handler, - configuration_attribute_type_t *type, - chunk_t *value) +METHOD(enumerator_t, initiator_enumerate, bool, + initiator_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + attribute_handler_t **handler; + chunk_t *value; + + VA_ARGS_VGET(args, handler, type, value); /* enumerate inner attributes using outer handler enumerator */ while (!this->inner || !this->inner->enumerate(this->inner, type, value)) { @@ -261,10 +261,8 @@ static bool initiator_enumerate(initiator_enumerator_t *this, return TRUE; } -/** - * Cleanup function of initiator attribute enumerator - */ -static void initiator_destroy(initiator_enumerator_t *this) +METHOD(enumerator_t, initiator_destroy, void, + initiator_enumerator_t *this) { this->this->lock->unlock(this->this->lock); this->outer->destroy(this->outer); @@ -281,8 +279,9 @@ METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)initiator_enumerate, - .destroy = (void*)initiator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _initiator_enumerate, + .destroy = _initiator_destroy, }, .this = this, .ike_sa = ike_sa, diff --git a/src/libcharon/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c index a2b7c2803..e1a9a6dce 100644 --- a/src/libcharon/attributes/mem_pool.c +++ b/src/libcharon/attributes/mem_pool.c @@ -512,10 +512,15 @@ typedef struct { } lease_enumerator_t; METHOD(enumerator_t, lease_enumerate, bool, - lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online) + lease_enumerator_t *this, va_list args) { - u_int *offset; + identification_t **id; unique_lease_t *lease; + host_t **addr; + u_int *offset; + bool *online; + + VA_ARGS_VGET(args, id, addr, online); DESTROY_IF(this->addr); this->addr = NULL; @@ -570,7 +575,8 @@ METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*, this->mutex->lock(this->mutex); INIT(enumerator, .public = { - .enumerate = (void*)_lease_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _lease_enumerate, .destroy = _lease_enumerator_destroy, }, .pool = this, diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index 5d7ab076e..fcdd6fdeb 100644 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -209,9 +209,12 @@ typedef struct { } child_cfgs_replace_enumerator_t; METHOD(enumerator_t, child_cfgs_replace_enumerate, bool, - child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added) + child_cfgs_replace_enumerator_t *this, va_list args) { - child_cfg_t *child_cfg; + child_cfg_t *child_cfg, **chd; + bool *added; + + VA_ARGS_VGET(args, chd, added); if (!this->wrapped) { @@ -303,8 +306,9 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_cfgs_replace_enumerate, - .destroy = (void*)_child_cfgs_replace_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_cfgs_replace_enumerate, + .destroy = _child_cfgs_replace_enumerator_destroy, }, .removed = removed, .added = added, @@ -336,8 +340,11 @@ METHOD(enumerator_t, child_cfg_enumerator_destroy, void, } METHOD(enumerator_t, child_cfg_enumerate, bool, - child_cfg_enumerator_t *this, child_cfg_t **chd) + child_cfg_enumerator_t *this, va_list args) { + child_cfg_t **chd; + + VA_ARGS_VGET(args, chd); return this->wrapped->enumerate(this->wrapped, chd); } @@ -348,8 +355,9 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_cfg_enumerate, - .destroy = (void*)_child_cfg_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_cfg_enumerate, + .destroy = _child_cfg_enumerator_destroy, }, .mutex = this->mutex, .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs), diff --git a/src/libcharon/encoding/payloads/certreq_payload.c b/src/libcharon/encoding/payloads/certreq_payload.c index 09bfa2458..643fbc42f 100644 --- a/src/libcharon/encoding/payloads/certreq_payload.c +++ b/src/libcharon/encoding/payloads/certreq_payload.c @@ -190,8 +190,12 @@ struct keyid_enumerator_t { }; METHOD(enumerator_t, keyid_enumerate, bool, - keyid_enumerator_t *this, chunk_t *chunk) + keyid_enumerator_t *this, va_list args) { + chunk_t *chunk; + + VA_ARGS_VGET(args, chunk); + if (this->pos == NULL) { this->pos = this->full.ptr; @@ -224,7 +228,8 @@ METHOD(certreq_payload_t, create_keyid_enumerator, enumerator_t*, } INIT(enumerator, .public = { - .enumerate = (void*)_keyid_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _keyid_enumerate, .destroy = (void*)free, }, .full = this->data, diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c index 584e6f22b..3634cd36c 100644 --- a/src/libcharon/encoding/payloads/delete_payload.c +++ b/src/libcharon/encoding/payloads/delete_payload.c @@ -306,8 +306,12 @@ typedef struct { } spi_enumerator_t; METHOD(enumerator_t, spis_enumerate, bool, - spi_enumerator_t *this, uint32_t *spi) + spi_enumerator_t *this, va_list args) { + uint32_t *spi; + + VA_ARGS_VGET(args, spi); + if (this->spis.len >= sizeof(*spi)) { memcpy(spi, this->spis.ptr, sizeof(*spi)); @@ -328,7 +332,8 @@ METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_spis_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _spis_enumerate, .destroy = (void*)free, }, .spis = this->spis, diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c index 8c3fc5933..923135da9 100644 --- a/src/libcharon/encoding/payloads/eap_payload.c +++ b/src/libcharon/encoding/payloads/eap_payload.c @@ -270,8 +270,12 @@ typedef struct { } type_enumerator_t; METHOD(enumerator_t, enumerate_types, bool, - type_enumerator_t *this, eap_type_t *type, uint32_t *vendor) + type_enumerator_t *this, va_list args) { + eap_type_t *type; + uint32_t *vendor; + + VA_ARGS_VGET(args, type, vendor); this->offset = extract_type(this->payload, this->offset, type, vendor); return this->offset; } @@ -289,7 +293,8 @@ METHOD(eap_payload_t, get_types, enumerator_t*, { INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_types, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_types, .destroy = (void*)free, }, .payload = this, 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/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_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/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_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index 2dc76d941..f94992d5d 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -2165,8 +2165,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 +2276,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, diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index efcf1c2a7..7b370666c 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, @@ -1789,13 +1793,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 +1897,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/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..880e80a56 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; @@ -132,7 +135,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/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..f640f9fbb 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, }, ); 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_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/sa/child_sa.c b/src/libcharon/sa/child_sa.c index e1ffc2aae..2a8ef0234 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -435,10 +435,11 @@ struct policy_enumerator_t { }; METHOD(enumerator_t, policy_enumerate, bool, - policy_enumerator_t *this, traffic_selector_t **my_out, - traffic_selector_t **other_out) + policy_enumerator_t *this, va_list args) { - traffic_selector_t *other_ts; + traffic_selector_t *other_ts, **my_out, **other_out; + + VA_ARGS_VGET(args, my_out, other_out); while (this->ts || this->mine->enumerate(this->mine, &this->ts)) { @@ -487,7 +488,8 @@ METHOD(child_sa_t, create_policy_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_policy_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _policy_enumerate, .destroy = _policy_destroy, }, .mine = array_create_enumerator(this->my_ts), diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 76e10691f..723da72e1 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1699,8 +1699,11 @@ typedef struct { } child_enumerator_t; METHOD(enumerator_t, child_enumerate, bool, - child_enumerator_t *this, child_sa_t **child_sa) + child_enumerator_t *this, va_list args) { + child_sa_t **child_sa; + + VA_ARGS_VGET(args, child_sa); if (this->inner->enumerate(this->inner, &this->current)) { *child_sa = this->current; @@ -1723,7 +1726,8 @@ METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_enumerate, .destroy = _child_enumerator_destroy, }, .inner = array_create_enumerator(this->child_sas), diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 15629fe61..fcb4cf0cd 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -513,8 +513,13 @@ struct private_enumerator_t { }; METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, entry_t **entry, u_int *segment) + private_enumerator_t *this, va_list args) { + entry_t **entry; + u_int *segment; + + VA_ARGS_VGET(args, entry, segment); + if (this->entry) { this->entry->condvar->signal(this->entry->condvar); @@ -572,7 +577,8 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = _enumerator_destroy, }, .manager = this, diff --git a/src/libimcv/imc/imc_os_info.c b/src/libimcv/imc/imc_os_info.c index 3315c209f..a40c30d20 100644 --- a/src/libimcv/imc/imc_os_info.c +++ b/src/libimcv/imc/imc_os_info.c @@ -283,23 +283,20 @@ typedef struct { } package_enumerator_t; -/** - * Implementation of package_enumerator.destroy. - */ -static void package_enumerator_destroy(package_enumerator_t *this) +METHOD(enumerator_t, package_enumerator_destroy, void, + package_enumerator_t *this) { pclose(this->file); free(this); } -/** - * Implementation of package_enumerator.enumerate - */ -static bool package_enumerator_enumerate(package_enumerator_t *this, ...) +METHOD(enumerator_t, package_enumerator_enumerate, bool, + package_enumerator_t *this, va_list args) { chunk_t *name, *version; u_char *pos; - va_list args; + + VA_ARGS_VGET(args, name, version); while (TRUE) { @@ -319,23 +316,16 @@ static bool package_enumerator_enumerate(package_enumerator_t *this, ...) { continue; } - va_start(args, this); - - name = va_arg(args, chunk_t*); name->ptr = pos; pos = strchr(pos, '\t'); if (!pos) { - va_end(args); return FALSE; } name->len = pos++ - name->ptr; - version = va_arg(args, chunk_t*); version->ptr = pos; version->len = strlen(pos) - 1; - - va_end(args); return TRUE; } } @@ -362,12 +352,14 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*, return NULL; } - /* Create a package enumerator instance */ - enumerator = malloc_thing(package_enumerator_t); - enumerator->public.enumerate = (void*)package_enumerator_enumerate; - enumerator->public.destroy = (void*)package_enumerator_destroy; - enumerator->file = file; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _package_enumerator_enumerate, + .destroy = _package_enumerator_destroy, + }, + .file = file, + ); return (enumerator_t*)enumerator; } diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index d0508624d..e96faa77e 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -626,22 +626,13 @@ typedef struct { } language_enumerator_t; -/** - * Implementation of language_enumerator.destroy. - */ -static void language_enumerator_destroy(language_enumerator_t *this) -{ - free(this); -} - -/** - * Implementation of language_enumerator.enumerate - */ -static bool language_enumerator_enumerate(language_enumerator_t *this, ...) +METHOD(enumerator_t, language_enumerator_enumerate, bool, + language_enumerator_t *this, va_list args) { char *pos, *cur_lang, **lang; TNC_UInt32 len; - va_list args; + + VA_ARGS_VGET(args, lang); if (!this->lang_len) { @@ -676,11 +667,7 @@ static bool language_enumerator_enumerate(language_enumerator_t *this, ...) } cur_lang[len] = '\0'; - va_start(args, this); - lang = va_arg(args, char**); *lang = cur_lang; - va_end(args); - return TRUE; } @@ -689,10 +676,13 @@ METHOD(imv_agent_t, create_language_enumerator, enumerator_t*, { language_enumerator_t *e; - /* Create a language enumerator instance */ - e = malloc_thing(language_enumerator_t); - e->public.enumerate = (void*)language_enumerator_enumerate; - e->public.destroy = (void*)language_enumerator_destroy; + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _language_enumerator_enumerate, + .destroy = (void*)free, + }, + ); if (!this->get_attribute || !this->get_attribute(this->id, state->get_connection_id(state), diff --git a/src/libimcv/pts/pts_pcr.c b/src/libimcv/pts/pts_pcr.c index d514532c5..9f098c08e 100644 --- a/src/libimcv/pts/pts_pcr.c +++ b/src/libimcv/pts/pts_pcr.c @@ -111,17 +111,12 @@ typedef struct { private_pts_pcr_t *pcrs; } pcr_enumerator_t; -/** - * Implementation of enumerator.enumerate - */ -static bool pcr_enumerator_enumerate(pcr_enumerator_t *this, ...) +METHOD(enumerator_t, pcr_enumerator_enumerate, bool, + pcr_enumerator_t *this, va_list args) { - uint32_t *pcr, i, f; - va_list args; + uint32_t i, f, *pcr; - va_start(args, this); - pcr = va_arg(args, uint32_t*); - va_end(args); + VA_ARGS_VGET(args, pcr); while (this->pcr <= this->pcrs->pcr_max) { @@ -148,7 +143,8 @@ METHOD(pts_pcr_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)pcr_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _pcr_enumerator_enumerate, .destroy = (void*)free, }, .pcrs = this, diff --git a/src/libpttls/sasl/sasl_mechanism.c b/src/libpttls/sasl/sasl_mechanism.c index 05a02e56d..4e54de314 100644 --- a/src/libpttls/sasl/sasl_mechanism.c +++ b/src/libpttls/sasl/sasl_mechanism.c @@ -59,8 +59,11 @@ typedef struct { } mech_enumerator_t; METHOD(enumerator_t, mech_enumerate, bool, - mech_enumerator_t *this, char **name) + mech_enumerator_t *this, va_list args) { + char **name; + + VA_ARGS_VGET(args, name); while (this->i < countof(mechs)) { if (mechs[this->i].server == this->server) @@ -83,7 +86,8 @@ enumerator_t* sasl_mechanism_create_enumerator(bool server) INIT(enumerator, .public = { - .enumerate = (void*)_mech_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _mech_enumerate, .destroy = (void*)free, }, .server = server, diff --git a/src/libradius/radius_message.c b/src/libradius/radius_message.c index 9705d3b53..51135fbea 100644 --- a/src/libradius/radius_message.c +++ b/src/libradius/radius_message.c @@ -244,8 +244,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, int *type, chunk_t *data) + attribute_enumerator_t *this, va_list args) { + chunk_t *data; + int *type; + + VA_ARGS_VGET(args, type, data); if (this->left == 0) { return FALSE; @@ -275,7 +279,8 @@ METHOD(radius_message_t, create_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = (void*)free, }, .next = (rattr_t*)this->msg->attributes, @@ -299,12 +304,14 @@ typedef struct { } vendor_enumerator_t; METHOD(enumerator_t, vendor_enumerate, bool, - vendor_enumerator_t *this, int *vendor, int *type, chunk_t *data) + vendor_enumerator_t *this, va_list args) { - chunk_t inner_data; - int inner_type; + chunk_t inner_data, *data; + int inner_type, *vendor, *type; uint8_t type8, len; + VA_ARGS_VGET(args, vendor, type, data); + while (TRUE) { if (this->reader) @@ -354,7 +361,8 @@ METHOD(radius_message_t, create_vendor_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_vendor_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _vendor_enumerate, .destroy = _vendor_destroy, }, .inner = create_enumerator(this), diff --git a/src/libstrongswan/collections/array.c b/src/libstrongswan/collections/array.c index 69e7df99e..c3dd6e0e9 100644 --- a/src/libstrongswan/collections/array.c +++ b/src/libstrongswan/collections/array.c @@ -214,9 +214,11 @@ typedef struct { } array_enumerator_t; METHOD(enumerator_t, enumerate, bool, - array_enumerator_t *this, void **out) + array_enumerator_t *this, va_list args) { - void *pos; + void *pos, **out; + + VA_ARGS_VGET(args, out); if (this->idx >= this->array->count) { @@ -250,7 +252,8 @@ enumerator_t* array_create_enumerator(array_t *array) INIT(enumerator, .public = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .array = array, diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index e96b235e3..cdf05d5e8 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -50,22 +50,24 @@ bool enumerator_enumerate_default(enumerator_t *enumerator, ...) return result; } -/** - * Implementation of enumerator_create_empty().enumerate - */ -static bool enumerate_empty(enumerator_t *enumerator, ...) +METHOD(enumerator_t, enumerate_empty, bool, + enumerator_t *enumerator, va_list args) { return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_empty() { - enumerator_t *this = malloc_thing(enumerator_t); - this->enumerate = enumerate_empty; - this->destroy = (void*)free; + enumerator_t *this; + + INIT(this, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_empty, + .destroy = (void*)free, + ); return this; } @@ -83,32 +85,31 @@ typedef struct { char *full_end; } dir_enum_t; -/** - * Implementation of enumerator_create_directory().destroy - */ -static void destroy_dir_enum(dir_enum_t *this) +METHOD(enumerator_t, destroy_dir_enum, void, + dir_enum_t *this) { closedir(this->dir); free(this); } -/** - * Implementation of enumerator_create_directory().enumerate - */ -static bool enumerate_dir_enum(dir_enum_t *this, char **relative, - char **absolute, struct stat *st) +METHOD(enumerator_t, enumerate_dir_enum, bool, + dir_enum_t *this, va_list args) { struct dirent *entry = readdir(this->dir); + struct stat *st; size_t remaining; + char **relative, **absolute; int len; + VA_ARGS_VGET(args, relative, absolute, st); + if (!entry) { return FALSE; } if (streq(entry->d_name, ".") || streq(entry->d_name, "..")) { - return enumerate_dir_enum(this, relative, absolute, st); + return this->public.enumerate(&this->public, relative, absolute, st); } if (relative) { @@ -141,15 +142,21 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative, return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_directory(const char *path) { + dir_enum_t *this; int len; - dir_enum_t *this = malloc_thing(dir_enum_t); - this->public.enumerate = (void*)enumerate_dir_enum; - this->public.destroy = (void*)destroy_dir_enum; + + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dir_enum, + .destroy = _destroy_dir_enum, + }, + ); if (*path == '\0') { @@ -171,9 +178,10 @@ enumerator_t* enumerator_create_directory(const char *path) this->full_end = &this->full[len]; this->dir = opendir(path); - if (this->dir == NULL) + if (!this->dir) { - DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, strerror(errno)); + DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, + strerror(errno)); free(this); return NULL; } @@ -196,21 +204,21 @@ typedef struct { char full[PATH_MAX]; } glob_enum_t; -/** - * Implementation of enumerator_create_glob().destroy - */ -static void destroy_glob_enum(glob_enum_t *this) +METHOD(enumerator_t, destroy_glob_enum, void, + glob_enum_t *this) { globfree(&this->glob); free(this); } -/** - * Implementation of enumerator_create_glob().enumerate - */ -static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) +METHOD(enumerator_t, enumerate_glob_enum, bool, + glob_enum_t *this, va_list args) { + struct stat *st; char *match; + char **file; + + VA_ARGS_VGET(args, file, st); if (this->pos >= this->glob.gl_pathc) { @@ -221,20 +229,17 @@ static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) { *file = match; } - if (st) + if (st && stat(match, st)) { - if (stat(match, st)) - { - DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, - strerror(errno)); - return FALSE; - } + DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, + strerror(errno)); + return FALSE; } return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_glob(const char *pattern) { @@ -248,8 +253,9 @@ enumerator_t* enumerator_create_glob(const char *pattern) INIT(this, .public = { - .enumerate = (void*)enumerate_glob_enum, - .destroy = (void*)destroy_glob_enum, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_glob_enum, + .destroy = _destroy_glob_enum, }, ); @@ -291,24 +297,22 @@ typedef struct { const char *trim; } token_enum_t; -/** - * Implementation of enumerator_create_token().destroy - */ -static void destroy_token_enum(token_enum_t *this) +METHOD(enumerator_t, destroy_token_enum, void, + token_enum_t *this) { free(this->string); free(this); } -/** - * Implementation of enumerator_create_token().enumerate - */ -static bool enumerate_token_enum(token_enum_t *this, char **token) +METHOD(enumerator_t, enumerate_token_enum, bool, + token_enum_t *this, va_list args) { const char *sep, *trim; - char *pos = NULL, *tmp; + char *pos = NULL, *tmp, **token; bool last = FALSE; + VA_ARGS_VGET(args, token); + /* trim leading characters/separators */ while (*this->pos) { @@ -409,52 +413,48 @@ static bool enumerate_token_enum(token_enum_t *this, char **token) return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_token(const char *string, const char *sep, const char *trim) { - token_enum_t *enumerator = malloc_thing(token_enum_t); + token_enum_t *this; - enumerator->public.enumerate = (void*)enumerate_token_enum; - enumerator->public.destroy = (void*)destroy_token_enum; - enumerator->string = strdup(string); - enumerator->pos = enumerator->string; - enumerator->sep = sep; - enumerator->trim = trim; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_token_enum, + .destroy = _destroy_token_enum, + }, + .string = strdup(string), + .sep = sep, + .trim = trim, + ); + this->pos = this->string; - return &enumerator->public; + return &this->public; } /** - * enumerator for nested enumerations + * Enumerator for nested enumerations */ typedef struct { - /* implements enumerator_t */ enumerator_t public; - /* outer enumerator */ enumerator_t *outer; - /* inner enumerator */ enumerator_t *inner; - /* constructor for inner enumerator */ enumerator_t *(*create_inner)(void *outer, void *data); - /* data to pass to constructor above */ void *data; - /* destructor for data */ - void (*destroy_data)(void *data); + void (*destructor)(void *data); } nested_enumerator_t; -/** - * Implementation of enumerator_create_nested().enumerate() - */ -static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_nested, bool, + nested_enumerator_t *this, va_list args) { while (TRUE) { - while (this->inner == NULL) + while (!this->inner) { void *outer; @@ -463,8 +463,13 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, return FALSE; } this->inner = this->create_inner(outer, this->data); + if (this->inner && !this->inner->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE NESTED: venumerate() missing !!!"); + return FALSE; + } } - if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5)) + if (this->inner->venumerate(this->inner, args)) { return TRUE; } @@ -473,42 +478,43 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, } } -/** - * Implementation of enumerator_create_nested().destroy() - **/ -static void destroy_nested(nested_enumerator_t *this) +METHOD(enumerator_t, destroy_nested, void, + nested_enumerator_t *this) { - if (this->destroy_data) + if (this->destructor) { - this->destroy_data(this->data); + this->destructor(this->data); } DESTROY_IF(this->inner); this->outer->destroy(this->outer); free(this); } -/** - * See header +/* + * Described in header */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)) + void *data, void (*destructor)(void *data)) { - nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t); + nested_enumerator_t *this; - enumerator->public.enumerate = (void*)enumerate_nested; - enumerator->public.destroy = (void*)destroy_nested; - enumerator->outer = outer; - enumerator->inner = NULL; - enumerator->create_inner = (void*)inner_constructor; - enumerator->data = data; - enumerator->destroy_data = destroy_data; - - return &enumerator->public; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_nested, + .destroy = _destroy_nested, + }, + .outer = outer, + .create_inner = inner_constructor, + .data = data, + .destructor = destructor, + ); + return &this->public; } /** - * enumerator for filtered enumerator + * Enumerator for filtered enumerator */ typedef struct { enumerator_t public; @@ -518,10 +524,8 @@ typedef struct { void (*destructor)(void *data); } filter_enumerator_t; -/** - * Implementation of enumerator_create_filter().destroy - */ -static void destroy_filter(filter_enumerator_t *this) +METHOD(enumerator_t, destroy_filter, void, + filter_enumerator_t *this) { if (this->destructor) { @@ -531,13 +535,14 @@ static void destroy_filter(filter_enumerator_t *this) free(this); } -/** - * Implementation of enumerator_create_filter().enumerate - */ -static bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2, - void *o3, void *o4, void *o5) +METHOD(enumerator_t, enumerate_filter, bool, + filter_enumerator_t *this, va_list args) { void *i1, *i2, *i3, *i4, *i5; + void *o1, *o2, *o3, *o4, *o5; + + /* FIXME: what happens if there are less than five arguments is not defined */ + VA_ARGS_VGET(args, o1, o2, o3, o4, o5); while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5)) { @@ -549,27 +554,31 @@ static bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2, return FALSE; } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, bool (*filter)(void *data, ...), void *data, void (*destructor)(void *data)) { - filter_enumerator_t *this = malloc_thing(filter_enumerator_t); - - this->public.enumerate = (void*)enumerate_filter; - this->public.destroy = (void*)destroy_filter; - this->unfiltered = unfiltered; - this->filter = filter; - this->data = data; - this->destructor = destructor; + filter_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_filter, + .destroy = _destroy_filter, + }, + .unfiltered = unfiltered, + .filter = filter, + .data = data, + .destructor = destructor, + ); return &this->public; } /** - * enumerator for cleaner enumerator + * Enumerator for cleaner enumerator */ typedef struct { enumerator_t public; @@ -578,44 +587,48 @@ typedef struct { void *data; } cleaner_enumerator_t; -/** - * Implementation of enumerator_create_cleanup().destroy - */ -static void destroy_cleaner(cleaner_enumerator_t *this) +METHOD(enumerator_t, destroy_cleaner, void, + cleaner_enumerator_t *this) { this->cleanup(this->data); this->wrapped->destroy(this->wrapped); free(this); } -/** - * Implementation of enumerator_create_cleaner().enumerate - */ -static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_cleaner, bool, + cleaner_enumerator_t *this, va_list args) { - return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5); + if (!this->wrapped->venumerate) + { + DBG1(DBG_LIB, "!!! CLEANER ENUMERATOR: venumerate() missing !!!"); + return FALSE; + } + return this->wrapped->venumerate(this->wrapped, args); } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped, void (*cleanup)(void *data), void *data) { - cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t); - - this->public.enumerate = (void*)enumerate_cleaner; - this->public.destroy = (void*)destroy_cleaner; - this->wrapped = wrapped; - this->cleanup = cleanup; - this->data = data; + cleaner_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_cleaner, + .destroy = _destroy_cleaner, + }, + .wrapped = wrapped, + .cleanup = cleanup, + .data = data, + ); return &this->public; } /** - * enumerator for single enumerator + * Enumerator for single enumerator */ typedef struct { enumerator_t public; @@ -624,10 +637,8 @@ typedef struct { bool done; } single_enumerator_t; -/** - * Implementation of enumerator_create_single().destroy - */ -static void destroy_single(single_enumerator_t *this) +METHOD(enumerator_t, destroy_single, void, + single_enumerator_t *this) { if (this->cleanup) { @@ -636,11 +647,12 @@ static void destroy_single(single_enumerator_t *this) free(this); } -/** - * Implementation of enumerator_create_single().enumerate - */ -static bool enumerate_single(single_enumerator_t *this, void **item) +METHOD(enumerator_t, enumerate_single, bool, + single_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); if (this->done) { return FALSE; @@ -650,18 +662,21 @@ static bool enumerate_single(single_enumerator_t *this, void **item) return TRUE; } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)) { - single_enumerator_t *this = malloc_thing(single_enumerator_t); - - this->public.enumerate = (void*)enumerate_single; - this->public.destroy = (void*)destroy_single; - this->item = item; - this->cleanup = cleanup; - this->done = FALSE; + single_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_single, + .destroy = _destroy_single, + }, + .item = item, + .cleanup = cleanup, + ); return &this->public; } diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index 224fe7ea8..e4b0547ba 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -172,17 +172,21 @@ enumerator_t* enumerator_create_token(const char *string, const char *sep, /** * Creates an enumerator which enumerates over enumerated enumerators :-). * - * The variable argument list of enumeration values is limit to 5. + * The outer enumerator is expected to return objects that, when passed to + * inner_contructor, will create a new enumerator that will be enumerated until + * completion (to this enumerator will the pointer arguments that are passed to + * this enumerator be forwarded) at which point a new element from the outer + * enumerator is requested to create a new inner enumerator. * * @param outer outer enumerator - * @param inner_constructor constructor to inner enumerator + * @param inner_constructor constructor to create inner enumerator * @param data data to pass to each inner_constructor call - * @param destroy_data destructor to pass to data + * @param destructor destructor function to clean up data after use * @return the nested enumerator */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(*inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)); + void *data, void (*destructor)(void *data)); /** * Creates an enumerator which filters output of another enumerator. diff --git a/src/libstrongswan/collections/hashtable.c b/src/libstrongswan/collections/hashtable.c index 2b77a37cc..b0eda9e6a 100644 --- a/src/libstrongswan/collections/hashtable.c +++ b/src/libstrongswan/collections/hashtable.c @@ -379,8 +379,13 @@ METHOD(hashtable_t, get_count, u_int, } METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, const void **key, void **value) + private_enumerator_t *this, va_list args) { + const void **key; + void **value; + + VA_ARGS_VGET(args, key, value); + while (this->count && this->row < this->table->capacity) { this->prev = this->current; @@ -417,7 +422,8 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .table = this, diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index b8fe81578..eb11339bc 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -119,8 +119,12 @@ struct private_enumerator_t { }; METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, void **item) + private_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); + if (this->finished) { return FALSE; @@ -152,7 +156,8 @@ METHOD(linked_list_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .list = this, diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 8a3e659fd..a9c8b3904 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -146,12 +146,14 @@ typedef struct { bool enumerated[AUTH_RULE_MAX]; } entry_enumerator_t; -/** - * enumerate function for item_enumerator_t - */ -static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value) +METHOD(enumerator_t, enumerate, bool, + entry_enumerator_t *this, va_list args) { + auth_rule_t *type; entry_t *entry; + void **value; + + VA_ARGS_VGET(args, type, value); while (this->inner->enumerate(this->inner, &entry)) { @@ -174,10 +176,8 @@ static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value) return FALSE; } -/** - * destroy function for item_enumerator_t - */ -static void entry_enumerator_destroy(entry_enumerator_t *this) +METHOD(enumerator_t, entry_enumerator_destroy, void, + entry_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -190,8 +190,9 @@ METHOD(auth_cfg_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)enumerate, - .destroy = (void*)entry_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _entry_enumerator_destroy, }, .inner = array_create_enumerator(this->entries), ); diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 8e8be7ef2..5dd8e42b1 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -155,8 +155,12 @@ METHOD(credential_manager_t, call_hook, void, } METHOD(enumerator_t, sets_enumerate, bool, - sets_enumerator_t *this, credential_set_t **set) + sets_enumerator_t *this, va_list args) { + credential_set_t **set; + + VA_ARGS_VGET(args, set); + if (this->exclusive) { if (this->exclusive->enumerate(this->exclusive, set)) @@ -202,7 +206,8 @@ static enumerator_t *create_sets_enumerator(private_credential_manager_t *this) INIT(enumerator, .public = { - .enumerate = (void*)_sets_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _sets_enumerate, .destroy = _sets_destroy, }, ); @@ -840,9 +845,12 @@ typedef struct { } trusted_enumerator_t; METHOD(enumerator_t, trusted_enumerate, bool, - trusted_enumerator_t *this, certificate_t **cert, auth_cfg_t **auth) + trusted_enumerator_t *this, va_list args) { - certificate_t *current; + certificate_t *current, **cert; + auth_cfg_t **auth; + + VA_ARGS_VGET(args, cert, auth); DESTROY_IF(this->auth); this->auth = auth_cfg_create(); @@ -931,7 +939,8 @@ METHOD(credential_manager_t, create_trusted_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_trusted_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _trusted_enumerate, .destroy = _trusted_destroy, }, .this = this, @@ -960,9 +969,13 @@ typedef struct { } public_enumerator_t; METHOD(enumerator_t, public_enumerate, bool, - public_enumerator_t *this, public_key_t **key, auth_cfg_t **auth) + public_enumerator_t *this, va_list args) { certificate_t *cert; + public_key_t **key; + auth_cfg_t **auth; + + VA_ARGS_VGET(args, key, auth); while (this->inner->enumerate(this->inner, &cert, auth)) { @@ -1001,7 +1014,8 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_public_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _public_enumerate, .destroy = _public_destroy, }, .inner = create_trusted_enumerator(this, type, id, online), diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 2c76ad680..87f7e6664 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -272,8 +272,12 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, signature_schemes_enumerate, bool, - private_enumerator_t *this, signature_scheme_t *scheme) + private_enumerator_t *this, va_list args) { + signature_scheme_t *scheme; + + VA_ARGS_VGET(args, scheme); + while (++this->index < countof(scheme_map)) { if (this->type == scheme_map[this->index].type && @@ -296,7 +300,8 @@ enumerator_t *signature_schemes_for_key(key_type_t type, int size) INIT(this, .public = { - .enumerate = (void*)_signature_schemes_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _signature_schemes_enumerate, .destroy = (void*)free, }, .index = -1, diff --git a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c index 8393d5b18..1cd4b9d03 100644 --- a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c +++ b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c @@ -112,15 +112,15 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, return TRUE; } -/** - * enumerate function for wrapper_enumerator_t - */ -static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +METHOD(enumerator_t, enumerate, bool, + wrapper_enumerator_t *this, va_list args) { auth_rule_t rule; - certificate_t *current; + certificate_t *current, **cert; public_key_t *public; + VA_ARGS_VGET(args, cert); + while (this->inner->enumerate(this->inner, &rule, ¤t)) { if (rule == AUTH_HELPER_IM_HASH_URL || @@ -164,10 +164,8 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) return FALSE; } -/** - * destroy function for wrapper_enumerator_t - */ -static void wrapper_enumerator_destroy(wrapper_enumerator_t *this) +METHOD(enumerator_t, wrapper_enumerator_destroy, void, + wrapper_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -183,14 +181,18 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, { return NULL; } - enumerator = malloc_thing(wrapper_enumerator_t); - enumerator->auth = this->auth; - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->inner = this->auth->create_enumerator(this->auth); - enumerator->public.enumerate = (void*)enumerate; - enumerator->public.destroy = (void*)wrapper_enumerator_destroy; + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _wrapper_enumerator_destroy, + }, + .auth = this->auth, + .cert = cert, + .key = key, + .id = id, + .inner = this->auth->create_enumerator(this->auth), + ); return &enumerator->public; } diff --git a/src/libstrongswan/credentials/sets/callback_cred.c b/src/libstrongswan/credentials/sets/callback_cred.c index bff33f029..0d72452da 100644 --- a/src/libstrongswan/credentials/sets/callback_cred.c +++ b/src/libstrongswan/credentials/sets/callback_cred.c @@ -60,9 +60,12 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerate, bool, - shared_enumerator_t *this, shared_key_t **out, - id_match_t *match_me, id_match_t *match_other) + shared_enumerator_t *this, va_list args) { + shared_key_t **out; + id_match_t *match_me, *match_other; + + VA_ARGS_VGET(args, out, match_me, match_other); DESTROY_IF(this->current); this->current = this->this->cb.shared(this->this->data, this->type, this->me, this->other, match_me, match_other); @@ -89,7 +92,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = _shared_destroy, }, .this = this, diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 24fdb194b..92d5efdc6 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -252,13 +252,14 @@ typedef struct { int locked; } cert_enumerator_t; -/** - * filter function for certs enumerator - */ -static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out) +METHOD(enumerator_t, cert_enumerate, bool, + cert_enumerator_t *this, va_list args) { public_key_t *public; relation_t *rel; + certificate_t **out; + + VA_ARGS_VGET(args, out); if (this->locked >= 0) { @@ -311,10 +312,8 @@ static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out) return FALSE; } -/** - * clean up enumeration data - */ -static void cert_enumerator_destroy(cert_enumerator_t *this) +METHOD(enumerator_t, cert_enumerator_destroy, void, + cert_enumerator_t *this) { relation_t *rel; @@ -336,16 +335,19 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, { return NULL; } - enumerator = malloc_thing(cert_enumerator_t); - enumerator->public.enumerate = (void*)cert_enumerate; - enumerator->public.destroy = (void*)cert_enumerator_destroy; - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->relations = this->relations; - enumerator->index = -1; - enumerator->locked = -1; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerate, + .destroy = _cert_enumerator_destroy, + }, + .cert = cert, + .key = key, + .id = id, + .relations = this->relations, + .index = -1, + .locked = -1, + ); return &enumerator->public; } diff --git a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c index 151d69216..12d3f8156 100644 --- a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c +++ b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c @@ -49,14 +49,15 @@ typedef struct { identification_t *id; } wrapper_enumerator_t; -/** - * enumerate function wrapper_enumerator_t - */ -static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +METHOD(enumerator_t, enumerate, bool, + wrapper_enumerator_t *this, va_list args) { - certificate_t *current; + certificate_t *current, **cert; public_key_t *public; + + VA_ARGS_VGET(args, cert); + while (this->inner->enumerate(this->inner, ¤t)) { if (this->cert != CERT_ANY && this->cert != current->get_type(current)) @@ -85,10 +86,8 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) return FALSE; } -/** - * destroy function for wrapper_enumerator_t - */ -static void enumerator_destroy(wrapper_enumerator_t *this) +METHOD(enumerator_t, enumerator_destroy, void, + wrapper_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -105,13 +104,17 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, return NULL; } - enumerator = malloc_thing(wrapper_enumerator_t); - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->inner = this->response->create_cert_enumerator(this->response); - enumerator->public.enumerate = (void*)enumerate; - enumerator->public.destroy = (void*)enumerator_destroy; + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _enumerator_destroy, + }, + .cert = cert, + .key = key, + .id = id, + .inner = this->response->create_cert_enumerator(this->response), + ); return &enumerator->public; } diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index bab59a06f..3414a21bd 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -1026,9 +1026,14 @@ typedef struct { } verify_enumerator_t; METHOD(enumerator_t, verify_enumerate, bool, - verify_enumerator_t *this, u_int *alg, const char **plugin, bool *valid) + verify_enumerator_t *this, va_list args) { + const char **plugin; entry_t *entry; + u_int *alg; + bool *valid; + + VA_ARGS_VGET(args, alg, plugin, valid); if (!this->inner->enumerate(this->inner, &entry)) { @@ -1123,7 +1128,8 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*, } INIT(enumerator, .public = { - .enumerate = (void*)_verify_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _verify_enumerate, .destroy = _verify_destroy, }, .inner = inner, diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c index 871cc59a0..211eba704 100644 --- a/src/libstrongswan/plugins/mysql/mysql_database.c +++ b/src/libstrongswan/plugins/mysql/mysql_database.c @@ -403,10 +403,8 @@ typedef struct { unsigned long *length; } mysql_enumerator_t; -/** - * create a mysql enumerator - */ -static void mysql_enumerator_destroy(mysql_enumerator_t *this) +METHOD(enumerator_t, mysql_enumerator_destroy, void, + mysql_enumerator_t *this) { int columns, i; @@ -434,13 +432,10 @@ static void mysql_enumerator_destroy(mysql_enumerator_t *this) free(this); } -/** - * Implementation of database.query().enumerate - */ -static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) +METHOD(enumerator_t, mysql_enumerator_enumerate, bool, + mysql_enumerator_t *this, va_list args) { int i, columns; - va_list args; columns = mysql_stmt_field_count(this->stmt); @@ -477,7 +472,6 @@ static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) return FALSE; } - va_start(args, this); for (i = 0; i < columns; i++) { switch (this->bind[i].buffer_type) @@ -526,7 +520,6 @@ static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) break; } } - va_end(args); return TRUE; } @@ -552,9 +545,9 @@ METHOD(database_t, query, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)mysql_enumerator_enumerate, - .destroy = (void*)mysql_enumerator_destroy, - + .enumerate = enumerator_enumerate_default, + .venumerate = _mysql_enumerator_enumerate, + .destroy = _mysql_enumerator_destroy, }, .db = this, .stmt = stmt, diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c index 20bac6be5..61cf3e884 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crl.c +++ b/src/libstrongswan/plugins/openssl/openssl_crl.c @@ -142,8 +142,14 @@ typedef struct { METHOD(enumerator_t, crl_enumerate, bool, - crl_enumerator_t *this, chunk_t *serial, time_t *date, crl_reason_t *reason) + crl_enumerator_t *this, va_list args) { + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + if (this->i < this->num) { X509_REVOKED *revoked; @@ -188,7 +194,8 @@ METHOD(crl_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_crl_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _crl_enumerate, .destroy = (void*)free, }, .stack = X509_CRL_get_REVOKED(this->crl), diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c index 5752d96de..83ac8df5b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c +++ b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c @@ -136,8 +136,12 @@ METHOD(enumerator_t, cert_destroy, void, } METHOD(enumerator_t, cert_enumerate, bool, - cert_enumerator_t *this, certificate_t **out) + cert_enumerator_t *this, va_list args) { + certificate_t **out; + + VA_ARGS_VGET(args, out); + if (!this->certs) { return FALSE; @@ -176,7 +180,8 @@ METHOD(pkcs7_t, create_cert_enumerator, enumerator_t*, { INIT(enumerator, .public = { - .enumerate = (void*)_cert_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerate, .destroy = _cert_destroy, }, .certs = CMS_get1_certs(this->cms), @@ -320,8 +325,12 @@ static bool verify_digest(CMS_ContentInfo *cms, CMS_SignerInfo *si, int hash_oid } METHOD(enumerator_t, signature_enumerate, bool, - signature_enumerator_t *this, auth_cfg_t **out) + signature_enumerator_t *this, va_list args) { + auth_cfg_t **out; + + VA_ARGS_VGET(args, out); + if (!this->signers) { return FALSE; @@ -382,7 +391,8 @@ METHOD(container_t, create_signature_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_signature_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _signature_enumerate, .destroy = _signature_destroy, }, .cms = this->cms, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c index dc8a1f17a..89ae1969e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -719,12 +719,14 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object) } METHOD(enumerator_t, object_enumerate, bool, - object_enumerator_t *this, CK_OBJECT_HANDLE *out) + object_enumerator_t *this, va_list args) { - CK_OBJECT_HANDLE object; + CK_OBJECT_HANDLE object, *out; CK_ULONG found; CK_RV rv; + VA_ARGS_VGET(args, out); + if (!this->object) { rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found); @@ -786,7 +788,8 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_object_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _object_enumerate, .destroy = _object_destroy, }, .session = session, @@ -806,7 +809,8 @@ METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_object_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _object_enumerate, .destroy = _object_destroy, }, .session = session, @@ -838,11 +842,14 @@ typedef struct { } mechanism_enumerator_t; METHOD(enumerator_t, enumerate_mech, bool, - mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type, - CK_MECHANISM_INFO *info) + mechanism_enumerator_t *this, va_list args) { + CK_MECHANISM_INFO *info; + CK_MECHANISM_TYPE *type; CK_RV rv; + VA_ARGS_VGET(args, type, info); + if (this->current >= this->count) { return FALSE; @@ -876,7 +883,8 @@ METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_mech, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_mech, .destroy = _destroy_mech, }, .lib = &this->public, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 96c4a180d..31bcb0d25 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -265,8 +265,13 @@ typedef struct { } token_enumerator_t; METHOD(enumerator_t, enumerate_token, bool, - token_enumerator_t *this, pkcs11_library_t **out, CK_SLOT_ID *slot) + token_enumerator_t *this, va_list args) { + pkcs11_library_t **out; + CK_SLOT_ID *slot; + + VA_ARGS_VGET(args, out, slot); + if (this->current >= this->count) { free(this->slots); @@ -301,7 +306,8 @@ METHOD(pkcs11_manager_t, create_token_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_token, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_token, .destroy = _destroy_token, }, .inner = this->libs->create_enumerator(this->libs), diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c index d224ef3aa..413c3fff5 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c @@ -179,7 +179,7 @@ typedef struct { } signature_enumerator_t; METHOD(enumerator_t, enumerate, bool, - signature_enumerator_t *this, auth_cfg_t **out) + signature_enumerator_t *this, va_list args) { signerinfo_t *info; signature_scheme_t scheme; @@ -187,11 +187,13 @@ METHOD(enumerator_t, enumerate, bool, enumerator_t *enumerator; certificate_t *cert; public_key_t *key; - auth_cfg_t *auth; + auth_cfg_t *auth, **out; chunk_t chunk, hash, content; hasher_t *hasher; bool valid; + VA_ARGS_VGET(args, out); + while (this->inner->enumerate(this->inner, &info)) { /* clean up previous round */ @@ -300,7 +302,8 @@ METHOD(container_t, create_signature_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = _enumerator_destroy, }, .inner = this->signerinfos->create_enumerator(this->signerinfos), diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c index 0a35e3017..9f874212e 100644 --- a/src/libstrongswan/plugins/sqlite/sqlite_database.c +++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c @@ -174,10 +174,8 @@ typedef struct { private_sqlite_database_t *database; } sqlite_enumerator_t; -/** - * destroy a sqlite enumerator - */ -static void sqlite_enumerator_destroy(sqlite_enumerator_t *this) +METHOD(enumerator_t, sqlite_enumerator_destroy, void, + sqlite_enumerator_t *this) { sqlite3_finalize(this->stmt); if (!is_threadsave()) @@ -188,13 +186,10 @@ static void sqlite_enumerator_destroy(sqlite_enumerator_t *this) free(this); } -/** - * Implementation of database.query().enumerate - */ -static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) +METHOD(enumerator_t, sqlite_enumerator_enumerate, bool, + sqlite_enumerator_t *this, va_list args) { int i; - va_list args; switch (sqlite3_step(this->stmt)) { @@ -207,7 +202,7 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) case SQLITE_DONE: return FALSE; } - va_start(args, this); + for (i = 0; i < this->count; i++) { switch (this->columns[i]) @@ -245,11 +240,9 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) } default: DBG1(DBG_LIB, "invalid result type supplied"); - va_end(args); return FALSE; } } - va_end(args); return TRUE; } @@ -270,13 +263,17 @@ METHOD(database_t, query, enumerator_t*, stmt = run(this, sql, &args); if (stmt) { - enumerator = malloc_thing(sqlite_enumerator_t); - enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate; - enumerator->public.destroy = (void*)sqlite_enumerator_destroy; - enumerator->stmt = stmt; - enumerator->count = sqlite3_column_count(stmt); + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _sqlite_enumerator_enumerate, + .destroy = _sqlite_enumerator_destroy, + }, + .stmt = stmt, + .count = sqlite3_column_count(stmt), + .database = this, + ); enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count); - enumerator->database = this; for (i = 0; i < enumerator->count; i++) { enumerator->columns[i] = va_arg(args, db_type_t); diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index b00e8190c..bef51800e 100644 --- a/src/libstrongswan/settings/settings.c +++ b/src/libstrongswan/settings/settings.c @@ -744,10 +744,8 @@ typedef struct { hashtable_t *seen; } enumerator_data_t; -/** - * Destroy enumerator data - */ -static void enumerator_destroy(enumerator_data_t *this) +CALLBACK(enumerator_destroy, void, + enumerator_data_t *this) { this->settings->lock->unlock(this->settings->lock); this->seen->destroy(this->seen); diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c index 6dd68d60e..18b19166e 100644 --- a/src/libstrongswan/utils/backtrace.c +++ b/src/libstrongswan/utils/backtrace.c @@ -668,8 +668,12 @@ typedef struct { } frame_enumerator_t; METHOD(enumerator_t, frame_enumerate, bool, - frame_enumerator_t *this, void **addr) + frame_enumerator_t *this, va_list args) { + void **addr; + + VA_ARGS_VGET(args, addr); + if (this->i < this->bt->frame_count) { *addr = this->bt->frames[this->i++]; @@ -685,7 +689,8 @@ METHOD(backtrace_t, create_frame_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_frame_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _frame_enumerate, .destroy = (void*)free, }, .bt = this, diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 384bd6c92..1a4769063 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -136,9 +136,12 @@ typedef struct { } rdn_enumerator_t; METHOD(enumerator_t, rdn_enumerate, bool, - rdn_enumerator_t *this, chunk_t *oid, u_char *type, chunk_t *data) + rdn_enumerator_t *this, va_list args) { - chunk_t rdn; + chunk_t rdn, *oid, *data; + u_char *type; + + VA_ARGS_VGET(args, oid, type, data); /* a DN contains one or more SET, each containing one or more SEQUENCES, * each containing a OID/value RDN */ @@ -173,7 +176,8 @@ static enumerator_t* create_rdn_enumerator(chunk_t dn) INIT(e, .public = { - .enumerate = (void*)_rdn_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rdn_enumerate, .destroy = (void*)free, }, ); @@ -199,10 +203,11 @@ typedef struct { } rdn_part_enumerator_t; METHOD(enumerator_t, rdn_part_enumerate, bool, - rdn_part_enumerator_t *this, id_part_t *type, chunk_t *data) + rdn_part_enumerator_t *this, va_list args) { int i, known_oid, strtype; - chunk_t oid, inner_data; + chunk_t oid, inner_data, *data; + id_part_t *type; static const struct { int oid; id_part_t type; @@ -228,6 +233,8 @@ METHOD(enumerator_t, rdn_part_enumerate, bool, {OID_EMPLOYEE_NUMBER, ID_PART_RDN_EN}, }; + VA_ARGS_VGET(args, type, data); + while (this->inner->enumerate(this->inner, &oid, &strtype, &inner_data)) { known_oid = asn1_known_oid(oid); @@ -263,7 +270,8 @@ METHOD(identification_t, create_part_enumerator, enumerator_t*, INIT(e, .inner = create_rdn_enumerator(this->encoded), .public = { - .enumerate = (void*)_rdn_part_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rdn_part_enumerate, .destroy = _rdn_part_enumerator_destroy, }, ); diff --git a/src/manager/xml.c b/src/manager/xml.c index bf5bbbf05..0aee5f69b 100644 --- a/src/manager/xml.c +++ b/src/manager/xml.c @@ -67,8 +67,13 @@ typedef struct { } child_enum_t; METHOD(enumerator_t, child_enumerate, bool, - child_enum_t *e, private_xml_t **child, char **name, char **value) + child_enum_t *e, va_list args) { + private_xml_t **child; + char **name, **value; + + VA_ARGS_VGET(args, child, name, value); + while (e->node && e->node->type != XML_ELEMENT_NODE) { e->node = e->node->next; @@ -120,7 +125,8 @@ METHOD(xml_t, children, enumerator_t*, child_enum_t *ce; INIT(ce, .e = { - .enumerate = (void*)_child_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_enumerate, .destroy = _child_destroy, }, .child = { diff --git a/src/starter/parser/conf_parser.c b/src/starter/parser/conf_parser.c index 6d1c54d20..9f71a0584 100644 --- a/src/starter/parser/conf_parser.c +++ b/src/starter/parser/conf_parser.c @@ -158,10 +158,13 @@ typedef struct { } dictionary_enumerator_t; METHOD(enumerator_t, dictionary_enumerate, bool, - dictionary_enumerator_t *this, char **key, char **value) + dictionary_enumerator_t *this, va_list args) { setting_t *setting; section_t *parent; + char **key, **value; + + VA_ARGS_VGET(args, key, value); while (TRUE) { @@ -221,7 +224,8 @@ METHOD(dictionary_t, dictionary_create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_dictionary_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _dictionary_enumerate, .destroy = _dictionary_enumerator_destroy, }, .seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8), From 525cc46cabe3dbf17d9f63e76ea9aa974d3665fa Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 12 May 2017 12:10:27 +0200 Subject: [PATCH 4/7] Change interface for enumerator_create_filter() callback This avoids the unportable 5 pointer hack, but requires enumerating in the callback. --- src/charon-nm/nm/nm_creds.c | 61 ++--- src/charon-nm/nm/nm_handler.c | 21 +- src/conftest/config.c | 21 +- src/libcharon/config/backend_manager.c | 30 +-- src/libcharon/config/proposal.c | 40 ++-- src/libcharon/plugins/attr/attr_provider.c | 26 ++- src/libcharon/plugins/dhcp/dhcp_transaction.c | 26 ++- .../plugins/forecast/forecast_listener.c | 30 ++- .../kernel_netlink/kernel_netlink_net.c | 97 ++++---- .../kernel_pfroute/kernel_pfroute_net.c | 103 +++++---- .../plugins/load_tester/load_tester_creds.c | 34 +-- .../plugins/stroke/stroke_attribute.c | 76 ++++--- src/libcharon/plugins/stroke/stroke_ca.c | 34 +-- src/libcharon/plugins/stroke/stroke_config.c | 21 +- src/libcharon/plugins/stroke/stroke_handler.c | 56 ++--- src/libcharon/plugins/unity/unity_handler.c | 29 +-- src/libcharon/plugins/vici/vici_attribute.c | 26 ++- src/libcharon/plugins/vici/vici_config.c | 21 +- .../plugins/whitelist/whitelist_listener.c | 21 +- src/libcharon/sa/eap/eap_manager.c | 53 +++-- src/libcharon/sa/ike_sa.c | 49 ++-- src/libcharon/sa/ike_sa_manager.c | 58 +++-- src/libcharon/sa/ikev2/task_manager_v2.c | 21 +- src/libcharon/sa/shunt_manager.c | 22 +- src/libcharon/sa/trap_manager.c | 41 ++-- src/libcharon/tests/utils/mock_ipsec.c | 30 ++- .../ietf/ietf_attr_installed_packages.c | 26 ++- src/libimcv/ietf/ietf_attr_port_filter.c | 29 ++- src/libimcv/ita/ita_attr_settings.c | 25 +- .../imv_attestation/imv_attestation_state.c | 32 +-- src/libimcv/pts/pts_file_meas.c | 25 +- .../tcg/pts/tcg_pts_attr_req_func_comp_evid.c | 28 ++- src/libsimaka/simaka_message.c | 25 +- src/libstrongswan/collections/enumerator.c | 29 +-- src/libstrongswan/collections/enumerator.h | 23 +- .../credentials/credential_factory.c | 26 ++- src/libstrongswan/credentials/sets/mem_cred.c | 214 +++++++++--------- src/libstrongswan/crypto/crypto_factory.c | 209 +++++++++++------ .../crypto/hashers/hash_algorithm_set.c | 17 +- .../plugins/pkcs11/pkcs11_creds.c | 38 ++-- src/libstrongswan/plugins/plugin_loader.c | 80 ++++--- src/libstrongswan/plugins/x509/x509_ac.c | 33 +-- src/libstrongswan/plugins/x509/x509_crl.c | 42 ++-- .../plugins/x509/x509_ocsp_response.c | 54 +++-- src/libstrongswan/settings/settings.c | 61 +++-- .../tests/suites/test_enumerator.c | 50 ++-- src/libtls/tls_crypto.c | 38 ++-- .../plugins/tnc_imv/tnc_imv_recommendations.c | 34 +-- src/pki/commands/signcrl.c | 28 ++- src/starter/parser/conf_parser.c | 47 ++-- 50 files changed, 1331 insertions(+), 929 deletions(-) diff --git a/src/charon-nm/nm/nm_creds.c b/src/charon-nm/nm/nm_creds.c index c191ffde5..e70fd9e89 100644 --- a/src/charon-nm/nm/nm_creds.c +++ b/src/charon-nm/nm/nm_creds.c @@ -120,48 +120,49 @@ typedef struct { identification_t *id; } cert_data_t; -/** - * Destroy CA certificate enumerator 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 certificates enumerator - */ -static bool cert_filter(cert_data_t *data, certificate_t **in, - certificate_t **out) +CALLBACK(cert_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { - certificate_t *cert = *in; + certificate_t *cert, **out; public_key_t *public; - public = cert->get_public_key(cert); - if (!public) - { - return FALSE; - } - if (data->key != KEY_ANY && public->get_type(public) != data->key) - { - public->destroy(public); - return FALSE; - } - if (data->id && data->id->get_type(data->id) == ID_KEY_ID && - public->has_fingerprint(public, data->id->get_encoding(data->id))) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &cert)) { + public = cert->get_public_key(cert); + if (!public) + { + continue; + } + if (data->key != KEY_ANY && public->get_type(public) != data->key) + { + public->destroy(public); + continue; + } + if (data->id && data->id->get_type(data->id) == ID_KEY_ID && + public->has_fingerprint(public, data->id->get_encoding(data->id))) + { + public->destroy(public); + *out = cert; + return TRUE; + } public->destroy(public); + if (data->id && !cert->has_subject(cert, data->id)) + { + continue; + } *out = cert; return TRUE; } - public->destroy(public); - if (data->id && !cert->has_subject(cert, data->id)) - { - return FALSE; - } - *out = cert; - return TRUE; + return FALSE; } /** @@ -181,7 +182,7 @@ static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this, this->lock->read_lock(this->lock); return enumerator_create_filter( this->certs->create_enumerator(this->certs), - (void*)cert_filter, data, (void*)cert_data_destroy); + cert_filter, data, cert_data_destroy); } METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index 6c81afa0e..3eb2eb13c 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -113,13 +113,20 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, return enumerator_create_empty(); } -/** - * convert plain byte ptrs to handy chunk during enumeration - */ -static bool filter_chunks(void* null, char **in, chunk_t *out) +CALLBACK(filter_chunks, bool, + void *null, enumerator_t *orig, va_list args) { - *out = chunk_create(*in, 4); - return TRUE; + chunk_t *out; + char *ptr; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &ptr)) + { + *out = chunk_create(ptr, 4); + return TRUE; + } + return FALSE; } METHOD(nm_handler_t, create_enumerator, enumerator_t*, @@ -139,7 +146,7 @@ METHOD(nm_handler_t, create_enumerator, enumerator_t*, return enumerator_create_empty(); } return enumerator_create_filter(list->create_enumerator(list), - (void*)filter_chunks, NULL, NULL); + filter_chunks, NULL, NULL); } METHOD(nm_handler_t, reset, void, diff --git a/src/conftest/config.c b/src/conftest/config.c index 06a685047..d926dfca2 100644 --- a/src/conftest/config.c +++ b/src/conftest/config.c @@ -36,13 +36,20 @@ struct private_config_t { linked_list_t *configs; }; -/** - * 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*, @@ -51,7 +58,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, return enumerator_create_filter( this->configs->create_enumerator(this->configs), - (void*)ike_filter, NULL, NULL); + ike_filter, NULL, NULL); } METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c index 79f1d9fee..4f154df9b 100644 --- a/src/libcharon/config/backend_manager.c +++ b/src/libcharon/config/backend_manager.c @@ -265,20 +265,24 @@ static void peer_enum_destroy(peer_data_t *data) free(data); } -/** - * convert enumerator value from match_entry to config - */ -static bool peer_enum_filter(linked_list_t *configs, - match_entry_t **in, peer_cfg_t **out) +CALLBACK(peer_enum_filter, bool, + linked_list_t *configs, enumerator_t *orig, va_list args) { - *out = (*in)->cfg; - return TRUE; + match_entry_t *entry; + peer_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &entry)) + { + *out = entry->cfg; + return TRUE; + } + return FALSE; } -/** - * Clean up temporary config list - */ -static void peer_enum_filter_destroy(linked_list_t *configs) +CALLBACK(peer_enum_filter_destroy, void, + linked_list_t *configs) { match_entry_t *entry; @@ -379,8 +383,8 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*, helper->destroy(helper); return enumerator_create_filter(configs->create_enumerator(configs), - (void*)peer_enum_filter, configs, - (void*)peer_enum_filter_destroy); + peer_enum_filter, configs, + peer_enum_filter_destroy); } METHOD(backend_manager_t, get_peer_cfg_by_name, peer_cfg_t*, diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index a2dc113a5..6c71f78d3 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -94,27 +94,31 @@ METHOD(proposal_t, add_algorithm, void, array_insert(this->transforms, ARRAY_TAIL, &entry); } -/** - * filter function for peer configs - */ -static bool alg_filter(uintptr_t type, entry_t **in, uint16_t *alg, - void **unused, uint16_t *key_size) +CALLBACK(alg_filter, bool, + uintptr_t type, enumerator_t *orig, va_list args) { - entry_t *entry = *in; + entry_t *entry; + uint16_t *alg, *key_size; - if (entry->type != type) + VA_ARGS_VGET(args, alg, key_size); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (entry->type != type) + { + continue; + } + if (alg) + { + *alg = entry->alg; + } + if (key_size) + { + *key_size = entry->key_size; + } + return TRUE; } - if (alg) - { - *alg = entry->alg; - } - if (key_size) - { - *key_size = entry->key_size; - } - return TRUE; + return FALSE; } METHOD(proposal_t, create_enumerator, enumerator_t*, @@ -122,7 +126,7 @@ METHOD(proposal_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( array_create_enumerator(this->transforms), - (void*)alg_filter, (void*)(uintptr_t)type, NULL); + alg_filter, (void*)(uintptr_t)type, NULL); } METHOD(proposal_t, get_algorithm, bool, 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/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/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/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index f94992d5d..cb8b79963 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -1518,35 +1518,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; + 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; } - 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; - } - *out = (*in)->ip; - return TRUE; + return FALSE; } /** @@ -1556,30 +1560,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; + 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; } - 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; - } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1596,9 +1605,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, diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index 7b370666c..6d06ee179 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -1054,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; } /** @@ -1098,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; + 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; } - 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; - } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1137,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, 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) + shared_key_t *key, **out; + id_match_t *me, *other; + + VA_ARGS_VGET(args, out, me, other); + + if (orig->enumerate(orig, &key)) { - *me = ID_MATCH_ANY; + *out = key; + if (me) + { + *me = ID_MATCH_ANY; + } + if (other) + { + *other = ID_MATCH_ANY; + } + return TRUE; } - if (other) - { - *other = ID_MATCH_ANY; - } - 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/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..0a20188e7 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; - if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + VA_ARGS_VGET(args, out); + + 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); } /** 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)) + 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; + } + if (host->is_anyaddr(host)) + { + *data = chunk_empty; + } + else + { + *data = host->get_address(host); + } + return TRUE; } - if (host->is_anyaddr(host)) - { - *data = chunk_empty; - } - else - { - *data = host->get_address(host); - } - 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/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c index f640f9fbb..4a1478c6d 100644 --- a/src/libcharon/plugins/unity/unity_handler.c +++ b/src/libcharon/plugins/unity/unity_handler.c @@ -411,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); @@ -446,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/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/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); } diff --git a/src/libcharon/sa/eap/eap_manager.c b/src/libcharon/sa/eap/eap_manager.c index e4fcbc8f0..b2a57ccfb 100644 --- a/src/libcharon/sa/eap/eap_manager.c +++ b/src/libcharon/sa/eap/eap_manager.c @@ -105,31 +105,38 @@ METHOD(eap_manager_t, remove_method, void, this->lock->unlock(this->lock); } -/** - * filter the registered methods - */ -static bool filter_methods(uintptr_t role, eap_entry_t **entry, - eap_type_t *type, void *in, uint32_t *vendor) +CALLBACK(filter_methods, bool, + uintptr_t role, enumerator_t *orig, va_list args) { - if ((*entry)->role != (eap_role_t)role) + eap_entry_t *entry; + eap_type_t *type; + uint32_t *vendor; + + VA_ARGS_VGET(args, type, vendor); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (entry->role != (eap_role_t)role) + { + continue; + } + if (entry->vendor == 0 && + (entry->type < 4 || entry->type == EAP_EXPANDED || + entry->type > EAP_EXPERIMENTAL)) + { /* filter invalid types */ + continue; + } + if (type) + { + *type = entry->type; + } + if (vendor) + { + *vendor = entry->vendor; + } + return TRUE; } - if ((*entry)->vendor == 0 && - ((*entry)->type < 4 || (*entry)->type == EAP_EXPANDED || - (*entry)->type > EAP_EXPERIMENTAL)) - { /* filter invalid types */ - return FALSE; - } - if (type) - { - *type = (*entry)->type; - } - if (vendor) - { - *vendor = (*entry)->vendor; - } - return TRUE; + return FALSE; } METHOD(eap_manager_t, create_enumerator, enumerator_t*, @@ -139,7 +146,7 @@ METHOD(eap_manager_t, create_enumerator, enumerator_t*, return enumerator_create_cleaner( enumerator_create_filter( this->methods->create_enumerator(this->methods), - (void*)filter_methods, (void*)(uintptr_t)role, NULL), + filter_methods, (void*)(uintptr_t)role, NULL), (void*)this->lock->unlock, this->lock); } diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 723da72e1..045858792 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1200,12 +1200,20 @@ METHOD(ike_sa_t, generate_message, status_t, return status; } -static bool filter_fragments(private_ike_sa_t *this, packet_t **fragment, - packet_t **packet) +CALLBACK(filter_fragments, bool, + private_ike_sa_t *this, enumerator_t *orig, va_list args) { - *packet = (*fragment)->clone(*fragment); - set_dscp(this, *packet); - return TRUE; + packet_t *fragment, **packet; + + VA_ARGS_VGET(args, packet); + + if (orig->enumerate(orig, &fragment)) + { + *packet = fragment->clone(fragment); + set_dscp(this, *packet); + return TRUE; + } + return FALSE; } METHOD(ike_sa_t, generate_message_fragmented, status_t, @@ -1265,7 +1273,7 @@ METHOD(ike_sa_t, generate_message_fragmented, status_t, { charon->bus->message(charon->bus, message, FALSE, FALSE); } - *packets = enumerator_create_filter(fragments, (void*)filter_fragments, + *packets = enumerator_create_filter(fragments, filter_fragments, this, NULL); } return status; @@ -2623,24 +2631,31 @@ METHOD(ike_sa_t, add_configuration_attribute, void, array_insert(this->attributes, ARRAY_TAIL, &entry); } -/** - * Enumerator filter for attributes - */ -static bool filter_attribute(void *null, attribute_entry_t **in, - configuration_attribute_type_t *type, void *in2, - chunk_t *data, void *in3, bool *handled) +CALLBACK(filter_attribute, bool, + void *null, enumerator_t *orig, va_list args) { - *type = (*in)->type; - *data = (*in)->data; - *handled = (*in)->handler != NULL; - return TRUE; + attribute_entry_t *entry; + configuration_attribute_type_t *type; + chunk_t *data; + bool *handled; + + VA_ARGS_VGET(args, type, data, handled); + + if (orig->enumerate(orig, &entry)) + { + *type = entry->type; + *data = entry->data; + *handled = entry->handler != NULL; + return TRUE; + } + return FALSE; } METHOD(ike_sa_t, create_attribute_enumerator, enumerator_t*, private_ike_sa_t *this) { return enumerator_create_filter(array_create_enumerator(this->attributes), - (void*)filter_attribute, NULL, NULL); + filter_attribute, NULL, NULL); } METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index fcb4cf0cd..c6b5494da 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1562,42 +1562,52 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, return ike_sa; } -/** - * enumerator filter function, waiting variant - */ -static bool enumerator_filter_wait(private_ike_sa_manager_t *this, - entry_t **in, ike_sa_t **out, u_int *segment) +CALLBACK(enumerator_filter_wait, bool, + private_ike_sa_manager_t *this, enumerator_t *orig, va_list args) { - if (wait_for_entry(this, *in, *segment)) + entry_t *entry; + u_int segment; + ike_sa_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry, &segment)) { - *out = (*in)->ike_sa; - charon->bus->set_sa(charon->bus, *out); - return TRUE; + if (wait_for_entry(this, entry, segment)) + { + *out = entry->ike_sa; + charon->bus->set_sa(charon->bus, *out); + return TRUE; + } } return FALSE; } -/** - * enumerator filter function, skipping variant - */ -static bool enumerator_filter_skip(private_ike_sa_manager_t *this, - entry_t **in, ike_sa_t **out, u_int *segment) +CALLBACK(enumerator_filter_skip, bool, + private_ike_sa_manager_t *this, enumerator_t *orig, va_list args) { - if (!(*in)->driveout_new_threads && - !(*in)->driveout_waiting_threads && - !(*in)->checked_out) + entry_t *entry; + u_int segment; + ike_sa_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry, &segment)) { - *out = (*in)->ike_sa; - charon->bus->set_sa(charon->bus, *out); - return TRUE; + if (!entry->driveout_new_threads && + !entry->driveout_waiting_threads && + !entry->checked_out) + { + *out = entry->ike_sa; + charon->bus->set_sa(charon->bus, *out); + return TRUE; + } } return FALSE; } -/** - * Reset threads SA after enumeration - */ -static void reset_sa(void *data) +CALLBACK(reset_sa, void, + void *data) { charon->bus->set_sa(charon->bus, NULL); } diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 5bd308f7a..d215596d2 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -2079,13 +2079,20 @@ METHOD(task_manager_t, reset, void, this->reset = TRUE; } -/** - * Filter queued tasks - */ -static bool filter_queued(void *unused, queued_task_t **queued, task_t **task) +CALLBACK(filter_queued, bool, + void *unused, enumerator_t *orig, va_list args) { - *task = (*queued)->task; - return TRUE; + queued_task_t *queued; + task_t **task; + + VA_ARGS_VGET(args, task); + + if (orig->enumerate(orig, &queued)) + { + *task = queued->task; + return TRUE; + } + return FALSE; } METHOD(task_manager_t, create_task_enumerator, enumerator_t*, @@ -2100,7 +2107,7 @@ METHOD(task_manager_t, create_task_enumerator, enumerator_t*, case TASK_QUEUE_QUEUED: return enumerator_create_filter( array_create_enumerator(this->queued_tasks), - (void*)filter_queued, NULL, NULL); + filter_queued, NULL, NULL); default: return enumerator_create_empty(); } diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c index b0162751d..ad12f0579 100644 --- a/src/libcharon/sa/shunt_manager.c +++ b/src/libcharon/sa/shunt_manager.c @@ -381,14 +381,24 @@ METHOD(shunt_manager_t, uninstall, bool, } CALLBACK(filter_entries, bool, - void *unused, entry_t **entry, char **ns, void **in, child_cfg_t **cfg) + void *unused, enumerator_t *orig, va_list args) { - if (ns) + entry_t *entry; + child_cfg_t **cfg; + char **ns; + + VA_ARGS_VGET(args, ns, cfg); + + if (orig->enumerate(orig, &entry)) { - *ns = (*entry)->ns; + if (ns) + { + *ns = entry->ns; + } + *cfg = entry->cfg; + return TRUE; } - *cfg = (*entry)->cfg; - return TRUE; + return FALSE; } METHOD(shunt_manager_t, create_enumerator, enumerator_t*, @@ -397,7 +407,7 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->shunts->create_enumerator(this->shunts), - (void*)filter_entries, this->lock, + filter_entries, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 51df7a0db..71190f306 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -335,25 +335,32 @@ METHOD(trap_manager_t, uninstall, bool, return TRUE; } -/** - * convert enumerated entries to peer_cfg, child_sa - */ -static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg, - void *none, child_sa_t **child_sa) +CALLBACK(trap_filter, bool, + rwlock_t *lock, enumerator_t *orig, va_list args) { - if (!(*entry)->child_sa) - { /* skip entries that are currently being installed */ - return FALSE; - } - if (peer_cfg) + entry_t *entry; + peer_cfg_t **peer_cfg; + child_sa_t **child_sa; + + VA_ARGS_VGET(args, peer_cfg, child_sa); + + while (orig->enumerate(orig, &entry)) { - *peer_cfg = (*entry)->peer_cfg; + if (!entry->child_sa) + { /* skip entries that are currently being installed */ + continue; + } + if (peer_cfg) + { + *peer_cfg = entry->peer_cfg; + } + if (child_sa) + { + *child_sa = entry->child_sa; + } + return TRUE; } - if (child_sa) - { - *child_sa = (*entry)->child_sa; - } - return TRUE; + return FALSE; } METHOD(trap_manager_t, create_enumerator, enumerator_t*, @@ -361,7 +368,7 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->traps->create_enumerator(this->traps), - (void*)trap_filter, this->lock, + trap_filter, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/tests/utils/mock_ipsec.c b/src/libcharon/tests/utils/mock_ipsec.c index 68daaac32..d6172f5bd 100644 --- a/src/libcharon/tests/utils/mock_ipsec.c +++ b/src/libcharon/tests/utils/mock_ipsec.c @@ -269,19 +269,27 @@ kernel_ipsec_t *mock_ipsec_create() return &this->public; } -/** - * Filter SAs - */ -static bool filter_sas(void *data, entry_t **entry, ike_sa_t **ike_sa, - void *unused, uint32_t *spi) + +CALLBACK(filter_sas, bool, + void *data, enumerator_t *orig, va_list args) { - if ((*entry)->alloc) + entry_t *entry; + ike_sa_t **ike_sa; + uint32_t *spi; + + VA_ARGS_VGET(args, ike_sa, spi); + + while (orig->enumerate(orig, &entry, NULL)) { - return FALSE; + if (entry->alloc) + { + continue; + } + *ike_sa = entry->ike_sa; + *spi = entry->spi; + return TRUE; } - *ike_sa = (*entry)->ike_sa; - *spi = (*entry)->spi; - return TRUE; + return FALSE; } /* @@ -291,5 +299,5 @@ enumerator_t *mock_ipsec_create_sa_enumerator() { return enumerator_create_filter( instance->sas->create_enumerator(instance->sas), - (void*)filter_sas, NULL, NULL); + filter_sas, NULL, NULL); } diff --git a/src/libimcv/ietf/ietf_attr_installed_packages.c b/src/libimcv/ietf/ietf_attr_installed_packages.c index 7a870ac40..d8e5b3342 100644 --- a/src/libimcv/ietf/ietf_attr_installed_packages.c +++ b/src/libimcv/ietf/ietf_attr_installed_packages.c @@ -179,7 +179,7 @@ METHOD(pa_tnc_attr_t, process, status_t, u_char *pos; if (this->offset == 0) - { + { if (this->length < IETF_INSTALLED_PACKAGES_MIN_SIZE) { DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF, @@ -291,15 +291,21 @@ METHOD(ietf_attr_installed_packages_t, add, void, this->packages->insert_last(this->packages, entry); } -/** - * Enumerate package filter entries - */ -static bool package_filter(void *null, package_entry_t **entry, chunk_t *name, - void *i2, chunk_t *version) +CALLBACK(package_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*entry)->name; - *version = (*entry)->version; - return TRUE; + package_entry_t *entry; + chunk_t *name, *version; + + VA_ARGS_VGET(args, name, version); + + if (orig->enumerate(orig, &entry)) + { + *name = entry->name; + *version = entry->version; + return TRUE; + } + return FALSE; } METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, @@ -307,7 +313,7 @@ METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( this->packages->create_enumerator(this->packages), - (void*)package_filter, NULL, NULL); + package_filter, NULL, NULL); } METHOD(ietf_attr_installed_packages_t, get_count, uint16_t, diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c index 05920fdd8..2f7e4452c 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.c +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -213,24 +213,31 @@ METHOD(ietf_attr_port_filter_t, add_port, void, this->ports->insert_last(this->ports, entry); } -/** - * Enumerate port filter entries - */ -static bool port_filter(void *null, port_entry_t **entry, - bool *blocked, void *i2, uint8_t *protocol, void *i3, - uint16_t *port) +CALLBACK(port_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *blocked = (*entry)->blocked; - *protocol = (*entry)->protocol; - *port = (*entry)->port; - return TRUE; + port_entry_t *entry; + uint16_t *port; + uint8_t *protocol; + bool *blocked; + + VA_ARGS_VGET(args, blocked, protocol, port); + + if (orig->enumerate(orig, &entry)) + { + *blocked = entry->blocked; + *protocol = entry->protocol; + *port = entry->port; + return TRUE; + } + return FALSE; } METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*, private_ietf_attr_port_filter_t *this) { return enumerator_create_filter(this->ports->create_enumerator(this->ports), - (void*)port_filter, NULL, NULL); + port_filter, NULL, NULL); } /** diff --git a/src/libimcv/ita/ita_attr_settings.c b/src/libimcv/ita/ita_attr_settings.c index c7c968a26..b0907789e 100644 --- a/src/libimcv/ita/ita_attr_settings.c +++ b/src/libimcv/ita/ita_attr_settings.c @@ -262,22 +262,29 @@ METHOD(ita_attr_settings_t, add, void, this->list->insert_last(this->list, entry); } -/** - * Enumerate name/value pairs - */ -static bool entry_filter(void *null, entry_t **entry, char **name, - void *i2, chunk_t *value) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*entry)->name; - *value = (*entry)->value; - return TRUE; + entry_t *entry; + chunk_t *value; + char **name; + + VA_ARGS_VGET(args, name, value); + + while (orig->enumerate(orig, &entry)) + { + *name = entry->name; + *value = entry->value; + return TRUE; + } + return FALSE; } METHOD(ita_attr_settings_t, create_enumerator, enumerator_t*, private_ita_attr_settings_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } /** diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c index 1c3b91aeb..d63940797 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c @@ -418,24 +418,24 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*, } } -/** - * Enumerate file measurement entries - */ -static bool entry_filter(void *null, func_comp_t **entry, uint8_t *flags, - void *i2, uint32_t *depth, - void *i3, pts_comp_func_name_t **comp_name) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - pts_component_t *comp; - pts_comp_func_name_t *name; + func_comp_t *entry; + pts_comp_func_name_t **comp_name; + uint32_t *depth; + uint8_t *flags; - comp = (*entry)->comp; - name = (*entry)->name; + VA_ARGS_VGET(args, flags, depth, comp_name); - *flags = comp->get_evidence_flags(comp); - *depth = comp->get_depth(comp); - *comp_name = name; - - return TRUE; + if (orig->enumerate(orig, &entry)) + { + *flags = entry->comp->get_evidence_flags(entry->comp); + *depth = entry->comp->get_depth(entry->comp); + *comp_name = entry->name; + return TRUE; + } + return FALSE; } METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*, @@ -443,7 +443,7 @@ METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*, { return enumerator_create_filter( this->components->create_enumerator(this->components), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } METHOD(imv_attestation_state_t, get_component, pts_component_t*, diff --git a/src/libimcv/pts/pts_file_meas.c b/src/libimcv/pts/pts_file_meas.c index 6cfb86cb3..92f513a2d 100644 --- a/src/libimcv/pts/pts_file_meas.c +++ b/src/libimcv/pts/pts_file_meas.c @@ -94,22 +94,29 @@ METHOD(pts_file_meas_t, add, void, this->list->insert_last(this->list, entry); } -/** - * Enumerate file measurement entries - */ -static bool entry_filter(void *null, entry_t **entry, char **filename, - void *i2, chunk_t *measurement) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *filename = (*entry)->filename; - *measurement = (*entry)->measurement; - return TRUE; + entry_t *entry; + chunk_t *measurement; + char **filename; + + VA_ARGS_VGET(args, filename, measurement); + + if (orig->enumerate(orig, &entry)) + { + *filename = entry->filename; + *measurement = entry->measurement; + return TRUE; + } + return FALSE; } METHOD(pts_file_meas_t, create_enumerator, enumerator_t*, private_pts_file_meas_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } METHOD(pts_file_meas_t, check, bool, diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c index da21003e3..0d8486756 100644 --- a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c +++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c @@ -115,18 +115,24 @@ struct entry_t { pts_comp_func_name_t *name; }; -/** - * Enumerate functional component entries - */ -static bool entry_filter(void *null, entry_t **entry, uint8_t *flags, - void *i2, uint32_t *depth, void *i3, - pts_comp_func_name_t **name) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *flags = (*entry)->flags; - *depth = (*entry)->depth; - *name = (*entry)->name; + entry_t *entry; + pts_comp_func_name_t **name; + uint32_t *depth; + uint8_t *flags; - return TRUE; + VA_ARGS_VGET(args, flags, depth, name); + + if (orig->enumerate(orig, &entry)) + { + *flags = entry->flags; + *depth = entry->depth; + *name = entry->name; + return TRUE; + } + return FALSE; } /** @@ -318,7 +324,7 @@ METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*, private_tcg_pts_attr_req_func_comp_evid_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } /** diff --git a/src/libsimaka/simaka_message.c b/src/libsimaka/simaka_message.c index 234d7ef2a..6827c1795 100644 --- a/src/libsimaka/simaka_message.c +++ b/src/libsimaka/simaka_message.c @@ -222,17 +222,22 @@ METHOD(simaka_message_t, get_type, eap_type_t, return this->hdr->type; } -/** - * convert attr_t to type and data enumeration - */ -static bool attr_enum_filter(void *null, attr_t **in, simaka_attribute_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_enum_filter, bool, + void *null, enumerator_t *orig, va_list args) { - attr_t *attr = *in; + attr_t *attr; + simaka_attribute_t *type; + chunk_t *data; - *type = attr->type; - *data = chunk_create(attr->data, attr->len); - return TRUE; + VA_ARGS_VGET(args, type, data); + + if (orig->enumerate(orig, &attr)) + { + *type = attr->type; + *data = chunk_create(attr->data, attr->len); + return TRUE; + } + return FALSE; } METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*, @@ -240,7 +245,7 @@ METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*, { return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attr_enum_filter, NULL, NULL); + attr_enum_filter, NULL, NULL); } METHOD(simaka_message_t, add_attribute, void, diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index cdf05d5e8..52c9e1cd5 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -518,9 +518,9 @@ enumerator_t *enumerator_create_nested(enumerator_t *outer, */ typedef struct { enumerator_t public; - enumerator_t *unfiltered; + enumerator_t *orig; void *data; - bool (*filter)(void *data, ...); + bool (*filter)(void*,enumerator_t*,va_list); void (*destructor)(void *data); } filter_enumerator_t; @@ -531,35 +531,28 @@ METHOD(enumerator_t, destroy_filter, void, { this->destructor(this->data); } - this->unfiltered->destroy(this->unfiltered); + this->orig->destroy(this->orig); free(this); } METHOD(enumerator_t, enumerate_filter, bool, filter_enumerator_t *this, va_list args) { - void *i1, *i2, *i3, *i4, *i5; - void *o1, *o2, *o3, *o4, *o5; + bool result = FALSE; - /* FIXME: what happens if there are less than five arguments is not defined */ - VA_ARGS_VGET(args, o1, o2, o3, o4, o5); - - while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5)) + if (this->filter(this->data, this->orig, args)) { - if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5)) - { - return TRUE; - } + result = TRUE; } - return FALSE; + return result; } /* * Described in header */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)) +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)) { filter_enumerator_t *this; @@ -569,7 +562,7 @@ enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, .venumerate = _enumerate_filter, .destroy = _destroy_filter, }, - .unfiltered = unfiltered, + .orig = orig, .filter = filter, .data = data, .destructor = destructor, diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index e4b0547ba..99f8847e4 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -189,25 +189,24 @@ enumerator_t *enumerator_create_nested(enumerator_t *outer, void *data, void (*destructor)(void *data)); /** - * Creates an enumerator which filters output of another enumerator. + * Creates an enumerator which filters/maps output of another enumerator. * - * The filter function receives the user supplied "data" followed by a - * unfiltered enumeration item, followed by an output pointer where to write - * the filtered data. Then the next input/output pair follows. - * It returns TRUE to deliver the - * values to the caller of enumerate(), FALSE to filter this enumeration. + * The filter function receives the user supplied "data" followed by the + * original enumerator, followed by the arguments passed to the outer + * enumerator. It returns TRUE to deliver the values assigned to these + * arguments to the caller of enumerate() and FALSE to end the enumeration. + * Filtering items is simple as the filter function may just skip enumerated + * items from the original enumerator. * - * The variable argument list of enumeration values is limit to 5. - * - * @param unfiltered unfiltered enumerator to wrap, gets destroyed + * @param orig original enumerator to wrap, gets destroyed * @param filter filter function * @param data user data to supply to filter * @param destructor destructor function to clean up data after use * @return the filtered enumerator */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)); +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)); /** * Create an enumerator wrapper which does a cleanup on destroy. diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c index 94c7820e1..07e6ea343 100644 --- a/src/libstrongswan/credentials/credential_factory.c +++ b/src/libstrongswan/credentials/credential_factory.c @@ -163,17 +163,23 @@ METHOD(credential_factory_t, create, void*, return construct; } -/** - * Filter function for builder enumerator - */ -static bool builder_filter(void *null, entry_t **entry, credential_type_t *type, - void *dummy1, int *subtype) +CALLBACK(builder_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*entry)->final) + entry_t *entry; + credential_type_t *type; + int *subtype; + + VA_ARGS_VGET(args, type, subtype); + + while (orig->enumerate(orig, &entry)) { - *type = (*entry)->type; - *subtype = (*entry)->subtype; - return TRUE; + if (entry->final) + { + *type = entry->type; + *subtype = entry->subtype; + return TRUE; + } } return FALSE; } @@ -184,7 +190,7 @@ METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->constructors->create_enumerator(this->constructors), - (void*)builder_filter, this->lock, (void*)this->lock->unlock); + builder_filter, this->lock, (void*)this->lock->unlock); } METHOD(credential_factory_t, destroy, void, diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 53e035f98..7576220bc 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -74,25 +74,27 @@ 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->lock->unlock(data->lock); free(data); } -/** - * filter function for certs enumerator - */ -static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **out) +CALLBACK(certs_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { public_key_t *public; - certificate_t *cert = *in; + certificate_t *cert, **out; - if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &cert)) { + if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) + { + continue; + } public = cert->get_public_key(cert); if (public) { @@ -102,7 +104,7 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t ** data->id->get_encoding(data->id))) { public->destroy(public); - *out = *in; + *out = cert; return TRUE; } } @@ -110,11 +112,11 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t ** } 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 = *in; + *out = cert; return TRUE; } } @@ -143,8 +145,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { enumerator = this->untrusted->create_enumerator(this->untrusted); } - return enumerator_create_filter(enumerator, (void*)certs_filter, data, - (void*)cert_data_destroy); + return enumerator_create_filter(enumerator, certs_filter, data, + cert_data_destroy); } static bool certificate_equals(certificate_t *item, certificate_t *cert) @@ -301,30 +303,30 @@ typedef struct { identification_t *id; } key_data_t; -/** - * Destroy key enumerator data - */ -static void key_data_destroy(key_data_t *data) +CALLBACK(key_data_destroy, void, + key_data_t *data) { data->lock->unlock(data->lock); free(data); } -/** - * filter function for private key enumerator - */ -static bool key_filter(key_data_t *data, private_key_t **in, private_key_t **out) +CALLBACK(key_filter, bool, + key_data_t *data, enumerator_t *orig, va_list args) { - private_key_t *key; + private_key_t *key, **out; - key = *in; - if (data->type == KEY_ANY || data->type == key->get_type(key)) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &key)) { - if (data->id == NULL || - key->has_fingerprint(key, data->id->get_encoding(data->id))) + if (data->type == KEY_ANY || data->type == key->get_type(key)) { - *out = key; - return TRUE; + if (data->id == NULL || + key->has_fingerprint(key, data->id->get_encoding(data->id))) + { + *out = key; + return TRUE; + } } } return FALSE; @@ -342,7 +344,7 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, ); this->lock->read_lock(this->lock); return enumerator_create_filter(this->keys->create_enumerator(this->keys), - (void*)key_filter, data, (void*)key_data_destroy); + key_filter, data, key_data_destroy); } METHOD(mem_cred_t, add_key, void, @@ -468,10 +470,8 @@ typedef struct { shared_key_type_t type; } shared_data_t; -/** - * free shared key enumerator data and unlock list - */ -static void shared_data_destroy(shared_data_t *data) +CALLBACK(shared_data_destroy, void, + shared_data_t *data) { data->lock->unlock(data->lock); free(data); @@ -499,44 +499,47 @@ static id_match_t has_owner(shared_entry_t *entry, identification_t *owner) return best; } -/** - * enumerator filter function for shared entries - */ -static bool shared_filter(shared_data_t *data, - shared_entry_t **in, shared_key_t **out, - void **unused1, id_match_t *me, - void **unused2, id_match_t *other) +CALLBACK(shared_filter, bool, + shared_data_t *data, enumerator_t *orig, va_list args) { id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE; - shared_entry_t *entry = *in; + shared_entry_t *entry; + shared_key_t **out; + id_match_t *me, *other; - if (data->type != SHARED_ANY && - entry->shared->get_type(entry->shared) != data->type) + VA_ARGS_VGET(args, out, me, other); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (data->type != SHARED_ANY && + entry->shared->get_type(entry->shared) != data->type) + { + continue; + } + if (data->me) + { + my_match = has_owner(entry, data->me); + } + if (data->other) + { + other_match = has_owner(entry, data->other); + } + if ((data->me || data->other) && (!my_match && !other_match)) + { + continue; + } + *out = entry->shared; + if (me) + { + *me = my_match; + } + if (other) + { + *other = other_match; + } + return TRUE; } - if (data->me) - { - my_match = has_owner(entry, data->me); - } - if (data->other) - { - other_match = has_owner(entry, data->other); - } - if ((data->me || data->other) && (!my_match && !other_match)) - { - return FALSE; - } - *out = entry->shared; - if (me) - { - *me = my_match; - } - if (other) - { - *other = other_match; - } - return TRUE; + return FALSE; } METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, @@ -554,7 +557,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, data->lock->read_lock(data->lock); return enumerator_create_filter( this->shared->create_enumerator(this->shared), - (void*)shared_filter, data, (void*)shared_data_destroy); + shared_filter, data, shared_data_destroy); } METHOD(mem_cred_t, add_shared_unique, void, @@ -648,23 +651,27 @@ METHOD(mem_cred_t, remove_shared_unique, void, this->lock->unlock(this->lock); } -/** - * Filter unique ids of shared keys (ingore secrets without unique id) - */ -static bool unique_filter(void *unused, - shared_entry_t **in, char **id) +CALLBACK(unique_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - shared_entry_t *entry = *in; + shared_entry_t *entry; + char **id; - if (!entry->id) + VA_ARGS_VGET(args, id); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (!entry->id) + { + continue; + } + if (id) + { + *id = entry->id; + } + return TRUE; } - if (id) - { - *id = entry->id; - } - return TRUE; + return FALSE; } METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*, @@ -673,7 +680,7 @@ METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->shared->create_enumerator(this->shared), - (void*)unique_filter, this->lock, + unique_filter, this->lock, (void*)this->lock->unlock); } @@ -721,30 +728,35 @@ typedef struct { rwlock_t *lock; } cdp_data_t; -/** - * Clean up CDP enumerator data - */ -static void cdp_data_destroy(cdp_data_t *data) +CALLBACK(cdp_data_destroy, void, + cdp_data_t *data) { data->lock->unlock(data->lock); free(data); } -/** - * CDP enumerator filter - */ -static bool cdp_filter(cdp_data_t *data, cdp_t **cdp, char **uri) +CALLBACK(cdp_filter, bool, + cdp_data_t *data, enumerator_t *orig, va_list args) { - if (data->type != CERT_ANY && data->type != (*cdp)->type) + cdp_t *cdp; + char **uri; + + VA_ARGS_VGET(args, uri); + + while (orig->enumerate(orig, &cdp)) { - return FALSE; + if (data->type != CERT_ANY && data->type != cdp->type) + { + continue; + } + if (data->id && !cdp->id->matches(cdp->id, data->id)) + { + continue; + } + *uri = cdp->uri; + return TRUE; } - if (data->id && !(*cdp)->id->matches((*cdp)->id, data->id)) - { - return FALSE; - } - *uri = (*cdp)->uri; - return TRUE; + return FALSE; } METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, @@ -759,7 +771,7 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, ); this->lock->read_lock(this->lock); return enumerator_create_filter(this->cdps->create_enumerator(this->cdps), - (void*)cdp_filter, data, (void*)cdp_data_destroy); + cdp_filter, data, cdp_data_destroy); } diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index 3414a21bd..42d795d0a 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -819,43 +819,57 @@ static bool entry_match(entry_t *a, entry_t *b) return a->algo == b->algo; } -/** - * check for uniqueness of an entry - */ -static bool unique_check(linked_list_t *list, entry_t **in, entry_t **out) +CALLBACK(unique_check, bool, + linked_list_t *list, enumerator_t *orig, va_list args) { - if (list->find_first(list, (void*)entry_match, NULL, *in) == SUCCESS) + entry_t *entry, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (list->find_first(list, (void*)entry_match, NULL, entry) == SUCCESS) + { + continue; + } + *out = entry; + list->insert_last(list, entry); + return TRUE; } - *out = *in; - list->insert_last(list, *in); - return TRUE; + return FALSE; } /** * create an enumerator over entry->algo in list with locking and unique check */ static enumerator_t *create_enumerator(private_crypto_factory_t *this, - linked_list_t *list, void *filter) + linked_list_t *list, + bool (*filter)(void*,enumerator_t*,va_list)) { this->lock->read_lock(this->lock); return enumerator_create_filter( enumerator_create_filter( - list->create_enumerator(list), (void*)unique_check, + list->create_enumerator(list), unique_check, linked_list_create(), (void*)list->destroy), filter, this->lock, (void*)this->lock->unlock); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool crypter_filter(void *n, entry_t **entry, encryption_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(crypter_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + encryption_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*, @@ -870,15 +884,22 @@ METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*, return create_enumerator(this, this->aeads, crypter_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool signer_filter(void *n, entry_t **entry, integrity_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(signer_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + integrity_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*, @@ -887,15 +908,22 @@ METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*, return create_enumerator(this, this->signers, signer_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool hasher_filter(void *n, entry_t **entry, hash_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(hasher_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + hash_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*, @@ -904,15 +932,22 @@ METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*, return create_enumerator(this, this->hashers, hasher_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool prf_filter(void *n, entry_t **entry, pseudo_random_function_t *algo, - void *i2, const char **plugin_name) +CALLBACK(prf_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + pseudo_random_function_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, @@ -921,15 +956,22 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, return create_enumerator(this, this->prfs, prf_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool xof_filter(void *n, entry_t **entry, ext_out_function_t *algo, - void *i2, const char **plugin_name) +CALLBACK(xof_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + ext_out_function_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*, @@ -938,15 +980,22 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*, return create_enumerator(this, this->xofs, xof_filter); } -/** - * Filter function to enumerate group, not entry - */ -static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group, - void *i2, const char **plugin_name) +CALLBACK(dh_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *group = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + diffie_hellman_group_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, @@ -955,15 +1004,22 @@ METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, return create_enumerator(this, this->dhs, dh_filter); } -/** - * Filter function to enumerate strength, not entry - */ -static bool rng_filter(void *n, entry_t **entry, rng_quality_t *quality, - void *i2, const char **plugin_name) +CALLBACK(rng_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *quality = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + rng_quality_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*, @@ -972,13 +1028,20 @@ METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*, return create_enumerator(this, this->rngs, rng_filter); } -/** - * Filter function to enumerate plugin name, not entry - */ -static bool nonce_gen_filter(void *n, entry_t **entry, const char **plugin_name) +CALLBACK(nonce_gen_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + const char **plugin_name; + + VA_ARGS_VGET(args, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*, diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c index 93b67cb13..4087fe1d9 100644 --- a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c @@ -71,17 +71,26 @@ METHOD(hash_algorithm_set_t, count, int, return array_count(this->algorithms); } -static bool hash_filter(void *data, void **in, hash_algorithm_t *out) +CALLBACK(hash_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = **(hash_algorithm_t**)in; - return TRUE; + hash_algorithm_t *algo, *out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &algo)) + { + *out = *algo; + return TRUE; + } + return FALSE; } METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*, private_hash_algorithm_set_t *this) { return enumerator_create_filter(array_create_enumerator(this->algorithms), - (void*)hash_filter, NULL, NULL); + hash_filter, NULL, NULL); } METHOD(hash_algorithm_set_t, destroy, void, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c index e65f3a06b..b1575540d 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c @@ -153,30 +153,32 @@ static bool load_certificates(private_pkcs11_creds_t *this) return TRUE; } -/** - * filter function for certs enumerator - */ -static bool certs_filter(identification_t *id, - certificate_t **in, certificate_t **out) +CALLBACK(certs_filter, bool, + identification_t *id, enumerator_t *orig, va_list args) { public_key_t *public; - certificate_t *cert = *in; + certificate_t *cert, **out; - if (id == NULL || cert->has_subject(cert, id)) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &cert)) { - *out = *in; - return TRUE; - } - public = cert->get_public_key(cert); - if (public) - { - if (public->has_fingerprint(public, id->get_encoding(id))) + if (id == NULL || cert->has_subject(cert, id)) { - public->destroy(public); - *out = *in; + *out = cert; return TRUE; } - public->destroy(public); + public = cert->get_public_key(cert); + if (public) + { + if (public->has_fingerprint(public, id->get_encoding(id))) + { + public->destroy(public); + *out = cert; + return TRUE; + } + public->destroy(public); + } } return FALSE; } @@ -199,7 +201,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { inner = this->untrusted->create_enumerator(this->untrusted); } - return enumerator_create_filter(inner, (void*)certs_filter, id, NULL); + return enumerator_create_filter(inner, certs_filter, id, NULL); } METHOD(pkcs11_creds_t, get_library, pkcs11_library_t*, diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 4daf3f13e..fcd11951f 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -465,34 +465,48 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name, return entry; } -/** - * Convert enumerated provided_feature_t to plugin_feature_t - */ -static bool feature_filter(void *null, provided_feature_t **provided, - plugin_feature_t **feature) +CALLBACK(feature_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *feature = (*provided)->feature; - return (*provided)->loaded; + provided_feature_t *provided; + plugin_feature_t **feature; + + VA_ARGS_VGET(args, feature); + + while (orig->enumerate(orig, &provided)) + { + if (provided->loaded) + { + *feature = provided->feature; + return TRUE; + } + } + return FALSE; } -/** - * Convert enumerated entries to plugin_t - */ -static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin, - void *in, linked_list_t **list) +CALLBACK(plugin_filter, bool, + void *null, enumerator_t *orig, va_list args) { - plugin_entry_t *this = *entry; + plugin_entry_t *entry; + linked_list_t **list; + plugin_t **plugin; - *plugin = this->plugin; - if (list) + VA_ARGS_VGET(args, plugin, list); + + if (orig->enumerate(orig, &entry)) { - enumerator_t *features; - features = enumerator_create_filter( - this->features->create_enumerator(this->features), - (void*)feature_filter, NULL, NULL); - *list = linked_list_create_from_enumerator(features); + *plugin = entry->plugin; + if (list) + { + enumerator_t *features; + features = enumerator_create_filter( + entry->features->create_enumerator(entry->features), + feature_filter, NULL, NULL); + *list = linked_list_create_from_enumerator(features); + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, @@ -500,7 +514,7 @@ METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, { return enumerator_create_filter( this->plugins->create_enumerator(this->plugins), - (void*)plugin_filter, NULL, NULL); + plugin_filter, NULL, NULL); } METHOD(plugin_loader_t, has_feature, bool, @@ -1095,14 +1109,20 @@ static int plugin_priority_cmp(const plugin_priority_t *a, return diff; } -/** - * Convert enumerated plugin_priority_t to a plugin name - */ -static bool plugin_priority_filter(void *null, plugin_priority_t **prio, - char **name) +CALLBACK(plugin_priority_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*prio)->name; - return TRUE; + plugin_priority_t *prio; + char **name; + + VA_ARGS_VGET(args, name); + + if (orig->enumerate(orig, &prio)) + { + *name = prio->name; + return TRUE; + } + return FALSE; } /** @@ -1142,7 +1162,7 @@ static char *modular_pluginlist(char *list) else { enumerator = enumerator_create_filter(array_create_enumerator(given), - (void*)plugin_priority_filter, NULL, NULL); + plugin_priority_filter, NULL, NULL); load_def = TRUE; } while (enumerator->enumerate(enumerator, &plugin)) diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index 638b01fb5..ba459288b 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -804,20 +804,27 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t, return this->authKeyIdentifier; } -/** - * Filter function for attribute enumeration - */ -static bool attr_filter(void *null, group_t **in, ac_group_type_t *type, - void *in2, chunk_t *out) +CALLBACK(attr_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*in)->type == AC_GROUP_TYPE_STRING && - !chunk_printable((*in)->value, NULL, 0)) - { /* skip non-printable strings */ - return FALSE; + group_t *group; + ac_group_type_t *type; + chunk_t *out; + + VA_ARGS_VGET(args, type, out); + + while (orig->enumerate(orig, &group)) + { + if (group->type == AC_GROUP_TYPE_STRING && + !chunk_printable(group->value, NULL, 0)) + { /* skip non-printable strings */ + continue; + } + *type = group->type; + *out = group->value; + return TRUE; } - *type = (*in)->type; - *out = (*in)->value; - return TRUE; + return FALSE; } METHOD(ac_t, create_group_enumerator, enumerator_t*, @@ -825,7 +832,7 @@ METHOD(ac_t, create_group_enumerator, enumerator_t*, { return enumerator_create_filter( this->groups->create_enumerator(this->groups), - (void*)attr_filter, NULL, NULL); + attr_filter, NULL, NULL); } METHOD(certificate_t, get_type, certificate_type_t, diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 414a03433..d8913ad73 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -364,25 +364,33 @@ end: return success; } -/** - * enumerator filter callback for create_enumerator - */ -static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2, - time_t *date, void *p3, crl_reason_t *reason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - if (serial) + revoked_t *revoked; + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + + if (orig->enumerate(orig, &revoked)) { - *serial = (*revoked)->serial; + if (serial) + { + *serial = revoked->serial; + } + if (date) + { + *date = revoked->date; + } + if (reason) + { + *reason = revoked->reason; + } + return TRUE; } - if (date) - { - *date = (*revoked)->date; - } - if (reason) - { - *reason = (*revoked)->reason; - } - return TRUE; + return FALSE; } METHOD(crl_t, get_serial, chunk_t, @@ -422,7 +430,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( this->revoked->create_enumerator(this->revoked), - (void*)filter, NULL, NULL); + filter, NULL, NULL); } METHOD(certificate_t, get_type, certificate_type_t, diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index b46af30fe..140e9bfa9 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -228,32 +228,38 @@ METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*, return this->certs->create_enumerator(this->certs); } -/** - * enumerator filter callback for create_response_enumerator - */ -static bool filter(void *data, single_response_t **response, - chunk_t *serialNumber, - void *p2, cert_validation_t *status, - void *p3, time_t *revocationTime, - void *p4, crl_reason_t *revocationReason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - if (serialNumber) + single_response_t *response; + cert_validation_t *status; + crl_reason_t *revocationReason; + chunk_t *serialNumber; + time_t *revocationTime; + + VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason); + + if (orig->enumerate(orig, &response)) { - *serialNumber = (*response)->serialNumber; + if (serialNumber) + { + *serialNumber = response->serialNumber; + } + if (status) + { + *status = response->status; + } + if (revocationTime) + { + *revocationTime = response->revocationTime; + } + if (revocationReason) + { + *revocationReason = response->revocationReason; + } + return TRUE; } - if (status) - { - *status = (*response)->status; - } - if (revocationTime) - { - *revocationTime = (*response)->revocationTime; - } - if (revocationReason) - { - *revocationReason = (*response)->revocationReason; - } - return TRUE; + return FALSE; } METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*, @@ -261,7 +267,7 @@ METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*, { return enumerator_create_filter( this->responses->create_enumerator(this->responses), - (void*)filter, NULL, NULL); + filter, NULL, NULL); } /** diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index bef51800e..2a92d523b 100644 --- a/src/libstrongswan/settings/settings.c +++ b/src/libstrongswan/settings/settings.c @@ -753,18 +753,25 @@ CALLBACK(enumerator_destroy, void, free(this); } -/** - * Enumerate section names, not sections - */ -static bool section_filter(hashtable_t *seen, section_t **in, char **out) +CALLBACK(section_filter, bool, + hashtable_t *seen, enumerator_t *orig, va_list args) { - *out = (*in)->name; - if (seen->get(seen, *out)) + section_t *section; + char **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, §ion)) { - return FALSE; + if (seen->get(seen, section->name)) + { + continue; + } + *out = section->name; + seen->put(seen, section->name, section->name); + return TRUE; } - seen->put(seen, *out, *out); - return TRUE; + return FALSE; } /** @@ -774,8 +781,8 @@ static enumerator_t *section_enumerator(section_t *section, enumerator_data_t *data) { return enumerator_create_filter( - array_create_enumerator(section->sections_order), - (void*)section_filter, data->seen, NULL); + array_create_enumerator(section->sections_order), + section_filter, data->seen, NULL); } METHOD(settings_t, create_section_enumerator, enumerator_t*, @@ -801,23 +808,29 @@ METHOD(settings_t, create_section_enumerator, enumerator_t*, .seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8), ); return enumerator_create_nested(array_create_enumerator(sections), - (void*)section_enumerator, data, (void*)enumerator_destroy); + (void*)section_enumerator, data, enumerator_destroy); } -/** - * Enumerate key and values, not kv_t entries - */ -static bool kv_filter(hashtable_t *seen, kv_t **in, char **key, - void *none, char **value) +CALLBACK(kv_filter, bool, + hashtable_t *seen, enumerator_t *orig, va_list args) { - *key = (*in)->key; - if (seen->get(seen, *key) || !(*in)->value) + kv_t *kv; + char **key, **value; + + VA_ARGS_VGET(args, key, value); + + while (orig->enumerate(orig, &kv)) { - return FALSE; + if (seen->get(seen, kv->key) || !kv->value) + { + continue; + } + *key = kv->key; + *value = kv->value; + seen->put(seen, kv->key, kv->key); + return TRUE; } - *value = (*in)->value; - seen->put(seen, *key, *key); - return TRUE; + return FALSE; } /** @@ -826,7 +839,7 @@ static bool kv_filter(hashtable_t *seen, kv_t **in, char **key, static enumerator_t *kv_enumerator(section_t *section, enumerator_data_t *data) { return enumerator_create_filter(array_create_enumerator(section->kv_order), - (void*)kv_filter, data->seen, NULL); + kv_filter, data->seen, NULL); } METHOD(settings_t, create_key_value_enumerator, enumerator_t*, diff --git a/src/libstrongswan/tests/suites/test_enumerator.c b/src/libstrongswan/tests/suites/test_enumerator.c index 9bd6d24f2..b781ae9fd 100644 --- a/src/libstrongswan/tests/suites/test_enumerator.c +++ b/src/libstrongswan/tests/suites/test_enumerator.c @@ -104,25 +104,45 @@ static void destroy_data(void *data) * filtered test */ -static bool filter(int *data, int **v, int *vo, int **w, int *wo, - int **x, int *xo, int **y, int *yo, int **z, int *zo) +CALLBACK(filter, bool, + int *data, enumerator_t *orig, va_list args) { - int val = **v; + int *item, *vo, *wo, *xo, *yo, *zo; - *vo = val++; - *wo = val++; - *xo = val++; - *yo = val++; - *zo = val++; - fail_if(data != (void*)101, "data does not match '101' in filter function"); - return TRUE; + VA_ARGS_VGET(args, vo, wo, xo, yo, zo); + + if (orig->enumerate(orig, &item)) + { + int val = *item; + *vo = val++; + *wo = val++; + *xo = val++; + *yo = val++; + *zo = val++; + fail_if(data != (void*)101, "data does not match '101' in filter function"); + return TRUE; + } + return FALSE; } -static bool filter_odd(void *data, int **item, int *out) +CALLBACK(filter_odd, bool, + void *data, enumerator_t *orig, va_list args) { + int *item, *out; + + VA_ARGS_VGET(args, out); + fail_if(data != (void*)101, "data does not match '101' in filter function"); - *out = **item; - return **item % 2 == 0; + + while (orig->enumerate(orig, &item)) + { + if (*item % 2 == 0) + { + *out = *item; + return TRUE; + } + } + return FALSE; } START_TEST(test_filtered) @@ -136,7 +156,7 @@ START_TEST(test_filtered) round = 1; enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter, (void*)101, destroy_data); + filter, (void*)101, destroy_data); while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z)) { ck_assert_int_eq(v, round); @@ -166,7 +186,7 @@ START_TEST(test_filtered_filter) /* should also work without destructor, so set this manually */ destroy_data_called = 1; enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter_odd, (void*)101, NULL); + filter_odd, (void*)101, NULL); while (enumerator->enumerate(enumerator, &x)) { ck_assert(x % 2 == 0); diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 84b511f53..05ae62b49 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -1296,28 +1296,32 @@ static struct { { ECP_192_BIT, TLS_SECP192R1}, }; -/** - * Filter EC groups, add TLS curve - */ -static bool group_filter(void *null, - diffie_hellman_group_t *in, diffie_hellman_group_t *out, - void* dummy1, tls_named_curve_t *curve) +CALLBACK(group_filter, bool, + void *null, enumerator_t *orig, va_list args) { + diffie_hellman_group_t group, *out; + tls_named_curve_t *curve; + char *plugin; int i; - for (i = 0; i < countof(curves); i++) + VA_ARGS_VGET(args, out, curve); + + while (orig->enumerate(orig, &group, &plugin)) { - if (curves[i].group == *in) + for (i = 0; i < countof(curves); i++) { - if (out) + if (curves[i].group == group) { - *out = curves[i].group; + if (out) + { + *out = curves[i].group; + } + if (curve) + { + *curve = curves[i].curve; + } + return TRUE; } - if (curve) - { - *curve = curves[i].curve; - } - return TRUE; } } return FALSE; @@ -1327,8 +1331,8 @@ METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, private_tls_crypto_t *this) { return enumerator_create_filter( - lib->crypto->create_dh_enumerator(lib->crypto), - (void*)group_filter, NULL, NULL); + lib->crypto->create_dh_enumerator(lib->crypto), + group_filter, NULL, NULL); } METHOD(tls_crypto_t, set_protection, void, diff --git a/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c index a9dbb2b9f..9c6307d65 100644 --- a/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c +++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c @@ -320,31 +320,33 @@ METHOD(recommendations_t, set_reason_language, TNC_Result, return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER; } -/** - * Enumerate reason and reason_language, not recommendation entries - */ -static bool reason_filter(void *null, recommendation_entry_t **entry, - TNC_IMVID *id, void *i2, chunk_t *reason, void *i3, - chunk_t *reason_language) +CALLBACK(reason_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*entry)->reason.len) + recommendation_entry_t *entry; + TNC_IMVID *id; + chunk_t *reason, *reason_language; + + VA_ARGS_VGET(args, id, reason, reason_language); + + while (orig->enumerate(orig, &entry)) { - *id = (*entry)->id; - *reason = (*entry)->reason; - *reason_language = (*entry)->reason_language; - return TRUE; - } - else - { - return FALSE; + if (entry->reason.len) + { + *id = entry->id; + *reason = entry->reason; + *reason_language = entry->reason_language; + return TRUE; + } } + return FALSE; } METHOD(recommendations_t, create_reason_enumerator, enumerator_t*, private_tnc_imv_recommendations_t *this) { return enumerator_create_filter(this->recs->create_enumerator(this->recs), - (void*)reason_filter, NULL, NULL); + reason_filter, NULL, NULL); } METHOD(recommendations_t, destroy, void, diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index 6bccf1b09..25a3aac52 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -61,16 +61,24 @@ static void revoked_destroy(revoked_t *revoked) free(revoked); } -/** - * Filter for revoked enumerator - */ -static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2, - time_t *date, void *p3, crl_reason_t *reason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - *serial = (*revoked)->serial; - *date = (*revoked)->date; - *reason = (*revoked)->reason; - return TRUE; + revoked_t *revoked; + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + + if (orig->enumerate(orig, &revoked)) + { + *serial = revoked->serial; + *date = revoked->date; + *reason = revoked->reason; + return TRUE; + } + return FALSE; } /** @@ -392,7 +400,7 @@ static int sign_crl() chunk_increment(crl_serial); enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter, NULL, NULL); + filter, NULL, NULL); crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca, BUILD_SERIAL, crl_serial, diff --git a/src/starter/parser/conf_parser.c b/src/starter/parser/conf_parser.c index 9f71a0584..66e0ae8e4 100644 --- a/src/starter/parser/conf_parser.c +++ b/src/starter/parser/conf_parser.c @@ -294,24 +294,43 @@ static dictionary_t *section_dictionary_create(private_conf_parser_t *parser, return &this->public; } -static bool conn_filter(void *unused, section_t **section, char **name) +CALLBACK(conn_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - if (streq((*section)->name, "%default")) + section_t *section; + char **name; + + VA_ARGS_VGET(args, name); + + while (orig->enumerate(orig, §ion)) { - return FALSE; + if (!streq(section->name, "%default")) + { + *name = section->name; + return TRUE; + } } - *name = (*section)->name; - return TRUE; + return FALSE; } -static bool ca_filter(void *unused, void *key, char **name, section_t **section) +CALLBACK(ca_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - if (streq((*section)->name, "%default")) + void *key; + section_t *section; + char **name; + + VA_ARGS_VGET(args, name); + + while (orig->enumerate(orig, &key, §ion)) { - return FALSE; + if (!streq(section->name, "%default")) + { + *name = section->name; + return TRUE; + } } - *name = (*section)->name; - return TRUE; + return FALSE; } METHOD(conf_parser_t, get_sections, enumerator_t*, @@ -321,12 +340,12 @@ METHOD(conf_parser_t, get_sections, enumerator_t*, { case CONF_PARSER_CONN: return enumerator_create_filter( - array_create_enumerator(this->conns_order), - (void*)conn_filter, NULL, NULL); + array_create_enumerator(this->conns_order), + conn_filter, NULL, NULL); case CONF_PARSER_CA: return enumerator_create_filter( - this->cas->create_enumerator(this->cas), - (void*)ca_filter, NULL, NULL); + this->cas->create_enumerator(this->cas), + ca_filter, NULL, NULL); case CONF_PARSER_CONFIG_SETUP: default: return enumerator_create_empty(); From 5cafea6edd74432f0a3c38b2a0b94f1256ebf4cf Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 15 May 2017 17:12:44 +0200 Subject: [PATCH 5/7] linked-list: invoke_offset() doesn't take any additional arguments anymore --- src/libstrongswan/collections/linked_list.c | 9 ++++----- src/libstrongswan/collections/linked_list.h | 5 +---- .../tests/suites/test_linked_list.c | 20 ++++++++++--------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index eb11339bc..8dc6834b1 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -394,16 +394,15 @@ METHOD(linked_list_t, find_first, status_t, } METHOD(linked_list_t, invoke_offset, void, - private_linked_list_t *this, size_t offset, - void *d1, void *d2, void *d3, void *d4, void *d5) + private_linked_list_t *this, size_t offset) { element_t *current = this->first; - linked_list_invoke_t *method; + void (**method)(void*); while (current) { method = current->value + offset; - (*method)(current->value, d1, d2, d3, d4, d5); + (*method)(current->value); current = current->next; } } @@ -555,7 +554,7 @@ linked_list_t *linked_list_create() .remove_last = _remove_last, .remove = _remove_, .remove_at = (void*)_remove_at, - .invoke_offset = (void*)_invoke_offset, + .invoke_offset = _invoke_offset, .invoke_function = (void*)_invoke_function, .clone_offset = _clone_offset, .equals_offset = _equals_offset, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index 0b73079d3..c123063f7 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -192,12 +192,9 @@ struct linked_list_t { * which can be evalutated at compile time using the offsetof * macro, e.g.: list->invoke(list, offsetof(object_t, method)); * - * @warning Only use pointers as user supplied data. - * * @param offset offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) */ - void (*invoke_offset) (linked_list_t *this, size_t offset, ...); + void (*invoke_offset)(linked_list_t *this, size_t offset); /** * Invoke a function on all of the contained objects. diff --git a/src/libstrongswan/tests/suites/test_linked_list.c b/src/libstrongswan/tests/suites/test_linked_list.c index 7a161817c..ec29d70ee 100644 --- a/src/libstrongswan/tests/suites/test_linked_list.c +++ b/src/libstrongswan/tests/suites/test_linked_list.c @@ -241,7 +241,7 @@ typedef struct invoke_t invoke_t; struct invoke_t { int val; - void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum); + void (*invoke)(invoke_t *item); }; static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum) @@ -253,9 +253,9 @@ static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum) *sum += item; } -static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum) +static void invoke_offset(invoke_t *item) { - invoke(item->val, a, b, c, d, sum); + item->val++; } START_TEST(test_invoke_function) @@ -282,17 +282,19 @@ START_TEST(test_invoke_offset) { .val = 3, .invoke = invoke_offset, }, { .val = 4, .invoke = invoke_offset, }, { .val = 5, .invoke = invoke_offset, }, - }; - int i, sum = 0; + }, *item; + int i; for (i = 0; i < countof(items); i++) { list->insert_last(list, &items[i]); } - list->invoke_offset(list, offsetof(invoke_t, invoke), - (uintptr_t)1, (uintptr_t)2, - (uintptr_t)3, (uintptr_t)4, &sum); - ck_assert_int_eq(sum, 15); + list->invoke_offset(list, offsetof(invoke_t, invoke)); + i = 2; + while (list->remove_first(list, (void**)&item) == SUCCESS) + { + ck_assert_int_eq(item->val, i++); + } } END_TEST From 8a2e4d4a8b87f5e8a5e5f663ee8eddd47988fa2c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 15 May 2017 17:51:19 +0200 Subject: [PATCH 6/7] linked-list: Change interface of callback for invoke_function() This avoids the unportable five pointer hack. --- .../main/jni/libandroidbridge/charonservice.c | 16 ++++++--- src/libcharon/bus/bus.c | 23 ++++++------ .../kernel_netlink/kernel_netlink_ipsec.c | 21 +++++++---- .../kernel_netlink/kernel_netlink_net.c | 10 ++++-- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 35 ++++++++++++++----- src/libcharon/sa/child_sa.c | 10 +++--- src/libstrongswan/collections/linked_list.c | 10 +++--- src/libstrongswan/collections/linked_list.h | 17 +++++---- .../tests/suites/test_linked_list.c | 10 ++++-- 9 files changed, 98 insertions(+), 54 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c b/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c index b9f6f1dda..c41ee94f5 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c @@ -215,7 +215,7 @@ failed: /** * Bypass a single socket */ -static bool bypass_single_socket(intptr_t fd, private_charonservice_t *this) +static bool bypass_single_socket(private_charonservice_t *this, int fd) { JNIEnv *env; jmethodID method_id; @@ -242,16 +242,24 @@ failed: return FALSE; } +CALLBACK(bypass_single_socket_cb, void, + intptr_t fd, va_list args) +{ + private_charonservice_t *this; + + VA_ARGS_VGET(args, this); + bypass_single_socket(this, fd); +} + METHOD(charonservice_t, bypass_socket, bool, private_charonservice_t *this, int fd, int family) { if (fd >= 0) { this->sockets->insert_last(this->sockets, (void*)(intptr_t)fd); - return bypass_single_socket((intptr_t)fd, this); + return bypass_single_socket(this, fd); } - this->sockets->invoke_function(this->sockets, (void*)bypass_single_socket, - this); + this->sockets->invoke_function(this->sockets, bypass_single_socket_cb, this); return TRUE; } diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index f4bba872f..4ee89dbc3 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -330,11 +330,12 @@ typedef struct { va_list args; } log_data_t; -/** - * logger->log() invocation as a invoke_function callback - */ -static void log_cb(log_entry_t *entry, log_data_t *data) +CALLBACK(log_cb, void, + log_entry_t *entry, va_list args) { + log_data_t *data; + + VA_ARGS_VGET(args, data); if (entry->logger->log && entry->levels[data->group] >= data->level) { entry->logger->log(entry->logger, data->group, data->level, @@ -342,11 +343,12 @@ static void log_cb(log_entry_t *entry, log_data_t *data) } } -/** - * logger->vlog() invocation as a invoke_function callback - */ -static void vlog_cb(log_entry_t *entry, log_data_t *data) +CALLBACK(vlog_cb, void, + log_entry_t *entry, va_list args) { + log_data_t *data; + + VA_ARGS_VGET(args, data); if (entry->logger->vlog && entry->levels[data->group] >= data->level) { va_list copy; @@ -405,8 +407,7 @@ METHOD(bus_t, vlog, void, } if (len > 0) { - loggers->invoke_function(loggers, (linked_list_invoke_t)log_cb, - &data); + loggers->invoke_function(loggers, log_cb, &data); } if (data.message != buf) { @@ -422,7 +423,7 @@ METHOD(bus_t, vlog, void, data.message = format; va_copy(data.args, args); - loggers->invoke_function(loggers, (linked_list_invoke_t)vlog_cb, &data); + loggers->invoke_function(loggers, vlog_cb, &data); va_end(data.args); } 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 cb8b79963..dd62044b9 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -1125,9 +1125,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); @@ -1217,7 +1221,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; } diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index fd427ebbb..16dae6b17 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,6 +576,15 @@ static void policy_entry_destroy(policy_entry_t *policy, free(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); +} + /** * compares two policy_entry_t */ @@ -2860,7 +2878,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 +2933,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 +3106,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/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 2a8ef0234..3d9f6133b 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1404,13 +1404,13 @@ METHOD(child_sa_t, get_rekey_spi, uint32_t, return this->rekey_spi; } -/** - * Callback to reinstall a virtual IP - */ -static void reinstall_vip(host_t *vip, host_t *me) +CALLBACK(reinstall_vip, void, + host_t *vip, va_list args) { + host_t *me; char *iface; + VA_ARGS_VGET(args, me); if (charon->kernel->get_interface(charon->kernel, me, &iface)) { charon->kernel->del_ip(charon->kernel, vip, -1, TRUE); @@ -1532,7 +1532,7 @@ METHOD(child_sa_t, update, status_t, /* we reinstall the virtual IP to handle interface roaming * correctly */ - vips->invoke_function(vips, (void*)reinstall_vip, me); + vips->invoke_function(vips, reinstall_vip, me); /* reinstall updated policies */ install_policies_internal(this, me, other, my_ts, other_ts, diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index 8dc6834b1..5fcf8bc05 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -408,14 +408,16 @@ METHOD(linked_list_t, invoke_offset, void, } METHOD(linked_list_t, invoke_function, void, - private_linked_list_t *this, linked_list_invoke_t fn, - void *d1, void *d2, void *d3, void *d4, void *d5) + private_linked_list_t *this, linked_list_invoke_t fn, ...) { element_t *current = this->first; + va_list args; while (current) { - fn(current->value, d1, d2, d3, d4, d5); + va_start(args, fn); + fn(current->value, args); + va_end(args); current = current->next; } } @@ -555,7 +557,7 @@ linked_list_t *linked_list_create() .remove = _remove_, .remove_at = (void*)_remove_at, .invoke_offset = _invoke_offset, - .invoke_function = (void*)_invoke_function, + .invoke_function = _invoke_function, .clone_offset = _clone_offset, .equals_offset = _equals_offset, .equals_function = _equals_function, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index c123063f7..3f80cd8db 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2015 Tobias Brunner + * Copyright (C) 2007-2017 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -39,12 +39,12 @@ typedef struct linked_list_t linked_list_t; typedef bool (*linked_list_match_t)(void *item, ...); /** - * Method to be invoked on elements in a linked list (used in invoke_* functions) + * Function to be invoked on elements in a linked list * * @param item current list item - * @param ... user supplied data (only pointers, at most 5) + * @param args user supplied data */ -typedef void (*linked_list_invoke_t)(void *item, ...); +typedef void (*linked_list_invoke_t)(void *item, va_list args); /** * Class implementing a double linked list. @@ -199,12 +199,11 @@ struct linked_list_t { /** * Invoke a function on all of the contained objects. * - * @warning Only use pointers as user supplied data. - * - * @param function offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) + * @param function function to call for each object + * @param ... user data to supply to called function */ - void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...); + void (*invoke_function)(linked_list_t *this, linked_list_invoke_t function, + ...); /** * Clones a list and its objects using the objects' clone method. diff --git a/src/libstrongswan/tests/suites/test_linked_list.c b/src/libstrongswan/tests/suites/test_linked_list.c index ec29d70ee..209e311d2 100644 --- a/src/libstrongswan/tests/suites/test_linked_list.c +++ b/src/libstrongswan/tests/suites/test_linked_list.c @@ -244,8 +244,13 @@ struct invoke_t { void (*invoke)(invoke_t *item); }; -static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum) +CALLBACK(invoke, void, + intptr_t item, va_list args) { + void *a, *b, *c, *d; + int *sum; + + VA_ARGS_VGET(args, a, b, c, d, sum); ck_assert_int_eq((uintptr_t)a, 1); ck_assert_int_eq((uintptr_t)b, 2); ck_assert_int_eq((uintptr_t)c, 3); @@ -267,8 +272,7 @@ START_TEST(test_invoke_function) list->insert_last(list, (void*)3); list->insert_last(list, (void*)4); list->insert_last(list, (void*)5); - list->invoke_function(list, (linked_list_invoke_t)invoke, - (uintptr_t)1, (uintptr_t)2, + list->invoke_function(list, invoke, (uintptr_t)1, (uintptr_t)2, (uintptr_t)3, (uintptr_t)4, &sum); ck_assert_int_eq(sum, 15); } From 2e4d110d1e94a3be9da06894832492ff469eec37 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 16 May 2017 12:11:24 +0200 Subject: [PATCH 7/7] linked-list: Change return value of find_first() and signature of its callback This avoids the unportable five pointer hack. --- src/charon-tkm/src/tkm/tkm_kernel_sad.c | 97 +++++------ src/dumm/cowfs.c | 13 +- .../jni/libandroidbridge/kernel/android_net.c | 16 +- src/libcharon/bus/bus.c | 20 +-- src/libcharon/config/child_cfg.c | 9 +- src/libcharon/daemon.c | 17 +- src/libcharon/kernel/kernel_interface.c | 9 +- .../plugins/bypass_lan/bypass_lan_listener.c | 7 +- src/libcharon/plugins/dhcp/dhcp_provider.c | 3 +- src/libcharon/plugins/dhcp/dhcp_socket.c | 3 +- .../plugins/eap_dynamic/eap_dynamic.c | 12 +- .../kernel_libipsec/kernel_libipsec_ipsec.c | 35 ++-- .../kernel_netlink/kernel_netlink_net.c | 51 +++--- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 45 +++-- src/libcharon/plugins/p_cscf/p_cscf_handler.c | 13 +- src/libcharon/plugins/stroke/stroke_ca.c | 15 +- src/libcharon/plugins/stroke/stroke_list.c | 3 +- src/libcharon/sa/ike_sa_manager.c | 24 ++- src/libcharon/sa/ikev2/connect_manager.c | 164 +++++++++--------- src/libcharon/sa/ikev2/tasks/child_delete.c | 13 +- src/libcharon/sa/trap_manager.c | 28 +-- src/libipsec/ipsec_sa_mgr.c | 91 ++++++---- src/libstrongswan/collections/linked_list.c | 42 ++++- src/libstrongswan/collections/linked_list.h | 36 ++-- .../credentials/credential_manager.c | 12 +- src/libstrongswan/credentials/sets/mem_cred.c | 16 +- src/libstrongswan/crypto/crypto_factory.c | 11 +- src/libstrongswan/plugins/plugin_loader.c | 38 ++-- .../tests/suites/test_linked_list.c | 81 +++++++-- 29 files changed, 526 insertions(+), 398 deletions(-) diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c index 22d2aac13..97226f1ac 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c @@ -101,61 +101,63 @@ static void sad_entry_destroy(sad_entry_t *entry) } } -/** - * Find a list entry with given src, dst, (remote) spi and proto values. - */ -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) +CALLBACK(sad_entry_match, bool, + sad_entry_t * const entry, va_list args) { + 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) { return FALSE; } - return src->ip_equals(entry->src, (host_t *)src) && dst->ip_equals(entry->dst, (host_t *)dst) && entry->spi_rem == *spi && entry->proto == *proto; } -/** - * Find a list entry with given reqid, spi and proto values. - */ -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) +CALLBACK(sad_entry_match_dst, bool, + sad_entry_t * const entry, va_list args) { + const uint32_t *reqid, *spi; + const uint8_t *proto; + + VA_ARGS_VGET(args, reqid, spi, proto); return entry->reqid == *reqid && entry->spi_rem == *spi && entry->proto == *proto; } -/** - * Find a list entry with given esa id. - */ -static bool sad_entry_match_esa_id(sad_entry_t * const entry, - const esa_id_type * const esa_id) +CALLBACK(sad_entry_match_esa_id, bool, + sad_entry_t * const entry, va_list args) { + const esa_id_type *esa_id; + + VA_ARGS_VGET(args, esa_id); return entry->esa_id == *esa_id; } -/** - * Find a list entry with given reqid and different esa id. - */ -static bool sad_entry_match_other_esa(sad_entry_t * const entry, - const esa_id_type * const esa_id, - const uint32_t * const reqid) +CALLBACK(sad_entry_match_other_esa, bool, + sad_entry_t * const entry, va_list args) { + const esa_id_type *esa_id; + const uint32_t *reqid; + + VA_ARGS_VGET(args, esa_id, reqid); return entry->reqid == *reqid && entry->esa_id != *esa_id; } -/** - * Compare two SAD entries for equality. - */ -static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) +CALLBACK(sad_entry_equal, bool, + sad_entry_t * const left, va_list args) { + sad_entry_t *right; + + VA_ARGS_VGET(args, right); + if (left->src == NULL || left->dst == NULL || right->src == 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 spi_loc, const uint32_t spi_rem, const uint8_t proto) { - status_t result; sad_entry_t *new_entry; + bool found; INIT(new_entry, .esa_id = esa_id, @@ -189,10 +191,9 @@ METHOD(tkm_kernel_sad_t, insert, bool, ); this->mutex->lock(this->mutex); - result = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_equal, NULL, + found = this->data->find_first(this->data, sad_entry_equal, NULL, new_entry); - if (result == NOT_FOUND) + if (!found) { 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, @@ -207,7 +208,7 @@ METHOD(tkm_kernel_sad_t, insert, bool, free(new_entry); } this->mutex->unlock(this->mutex); - return result == NOT_FOUND; + return !found; } 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; this->mutex->lock(this->mutex); - const status_t res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match, - (void**)&entry, src, dst, &spi, - &proto); - if (res == SUCCESS && entry) + const bool res = this->data->find_first(this->data, sad_entry_match, + (void**)&entry, src, dst, &spi, + &proto); + if (res && entry) { id = entry->esa_id; 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; sad_entry_t *entry = NULL; uint32_t reqid; - status_t res; + bool res; this->mutex->lock(this->mutex); - res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_esa_id, + res = this->data->find_first(this->data, sad_entry_match_esa_id, (void**)&entry, &esa_id); - if (res == SUCCESS && entry) + if (res && entry) { reqid = entry->reqid; } @@ -260,10 +259,9 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type, return id; } - res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_other_esa, + res = this->data->find_first(this->data, sad_entry_match_other_esa, (void**)&entry, &esa_id, &reqid); - if (res == SUCCESS && entry) + if (res && entry) { id = entry->esa_id; 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; this->mutex->lock(this->mutex); - const status_t res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_dst, - (void**)&entry, &reqid, &spi, &proto); - if (res == SUCCESS && entry) + const bool res = this->data->find_first(this->data, sad_entry_match_dst, + (void**)&entry, &reqid, &spi, &proto); + if (res && entry) { dst = entry->dst; DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u," diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c index 28c62c217..5332ba551 100644 --- a/src/dumm/cowfs.c +++ b/src/dumm/cowfs.c @@ -92,11 +92,12 @@ static void overlay_destroy(overlay_t *this) free(this); } -/** - * compare two overlays by path - */ -static bool overlay_equals(overlay_t *this, overlay_t *other) +CALLBACK(overlay_equals, bool, + overlay_t *this, va_list args) { + overlay_t *other; + + VA_ARGS_VGET(args, other); return streq(this->path, other->path); } @@ -108,8 +109,8 @@ static bool overlay_remove(private_cowfs_t *this, char *path) { overlay_t over, *current; over.path = path; - if (this->overlays->find_first(this->overlays, - (linked_list_match_t)overlay_equals, (void**)¤t, &over) != SUCCESS) + if (!this->overlays->find_first(this->overlays, overlay_equals, + (void**)¤t, &over)) { return FALSE; } diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c index a73a3c06e..c6ef06af5 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c @@ -167,6 +167,15 @@ METHOD(kernel_net_t, get_source_addr, host_t*, 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*, 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) { this->mutex->lock(this->mutex); - if (this->vips->find_first(this->vips, (void*)host->ip_equals, - NULL, host) == SUCCESS) + if (this->vips->find_first(this->vips, vip_equals, NULL, host)) { host->destroy(host); host = NULL; @@ -236,8 +244,8 @@ METHOD(kernel_net_t, del_ip, status_t, host_t *vip; this->mutex->lock(this->mutex); - if (this->vips->find_first(this->vips, (void*)virtual_ip->ip_equals, - (void**)&vip, virtual_ip) == SUCCESS) + if (this->vips->find_first(this->vips, vip_equals, (void**)&vip, + virtual_ip)) { this->vips->remove(this->vips, vip, NULL); vip->destroy(vip); diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 4ee89dbc3..77a910197 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -207,20 +207,20 @@ static inline void register_logger(private_bus_t *this, debug_t group, } } -/** - * Find the log level of the first registered logger that implements log or - * vlog (or both). - */ -static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level, - level_t *vlevel) +CALLBACK(find_max_levels, bool, + log_entry_t *entry, va_list args) { + level_t *level, *vlevel; + debug_t group; + + VA_ARGS_VGET(args, group, level, vlevel); if (entry->logger->log && *level == LEVEL_SILENT) { - *level = entry->levels[*group]; + *level = entry->levels[group]; } if (entry->logger->vlog && *vlevel == LEVEL_SILENT) { - *vlevel = entry->levels[*group]; + *vlevel = entry->levels[group]; } 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->remove(loggers, found, NULL); - loggers->find_first(loggers, (linked_list_match_t)find_max_levels, - NULL, &group, &level, &vlevel); + loggers->find_first(loggers, find_max_levels, NULL, group, + &level, &vlevel); set_level(&this->max_level[group], level); set_level(&this->max_vlevel[group], vlevel); } diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 669eedf7a..ec2a12431 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -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); } @@ -185,8 +189,7 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*, { current->strip_dh(current, MODP_NONE); } - if (proposals->find_first(proposals, (linked_list_match_t)match_proposal, - NULL, current) == SUCCESS) + if (proposals->find_first(proposals, match_proposal, NULL, current)) { current->destroy(current); continue; diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index 8daea783f..7c9f83d12 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -282,13 +282,14 @@ static void logger_entry_unregister_destroy(logger_entry_t *this) logger_entry_destroy(this); } -/** - * Match a logger entry by target and whether it is a file or syslog logger - */ -static bool logger_entry_match(logger_entry_t *this, char *target, - logger_type_t *type) +CALLBACK(logger_entry_match, bool, + logger_entry_t *this, va_list args) { - 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; - if (existing->find_first(existing, (void*)logger_entry_match, - (void**)&entry, target, &type) != SUCCESS) + if (!existing->find_first(existing, logger_entry_match, (void**)&entry, + target, type)) { INIT(entry, .target = strdup(target), diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c index ea5af9eb8..3d736b25b 100644 --- a/src/libcharon/kernel/kernel_interface.c +++ b/src/libcharon/kernel/kernel_interface.c @@ -632,21 +632,18 @@ METHOD(kernel_interface_t, enable_udp_decap, bool, METHOD(kernel_interface_t, is_interface_usable, bool, private_kernel_interface_t *this, const char *iface) { - status_t expected; - if (!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; } METHOD(kernel_interface_t, all_interfaces_usable, bool, private_kernel_interface_t *this) { - return this->ifaces_filter == NULL; + return !this->ifaces_filter; } METHOD(kernel_interface_t, get_address_by_ts, status_t, 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/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/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_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index dd62044b9..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); } @@ -1175,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, @@ -1292,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, @@ -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); 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; } @@ -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); 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); } @@ -1941,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; } @@ -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 */ 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 16dae6b17..fd1adb2ae 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -585,12 +585,12 @@ CALLBACK(policy_entry_destroy_cb, void, policy_entry_destroy(policy, this); } -/** - * compares two policy_entry_t - */ -static inline bool policy_entry_equals(policy_entry_t *current, - policy_entry_t *policy) +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 && @@ -600,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; } /** @@ -1279,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; @@ -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 */ 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"); @@ -2624,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); @@ -2719,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); @@ -2832,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); diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.c b/src/libcharon/plugins/p_cscf/p_cscf_handler.c index 880e80a56..cdf266054 100644 --- a/src/libcharon/plugins/p_cscf/p_cscf_handler.c +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.c @@ -106,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; } /** @@ -119,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 *, diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index 0a20188e7..4593e9bdc 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -358,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); } @@ -409,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); @@ -515,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_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/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index c6b5494da..c0bfebb83 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -151,8 +151,10 @@ static entry_t *entry_create() /** * 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)) { 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. */ -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; } @@ -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, 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; 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) { 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) { 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); } +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. */ @@ -886,8 +897,7 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) entry->other_id, family)) { if (connected_peers->sas->find_first(connected_peers->sas, - (linked_list_match_t)entry->ike_sa_id->equals, - NULL, entry->ike_sa_id) == SUCCESS) + id_matches, NULL, entry->ike_sa_id)) { lock->unlock(lock); return; diff --git a/src/libcharon/sa/ikev2/connect_manager.c b/src/libcharon/sa/ikev2/connect_manager.c index 280796d8c..35856788c 100644 --- a/src/libcharon/sa/ikev2/connect_manager.c +++ b/src/libcharon/sa/ikev2/connect_manager.c @@ -450,22 +450,21 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist, return this; } -/** - * Find an initiated connection by the peers' ids - */ -static bool match_initiated_by_ids(initiated_t *current, identification_t *id, - identification_t *peer_id) +CALLBACK(match_initiated_by_ids, bool, + initiated_t *current, va_list args) { + 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); } -static status_t get_initiated_by_ids(private_connect_manager_t *this, - identification_t *id, - identification_t *peer_id, - initiated_t **initiated) +static bool get_initiated_by_ids(private_connect_manager_t *this, + identification_t *id, + identification_t *peer_id, + initiated_t **initiated) { - return this->initiated->find_first(this->initiated, - (linked_list_match_t)match_initiated_by_ids, + return this->initiated->find_first(this->initiated, match_initiated_by_ids, (void**)initiated, id, peer_id); } @@ -490,21 +489,20 @@ static void remove_initiated(private_connect_manager_t *this, enumerator->destroy(enumerator); } -/** - * Find the checklist with a specific connect ID - */ -static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id) +CALLBACK(match_checklist_by_id, bool, + check_list_t *current, va_list args) { - 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, - chunk_t connect_id, - check_list_t **check_list) +static bool get_checklist_by_id(private_connect_manager_t *this, + chunk_t connect_id, check_list_t **check_list) { - return this->checklists->find_first(this->checklists, - (linked_list_match_t)match_checklist_by_id, - (void**)check_list, &connect_id); + return this->checklists->find_first(this->checklists, match_checklist_by_id, + (void**)check_list, connect_id); } /** @@ -528,19 +526,19 @@ static void remove_checklist(private_connect_manager_t *this, enumerator->destroy(enumerator); } -/** - * Checks if a list of endpoint_notify_t contains a certain host_t - */ -static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host) +CALLBACK(match_endpoint_by_host, bool, + endpoint_notify_t *current, va_list args) { + host_t *host; + + VA_ARGS_VGET(args, host); 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) { - return endpoints->find_first(endpoints, - (linked_list_match_t)match_endpoint_by_host, + return endpoints->find_first(endpoints, match_endpoint_by_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); } -/** - * Searches a list of endpoint_pair_t for a pair with specific host_ts - */ -static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local, - host_t *remote) +CALLBACK(match_pair_by_hosts, bool, + endpoint_pair_t *current, va_list args) { - 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, - host_t *remote, endpoint_pair_t **pair) +static bool get_pair_by_hosts(linked_list_t *pairs, host_t *local, + host_t *remote, endpoint_pair_t **pair) { - return pairs->find_first(pairs, (linked_list_match_t)match_pair_by_hosts, - (void**)pair, local, remote); + return pairs->find_first(pairs, match_pair_by_hosts, (void**)pair, local, + 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 */ -static status_t get_pair_by_id(check_list_t *checklist, uint32_t id, - endpoint_pair_t **pair) +static bool get_pair_by_id(check_list_t *checklist, uint32_t id, + endpoint_pair_t **pair) { - return checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_pair_by_id, - (void**)pair, &id); + return checklist->pairs->find_first(checklist->pairs, match_pair_by_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; } @@ -600,15 +603,14 @@ static bool match_succeeded_pair(endpoint_pair_t *current) /** * Returns the best pair of state CHECK_SUCCEEDED from a checklist. */ -static status_t get_best_valid_pair(check_list_t *checklist, - endpoint_pair_t **pair) +static bool get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair) { - return checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_succeeded_pair, - (void**)pair); + return checklist->pairs->find_first(checklist->pairs, match_succeeded_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; } @@ -865,7 +867,7 @@ static job_requeue_t initiator_finish(callback_data_t *data) this->mutex->lock(this->mutex); 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 " "connectivity checks", &data->connect_id); @@ -953,7 +955,7 @@ static job_requeue_t retransmit(callback_data_t *data) this->mutex->lock(this->mutex); 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 " "connectivity check", &data->connect_id); @@ -962,7 +964,7 @@ static job_requeue_t retransmit(callback_data_t *data) } 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 " "connectivity check", data->mid); @@ -1108,7 +1110,7 @@ static job_requeue_t sender(callback_data_t *data) this->mutex->lock(this->mutex); 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 " "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"); - if (checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_waiting_pair, - (void**)&pair) != SUCCESS) + if (!checklist->pairs->find_first(checklist->pairs, match_waiting_pair, + (void**)&pair)) { this->mutex->unlock(this->mutex); 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; 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; 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; if (get_initiated_by_ids(this, checklist->initiator.id, - checklist->responder.id, &initiated) == SUCCESS) + checklist->responder.id, &initiated)) { callback_job_t *job; @@ -1247,7 +1248,7 @@ static void process_response(private_connect_manager_t *this, check_t *check, check_list_t *checklist) { 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) && 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; endpoint_notify_t *local_endpoint; - if (endpoints_contain(local_endpoints, - check->endpoint->get_host(check->endpoint), - &local_endpoint) != SUCCESS) + if (!endpoints_contain(local_endpoints, + check->endpoint->get_host(check->endpoint), + &local_endpoint)) { local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE, 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, 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_endpoints->insert_last(remote_endpoints, remote_endpoint); } endpoint_pair_t *pair; - if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, - &pair) == SUCCESS) + if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, &pair)) { switch(pair->state) { @@ -1389,7 +1389,7 @@ METHOD(connect_manager_t, process_check, void, this->mutex->lock(this->mutex); 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", &check->connect_id); @@ -1423,6 +1423,15 @@ METHOD(connect_manager_t, process_check, void, 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, private_connect_manager_t *this, identification_t *id, 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); - 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'", peer_id); @@ -1441,9 +1450,8 @@ METHOD(connect_manager_t, check_and_register, bool, already_there = FALSE; } - if (initiated->mediated->find_first(initiated->mediated, - (linked_list_match_t)mediated_sa->equals, - NULL, mediated_sa) != SUCCESS) + if (!initiated->mediated->find_first(initiated->mediated, id_matches, + NULL, mediated_sa)) { initiated->mediated->insert_last(initiated->mediated, mediated_sa->clone(mediated_sa)); @@ -1462,7 +1470,7 @@ METHOD(connect_manager_t, check_and_initiate, void, 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); this->mutex->unlock(this->mutex); @@ -1492,7 +1500,7 @@ METHOD(connect_manager_t, set_initiator_data, status_t, 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", &connect_id); @@ -1517,7 +1525,7 @@ METHOD(connect_manager_t, set_responder_data, status_t, 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", &connect_id); @@ -1547,7 +1555,7 @@ METHOD(connect_manager_t, stop_checks, status_t, 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", &connect_id); diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c index 160865636..626796383 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.c +++ b/src/libcharon/sa/ikev2/tasks/child_delete.c @@ -81,11 +81,12 @@ typedef struct { bool check_delete_action; } entry_t; -/** - * Check if the given entry is for the same CHILD_SA - */ -static bool match_child(entry_t *entry, child_sa_t *child_sa) +CALLBACK(match_child, bool, + entry_t *entry, va_list args) { + child_sa_t *child_sa; + + VA_ARGS_VGET(args, 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", protocol_id_names, protocol, ntohl(spi)); - if (this->child_sas->find_first(this->child_sas, - (void*)match_child, NULL, child_sa) == SUCCESS) + if (this->child_sas->find_first(this->child_sas, match_child, + NULL, child_sa)) { continue; } diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 71190f306..f9fee5e7e 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -140,19 +140,21 @@ static void destroy_acquire(acquire_t *this) free(this); } -/** - * match an acquire entry by reqid - */ -static bool acquire_by_reqid(acquire_t *this, uint32_t *reqid) +CALLBACK(acquire_by_reqid, bool, + acquire_t *this, va_list args) { - return this->reqid == *reqid; + uint32_t reqid; + + VA_ARGS_VGET(args, reqid); + return this->reqid == reqid; } -/** - * match an acquire entry by destination address - */ -static bool acquire_by_dst(acquire_t *this, host_t *dst) +CALLBACK(acquire_by_dst, bool, + acquire_t *this, va_list args) { + host_t *dst; + + VA_ARGS_VGET(args, dst); return this->dst && this->dst->ip_equals(this->dst, dst); } @@ -439,8 +441,8 @@ METHOD(trap_manager_t, acquire, void, uint8_t mask; dst->to_subnet(dst, &host, &mask); - if (this->acquires->find_first(this->acquires, (void*)acquire_by_dst, - (void**)&acquire, host) == SUCCESS) + if (this->acquires->find_first(this->acquires, acquire_by_dst, + (void**)&acquire, host)) { host->destroy(host); ignore = TRUE; @@ -456,8 +458,8 @@ METHOD(trap_manager_t, acquire, void, } else { - if (this->acquires->find_first(this->acquires, (void*)acquire_by_reqid, - (void**)&acquire, &reqid) == SUCCESS) + if (this->acquires->find_first(this->acquires, acquire_by_reqid, + (void**)&acquire, reqid)) { ignore = TRUE; } diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c index a1fa23e28..957d930f2 100644 --- a/src/libipsec/ipsec_sa_mgr.c +++ b/src/libipsec/ipsec_sa_mgr.c @@ -224,42 +224,60 @@ static void flush_entries(private_ipsec_sa_mgr_t *this) enumerator->destroy(enumerator); } -/* - * Different match functions to find SAs in the linked list - */ -static bool match_entry_by_ptr(ipsec_sa_entry_t *item, ipsec_sa_entry_t *entry) +CALLBACK(match_entry_by_sa_ptr, bool, + ipsec_sa_entry_t *item, va_list args) { - 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; } -static bool match_entry_by_spi_inbound(ipsec_sa_entry_t *item, uint32_t *spi, - bool *inbound) +CALLBACK(match_entry_by_spi_inbound, bool, + ipsec_sa_entry_t *item, va_list args) { - return item->sa->get_spi(item->sa) == *spi && - item->sa->is_inbound(item->sa) == *inbound; + uint32_t spi; + 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) { - 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, - uint32_t *reqid, bool *inbound) +CALLBACK(match_entry_by_spi_src_dst_cb, bool, + 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, - host_t *dst) +CALLBACK(match_entry_by_reqid_inbound, bool, + 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; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_ptr, - NULL, expired->entry) == SUCCESS) + if (this->sas->find_first(this->sas, NULL, (void**)&expired->entry)) { 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; if (this->allocated_spis->get(this->allocated_spis, &spi) || - this->sas->find_first(this->sas, (void*)match_entry_by_spi_inbound, - NULL, &spi, TRUE) == SUCCESS) + this->sas->find_first(this->sas, match_entry_by_spi_inbound, + NULL, spi, TRUE)) { return FALSE; } @@ -484,8 +501,8 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, free(spi_alloc); } - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - NULL, &spi, src, dst) == SUCCESS) + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, NULL, + spi, src, dst)) { this->mutex->unlock(this->mutex); 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); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - (void**)&entry, &spi, src, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, + (void**)&entry, spi, src, dst) && wait_for_entry(this, entry)) { 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; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - (void**)&entry, &spi, src, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, + (void**)&entry, spi, src, dst) && wait_for_entry(this, entry)) { 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); while (enumerator->enumerate(enumerator, (void**)¤t)) { - 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)) { @@ -602,8 +619,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_reqid, ipsec_sa_t*, ipsec_sa_t *sa = NULL; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_reqid_inbound, - (void**)&entry, &reqid, &inbound) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_reqid_inbound, + (void**)&entry, reqid, inbound) && wait_for_entry(this, entry)) { sa = entry->sa; @@ -619,8 +636,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_spi, ipsec_sa_t*, ipsec_sa_t *sa = NULL; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_dst, - (void**)&entry, &spi, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_dst, + (void**)&entry, spi, dst) && wait_for_entry(this, entry)) { sa = entry->sa; @@ -635,8 +652,8 @@ METHOD(ipsec_sa_mgr_t, checkin, void, ipsec_sa_entry_t *entry; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_sa_ptr, - (void**)&entry, sa) == SUCCESS) + if (this->sas->find_first(this->sas, match_entry_by_sa_ptr, + (void**)&entry, sa)) { if (entry->locked) { diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index 5fcf8bc05..f877be5a6 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -47,6 +47,17 @@ struct element_t { 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. */ @@ -371,26 +382,41 @@ METHOD(linked_list_t, remove_at, void, } } -METHOD(linked_list_t, find_first, status_t, - private_linked_list_t *this, linked_list_match_t match, - void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +METHOD(linked_list_t, find_first, bool, + private_linked_list_t *this, linked_list_match_t match, void **item, ...) { element_t *current = this->first; + va_list args; + bool matched = FALSE; + + if (!match && !item) + { + return FALSE; + } while (current) { - if ((match && match(current->value, d1, d2, d3, d4, d5)) || - (!match && item && current->value == *item)) + if (match) + { + va_start(args, item); + matched = match(current->value, args); + va_end(args); + } + else + { + matched = current->value == *item; + } + if (matched) { if (item != NULL) { *item = current->value; } - return SUCCESS; + return TRUE; } current = current->next; } - return NOT_FOUND; + return FALSE; } METHOD(linked_list_t, invoke_offset, void, @@ -548,7 +574,7 @@ linked_list_t *linked_list_create() .reset_enumerator = (void*)_reset_enumerator, .get_first = _get_first, .get_last = _get_last, - .find_first = (void*)_find_first, + .find_first = _find_first, .insert_first = _insert_first, .insert_last = _insert_last, .insert_before = (void*)_insert_before, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index 3f80cd8db..246b9a5c5 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -28,15 +28,22 @@ typedef struct linked_list_t linked_list_t; #include /** - * 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 ... user supplied data (only pointers, at most 5) - * @return - * - TRUE, if the item matched - * - FALSE, otherwise + * @param args user supplied data + * @return 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 @@ -167,21 +174,20 @@ struct linked_list_t { * * The first object passed to the match function is the current list item, * followed by the user supplied data. - * If the supplied function returns TRUE this function returns SUCCESS, and - * the current object is returned in the third parameter, otherwise, + * If the supplied function returns TRUE so does this function, and the + * current object is returned in the third parameter (if given), otherwise, * the next item is checked. * * 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 item the list item, if found - * @param ... user data to supply to match function (limited to 5 arguments) - * @return SUCCESS if found, NOT_FOUND otherwise + * @param item the list item, if found, or NULL + * @param ... user data to supply to match function + * @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, - void **item, ...); + bool (*find_first)(linked_list_t *this, linked_list_match_t match, + void **item, ...); /** * Invoke a method on all of the contained objects. diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 5dd8e42b1..0a8d3d101 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -812,11 +812,12 @@ static bool verify_trust_chain(private_credential_manager_t *this, return trusted; } -/** - * List find match function for certificates - */ -static bool cert_equals(certificate_t *a, certificate_t *b) +CALLBACK(cert_equals, bool, + certificate_t *a, va_list args) { + certificate_t *b; + + VA_ARGS_VGET(args, b); return a->equals(a, b); } @@ -896,8 +897,7 @@ METHOD(enumerator_t, trusted_enumerate, bool, continue; } - if (this->failed->find_first(this->failed, (void*)cert_equals, - NULL, current) == SUCCESS) + if (this->failed->find_first(this->failed, cert_equals, NULL, current)) { /* check each candidate only once */ continue; } diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 7576220bc..4d594e439 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -149,8 +149,12 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, 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); } @@ -163,9 +167,8 @@ static certificate_t *add_cert_internal(private_mem_cred_t *this, bool trusted, { certificate_t *cached; this->lock->write_lock(this->lock); - if (this->untrusted->find_first(this->untrusted, - (linked_list_match_t)certificate_equals, - (void**)&cached, cert) == SUCCESS) + if (this->untrusted->find_first(this->untrusted, certificate_equals, + (void**)&cached, cert)) { cert->destroy(cert); cert = cached->get_ref(cached); @@ -201,9 +204,8 @@ METHOD(mem_cred_t, get_cert_ref, certificate_t*, certificate_t *cached; this->lock->read_lock(this->lock); - if (this->untrusted->find_first(this->untrusted, - (linked_list_match_t)certificate_equals, - (void**)&cached, cert) == SUCCESS) + if (this->untrusted->find_first(this->untrusted, certificate_equals, + (void**)&cached, cert)) { cert->destroy(cert); cert = cached->get_ref(cached); diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index 42d795d0a..096bcbc9c 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -811,11 +811,12 @@ METHOD(crypto_factory_t, remove_dh, void, this->lock->unlock(this->lock); } -/** - * match algorithms of an entry? - */ -static bool entry_match(entry_t *a, entry_t *b) +CALLBACK(entry_match, bool, + entry_t *a, va_list args) { + entry_t *b; + + VA_ARGS_VGET(args, b); return a->algo == b->algo; } @@ -828,7 +829,7 @@ CALLBACK(unique_check, bool, 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; } diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index fcd11951f..42d443b7a 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -606,18 +606,14 @@ static void load_provided(private_plugin_loader_t *this, provided_feature_t *provided, int level); -/** - * Used to find a loaded feature - */ -static bool is_feature_loaded(provided_feature_t *item) +CALLBACK(is_feature_loaded, bool, + provided_feature_t *item, va_list args) { return item->loaded; } -/** - * Used to find a loadable feature - */ -static bool is_feature_loadable(provided_feature_t *item) +CALLBACK(is_feature_loadable, bool, + provided_feature_t *item, va_list args) { 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)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loaded, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loaded, NULL); } return FALSE; } @@ -644,8 +639,7 @@ static bool loadable_feature_equals(registered_feature_t *a, { if (plugin_feature_equals(a->feature, b->feature)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loadable, NULL); } return FALSE; } @@ -658,8 +652,7 @@ static bool loadable_feature_matches(registered_feature_t *a, { if (plugin_feature_matches(a->feature, b->feature)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loadable, NULL); } return FALSE; } @@ -1011,8 +1004,8 @@ static void purge_plugins(private_plugin_loader_t *this) { /* feature interface not supported */ continue; } - if (entry->features->find_first(entry->features, - (void*)is_feature_loaded, NULL) != SUCCESS) + if (!entry->features->find_first(entry->features, is_feature_loaded, + NULL)) { DBG2(DBG_LIB, "unloading plugin '%s' without loaded features", entry->plugin->get_name(entry->plugin)); @@ -1062,6 +1055,15 @@ static bool find_plugin(char *path, char *name, char *buf, char **file) 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 */ @@ -1244,8 +1246,8 @@ METHOD(plugin_loader_t, load_plugins, bool, } if (this->paths) { - this->paths->find_first(this->paths, (void*)find_plugin, NULL, - token, buf, &file); + this->paths->find_first(this->paths, find_plugin_cb, NULL, token, + buf, &file); } if (!file) { diff --git a/src/libstrongswan/tests/suites/test_linked_list.c b/src/libstrongswan/tests/suites/test_linked_list.c index 209e311d2..aa1e0429f 100644 --- a/src/libstrongswan/tests/suites/test_linked_list.c +++ b/src/libstrongswan/tests/suites/test_linked_list.c @@ -183,26 +183,48 @@ END_TEST * 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(b == (void*)2); 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) { 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); - ck_assert(list->find_first(list, NULL, &a) == SUCCESS); - ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND); + ck_assert(list->find_first(list, NULL, &a)); + ck_assert(!list->find_first(list, NULL, &b)); list->insert_last(list, b); - ck_assert(list->find_first(list, NULL, &a) == SUCCESS); - ck_assert(list->find_first(list, NULL, &b) == SUCCESS); + ck_assert(list->find_first(list, NULL, &a)); + 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 @@ -210,29 +232,57 @@ START_TEST(test_find_callback) { 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); - 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; - 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(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); 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); 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(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); 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); } 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 */ @@ -464,6 +514,7 @@ Suite *linked_list_suite_create() tcase_add_checked_fixture(tc, setup_list, teardown_list); tcase_add_test(tc, test_find); tcase_add_test(tc, test_find_callback); + tcase_add_test(tc, test_find_callback_args); suite_add_tcase(s, tc); tc = tcase_create("invoke");