diff options
| author | Tobias Brunner <tobias@strongswan.org> | 2017-05-26 13:57:57 +0200 |
|---|---|---|
| committer | Tobias Brunner <tobias@strongswan.org> | 2017-05-26 14:24:13 +0200 |
| commit | b668bf3f9ec1e6e44cb31c727ac928105e383b32 (patch) | |
| tree | db62e4fcd1a955b5179c6f172a9403500bb24e50 /src/libcharon/plugins/stroke/stroke_handler.c | |
| parent | 0da10b73addd8c181bed0772c7eac32d28d8af77 (diff) | |
| parent | 2e4d110d1e94a3be9da06894832492ff469eec37 (diff) | |
| download | strongswan-b668bf3f9ec1.tar.bz2 strongswan-b668bf3f9ec1.tar.xz | |
Merge branch 'variadic-enumerators'
This adds several changes to enumerator_t and linked_list_t to improve
portability. In particular to Apple's ARM64 iOS platform, whose calling
convention for variadic and regular functions are different. This means
that assigning a non-variadic function to a variadic function pointer,
as we did with our enumerator_t::enumerate() implementations and several
callbacks, will result in crashes as the called function will access the
arguments differently than the caller provided them.
To avoid this issue the enumerator_t interface is now fully variadic.
A new mandatory method is added, venumerate(), that takes a va_list with
the arguments provided while enumerating. enumerate() is replaced with
a generic implementation that prepares a va_list and calls the
enumerator's venumerate() implementation. As this allows passing the
arguments of one enumerator to another it avoids the five pointer hack
used by enumerator_create_nested() and enumerator_create_cleaner().
To simplify the implementation of venumerate() a helper macro is provided
that assigns values from a given va_list to local variables.
The signature of the callback passed to enumerator_create_filter() has
also changed significantly. It's now required to enumerate over the
original enumerator in the callback as this avoids the previous in/out
pointer hack. The arguments to the outer enumerator are provided in a
va_list.
Similar changes to avoid such five pointer hacks affect the signatures
of the callbacks for linked_list_t's invoke_function() and find_first()
methods. For the latter the return type also changed from status_t to
bool, which is important as SUCCESS is defined as 0, so checks for ==
SUCCESS will now fail.
Diffstat (limited to 'src/libcharon/plugins/stroke/stroke_handler.c')
| -rw-r--r-- | src/libcharon/plugins/stroke/stroke_handler.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c index d0cc9afab..19d5a62a1 100644 --- a/src/libcharon/plugins/stroke/stroke_handler.c +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -62,35 +62,39 @@ static void attributes_destroy(attributes_t *this) free(this); } -/** - * Filter function to convert host to DNS configuration attributes - */ -static bool attr_filter(void *lock, host_t **in, - configuration_attribute_type_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - host_t *host = *in; + configuration_attribute_type_t *type; + chunk_t *data; + host_t *host; - switch (host->get_family(host)) - { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; - } - if (host->is_anyaddr(host)) - { - *data = chunk_empty; - } - else + VA_ARGS_VGET(args, type, data); + + while (orig->enumerate(orig, &host)) { - *data = host->get_address(host); + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + continue; + } + if (host->is_anyaddr(host)) + { + *data = chunk_empty; + } + else + { + *data = host->get_address(host); + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, @@ -114,7 +118,7 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, enumerator->destroy(enumerator); return enumerator_create_filter( attr->dns->create_enumerator(attr->dns), - (void*)attr_filter, this->lock, + attr_filter, this->lock, (void*)this->lock->unlock); } } |
