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/kernel_netlink/kernel_netlink_ipsec.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/kernel_netlink/kernel_netlink_ipsec.c')
| -rw-r--r-- | src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c | 21 |
1 files changed, 15 insertions, 6 deletions
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) |
