From e85b83c737efd2a37696de22339a9b2d29b015dd Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 15 Jul 2009 16:12:02 +0200 Subject: [PATCH] added an alert() bus hook to raise critical system errors and notifications --- src/charon/bus/bus.c | 36 +++++++++++++++++++++++++++++ src/charon/bus/bus.h | 18 ++++++++++++++- src/charon/bus/listeners/listener.h | 17 +++++++++++--- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index a5f8fc255..67548a187 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -350,6 +350,41 @@ static void unregister_listener(private_bus_t *this, entry_t *entry, this->listeners->remove_at(this->listeners, enumerator); } +/** + * Implementation of bus_t.alert + */ +static void alert(private_bus_t *this, alert_t alert, ...) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + va_list args; + 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->alert) + { + continue; + } + entry->calling++; + va_start(args, alert); + keep = entry->listener->alert(entry->listener, ike_sa, alert, args); + va_end(args); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + /** * Implementation of bus_t.ike_state_change */ @@ -711,6 +746,7 @@ bus_t *bus_create() this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa; 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.alert = (void(*)(bus_t*, alert_t alert, ...))alert; 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; diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h index 67603bf21..04d33e554 100644 --- a/src/charon/bus/bus.h +++ b/src/charon/bus/bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ typedef enum debug_t debug_t; typedef enum level_t level_t; +typedef enum alert_t alert_t; typedef struct bus_t bus_t; #include @@ -126,6 +127,12 @@ enum level_t { # define DBG4(...) {} #endif /* DBG4 */ +/** + * Kind of alerts to raise. + */ +enum alert_t { +}; + /** * The bus receives events and sends them to all registered listeners. * @@ -206,6 +213,15 @@ struct bus_t { */ void (*vlog)(bus_t *this, debug_t group, level_t level, char* format, va_list args); + + /** + * Raise an alert over the bus. + * + * @param alert kind of alert + * @param ... alert specific attributes + */ + void (*alert)(bus_t *this, alert_t alert, ...); + /** * Send a IKE_SA state change event to the bus. * diff --git a/src/charon/bus/listeners/listener.h b/src/charon/bus/listeners/listener.h index 1cab0a26b..578f08ebe 100644 --- a/src/charon/bus/listeners/listener.h +++ b/src/charon/bus/listeners/listener.h @@ -38,7 +38,7 @@ struct listener_t { * Calling bus_t.log() inside of a registered listener is possible, * but the bus does not invoke listeners recursively. * - * @param singal kind of the signal (up, down, rekeyed, ...) + * @param group kind of the signal (up, down, rekeyed, ...) * @param level verbosity level of the signal * @param thread ID of the thread raised this signal * @param ike_sa IKE_SA associated to the event @@ -46,8 +46,19 @@ struct listener_t { * @param args vprintf() style va_list argument list " @return TRUE to stay registered, FALSE to unregister */ - bool (*log) (listener_t *this, debug_t group, level_t level, int thread, - ike_sa_t *ike_sa, char* format, va_list args); + bool (*log)(listener_t *this, debug_t group, level_t level, int thread, + ike_sa_t *ike_sa, char* format, va_list args); + + /** + * Hook called if a critical alert is risen. + * + * @param ike_sa IKE_SA associated to the alert, if any + * @param alert kind of alert + * @param ... alert specific argument list + " @return TRUE to stay registered, FALSE to unregister + */ + bool (*alert)(listener_t *this, ike_sa_t *ike_sa, + alert_t alert, va_list args); /** * Handle state changes in an IKE_SA.