summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/enumerator.c62
-rw-r--r--src/libstrongswan/utils/hashtable.c433
-rw-r--r--src/libstrongswan/utils/hashtable.h116
-rw-r--r--src/libstrongswan/utils/host.c6
-rw-r--r--src/libstrongswan/utils/identification.c3
-rw-r--r--src/libstrongswan/utils/leak_detective.c16
-rw-r--r--src/libstrongswan/utils/lexparser.c28
-rw-r--r--src/libstrongswan/utils/lexparser.h8
-rw-r--r--src/libstrongswan/utils/mutex.c52
-rw-r--r--src/libstrongswan/utils/mutex.h12
10 files changed, 675 insertions, 61 deletions
diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c
index 4ebc2e097..e7653a9b2 100644
--- a/src/libstrongswan/utils/enumerator.c
+++ b/src/libstrongswan/utils/enumerator.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -12,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: enumerator.c 4142 2008-07-02 08:09:07Z martin $
+ * $Id: enumerator.c 4744 2008-12-03 10:03:59Z tobias $
*/
#include "enumerator.h"
@@ -215,27 +216,48 @@ static bool enumerate_token_enum(token_enum_t *this, char **token)
}
}
- /* find separators */
- sep = this->sep;
- while (*sep)
+ switch (*this->pos)
{
- tmp = strchr(this->pos, *sep);
- if (tmp && (pos == NULL || tmp < pos))
+ case '"':
+ case '\'':
{
- pos = tmp;
+ /* read quoted token */
+ tmp = strchr(this->pos + 1, *this->pos);
+ if (tmp)
+ {
+ *token = this->pos + 1;
+ *tmp = '\0';
+ this->pos = tmp + 1;
+ return TRUE;
+ }
+ /* unterminated string, FALL-THROUGH */
+ }
+ default:
+ {
+ /* find nearest separator */
+ sep = this->sep;
+ while (*sep)
+ {
+ tmp = strchr(this->pos, *sep);
+ if (tmp && (pos == NULL || tmp < pos))
+ {
+ pos = tmp;
+ }
+ sep++;
+ }
+ *token = this->pos;
+ if (pos)
+ {
+ *pos = '\0';
+ this->pos = pos + 1;
+ }
+ else
+ {
+ last = TRUE;
+ pos = this->pos = strchr(this->pos, '\0');
+ }
+ break;
}
- sep++;
- }
- *token = this->pos;
- if (pos)
- {
- *pos = '\0';
- this->pos = pos + 1;
- }
- else
- {
- last = TRUE;
- pos = this->pos = strchr(this->pos, '\0');
}
/* trim trailing characters/separators */
@@ -268,7 +290,7 @@ static bool enumerate_token_enum(token_enum_t *this, char **token)
}
}
- if (!last || pos > *token)
+ if (!last || pos >= *token)
{
return TRUE;
}
diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c
new file mode 100644
index 000000000..892d08b6c
--- /dev/null
+++ b/src/libstrongswan/utils/hashtable.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: hashtable.c 4812 2008-12-17 09:56:05Z tobias $
+ */
+
+#include <utils/linked_list.h>
+
+#include "hashtable.h"
+
+/** The maximum capacity of the hash table (MUST be a power of 2) */
+#define MAX_CAPACITY (1 << 30)
+
+typedef struct pair_t pair_t;
+
+/**
+ * This pair holds a pointer to the key and value it represents.
+ */
+struct pair_t {
+ /**
+ * Key of a hash table item.
+ */
+ void *key;
+
+ /**
+ * Value of a hash table item.
+ */
+ void *value;
+
+ /**
+ * Cached hash (used in case of a resize).
+ */
+ u_int hash;
+};
+
+/**
+ * Creates an empty pair object.
+ */
+pair_t *pair_create(void *key, void *value, u_int hash)
+{
+ pair_t *this = malloc_thing(pair_t);
+
+ this->key = key;
+ this->value = value;
+ this->hash = hash;
+
+ return this;
+}
+
+typedef struct private_hashtable_t private_hashtable_t;
+
+/**
+ * Private data of a hashtable_t object.
+ *
+ */
+struct private_hashtable_t {
+ /**
+ * Public part of hash table.
+ */
+ hashtable_t public;
+
+ /**
+ * The number of items in the hash table.
+ */
+ u_int count;
+
+ /**
+ * The current capacity of the hash table (always a power of 2).
+ */
+ u_int capacity;
+
+ /**
+ * The current mask to calculate the row index (capacity - 1).
+ */
+ u_int mask;
+
+ /**
+ * The load factor.
+ */
+ float load_factor;
+
+ /**
+ * The actual table.
+ */
+ linked_list_t **table;
+
+ /**
+ * The hashing function.
+ */
+ hashtable_hash_t hash;
+
+ /**
+ * The equality function.
+ */
+ hashtable_equals_t equals;
+};
+
+typedef struct private_enumerator_t private_enumerator_t;
+
+/**
+ * hash table enumerator implementation
+ */
+struct private_enumerator_t {
+
+ /**
+ * implements enumerator interface
+ */
+ enumerator_t enumerator;
+
+ /**
+ * associated hash table
+ */
+ private_hashtable_t *table;
+
+ /**
+ * current row index
+ */
+ u_int row;
+
+ /**
+ * enumerator for the current row
+ */
+ enumerator_t *current;
+};
+
+/**
+ * Compare a pair in a list with the given key.
+ */
+static inline bool pair_equals(pair_t *pair, private_hashtable_t *this, void *key)
+{
+ return this->equals(key, pair->key);
+}
+
+/**
+ * This function returns the next-highest power of two for the given number.
+ * The algorithm works by setting all bits on the right-hand side of the most
+ * significant 1 to 1 and then increments the whole number so it rolls over
+ * to the nearest power of two. Note: returns 0 for n == 0
+ */
+static u_int get_nearest_powerof2(u_int n)
+{
+ u_int i;
+ --n;
+ for (i = 1; i < sizeof(u_int) * 8; i <<= 1)
+ {
+ n |= n >> i;
+ }
+ return ++n;
+}
+
+/**
+ * Init hash table parameters
+ */
+static void init_hashtable(private_hashtable_t *this, u_int capacity)
+{
+ capacity = max(1, min(capacity, MAX_CAPACITY));
+ this->capacity = get_nearest_powerof2(capacity);
+ this->mask = this->capacity - 1;
+ this->load_factor = 0.75;
+
+ this->table = calloc(this->capacity, sizeof(linked_list_t*));
+}
+
+/**
+ * Double the size of the hash table and rehash all the elements.
+ */
+static void rehash(private_hashtable_t *this)
+{
+ u_int row;
+ u_int old_capacity = this->capacity;
+ linked_list_t **old_table = this->table;
+
+ if (old_capacity >= MAX_CAPACITY)
+ {
+ return;
+ }
+
+ init_hashtable(this, old_capacity << 1);
+
+ for (row = 0; row < old_capacity; ++row)
+ {
+ linked_list_t *list;
+ if ((list = old_table[row]) != NULL)
+ {
+ pair_t *pair;
+ enumerator_t *enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &pair))
+ {
+ linked_list_t *new_list;
+ u_int new_row = pair->hash & this->mask;
+ list->remove_at(list, enumerator);
+ if ((new_list = this->table[new_row]) == NULL)
+ {
+ new_list = this->table[new_row] = linked_list_create();
+ }
+ new_list->insert_last(new_list, pair);
+ }
+ enumerator->destroy(enumerator);
+ list->destroy(list);
+ }
+ }
+ free(old_table);
+}
+
+/**
+ * Implementation of hashtable_t.put
+ */
+static void *put(private_hashtable_t *this, void *key, void *value)
+{
+ linked_list_t *list;
+ void *old_value = NULL;
+ u_int hash = this->hash(key);
+ u_int row = hash & this->mask;
+
+ if ((list = this->table[row]) != NULL)
+ {
+ pair_t *pair;
+ enumerator_t *enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &pair))
+ {
+ if (pair_equals(pair, this, key))
+ {
+ old_value = pair->value;
+ pair->value = value;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ list = this->table[row] = linked_list_create();
+ }
+
+ if (!old_value)
+ {
+ list->insert_last(list, pair_create(key, value, hash));
+ this->count++;
+ }
+
+ if (this->count >= this->capacity * this->load_factor)
+ {
+ rehash(this);
+ }
+
+ return old_value;
+}
+
+/**
+ * Implementation of hashtable_t.get
+ */
+static void *get(private_hashtable_t *this, void *key)
+{
+ void *value = NULL;
+ linked_list_t *list;
+ u_int row = this->hash(key) & this->mask;
+
+ if ((list = this->table[row]) != NULL)
+ {
+ pair_t *pair;
+ if (list->find_first(list, (linked_list_match_t)pair_equals,
+ (void**)&pair, this, key) == SUCCESS)
+ {
+ value = pair->value;
+ }
+ }
+
+ return value;
+}
+
+/**
+ * Implementation of hashtable_t.remove
+ */
+static void *remove(private_hashtable_t *this, void *key)
+{
+ void *value = NULL;
+ linked_list_t *list;
+ u_int row = this->hash(key) & this->mask;
+
+ if ((list = this->table[row]) != NULL)
+ {
+ pair_t *pair;
+ enumerator_t *enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &pair))
+ {
+ if (pair_equals(pair, this, key))
+ {
+ list->remove_at(list, enumerator);
+ value = pair->value;
+ this->count--;
+ free(pair);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ return value;
+}
+
+/**
+ * Implementation of hashtable_t.get_count
+ */
+static u_int get_count(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)
+{
+ while (this->row < this->table->capacity)
+ {
+ if (this->current)
+ {
+ pair_t *pair;
+
+ if (this->current->enumerate(this->current, &pair))
+ {
+ if (key)
+ {
+ *key = pair->key;
+ }
+ if (value)
+ {
+ *value = pair->value;
+ }
+ return TRUE;
+ }
+ this->current->destroy(this->current);
+ this->current = NULL;
+ }
+ else
+ {
+ linked_list_t *list;
+
+ if ((list = this->table->table[this->row]) != NULL)
+ {
+ this->current = list->create_enumerator(list);
+ continue;
+ }
+ }
+ this->row++;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_enumerator_t.enumerator.destroy.
+ */
+static void enumerator_destroy(private_enumerator_t *this)
+{
+ if (this->current)
+ {
+ this->current->destroy(this->current);
+ }
+ free(this);
+}
+
+/**
+ * Implementation of hashtable_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_hashtable_t *this)
+{
+ private_enumerator_t *enumerator = malloc_thing(private_enumerator_t);
+
+ enumerator->enumerator.enumerate = (void*)enumerate;
+ enumerator->enumerator.destroy = (void*)enumerator_destroy;
+ enumerator->table = this;
+ enumerator->row = 0;
+ enumerator->current = NULL;
+
+ return &enumerator->enumerator;
+}
+
+/**
+ * Implementation of hashtable_t.destroy
+ */
+static void destroy(private_hashtable_t *this)
+{
+ u_int row;
+ for (row = 0; row < this->capacity; ++row)
+ {
+ linked_list_t *list;
+ if ((list = this->table[row]) != NULL)
+ {
+ list->destroy_function(list, free);
+ }
+ }
+ free(this->table);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+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;
+
+ init_hashtable(this, capacity);
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/utils/hashtable.h b/src/libstrongswan/utils/hashtable.h
new file mode 100644
index 000000000..3d3005e73
--- /dev/null
+++ b/src/libstrongswan/utils/hashtable.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: hashtable.h 4762 2008-12-05 10:01:52Z martin $
+ */
+
+/**
+ * @defgroup hashtable hashtable
+ * @{ @ingroup utils
+ */
+
+#ifndef HASHTABLE_H_
+#define HASHTABLE_H_
+
+#include <utils/enumerator.h>
+
+typedef struct hashtable_t hashtable_t;
+
+/**
+ * Prototype for a function that computes the hash code from the given key.
+ *
+ * @param key key to hash
+ * @return hash code
+ */
+typedef u_int (*hashtable_hash_t)(void *key);
+
+/**
+ * Prototype for a function that compares the two keys for equality.
+ *
+ * @param key first key (the one we are looking for)
+ * @param other_key second key
+ * @return TRUE if the keys are equal
+ */
+typedef bool (*hashtable_equals_t)(void *key, void *other_key);
+
+/**
+ * Class implementing a hash table.
+ *
+ * General purpose hash table. This hash table is not synchronized.
+ */
+struct hashtable_t {
+
+ /**
+ * Create an enumerator over the hash table key/value pairs.
+ *
+ * @return enumerator over (void *key, void *value)
+ */
+ enumerator_t *(*create_enumerator) (hashtable_t *this);
+
+ /**
+ * Adds the given value with the given key to the hash table, if there
+ * exists no entry with that key. NULL is returned in this case.
+ * Otherwise the existing value is replaced and the function returns the
+ * old value.
+ *
+ * @param key the key to store
+ * @param value the value to store
+ * @return NULL if no item was replaced, the old value otherwise
+ */
+ void *(*put) (hashtable_t *this, void *key, void *value);
+
+ /**
+ * Returns the value with the given key, if the hash table contains such an
+ * entry, otherwise NULL is returned.
+ *
+ * @param key the key of the requested value
+ * @return the value, NULL if not found
+ */
+ void *(*get) (hashtable_t *this, void *key);
+
+ /**
+ * Removes the value with the given key from the hash table and returns the
+ * removed value (or NULL if no such value existed).
+ *
+ * @param key the key of the value to remove
+ * @return the removed value, NULL if not found
+ */
+ void *(*remove) (hashtable_t *this, void *key);
+
+ /**
+ * Gets the number of items in the hash table.
+ *
+ * @return number of items
+ */
+ u_int (*get_count) (hashtable_t *this);
+
+ /**
+ * Destroys a hash table object.
+ */
+ void (*destroy) (hashtable_t *this);
+
+};
+
+/**
+ * Creates an empty hash table object.
+ *
+ * @param hash hash function
+ * @param equals equals function
+ * @param capacity initial capacity
+ * @return hashtable_t object.
+ */
+hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals,
+ u_int capacity);
+
+#endif /* HASHTABLE_H_ @} */
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index 4702222e8..719c5a529 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -15,7 +15,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: host.c 4639 2008-11-12 15:09:24Z martin $
+ * $Id: host.c 4856 2009-02-05 22:13:48Z andreas $
*/
#define _GNU_SOURCE
@@ -453,6 +453,10 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port)
{
return host_create_any(af ? af : AF_INET);
}
+ if (streq(string, "%any6"))
+ {
+ return host_create_any(af ? af : AF_INET6);
+ }
else if (strchr(string, ':'))
{
/* gethostbyname does not like IPv6 addresses - fallback */
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index db442e9ab..529e62509 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: identification.c 4344 2008-09-17 02:17:01Z andreas $
+ * $Id: identification.c 4856 2009-02-05 22:13:48Z andreas $
*/
#define _GNU_SOURCE
@@ -1046,6 +1046,7 @@ identification_t *identification_create_from_string(char *string)
else if (strchr(string, '@') == NULL)
{
if (streq(string, "%any")
+ || streq(string, "%any6")
|| streq(string, "0.0.0.0")
|| streq(string, "*")
|| streq(string, "::")
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index 73409158d..4c56c9596 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -12,9 +12,11 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: leak_detective.c 4609 2008-11-10 16:44:27Z martin $
+ * $Id: leak_detective.c 4796 2008-12-12 09:10:52Z martin $
*/
+#define _GNU_SOURCE
+#include <sched.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
@@ -160,6 +162,7 @@ char *whitelist[] = {
/* pthread stuff */
"pthread_create",
"pthread_setspecific",
+ "__pthread_setspecific",
/* glibc functions */
"mktime",
"__gmtime_r",
@@ -199,6 +202,7 @@ char *whitelist[] = {
"RSA_new_method",
"DH_new_method",
"ENGINE_load_builtin_engines",
+ "OPENSSL_config",
};
/**
@@ -471,6 +475,16 @@ leak_detective_t *leak_detective_create()
if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
{
+ cpu_set_t mask;
+
+ CPU_ZERO(&mask);
+ CPU_SET(0, &mask);
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) != 0)
+ {
+ fprintf(stderr, "setting CPU affinity failed: %m");
+ }
+
lib->leak_detective = TRUE;
install_hooks();
}
diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c
index 8b7b3b547..5725df1ea 100644
--- a/src/libstrongswan/utils/lexparser.c
+++ b/src/libstrongswan/utils/lexparser.c
@@ -11,16 +11,11 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: lexparser.c 3872 2008-04-25 07:04:59Z andreas $
+ * $Id: lexparser.c 4877 2009-02-18 09:45:54Z martin $
*/
-/* memrchr is a GNU extension */
-#define _GNU_SOURCE
-#include <string.h>
-
#include "lexparser.h"
-
/**
* eat whitespace
*/
@@ -30,7 +25,7 @@ bool eat_whitespace(chunk_t *src)
{
src->ptr++; src->len--;
}
- return src->len > 0 && *src->ptr != '#';
+ return src->len > 0 && *src->ptr != '#';
}
/**
@@ -51,11 +46,11 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src)
if (termination == ' ')
{
u_char *eot_tab = memchr(src->ptr, '\t', src->len);
-
+
/* check if a tab instead of a space terminates the token */
eot = ( eot_tab == NULL || (eot && eot < eot_tab) ) ? eot : eot_tab;
}
-
+
/* initialize empty token */
*token = chunk_empty;
@@ -76,16 +71,17 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src)
}
/**
- * extracts a token ending with the last occurrence of a given termination symbol
+ * extracts a token ending with the first occurrence of a given null-terminated string
*/
-bool extract_last_token(chunk_t *token, const char termination, chunk_t *src)
+bool extract_token_str(chunk_t *token, const char *termination, chunk_t *src)
{
- u_char *eot = memrchr(src->ptr, termination, src->len);
+ u_char *eot = memstr(src->ptr, termination, src->len);
+ size_t l = strlen(termination);
/* initialize empty token */
*token = chunk_empty;
- if (eot == NULL) /* termination symbol not found */
+ if (eot == NULL) /* termination string not found */
{
return FALSE;
}
@@ -94,9 +90,9 @@ bool extract_last_token(chunk_t *token, const char termination, chunk_t *src)
token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr);
- /* advance src pointer after termination symbol */
- src->ptr = eot + 1;
- src->len -= (token->len + 1);
+ /* advance src pointer after termination string */
+ src->ptr = eot + l;
+ src->len -= (token->len + l);
return TRUE;
}
diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h
index 7d54ca22e..c47f65718 100644
--- a/src/libstrongswan/utils/lexparser.h
+++ b/src/libstrongswan/utils/lexparser.h
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: lexparser.h 3876 2008-04-26 09:24:14Z andreas $
+ * $Id: lexparser.h 4877 2009-02-18 09:45:54Z martin $
*/
/**
@@ -37,14 +37,14 @@ bool eat_whitespace(chunk_t *src);
bool match(const char *pattern, const chunk_t *ch);
/**
- * Extracts a token ending with the first occurence a given termination symbol
+ * Extracts a token ending with the first occurrence of a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src);
/**
- * Extracts a token ending with the last occurence a given termination symbol
+ * Extracts a token ending with the first occurrence of a given null-terminated string
*/
-bool extract_last_token(chunk_t *token, const char termination, chunk_t *src);
+bool extract_token_str(chunk_t *token, const char *termination, chunk_t *src);
/**
* Fetches a new text line terminated by \n or \r\n
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
index ddb0d2df6..ba4b72b0c 100644
--- a/src/libstrongswan/utils/mutex.c
+++ b/src/libstrongswan/utils/mutex.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -12,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: mutex.c 4591 2008-11-05 16:12:54Z martin $
+ * $Id: mutex.c 4803 2008-12-15 09:13:43Z martin $
*/
#define _GNU_SOURCE
@@ -76,7 +77,7 @@ static void profiler_cleanup(lock_profile_t *profile)
*/
static void profiler_init(lock_profile_t *profile)
{
- profile->backtrace = backtrace_create(3);
+ profile->backtrace = backtrace_create(2);
timerclear(&profile->waited);
}
@@ -332,28 +333,17 @@ static void wait(private_condvar_t *this, private_mutex_t *mutex)
}
/**
- * Implementation of condvar_t.timed_wait.
+ * Implementation of condvar_t.timed_wait_abs.
*/
-static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
- u_int timeout)
+static bool timed_wait_abs(private_condvar_t *this, private_mutex_t *mutex,
+ timeval_t time)
{
struct timespec ts;
- struct timeval tv;
- u_int s, ms;
bool timed_out;
- gettimeofday(&tv, NULL);
-
- s = timeout / 1000;
- ms = timeout % 1000;
+ ts.tv_sec = time.tv_sec;
+ ts.tv_nsec = time.tv_usec * 1000;
- ts.tv_sec = tv.tv_sec + s;
- ts.tv_nsec = tv.tv_usec * 1000 + ms * 1000000;
- if (ts.tv_nsec > 1000000000 /* 1s */)
- {
- ts.tv_nsec -= 1000000000;
- ts.tv_sec++;
- }
if (mutex->recursive)
{
private_r_mutex_t* recursive = (private_r_mutex_t*)mutex;
@@ -372,6 +362,31 @@ static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
}
/**
+ * Implementation of condvar_t.timed_wait.
+ */
+static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
+ u_int timeout)
+{
+ timeval_t tv;
+ u_int s, ms;
+
+ gettimeofday(&tv, NULL);
+
+ s = timeout / 1000;
+ ms = timeout % 1000;
+
+ tv.tv_sec += s;
+ tv.tv_usec += ms * 1000;
+
+ if (tv.tv_usec > 1000000 /* 1s */)
+ {
+ tv.tv_usec -= 1000000;
+ tv.tv_sec++;
+ }
+ return timed_wait_abs(this, mutex, tv);
+}
+
+/**
* Implementation of condvar_t.signal.
*/
static void signal(private_condvar_t *this)
@@ -410,6 +425,7 @@ condvar_t *condvar_create(condvar_type_t type)
this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))wait;
this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
+ this->public.timed_wait_abs = (bool(*)(condvar_t*, mutex_t *mutex, timeval_t time))timed_wait_abs;
this->public.signal = (void(*)(condvar_t*))signal;
this->public.broadcast = (void(*)(condvar_t*))broadcast;
this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
index a0a198024..4cdd96a99 100644
--- a/src/libstrongswan/utils/mutex.h
+++ b/src/libstrongswan/utils/mutex.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -11,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: mutex.h 4697 2008-11-25 19:30:02Z tobias $
*/
/**
@@ -99,6 +102,15 @@ struct condvar_t {
bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout);
/**
+ * Wait on a condvar until it gets signalized, or times out.
+ *
+ * @param mutex mutex to release while waiting
+ * @param time absolute time until timeout
+ * @return TRUE if timed out, FALSE otherwise
+ */
+ bool (*timed_wait_abs)(condvar_t *this, mutex_t *mutex, timeval_t timeout);
+
+ /**
* Wake up a single thread in a condvar.
*/
void (*signal)(condvar_t *this);