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>