diff options
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r-- | src/libstrongswan/utils/identification.c | 28 | ||||
-rw-r--r-- | src/libstrongswan/utils/iterator.h | 42 | ||||
-rw-r--r-- | src/libstrongswan/utils/leak_detective.c | 17 | ||||
-rw-r--r-- | src/libstrongswan/utils/linked_list.c | 59 |
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; } |