Annotation of embedaddon/strongswan/src/libstrongswan/networking/streams/stream_manager.c, revision 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>