Annotation of embedaddon/strongswan/src/libcharon/plugins/duplicheck/duplicheck_notify.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011 Martin Willi
                      3:  * Copyright (C) 2011 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 "duplicheck_notify.h"
                     17: #include "duplicheck_msg.h"
                     18: 
                     19: #include <sys/types.h>
                     20: #include <sys/stat.h>
                     21: #include <sys/socket.h>
                     22: #include <sys/un.h>
                     23: #include <unistd.h>
                     24: #include <errno.h>
                     25: 
                     26: #include <daemon.h>
                     27: #include <threading/mutex.h>
                     28: #include <threading/thread.h>
                     29: #include <collections/linked_list.h>
                     30: #include <processing/jobs/callback_job.h>
                     31: 
                     32: 
                     33: typedef struct private_duplicheck_notify_t private_duplicheck_notify_t;
                     34: 
                     35: /**
                     36:  * Private data of an duplicheck_notify_t object.
                     37:  */
                     38: struct private_duplicheck_notify_t {
                     39: 
                     40:        /**
                     41:         * Public duplicheck_notify_t interface.
                     42:         */
                     43:        duplicheck_notify_t public;
                     44: 
                     45:        /**
                     46:         * Mutex to lock list
                     47:         */
                     48:        mutex_t *mutex;
                     49: 
                     50:        /**
                     51:         * List of connected clients, as stream_t
                     52:         */
                     53:        linked_list_t *connected;
                     54: 
                     55:        /**
                     56:         * stream service accepting connections
                     57:         */
                     58:        stream_service_t *service;
                     59: };
                     60: 
                     61: /**
                     62:  * Accept duplicheck notification connections
                     63:  */
                     64: static bool on_accept(private_duplicheck_notify_t *this, stream_t *stream)
                     65: {
                     66:        this->mutex->lock(this->mutex);
                     67:        this->connected->insert_last(this->connected, stream);
                     68:        this->mutex->unlock(this->mutex);
                     69: 
                     70:        return TRUE;
                     71: }
                     72: 
                     73: METHOD(duplicheck_notify_t, send_, void,
                     74:        private_duplicheck_notify_t *this, identification_t *id)
                     75: {
                     76:        enumerator_t *enumerator;
                     77:        stream_t *stream;
                     78:        uint16_t nlen;
                     79:        char buf[512];
                     80:        int len;
                     81: 
                     82:        len = snprintf(buf, sizeof(buf), "%Y", id);
                     83:        if (len > 0 && len < sizeof(buf))
                     84:        {
                     85:                nlen = htons(len);
                     86: 
                     87:                this->mutex->lock(this->mutex);
                     88:                enumerator = this->connected->create_enumerator(this->connected);
                     89:                while (enumerator->enumerate(enumerator, &stream))
                     90:                {
                     91:                        if (!stream->write_all(stream, &nlen, sizeof(nlen)) ||
                     92:                                !stream->write_all(stream, buf, len))
                     93:                        {
                     94:                                DBG1(DBG_CFG, "sending duplicheck notify failed: %s",
                     95:                                         strerror(errno));
                     96:                                this->connected->remove_at(this->connected, enumerator);
                     97:                                stream->destroy(stream);
                     98:                        }
                     99:                }
                    100:                enumerator->destroy(enumerator);
                    101:                this->mutex->unlock(this->mutex);
                    102:        }
                    103: }
                    104: 
                    105: METHOD(duplicheck_notify_t, destroy, void,
                    106:        private_duplicheck_notify_t *this)
                    107: {
                    108:        DESTROY_IF(this->service);
                    109:        this->connected->destroy_offset(this->connected, offsetof(stream_t, destroy));
                    110:        this->mutex->destroy(this->mutex);
                    111:        free(this);
                    112: }
                    113: 
                    114: /**
                    115:  * See header
                    116:  */
                    117: duplicheck_notify_t *duplicheck_notify_create()
                    118: {
                    119:        private_duplicheck_notify_t *this;
                    120:        char *uri;
                    121: 
                    122:        INIT(this,
                    123:                .public = {
                    124:                        .send = _send_,
                    125:                        .destroy = _destroy,
                    126:                },
                    127:                .connected = linked_list_create(),
                    128:                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                    129:        );
                    130: 
                    131:        uri = lib->settings->get_str(lib->settings,
                    132:                                        "%s.plugins.duplicheck.socket", "unix://" DUPLICHECK_SOCKET,
                    133:                                        lib->ns);
                    134:        this->service = lib->streams->create_service(lib->streams, uri, 3);
                    135:        if (!this->service)
                    136:        {
                    137:                DBG1(DBG_CFG, "creating duplicheck socket failed");
                    138:                destroy(this);
                    139:                return NULL;
                    140:        }
                    141:        this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
                    142:                                                         this, JOB_PRIO_CRITICAL, 1);
                    143: 
                    144:        return &this->public;
                    145: }

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