Migrated stroke_attribute_t to METHOD/INIT macros.
[strongswan.git] / src / libcharon / plugins / stroke / stroke_attribute.c
1 /*
2 * Copyright (C) 2010 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "stroke_attribute.h"
18
19 #include <daemon.h>
20 #include <attributes/mem_pool.h>
21 #include <utils/linked_list.h>
22 #include <threading/mutex.h>
23
24 typedef struct private_stroke_attribute_t private_stroke_attribute_t;
25
26 /**
27 * private data of stroke_attribute
28 */
29 struct private_stroke_attribute_t {
30
31 /**
32 * public functions
33 */
34 stroke_attribute_t public;
35
36 /**
37 * list of pools, contains mem_pool_t
38 */
39 linked_list_t *pools;
40
41 /**
42 * mutex to lock access to pools
43 */
44 mutex_t *mutex;
45 };
46
47 /**
48 * find a pool by name
49 */
50 static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
51 {
52 enumerator_t *enumerator;
53 mem_pool_t *current, *found = NULL;
54
55 enumerator = this->pools->create_enumerator(this->pools);
56 while (enumerator->enumerate(enumerator, &current))
57 {
58 if (streq(name, current->get_name(current)))
59 {
60 found = current;
61 break;
62 }
63 }
64 enumerator->destroy(enumerator);
65 return found;
66 }
67
68 METHOD(attribute_provider_t, acquire_address, host_t*,
69 private_stroke_attribute_t *this, char *name, identification_t *id,
70 host_t *requested)
71 {
72 mem_pool_t *pool;
73 host_t *addr = NULL;
74 this->mutex->lock(this->mutex);
75 pool = find_pool(this, name);
76 if (pool)
77 {
78 addr = pool->acquire_address(pool, id, requested);
79 }
80 this->mutex->unlock(this->mutex);
81 return addr;
82 }
83
84 METHOD(attribute_provider_t, release_address, bool,
85 private_stroke_attribute_t *this, char *name, host_t *address,
86 identification_t *id)
87 {
88 mem_pool_t *pool;
89 bool found = FALSE;
90 this->mutex->lock(this->mutex);
91 pool = find_pool(this, name);
92 if (pool)
93 {
94 found = pool->release_address(pool, address, id);
95 }
96 this->mutex->unlock(this->mutex);
97 return found;
98 }
99
100 METHOD(stroke_attribute_t, add_pool, void,
101 private_stroke_attribute_t *this, stroke_msg_t *msg)
102 {
103 if (msg->add_conn.other.sourceip_mask)
104 {
105 mem_pool_t *pool;
106 host_t *base = NULL;
107 u_int32_t bits = 0;
108
109 /* if %config, add an empty pool, otherwise */
110 if (msg->add_conn.other.sourceip)
111 {
112 DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d",
113 msg->add_conn.name, msg->add_conn.other.sourceip,
114 msg->add_conn.other.sourceip_mask);
115 base = host_create_from_string(msg->add_conn.other.sourceip, 0);
116 if (!base)
117 {
118 DBG1(DBG_CFG, "virtual IP address invalid, discarded");
119 return;
120 }
121 bits = msg->add_conn.other.sourceip_mask;
122 }
123 pool = mem_pool_create(msg->add_conn.name, base, bits);
124 DESTROY_IF(base);
125
126 this->mutex->lock(this->mutex);
127 this->pools->insert_last(this->pools, pool);
128 this->mutex->unlock(this->mutex);
129 }
130 }
131
132 METHOD(stroke_attribute_t, del_pool, void,
133 private_stroke_attribute_t *this, stroke_msg_t *msg)
134 {
135 enumerator_t *enumerator;
136 mem_pool_t *pool;
137
138 this->mutex->lock(this->mutex);
139 enumerator = this->pools->create_enumerator(this->pools);
140 while (enumerator->enumerate(enumerator, &pool))
141 {
142 if (streq(msg->del_conn.name, pool->get_name(pool)))
143 {
144 this->pools->remove_at(this->pools, enumerator);
145 pool->destroy(pool);
146 break;
147 }
148 }
149 enumerator->destroy(enumerator);
150 this->mutex->unlock(this->mutex);
151 }
152
153 /**
154 * Pool enumerator filter function, converts pool_t to name, size, ...
155 */
156 static bool pool_filter(void *mutex, mem_pool_t **poolp, const char **name,
157 void *d1, u_int *size, void *d2, u_int *online,
158 void *d3, u_int *offline)
159 {
160 mem_pool_t *pool = *poolp;
161 *name = pool->get_name(pool);
162 *size = pool->get_size(pool);
163 *online = pool->get_online(pool);
164 *offline = pool->get_offline(pool);
165 return TRUE;
166 }
167
168 METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*,
169 private_stroke_attribute_t *this)
170 {
171 this->mutex->lock(this->mutex);
172 return enumerator_create_filter(this->pools->create_enumerator(this->pools),
173 (void*)pool_filter,
174 this->mutex, (void*)this->mutex->unlock);
175 }
176
177 METHOD(stroke_attribute_t, create_lease_enumerator, enumerator_t*,
178 private_stroke_attribute_t *this, char *name)
179 {
180 mem_pool_t *pool;
181 this->mutex->lock(this->mutex);
182 pool = find_pool(this, name);
183 if (!pool)
184 {
185 this->mutex->unlock(this->mutex);
186 return NULL;
187 }
188 return enumerator_create_cleaner(pool->create_lease_enumerator(pool),
189 (void*)this->mutex->unlock, this->mutex);
190 }
191
192 METHOD(stroke_attribute_t, destroy, void,
193 private_stroke_attribute_t *this)
194 {
195 this->mutex->destroy(this->mutex);
196 this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
197 free(this);
198 }
199
200 /*
201 * see header file
202 */
203 stroke_attribute_t *stroke_attribute_create()
204 {
205 private_stroke_attribute_t *this;
206
207 INIT(this,
208 .public = {
209 .provider = {
210 .acquire_address = _acquire_address,
211 .release_address = _release_address,
212 .create_attribute_enumerator = enumerator_create_empty,
213 },
214 .add_pool = _add_pool,
215 .del_pool = _del_pool,
216 .create_pool_enumerator = _create_pool_enumerator,
217 .create_lease_enumerator = _create_lease_enumerator,
218 .destroy = _destroy,
219 },
220 .pools = linked_list_create(),
221 .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
222 );
223
224 return &this->public;
225 }
226