diff options
Diffstat (limited to 'src/libcharon/bus/bus.c')
-rw-r--r-- | src/libcharon/bus/bus.c | 102 |
1 files changed, 89 insertions, 13 deletions
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 0db5a8a9c..b46184809 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -53,6 +53,11 @@ struct private_bus_t { level_t max_level[DBG_MAX + 1]; /** + * Same as max level, but for loggers using the vlog() method. + */ + level_t max_vlevel[DBG_MAX + 1]; + + /** * Mutex for the list of listeners, recursively. */ mutex_t *mutex; @@ -166,7 +171,14 @@ static inline void register_logger(private_bus_t *this, debug_t group, loggers->insert_before(loggers, enumerator, entry); enumerator->destroy(enumerator); - this->max_level[group] = max(this->max_level[group], level); + if (entry->logger->log) + { + this->max_level[group] = max(this->max_level[group], level); + } + if (entry->logger->vlog) + { + this->max_vlevel[group] = max(this->max_vlevel[group], level); + } } /** @@ -194,6 +206,7 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger) if (found) { debug_t group; + for (group = 0; group < DBG_MAX; group++) { if (found->levels[group] > LEVEL_SILENT) @@ -202,9 +215,11 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger) loggers->remove(loggers, found, NULL); this->max_level[group] = LEVEL_SILENT; + this->max_vlevel[group] = LEVEL_SILENT; if (loggers->get_first(loggers, (void**)&entry) == SUCCESS) { this->max_level[group] = entry->levels[group]; + this->max_vlevel[group] = entry->levels[group]; } } } @@ -268,8 +283,10 @@ typedef struct { debug_t group; /** debug level */ level_t level; - /** message */ + /** message/fmt */ char *message; + /** argument list if message is a format string for vlog() */ + va_list args; } log_data_t; /** @@ -277,24 +294,41 @@ typedef struct { */ static void log_cb(log_entry_t *entry, log_data_t *data) { - if (entry->levels[data->group] < data->level) + if (entry->logger->log && entry->levels[data->group] >= data->level) + { + entry->logger->log(entry->logger, data->group, data->level, + data->thread, data->ike_sa, data->message); + } +} + +/** + * logger->vlog() invocation as a invoke_function callback + */ +static void vlog_cb(log_entry_t *entry, log_data_t *data) +{ + if (entry->logger->vlog && entry->levels[data->group] >= data->level) { - return; + va_list copy; + + va_copy(copy, data->args); + entry->logger->vlog(entry->logger, data->group, data->level, + data->thread, data->ike_sa, data->message, copy); + va_end(copy); } - entry->logger->log(entry->logger, data->group, data->level, - data->thread, data->ike_sa, data->message); } METHOD(bus_t, vlog, void, private_bus_t *this, debug_t group, level_t level, char* format, va_list args) { + linked_list_t *loggers; + log_data_t data; + this->log_lock->read_lock(this->log_lock); + loggers = this->loggers[group]; + if (this->max_level[group] >= level) { - linked_list_t *loggers = this->loggers[group]; - log_data_t data; - va_list copy; char buf[1024]; ssize_t len; @@ -304,9 +338,9 @@ METHOD(bus_t, vlog, void, data.level = level; data.message = buf; - va_copy(copy, args); - len = vsnprintf(data.message, sizeof(buf), format, copy); - va_end(copy); + va_copy(data.args, args); + len = vsnprintf(data.message, sizeof(buf), format, data.args); + va_end(data.args); if (len >= sizeof(buf)) { len++; @@ -323,6 +357,19 @@ METHOD(bus_t, vlog, void, free(data.message); } } + if (this->max_vlevel[group] >= level) + { + data.ike_sa = this->thread_sa->get(this->thread_sa); + data.thread = thread_current_id(); + data.group = group; + data.level = level; + data.message = format; + + va_copy(data.args, args); + loggers->invoke_function(loggers, (linked_list_invoke_t)vlog_cb, &data); + va_end(data.args); + } + this->log_lock->unlock(this->log_lock); } @@ -786,10 +833,37 @@ METHOD(bus_t, assign_vips, void, this->mutex->unlock(this->mutex); } +/** + * Credential manager hook function to forward bus alerts + */ +static void hook_creds(private_bus_t *this, credential_hook_type_t type, + certificate_t *cert) +{ + switch (type) + { + case CRED_HOOK_EXPIRED: + return alert(this, ALERT_CERT_EXPIRED, cert); + case CRED_HOOK_REVOKED: + return alert(this, ALERT_CERT_REVOKED, cert); + case CRED_HOOK_VALIDATION_FAILED: + return alert(this, ALERT_CERT_VALIDATION_FAILED, cert); + case CRED_HOOK_NO_ISSUER: + return alert(this, ALERT_CERT_NO_ISSUER, cert); + case CRED_HOOK_UNTRUSTED_ROOT: + return alert(this, ALERT_CERT_UNTRUSTED_ROOT, cert); + case CRED_HOOK_EXCEEDED_PATH_LEN: + return alert(this, ALERT_CERT_EXCEEDED_PATH_LEN, cert); + case CRED_HOOK_POLICY_VIOLATION: + return alert(this, ALERT_CERT_POLICY_VIOLATION, cert); + } +} + METHOD(bus_t, destroy, void, private_bus_t *this) { debug_t group; + + lib->credmgr->set_hook(lib->credmgr, NULL, NULL); for (group = 0; group < DBG_MAX; group++) { this->loggers[group]->destroy(this->loggers[group]); @@ -847,8 +921,10 @@ bus_t *bus_create() { this->loggers[group] = linked_list_create(); this->max_level[group] = LEVEL_SILENT; + this->max_vlevel[group] = LEVEL_SILENT; } + lib->credmgr->set_hook(lib->credmgr, (credential_hook_t)hook_creds, this); + return &this->public; } - |