summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/identification.c28
-rw-r--r--src/libstrongswan/utils/iterator.h42
-rw-r--r--src/libstrongswan/utils/leak_detective.c17
-rw-r--r--src/libstrongswan/utils/linked_list.c59
4 files changed, 107 insertions, 39 deletions
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 673cbb828..ba0a76893 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -759,6 +759,24 @@ static bool equals_dn(private_identification_t *this,
}
/**
+ * Special implementation of identification_t.equals for RFC822 and FQDN.
+ */
+static bool equals_strcasecmp(private_identification_t *this,
+ private_identification_t *other)
+{
+ /* we do some extra sanity checks to check for invalid IDs with a
+ * terminating null in it. */
+ if (this->encoded.len == other->encoded.len &&
+ memchr(this->encoded.ptr, 0, this->encoded.len) == NULL &&
+ memchr(other->encoded.ptr, 0, other->encoded.len) == NULL &&
+ strncasecmp(this->encoded.ptr, other->encoded.ptr, this->encoded.len) == 0)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* Default implementation of identification_t.matches.
*/
static bool matches_binary(private_identification_t *this,
@@ -1094,6 +1112,8 @@ identification_t *identification_create_from_string(char *string)
this->encoded.len = strlen(string + 1);
this->public.matches = (bool (*)
(identification_t*,identification_t*,int*))matches_string;
+ this->public.equals = (bool (*)
+ (identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
}
}
@@ -1104,6 +1124,8 @@ identification_t *identification_create_from_string(char *string)
this->encoded.len = strlen(string);
this->public.matches = (bool (*)
(identification_t*,identification_t*,int*))matches_string;
+ this->public.equals = (bool (*)
+ (identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
}
}
@@ -1123,12 +1145,11 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
(identification_t*,identification_t*,int*))matches_any;
break;
case ID_FQDN:
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
- break;
case ID_RFC822_ADDR:
this->public.matches = (bool (*)
(identification_t*,identification_t*,int*))matches_string;
+ this->public.equals = (bool (*)
+ (identification_t*,identification_t*))equals_strcasecmp;
break;
case ID_DER_ASN1_DN:
this->public.equals = (bool (*)
@@ -1152,3 +1173,4 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
}
return &(this->public);
}
+
diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h
index 02a15c534..b4ff85bfb 100644
--- a/src/libstrongswan/utils/iterator.h
+++ b/src/libstrongswan/utils/iterator.h
@@ -26,15 +26,46 @@
#include <library.h>
+typedef enum hook_result_t hook_result_t;
+
+/**
+ * @brief Return value of an iterator hook.
+ *
+ * Returning HOOK_AGAIN is useful to "inject" additional elements in an
+ * iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may
+ * be used to filter elements out.
+ *
+ * @ingroup utils
+ */
+enum hook_result_t {
+
+ /**
+ * A value was placed in out, hook is called again with the same "in"
+ */
+ HOOK_AGAIN,
+
+ /**
+ * A value was placed in out, hook is called again with next "in" (if any)
+ */
+ HOOK_NEXT,
+
+ /**
+ * No value in out, call again with next "in" (if any)
+ */
+ HOOK_SKIP,
+};
+
/**
* @brief Iterator hook function prototype.
*
* @param param user supplied parameter
* @param in the value the hook receives from the iterator
* @param out the value supplied as a result to the iterator
- * @return TRUE to return "out", FALSE to skip this value
+ * @return a hook_result_t
+ *
+ * @ingroup utils
*/
-typedef bool (iterator_hook_t)(void *param, void *in, void **out);
+typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
typedef struct iterator_t iterator_t;
@@ -45,8 +76,6 @@ typedef struct iterator_t iterator_t;
* iterator_t defines an interface for iterating over collections.
* It allows searching, deleting, updating and inserting.
*
- * Thanks to JMP for iterator lessons :-)
- *
* @b Constructors:
* - via linked_list_t.create_iterator, or
* - any other class which supports the iterator_t interface
@@ -84,8 +113,11 @@ struct iterator_t {
* Sometimes it is useful to hook in an iterator. The hook function is
* called before any successful return of iterate(). It takes the
* iterator value, may manipulate it (or the references object), and returns
- * the value that the iterate() function returns.
+ * the value that the iterate() function returns. Depending on the hook
+ * return value, the hook is called again, called with next, or skipped.
* A value of NULL deactivates the iterator hook.
+ * If an iterator is hooked, only the iterate() method is valid,
+ * all other methods behave undefined.
*
* @param this calling object
* @param hook iterator hook which manipulates the iterated value
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index b8a023270..a28ebba51 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -410,7 +410,10 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
*/
void __attribute__ ((constructor)) leak_detective_init()
{
- install_hooks();
+ if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
+ {
+ install_hooks();
+ }
}
/**
@@ -418,8 +421,11 @@ void __attribute__ ((constructor)) leak_detective_init()
*/
void __attribute__ ((destructor)) leak_detective_cleanup()
{
- uninstall_hooks();
- report_leaks();
+ if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
+ {
+ uninstall_hooks();
+ report_leaks();
+ }
}
/**
@@ -431,6 +437,11 @@ void leak_detective_status(FILE *stream)
size_t bytes = 0;
memory_header_t *hdr = &first_header;
+ if (getenv("LEAK_DETECTIVE_DISABLE"))
+ {
+ return;
+ }
+
pthread_mutex_lock(&mutex);
while ((hdr = hdr->next))
{
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index de043a02e..de52ea46a 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -151,10 +151,10 @@ static int get_list_count(private_iterator_t *this)
/**
* default iterator hook which does nothing
*/
-static bool iterator_hook(void *param, void *in, void **out)
+static hook_result_t iterator_hook(void *param, void *in, void **out)
{
*out = in;
- return TRUE;
+ return HOOK_NEXT;
}
/**
@@ -180,40 +180,43 @@ static void set_iterator_hook(private_iterator_t *this, iterator_hook_t *hook,
*/
static bool iterate(private_iterator_t *this, void** value)
{
- if (this->list->count == 0)
- {
- return FALSE;
- }
- if (this->current == NULL)
+ while (TRUE)
{
- this->current = (this->forward) ? this->list->first : this->list->last;
- if (!this->hook(this->hook_param, this->current->value, value))
+ if (this->forward)
{
- return iterate(this, value);
+ this->current = this->current ? this->current->next : this->list->first;
}
- return TRUE;
- }
- if (this->forward)
- {
- if (this->current->next == NULL)
+ else
+ {
+ this->current = this->current ? this->current->previous : this->list->last;
+ }
+
+ if (this->current == NULL)
{
return FALSE;
}
- this->current = this->current->next;
- if (!this->hook(this->hook_param, this->current->value, value))
+
+ switch (this->hook(this->hook_param, this->current->value, value))
{
- return iterate(this, value);
+ case HOOK_AGAIN:
+ /* rewind */
+ if (this->forward)
+ {
+ this->current = this->current->previous;
+ }
+ else
+ {
+ this->current = this->current->next;
+ }
+ break;
+ case HOOK_NEXT:
+ /* normal iteration */
+ break;
+ case HOOK_SKIP:
+ /* advance */
+ continue;
}
- return TRUE;
- }
- if (this->current->previous == NULL)
- {
- return FALSE;
- }
- this->current = this->current->previous;
- if (!this->hook(this->hook_param, this->current->value, value))
- {
- return iterate(this, value);
+ break;
}
return TRUE;
}