summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/backtrace.c42
-rw-r--r--src/libstrongswan/utils/backtrace.h5
-rw-r--r--src/libstrongswan/utils/hashtable.c135
-rw-r--r--src/libstrongswan/utils/hashtable.h14
-rw-r--r--src/libstrongswan/utils/identification.c16
-rw-r--r--src/libstrongswan/utils/identification.h5
-rw-r--r--src/libstrongswan/utils/leak_detective.c61
-rw-r--r--src/libstrongswan/utils/leak_detective.h9
8 files changed, 164 insertions, 123 deletions
diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c
index 5bba8ec21..a67245194 100644
--- a/src/libstrongswan/utils/backtrace.c
+++ b/src/libstrongswan/utils/backtrace.c
@@ -53,7 +53,7 @@ struct private_backtrace_t {
/**
* Implementation of backtrace_t.log
*/
-static void log_(private_backtrace_t *this, FILE *file)
+static void log_(private_backtrace_t *this, FILE *file, bool detailed)
{
#ifdef HAVE_BACKTRACE
size_t i;
@@ -78,7 +78,6 @@ static void log_(private_backtrace_t *this, FILE *file)
{
ptr = (void*)(this->frames[i] - info.dli_fbase);
}
- snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr);
if (info.dli_sname)
{
fprintf(file, " \e[33m%s\e[0m @ %p (\e[31m%s\e[0m+0x%x) [%p]\n",
@@ -90,28 +89,33 @@ static void log_(private_backtrace_t *this, FILE *file)
fprintf(file, " \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname,
info.dli_fbase, this->frames[i]);
}
- fprintf(file, " -> \e[32m");
- output = popen(cmd, "r");
- if (output)
+ if (detailed)
{
- while (TRUE)
+ fprintf(file, " -> \e[32m");
+ snprintf(cmd, sizeof(cmd), "addr2line -e %s %p",
+ info.dli_fname, ptr);
+ output = popen(cmd, "r");
+ if (output)
{
- c = getc(output);
- if (c == '\n' || c == EOF)
+ while (TRUE)
{
- break;
+ c = getc(output);
+ if (c == '\n' || c == EOF)
+ {
+ break;
+ }
+ fputc(c, file);
}
- fputc(c, file);
+ pclose(output);
}
- pclose(output);
- }
- else
- {
-#endif /* HAVE_DLADDR */
- fprintf(file, " %s\n", strings[i]);
-#ifdef HAVE_DLADDR
+ else
+ {
+ #endif /* HAVE_DLADDR */
+ fprintf(file, " %s\n", strings[i]);
+ #ifdef HAVE_DLADDR
+ }
+ fprintf(file, "\n\e[0m");
}
- fprintf(file, "\n\e[0m");
}
else
{
@@ -174,7 +178,7 @@ backtrace_t *backtrace_create(int skip)
memcpy(this->frames, frames + skip, frame_count * sizeof(void*));
this->frame_count = frame_count;
- this->public.log = (void(*)(backtrace_t*,FILE*))log_;
+ this->public.log = (void(*)(backtrace_t*,FILE*,bool))log_;
this->public.contains_function = (bool(*)(backtrace_t*, char *function))contains_function;
this->public.destroy = (void(*)(backtrace_t*))destroy;
diff --git a/src/libstrongswan/utils/backtrace.h b/src/libstrongswan/utils/backtrace.h
index c4d4284d1..c6b0ec78f 100644
--- a/src/libstrongswan/utils/backtrace.h
+++ b/src/libstrongswan/utils/backtrace.h
@@ -34,8 +34,11 @@ struct backtrace_t {
/**
* Log the backtrace to a FILE stream.
+ *
+ * @param file FILE to log backtrace to
+ * @param detailed TRUE to resolve line/file using addr2line (slow)
*/
- void (*log)(backtrace_t *this, FILE *file);
+ void (*log)(backtrace_t *this, FILE *file, bool detailed);
/**
* Check if the backtrace contains a frame in a specific function.
diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c
index 02c225833..dde57dc65 100644
--- a/src/libstrongswan/utils/hashtable.c
+++ b/src/libstrongswan/utils/hashtable.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2010 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -47,11 +47,13 @@ struct pair_t {
*/
pair_t *pair_create(void *key, void *value, u_int hash)
{
- pair_t *this = malloc_thing(pair_t);
+ pair_t *this;
- this->key = key;
- this->value = value;
- this->hash = hash;
+ INIT(this,
+ .key = key,
+ .value = value,
+ .hash = hash,
+ );
return this;
}
@@ -127,6 +129,11 @@ struct private_enumerator_t {
u_int row;
/**
+ * current pair
+ */
+ pair_t *pair;
+
+ /**
* enumerator for the current row
*/
enumerator_t *current;
@@ -219,10 +226,8 @@ static void rehash(private_hashtable_t *this)
free(old_table);
}
-/**
- * Implementation of hashtable_t.put
- */
-static void *put(private_hashtable_t *this, void *key, void *value)
+METHOD(hashtable_t, put, void*,
+ private_hashtable_t *this, void *key, void *value)
{
void *old_value = NULL;
linked_list_t *list;
@@ -265,10 +270,8 @@ static void *put(private_hashtable_t *this, void *key, void *value)
return old_value;
}
-/**
- * Implementation of hashtable_t.get
- */
-static void *get(private_hashtable_t *this, void *key)
+METHOD(hashtable_t, get, void*,
+ private_hashtable_t *this, void *key)
{
void *value = NULL;
linked_list_t *list;
@@ -286,10 +289,8 @@ static void *get(private_hashtable_t *this, void *key)
return value;
}
-/**
- * Implementation of hashtable_t.remove
- */
-static void *remove_(private_hashtable_t *this, void *key)
+METHOD(hashtable_t, remove_, void*,
+ private_hashtable_t *this, void *key)
{
void *value = NULL;
linked_list_t *list;
@@ -317,34 +318,44 @@ static void *remove_(private_hashtable_t *this, void *key)
return value;
}
-/**
- * Implementation of hashtable_t.get_count
- */
-static u_int get_count(private_hashtable_t *this)
+METHOD(hashtable_t, remove_at, void,
+ private_hashtable_t *this, private_enumerator_t *enumerator)
+{
+ if (enumerator->table == this && enumerator->current)
+ {
+ linked_list_t *list;
+ list = this->table[enumerator->row];
+ if (list)
+ {
+ list->remove_at(list, enumerator->current);
+ free(enumerator->pair);
+ this->count--;
+ }
+ }
+}
+
+METHOD(hashtable_t, get_count, u_int,
+ private_hashtable_t *this)
{
return this->count;
}
-/**
- * Implementation of private_enumerator_t.enumerator.enumerate.
- */
-static bool enumerate(private_enumerator_t *this, void **key, void **value)
+METHOD(enumerator_t, enumerate, bool,
+ private_enumerator_t *this, void **key, void **value)
{
while (this->row < this->table->capacity)
{
if (this->current)
{
- pair_t *pair;
-
- if (this->current->enumerate(this->current, &pair))
+ if (this->current->enumerate(this->current, &this->pair))
{
if (key)
{
- *key = pair->key;
+ *key = this->pair->key;
}
if (value)
{
- *value = pair->value;
+ *value = this->pair->value;
}
return TRUE;
}
@@ -354,7 +365,6 @@ static bool enumerate(private_enumerator_t *this, void **key, void **value)
else
{
linked_list_t *list;
-
list = this->table->table[this->row];
if (list)
{
@@ -367,10 +377,8 @@ static bool enumerate(private_enumerator_t *this, void **key, void **value)
return FALSE;
}
-/**
- * Implementation of private_enumerator_t.enumerator.destroy.
- */
-static void enumerator_destroy(private_enumerator_t *this)
+METHOD(enumerator_t, enumerator_destroy, void,
+ private_enumerator_t *this)
{
if (this->current)
{
@@ -379,26 +387,24 @@ static void enumerator_destroy(private_enumerator_t *this)
free(this);
}
-/**
- * Implementation of hashtable_t.create_enumerator.
- */
-static enumerator_t* create_enumerator(private_hashtable_t *this)
+METHOD(hashtable_t, create_enumerator, enumerator_t*,
+ private_hashtable_t *this)
{
- private_enumerator_t *enumerator = malloc_thing(private_enumerator_t);
+ private_enumerator_t *enumerator;
- enumerator->enumerator.enumerate = (void*)enumerate;
- enumerator->enumerator.destroy = (void*)enumerator_destroy;
- enumerator->table = this;
- enumerator->row = 0;
- enumerator->current = NULL;
+ INIT(enumerator,
+ .enumerator = {
+ .enumerate = (void*)_enumerate,
+ .destroy = (void*)_enumerator_destroy,
+ },
+ .table = this,
+ );
return &enumerator->enumerator;
}
-/**
- * Implementation of hashtable_t.destroy
- */
-static void destroy(private_hashtable_t *this)
+METHOD(hashtable_t, destroy, void,
+ private_hashtable_t *this)
{
linked_list_t *list;
u_int row;
@@ -421,22 +427,21 @@ static void destroy(private_hashtable_t *this)
hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals,
u_int capacity)
{
- private_hashtable_t *this = malloc_thing(private_hashtable_t);
-
- this->public.put = (void*(*)(hashtable_t*,void*,void*))put;
- this->public.get = (void*(*)(hashtable_t*,void*))get;
- this->public.remove = (void*(*)(hashtable_t*,void*))remove_;
- this->public.get_count = (u_int(*)(hashtable_t*))get_count;
- this->public.create_enumerator = (enumerator_t*(*)(hashtable_t*))create_enumerator;
- this->public.destroy = (void(*)(hashtable_t*))destroy;
-
- this->count = 0;
- this->capacity = 0;
- this->mask = 0;
- this->load_factor = 0;
- this->table = NULL;
- this->hash = hash;
- this->equals = equals;
+ private_hashtable_t *this;
+
+ INIT(this,
+ .public = {
+ .put = _put,
+ .get = _get,
+ .remove = _remove_,
+ .remove_at = (void*)_remove_at,
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .hash = hash,
+ .equals = equals,
+ );
init_hashtable(this, capacity);
diff --git a/src/libstrongswan/utils/hashtable.h b/src/libstrongswan/utils/hashtable.h
index 142ea6329..27aca9b68 100644
--- a/src/libstrongswan/utils/hashtable.h
+++ b/src/libstrongswan/utils/hashtable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2010 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -87,9 +87,17 @@ struct hashtable_t {
void *(*remove) (hashtable_t *this, void *key);
/**
+ * Removes the key and value pair from the hash table at which the given
+ * enumerator currently points.
+ *
+ * @param enumerator enumerator, from create_enumerator
+ */
+ void (*remove_at) (hashtable_t *this, enumerator_t *enumerator);
+
+ /**
* Gets the number of items in the hash table.
*
- * @return number of items
+ * @return number of items
*/
u_int (*get_count) (hashtable_t *this);
@@ -106,7 +114,7 @@ struct hashtable_t {
* @param hash hash function
* @param equals equals function
* @param capacity initial capacity
- * @return hashtable_t object.
+ * @return hashtable_t object.
*/
hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals,
u_int capacity);
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 6a3c3936c..3caeb8f0e 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -50,8 +50,7 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_DER_ASN1_GN",
"ID_KEY_ID");
ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_MYID, ID_KEY_ID,
- "ID_DER_ASN1_GN_URI"
- "ID_IETF_ATTR_STRING"
+ "ID_DER_ASN1_GN_URI",
"ID_MYID");
ENUM_END(id_type_names, ID_MYID);
@@ -297,18 +296,30 @@ static void dntoa(chunk_t dn, char *buf, size_t len)
{
written = snprintf(buf, len,"%s=", oid_names[oid].name);
}
+ if (written < 0 || written >= len)
+ {
+ break;
+ }
buf += written;
len -= written;
chunk_printable(data, &printable, '?');
written = snprintf(buf, len, "%.*s", printable.len, printable.ptr);
chunk_free(&printable);
+ if (written < 0 || written >= len)
+ {
+ break;
+ }
buf += written;
len -= written;
if (data.ptr + data.len != dn.ptr + dn.len)
{
written = snprintf(buf, len, ", ");
+ if (written < 0 || written >= len)
+ {
+ break;
+ }
buf += written;
len -= written;
}
@@ -761,7 +772,6 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
case ID_FQDN:
case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI:
- case ID_IETF_ATTR_STRING:
chunk_printable(this->encoded, &proper, '?');
snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper);
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index fe5c7d0fd..c463b0274 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -131,11 +131,6 @@ enum id_type_t {
ID_DER_ASN1_GN_URI = 201,
/**
- * IETF Attribute Syntax String (RFC 3281)
- */
- ID_IETF_ATTR_STRING = 202,
-
- /**
* Private ID used by the pluto daemon for opportunistic encryption
*/
ID_MYID = 203,
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index 2f8a7187c..0673878a5 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -207,6 +207,7 @@ char *whitelist[] = {
"ENGINE_load_builtin_engines",
"OPENSSL_config",
"ecdsa_check",
+ "ERR_put_error",
/* libgcrypt */
"gcry_control",
"gcry_check_version",
@@ -233,39 +234,45 @@ static bool is_whitelisted(backtrace_t *backtrace)
/**
* Report leaks at library destruction
*/
-void report_leaks()
+static void report(private_leak_detective_t *this, bool detailed)
{
- memory_header_t *hdr;
- int leaks = 0, whitelisted = 0;
-
- for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
+ if (lib->leak_detective)
{
- if (is_whitelisted(hdr->backtrace))
+ memory_header_t *hdr;
+ int leaks = 0, whitelisted = 0;
+
+ for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
{
- whitelisted++;
+ if (is_whitelisted(hdr->backtrace))
+ {
+ whitelisted++;
+ }
+ else
+ {
+ fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
+ /* skip the first frame, contains leak detective logic */
+ hdr->backtrace->log(hdr->backtrace, stderr, detailed);
+ leaks++;
+ }
}
- else
+ switch (leaks)
{
- fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
- /* skip the first frame, contains leak detective logic */
- hdr->backtrace->log(hdr->backtrace, stderr);
- leaks++;
+ case 0:
+ fprintf(stderr, "No leaks detected");
+ break;
+ case 1:
+ fprintf(stderr, "One leak detected");
+ break;
+ default:
+ fprintf(stderr, "%d leaks detected", leaks);
+ break;
}
+ fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
}
-
- switch (leaks)
+ else
{
- case 0:
- fprintf(stderr, "No leaks detected");
- break;
- case 1:
- fprintf(stderr, "One leak detected");
- break;
- default:
- fprintf(stderr, "%d leaks detected", leaks);
- break;
+ fprintf(stderr, "Leak detective disabled\n");
}
- fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
}
/**
@@ -395,7 +402,7 @@ void free_hook(void *ptr, const void *caller)
fprintf(stderr, "freeing invalid memory (%p)", ptr);
}
backtrace = backtrace_create(3);
- backtrace->log(backtrace, stderr);
+ backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
}
else
@@ -454,7 +461,7 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
"header magic 0x%x, tail magic 0x%x:\n",
old, hdr->magic, tail->magic);
backtrace = backtrace_create(3);
- backtrace->log(backtrace, stderr);
+ backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
}
/* clear tail magic, allocate, set tail magic */
@@ -487,7 +494,6 @@ static void destroy(private_leak_detective_t *this)
if (installed)
{
uninstall_hooks();
- report_leaks();
}
free(this);
}
@@ -499,6 +505,7 @@ leak_detective_t *leak_detective_create()
{
private_leak_detective_t *this = malloc_thing(private_leak_detective_t);
+ this->public.report = (void(*)(leak_detective_t*,bool))report;
this->public.destroy = (void(*)(leak_detective_t*))destroy;
if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h
index 181f8f3db..fa45a6076 100644
--- a/src/libstrongswan/utils/leak_detective.h
+++ b/src/libstrongswan/utils/leak_detective.h
@@ -23,6 +23,8 @@
typedef struct leak_detective_t leak_detective_t;
+#include <library.h>
+
/**
* Leak detective finds leaks and bad frees using malloc hooks.
*
@@ -34,6 +36,13 @@ typedef struct leak_detective_t leak_detective_t;
struct leak_detective_t {
/**
+ * Report leaks to stderr.
+ *
+ * @param detailed TRUE to resolve line/filename of leak (slow)
+ */
+ void (*report)(leak_detective_t *this, bool detailed);
+
+ /**
* Destroy a leak_detective instance.
*/
void (*destroy)(leak_detective_t *this);