aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon-nm/nm
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-05-26 13:57:57 +0200
committerTobias Brunner <tobias@strongswan.org>2017-05-26 14:24:13 +0200
commitb668bf3f9ec1e6e44cb31c727ac928105e383b32 (patch)
treedb62e4fcd1a955b5179c6f172a9403500bb24e50 /src/charon-nm/nm
parent0da10b73addd8c181bed0772c7eac32d28d8af77 (diff)
parent2e4d110d1e94a3be9da06894832492ff469eec37 (diff)
downloadstrongswan-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/charon-nm/nm')
-rw-r--r--src/charon-nm/nm/nm_creds.c72
-rw-r--r--src/charon-nm/nm/nm_handler.c48
2 files changed, 69 insertions, 51 deletions
diff --git a/src/charon-nm/nm/nm_creds.c b/src/charon-nm/nm/nm_creds.c
index f8fae9504..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*,
@@ -235,9 +236,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 +312,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..3eb2eb13c 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;
@@ -108,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*,
@@ -134,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,