summaryrefslogtreecommitdiff
path: root/src/charon/bus/bus.c
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-12-05 16:44:41 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-12-05 16:44:41 +0000
commit2db1ef4ac8928944958712923b9c89c263a337d2 (patch)
tree700043d9d97b7e7ba344b448918728af0a8be8d1 /src/charon/bus/bus.c
parent5dc75410286b0e3a16845b44dd696ba0f40df573 (diff)
downloadvyos-strongswan-2db1ef4ac8928944958712923b9c89c263a337d2.tar.gz
vyos-strongswan-2db1ef4ac8928944958712923b9c89c263a337d2.zip
- Updated to new upstream.
Diffstat (limited to 'src/charon/bus/bus.c')
-rw-r--r--src/charon/bus/bus.c335
1 files changed, 255 insertions, 80 deletions
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index a102a3984..504947465 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -12,20 +12,18 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: bus.c 4198 2008-07-21 14:23:43Z martin $
+ * $Id: bus.c 4622 2008-11-11 10:52:37Z martin $
*/
#include "bus.h"
#include <pthread.h>
+#include <stdint.h>
#include <daemon.h>
#include <utils/mutex.h>
-ENUM(signal_names, SIG_ANY, SIG_MAX,
- /** should not get printed */
- "SIG_ANY",
- /** debugging message types */
+ENUM(debug_names, DBG_DMN, DBG_LIB,
"DMN",
"MGR",
"IKE",
@@ -36,19 +34,19 @@ ENUM(signal_names, SIG_ANY, SIG_MAX,
"NET",
"ENC",
"LIB",
- /** should not get printed */
- "SIG_DBG_MAX",
- /** all level0 signals are AUDIT signals */
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- "AUD", "AUD", "AUD",
- /** should not get printed */
- "SIG_MAX",
+);
+
+ENUM(debug_lower_names, DBG_DMN, DBG_LIB,
+ "dmn",
+ "mgr",
+ "ike",
+ "chd",
+ "job",
+ "cfg",
+ "knl",
+ "net",
+ "enc",
+ "lib",
);
typedef struct private_bus_t private_bus_t;
@@ -93,7 +91,7 @@ struct entry_t {
/**
* registered listener interface
*/
- bus_listener_t *listener;
+ listener_t *listener;
/**
* is this a active listen() call with a blocking thread
@@ -103,7 +101,7 @@ struct entry_t {
/**
* are we currently calling this listener
*/
- bool calling;
+ int calling;
/**
* condvar where active listeners wait
@@ -114,13 +112,13 @@ struct entry_t {
/**
* create a listener entry
*/
-static entry_t *entry_create(bus_listener_t *listener, bool blocker)
+static entry_t *entry_create(listener_t *listener, bool blocker)
{
entry_t *this = malloc_thing(entry_t);
this->listener = listener;
this->blocker = blocker;
- this->calling = FALSE;
+ this->calling = 0;
this->condvar = condvar_create(CONDVAR_DEFAULT);
return this;
@@ -140,12 +138,12 @@ static void entry_destroy(entry_t *entry)
* pthread_self returns large and ugly numbers, use this function
* for logging; these numbers are incremental starting at 1
*/
-static int get_thread_number(private_bus_t *this)
+static u_int get_thread_number(private_bus_t *this)
{
- static long current_num = 0;
- long stored_num;
+ static uintptr_t current_num = 0;
+ uintptr_t stored_num;
- stored_num = (long)pthread_getspecific(this->thread_id);
+ stored_num = (uintptr_t)pthread_getspecific(this->thread_id);
if (stored_num == 0)
{ /* first call of current thread */
pthread_setspecific(this->thread_id, (void*)++current_num);
@@ -160,7 +158,7 @@ static int get_thread_number(private_bus_t *this)
/**
* Implementation of bus_t.add_listener.
*/
-static void add_listener(private_bus_t *this, bus_listener_t *listener)
+static void add_listener(private_bus_t *this, listener_t *listener)
{
this->mutex->lock(this->mutex);
this->listeners->insert_last(this->listeners, entry_create(listener, FALSE));
@@ -170,23 +168,23 @@ static void add_listener(private_bus_t *this, bus_listener_t *listener)
/**
* Implementation of bus_t.remove_listener.
*/
-static void remove_listener(private_bus_t *this, bus_listener_t *listener)
+static void remove_listener(private_bus_t *this, listener_t *listener)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *entry;
this->mutex->lock(this->mutex);
- iterator = this->listeners->create_iterator(this->listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
{
if (entry->listener == listener)
{
- iterator->remove(iterator);
+ this->listeners->remove_at(this->listeners, enumerator);
entry_destroy(entry);
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
}
@@ -207,26 +205,14 @@ struct cleanup_data_t {
*/
static void listener_cleanup(cleanup_data_t *data)
{
- iterator_t *iterator;
- entry_t *entry;
-
- iterator = data->this->listeners->create_iterator(data->this->listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
- {
- if (entry == data->entry)
- {
- iterator->remove(iterator);
- entry_destroy(entry);
- break;
- }
- }
- iterator->destroy(iterator);
+ data->this->listeners->remove(data->this->listeners, data->entry, NULL);
+ entry_destroy(data->entry);
}
/**
* Implementation of bus_t.listen.
*/
-static void listen_(private_bus_t *this, bus_listener_t *listener, job_t *job)
+static void listen_(private_bus_t *this, listener_t *listener, job_t *job)
{
int old;
cleanup_data_t data;
@@ -267,33 +253,31 @@ typedef struct {
ike_sa_t *ike_sa;
/** invoking thread */
long thread;
- /** signal type */
- signal_t signal;
- /** signal level */
+ /** debug group */
+ debug_t group;
+ /** debug level */
level_t level;
- /** signal specific user data */
- void *user;
/** format string */
char *format;
/** argument list */
va_list args;
-} signal_data_t;
+} log_data_t;
/**
- * listener invocation as a list remove callback
+ * listener->log() invocation as a list remove callback
*/
-static bool signal_cb(entry_t *entry, signal_data_t *data)
+static bool log_cb(entry_t *entry, log_data_t *data)
{
va_list args;
- if (entry->calling)
+ if (entry->calling || !entry->listener->log)
{ /* avoid recursive calls */
return FALSE;
}
- entry->calling = TRUE;
+ entry->calling++;
va_copy(args, data->args);
- if (!entry->listener->signal(entry->listener, data->signal, data->level,
- data->thread, data->ike_sa, data->user, data->format, args))
+ if (!entry->listener->log(entry->listener, data->group, data->level,
+ data->thread, data->ike_sa, data->format, args))
{
if (entry->blocker)
{
@@ -305,52 +289,238 @@ static bool signal_cb(entry_t *entry, signal_data_t *data)
entry_destroy(entry);
}
va_end(args);
- entry->calling = FALSE;
+ entry->calling--;
return TRUE;
}
va_end(args);
- entry->calling = FALSE;
+ entry->calling--;
return FALSE;
}
/**
- * Implementation of bus_t.vsignal.
+ * Implementation of bus_t.vlog.
*/
-static void vsignal(private_bus_t *this, signal_t signal, level_t level,
- void *user, char* format, va_list args)
+static void vlog(private_bus_t *this, debug_t group, level_t level,
+ char* format, va_list args)
{
- signal_data_t data;
+ log_data_t data;
data.ike_sa = pthread_getspecific(this->thread_sa);
data.thread = get_thread_number(this);
- data.signal = signal;
+ data.group = group;
data.level = level;
- data.user = user;
data.format = format;
va_copy(data.args, args);
this->mutex->lock(this->mutex);
- /* we use the remove() method to invoke all listeners with small overhead */
- this->listeners->remove(this->listeners, &data, (void*)signal_cb);
+ /* We use the remove() method to invoke all listeners. This is cheap and
+ * does not require an allocation for this performance critical function. */
+ this->listeners->remove(this->listeners, &data, (void*)log_cb);
this->mutex->unlock(this->mutex);
va_end(data.args);
}
/**
- * Implementation of bus_t.signal.
+ * Implementation of bus_t.log.
*/
-static void signal_(private_bus_t *this, signal_t signal, level_t level,
- void* data, char* format, ...)
+static void log_(private_bus_t *this, debug_t group, level_t level,
+ char* format, ...)
{
va_list args;
va_start(args, format);
- vsignal(this, signal, level, data, format, args);
+ vlog(this, group, level, format, args);
va_end(args);
}
/**
+ * unregister a listener
+ */
+static void unregister_listener(private_bus_t *this, entry_t *entry,
+ enumerator_t *enumerator)
+{
+ if (entry->blocker)
+ {
+ entry->blocker = FALSE;
+ entry->condvar->signal(entry->condvar);
+ }
+ else
+ {
+ entry_destroy(entry);
+ }
+ this->listeners->remove_at(this->listeners, enumerator);
+}
+
+/**
+ * Implementation of bus_t.ike_state_change
+ */
+static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa,
+ ike_sa_state_t state)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool keep;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->ike_state_change)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->ike_state_change(entry->listener, ike_sa, state);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of bus_t.child_state_change
+ */
+static void child_state_change(private_bus_t *this, child_sa_t *child_sa,
+ child_sa_state_t state)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep;
+
+ ike_sa = pthread_getspecific(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->child_state_change)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->child_state_change(entry->listener, ike_sa,
+ child_sa, state);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of bus_t.message
+ */
+static void message(private_bus_t *this, message_t *message, bool incoming)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep;
+
+ ike_sa = pthread_getspecific(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->message)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->message(entry->listener, ike_sa,
+ message, incoming);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of bus_t.ike_keys
+ */
+static void ike_keys(private_bus_t *this, ike_sa_t *ike_sa,
+ diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r,
+ ike_sa_t *rekey)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool keep;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->ike_keys)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->ike_keys(entry->listener, ike_sa, dh,
+ nonce_i, nonce_r, rekey);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of bus_t.child_keys
+ */
+static void child_keys(private_bus_t *this, child_sa_t *child_sa,
+ diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep;
+
+ ike_sa = pthread_getspecific(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->child_keys)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->child_keys(entry->listener, ike_sa, child_sa,
+ dh, nonce_i, nonce_r);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
* Implementation of bus_t.destroy.
*/
static void destroy(private_bus_t *this)
@@ -367,16 +537,21 @@ bus_t *bus_create()
{
private_bus_t *this = malloc_thing(private_bus_t);
- this->public.add_listener = (void(*)(bus_t*,bus_listener_t*))add_listener;
- this->public.remove_listener = (void(*)(bus_t*,bus_listener_t*))remove_listener;
- this->public.listen = (void(*)(bus_t*, bus_listener_t *listener, job_t *job))listen_;
+ this->public.add_listener = (void(*)(bus_t*,listener_t*))add_listener;
+ this->public.remove_listener = (void(*)(bus_t*,listener_t*))remove_listener;
+ this->public.listen = (void(*)(bus_t*, listener_t *listener, job_t *job))listen_;
this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa;
- this->public.signal = (void(*)(bus_t*,signal_t,level_t,void*,char*,...))signal_;
- this->public.vsignal = (void(*)(bus_t*,signal_t,level_t,void*,char*,va_list))vsignal;
+ this->public.log = (void(*)(bus_t*,debug_t,level_t,char*,...))log_;
+ this->public.vlog = (void(*)(bus_t*,debug_t,level_t,char*,va_list))vlog;
+ this->public.ike_state_change = (void(*)(bus_t*,ike_sa_t*,ike_sa_state_t))ike_state_change;
+ this->public.child_state_change = (void(*)(bus_t*,child_sa_t*,child_sa_state_t))child_state_change;
+ this->public.message = (void(*)(bus_t*, message_t *message, bool incoming))message;
+ this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
+ this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create();
- this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
pthread_key_create(&this->thread_id, NULL);
pthread_key_create(&this->thread_sa, NULL);