Annotation of embedaddon/strongswan/src/libstrongswan/networking/streams/stream_manager.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Martin Willi
                      3:  * Copyright (C) 2013 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 "stream_manager.h"
                     17: 
                     18: #include "stream_tcp.h"
                     19: #include "stream_service_tcp.h"
                     20: #ifndef WIN32
                     21: # include "stream_unix.h"
                     22: # include "stream_service_unix.h"
                     23: #endif
                     24: #ifdef USE_SYSTEMD
                     25: # include "stream_service_systemd.h"
                     26: #endif
                     27: 
                     28: #include <threading/rwlock.h>
                     29: 
                     30: typedef struct private_stream_manager_t private_stream_manager_t;
                     31: 
                     32: /**
                     33:  * Private data of an stream_manager_t object.
                     34:  */
                     35: struct private_stream_manager_t {
                     36: 
                     37:        /**
                     38:         * Public stream_manager_t interface.
                     39:         */
                     40:        stream_manager_t public;
                     41: 
                     42:        /**
                     43:         * List of registered stream constructors, as stream_entry_t
                     44:         */
                     45:        linked_list_t *streams;
                     46: 
                     47:        /**
                     48:         * List of registered service constructors, as service_entry_t
                     49:         */
                     50:        linked_list_t *services;
                     51: 
                     52:        /**
                     53:         * Lock for all lists
                     54:         */
                     55:        rwlock_t *lock;
                     56: };
                     57: 
                     58: /**
                     59:  * Registered stream backend
                     60:  */
                     61: typedef struct {
                     62:        /** URI prefix */
                     63:        char *prefix;
                     64:        /** constructor function */
                     65:        stream_constructor_t create;
                     66: } stream_entry_t;
                     67: 
                     68: /**
                     69:  * Registered service backend
                     70:  */
                     71: typedef struct {
                     72:        /** URI prefix */
                     73:        char *prefix;
                     74:        /** constructor function */
                     75:        stream_service_constructor_t create;
                     76: } service_entry_t;
                     77: 
                     78: METHOD(stream_manager_t, connect_, stream_t*,
                     79:        private_stream_manager_t *this, char *uri)
                     80: {
                     81:        enumerator_t *enumerator;
                     82:        stream_entry_t *entry;
                     83:        stream_t *stream = NULL;
                     84: 
                     85:        this->lock->read_lock(this->lock);
                     86:        enumerator = this->streams->create_enumerator(this->streams);
                     87:        while (enumerator->enumerate(enumerator, &entry))
                     88:        {
                     89:                if (strpfx(uri, entry->prefix))
                     90:                {
                     91:                        stream = entry->create(uri);
                     92:                        if (stream)
                     93:                        {
                     94:                                break;
                     95:                        }
                     96:                }
                     97:        }
                     98:        enumerator->destroy(enumerator);
                     99:        this->lock->unlock(this->lock);
                    100: 
                    101:        return stream;
                    102: }
                    103: 
                    104: METHOD(stream_manager_t, create_service, stream_service_t*,
                    105:        private_stream_manager_t *this, char *uri, int backlog)
                    106: {
                    107:        enumerator_t *enumerator;
                    108:        service_entry_t *entry;
                    109:        stream_service_t *service = NULL;
                    110: 
                    111:        this->lock->read_lock(this->lock);
                    112:        enumerator = this->services->create_enumerator(this->services);
                    113:        while (enumerator->enumerate(enumerator, &entry))
                    114:        {
                    115:                if (strpfx(uri, entry->prefix))
                    116:                {
                    117:                        service = entry->create(uri, backlog);
                    118:                        if (service)
                    119:                        {
                    120:                                break;
                    121:                        }
                    122:                }
                    123:        }
                    124:        enumerator->destroy(enumerator);
                    125:        this->lock->unlock(this->lock);
                    126: 
                    127:        return service;
                    128: }
                    129: 
                    130: METHOD(stream_manager_t, add_stream, void,
                    131:        private_stream_manager_t *this, char *prefix, stream_constructor_t create)
                    132: {
                    133:        stream_entry_t *entry;
                    134: 
                    135:        INIT(entry,
                    136:                .prefix = strdup(prefix),
                    137:                .create = create,
                    138:        );
                    139: 
                    140:        this->lock->write_lock(this->lock);
                    141:        this->streams->insert_last(this->streams, entry);
                    142:        this->lock->unlock(this->lock);
                    143: }
                    144: 
                    145: METHOD(stream_manager_t, remove_stream, void,
                    146:        private_stream_manager_t *this, stream_constructor_t create)
                    147: {
                    148:        enumerator_t *enumerator;
                    149:        stream_entry_t *entry;
                    150: 
                    151:        this->lock->write_lock(this->lock);
                    152:        enumerator = this->streams->create_enumerator(this->streams);
                    153:        while (enumerator->enumerate(enumerator, &entry))
                    154:        {
                    155:                if (entry->create == create)
                    156:                {
                    157:                        this->streams->remove_at(this->streams, enumerator);
                    158:                        free(entry->prefix);
                    159:                        free(entry);
                    160:                }
                    161:        }
                    162:        enumerator->destroy(enumerator);
                    163:        this->lock->unlock(this->lock);
                    164: }
                    165: 
                    166: METHOD(stream_manager_t, add_service, void,
                    167:        private_stream_manager_t *this, char *prefix,
                    168:        stream_service_constructor_t create)
                    169: {
                    170:        service_entry_t *entry;
                    171: 
                    172:        INIT(entry,
                    173:                .prefix = strdup(prefix),
                    174:                .create = create,
                    175:        );
                    176: 
                    177:        this->lock->write_lock(this->lock);
                    178:        this->services->insert_last(this->services, entry);
                    179:        this->lock->unlock(this->lock);
                    180: }
                    181: 
                    182: METHOD(stream_manager_t, remove_service, void,
                    183:        private_stream_manager_t *this, stream_service_constructor_t create)
                    184: {
                    185:        enumerator_t *enumerator;
                    186:        service_entry_t *entry;
                    187: 
                    188:        this->lock->write_lock(this->lock);
                    189:        enumerator = this->services->create_enumerator(this->services);
                    190:        while (enumerator->enumerate(enumerator, &entry))
                    191:        {
                    192:                if (entry->create == create)
                    193:                {
                    194:                        this->services->remove_at(this->services, enumerator);
                    195:                        free(entry->prefix);
                    196:                        free(entry);
                    197:                }
                    198:        }
                    199:        enumerator->destroy(enumerator);
                    200:        this->lock->unlock(this->lock);
                    201: }
                    202: 
                    203: METHOD(stream_manager_t, destroy, void,
                    204:        private_stream_manager_t *this)
                    205: {
                    206:        remove_stream(this, stream_create_tcp);
                    207:        remove_service(this, stream_service_create_tcp);
                    208: #ifndef WIN32
                    209:        remove_stream(this, stream_create_unix);
                    210:        remove_service(this, stream_service_create_unix);
                    211: #endif
                    212: #ifdef USE_SYSTEMD
                    213:        remove_service(this, stream_service_create_systemd);
                    214: #endif
                    215: 
                    216:        this->streams->destroy(this->streams);
                    217:        this->services->destroy(this->services);
                    218:        this->lock->destroy(this->lock);
                    219:        free(this);
                    220: }
                    221: 
                    222: /**
                    223:  * See header
                    224:  */
                    225: stream_manager_t *stream_manager_create()
                    226: {
                    227:        private_stream_manager_t *this;
                    228: 
                    229:        INIT(this,
                    230:                .public = {
                    231:                        .connect = _connect_,
                    232:                        .create_service = _create_service,
                    233:                        .add_stream = _add_stream,
                    234:                        .remove_stream = _remove_stream,
                    235:                        .add_service = _add_service,
                    236:                        .remove_service = _remove_service,
                    237:                        .destroy = _destroy,
                    238:                },
                    239:                .streams = linked_list_create(),
                    240:                .services = linked_list_create(),
                    241:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                    242:        );
                    243: 
                    244:        add_stream(this, "tcp://", stream_create_tcp);
                    245:        add_service(this, "tcp://", stream_service_create_tcp);
                    246: #ifndef WIN32
                    247:        add_stream(this, "unix://", stream_create_unix);
                    248:        add_service(this, "unix://", stream_service_create_unix);
                    249: #endif
                    250: #ifdef USE_SYSTEMD
                    251:        add_service(this, "systemd://", stream_service_create_systemd);
                    252: #endif
                    253: 
                    254:        return &this->public;
                    255: }

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