Return to stream_manager.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / networking / streams |
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: }