linked-list: Change interface of callback for invoke_function()
authorTobias Brunner <tobias@strongswan.org>
Mon, 15 May 2017 15:51:19 +0000 (17:51 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 26 May 2017 11:56:44 +0000 (13:56 +0200)
This avoids the unportable five pointer hack.

src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c
src/libcharon/bus/bus.c
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/libcharon/sa/child_sa.c
src/libstrongswan/collections/linked_list.c
src/libstrongswan/collections/linked_list.h
src/libstrongswan/tests/suites/test_linked_list.c

index b9f6f1d..c41ee94 100644 (file)
@@ -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;
 }
 
index f4bba87..4ee89db 100644 (file)
@@ -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);
        }
 
index da05de3..c411b82 100644 (file)
@@ -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)
index cb8b799..dd62044 100644 (file)
@@ -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;
                                }
index fd427eb..16dae6b 100644 (file)
@@ -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);
index 2a8ef02..3d9f613 100644 (file)
@@ -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,
index 8dc6834..5fcf8bc 100644 (file)
@@ -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,
index c123063..3f80cd8 100644 (file)
@@ -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.
index ec29d70..209e311 100644 (file)
@@ -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);
 }