Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_logger.c, revision 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>