Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_logger.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2014 Martin Willi
                      3:  * Copyright (C) 2014 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "vici_logger.h"
                     17: #include "vici_builder.h"
                     18: 
                     19: #include <daemon.h>
                     20: #include <threading/mutex.h>
                     21: #include <processing/jobs/callback_job.h>
                     22: 
                     23: typedef struct private_vici_logger_t private_vici_logger_t;
                     24: 
                     25: /**
                     26:  * Private data of an vici_logger_t object.
                     27:  */
                     28: struct private_vici_logger_t {
                     29: 
                     30:        /**
                     31:         * Public vici_logger_t interface.
                     32:         */
                     33:        vici_logger_t public;
                     34: 
                     35:        /**
                     36:         * Dispatcher
                     37:         */
                     38:        vici_dispatcher_t *dispatcher;
                     39: 
                     40:        /**
                     41:         * Recursiveness avoidance counter
                     42:         */
                     43:        int recursive;
                     44: 
                     45:        /**
                     46:         * List of messages to raise async events
                     47:         */
                     48:        linked_list_t *queue;
                     49: 
                     50:        /**
                     51:         * Mutex to synchronize logging
                     52:         */
                     53:        mutex_t *mutex;
                     54: };
                     55: 
                     56: /**
                     57:  * Async callback to raise events for queued messages
                     58:  */
                     59: static job_requeue_t raise_events(private_vici_logger_t *this)
                     60: {
                     61:        vici_message_t *message;
                     62:        u_int count;
                     63: 
                     64:        this->mutex->lock(this->mutex);
                     65:        count = this->queue->get_count(this->queue);
                     66:        this->queue->remove_first(this->queue, (void**)&message);
                     67:        this->mutex->unlock(this->mutex);
                     68: 
                     69:        if (count > 0)
                     70:        {
                     71:                this->dispatcher->raise_event(this->dispatcher, "log", 0, message);
                     72:        }
                     73:        if (count > 1)
                     74:        {
                     75:                return JOB_REQUEUE_DIRECT;
                     76:        }
                     77:        return JOB_REQUEUE_NONE;
                     78: }
                     79: 
                     80: /**
                     81:  * Queue a message for async processing
                     82:  */
                     83: static void queue_message(private_vici_logger_t *this, vici_message_t *message)
                     84: {
                     85:        this->queue->insert_last(this->queue, message);
                     86:        if (this->queue->get_count(this->queue) == 1)
                     87:        {
                     88:                lib->processor->queue_job(lib->processor, (job_t*)
                     89:                                        callback_job_create((callback_job_cb_t)raise_events,
                     90:                                                                                this, NULL, NULL));
                     91:        }
                     92: }
                     93: 
                     94: METHOD(logger_t, log_, void,
                     95:        private_vici_logger_t *this, debug_t group, level_t level, int thread,
                     96:        ike_sa_t* ike_sa, const char *msg)
                     97: {
                     98:        if (!this->dispatcher->has_event_listeners(this->dispatcher, "log"))
                     99:        {
                    100:                return;
                    101:        }
                    102: 
                    103:        this->mutex->lock(this->mutex);
                    104: 
                    105:        /* avoid recursive invocations by the vici subsystem */
                    106:        if (this->recursive++ == 0)
                    107:        {
                    108:                vici_message_t *message;
                    109:                vici_builder_t *builder;
                    110: 
                    111:                builder = vici_builder_create();
                    112:                builder->add_kv(builder, "group", "%N", debug_names, group);
                    113:                builder->add_kv(builder, "level", "%d", level);
                    114:                builder->add_kv(builder, "thread", "%d", thread);
                    115:                if (ike_sa)
                    116:                {
                    117:                        builder->add_kv(builder, "ikesa-name", "%s",
                    118:                                                        ike_sa->get_name(ike_sa));
                    119:                        builder->add_kv(builder, "ikesa-uniqueid", "%u",
                    120:                                                        ike_sa->get_unique_id(ike_sa));
                    121:                }
                    122:                builder->add_kv(builder, "msg", "%s", msg);
                    123: 
                    124:                message = builder->finalize(builder);
                    125:                if (message)
                    126:                {
                    127:                        queue_message(this, message);
                    128:                }
                    129:        }
                    130:        this->recursive--;
                    131: 
                    132:        this->mutex->unlock(this->mutex);
                    133: }
                    134: 
                    135: METHOD(logger_t, get_level, level_t,
                    136:        private_vici_logger_t *this, debug_t group)
                    137: {
                    138:        /* anything higher might produce a loop as sending messages or listening
                    139:         * for clients might cause log messages itself */
                    140:        return LEVEL_CTRL;
                    141: }
                    142: 
                    143: /**
                    144:  * (Un-)register dispatcher functions/events
                    145:  */
                    146: static void manage_commands(private_vici_logger_t *this, bool reg)
                    147: {
                    148:        this->dispatcher->manage_event(this->dispatcher, "log", reg);
                    149: }
                    150: 
                    151: METHOD(vici_logger_t, destroy, void,
                    152:        private_vici_logger_t *this)
                    153: {
                    154:        manage_commands(this, FALSE);
                    155:        this->queue->destroy_offset(this->queue, offsetof(vici_message_t, destroy));
                    156:        this->mutex->destroy(this->mutex);
                    157:        free(this);
                    158: }
                    159: 
                    160: /**
                    161:  * See header
                    162:  */
                    163: vici_logger_t *vici_logger_create(vici_dispatcher_t *dispatcher)
                    164: {
                    165:        private_vici_logger_t *this;
                    166: 
                    167:        INIT(this,
                    168:                .public = {
                    169:                        .logger = {
                    170:                                .log = _log_,
                    171:                                .get_level = _get_level,
                    172:                        },
                    173:                        .destroy = _destroy,
                    174:                },
                    175:                .dispatcher = dispatcher,
                    176:                .queue = linked_list_create(),
                    177:                .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
                    178:        );
                    179: 
                    180:        manage_commands(this, TRUE);
                    181: 
                    182:        return &this->public;
                    183: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>