2 * Copyright (C) 2010 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include "stroke_attribute.h"
20 #include <utils/linked_list.h>
21 #include <threading/rwlock.h>
23 typedef struct private_stroke_attribute_t private_stroke_attribute_t
;
26 * private data of stroke_attribute
28 struct private_stroke_attribute_t
{
33 stroke_attribute_t
public;
36 * list of pools, contains mem_pool_t
41 * List of connection specific attributes, as attributes_t
46 * rwlock to lock access to pools
52 * Attributes assigned to a connection
55 /** name of the connection */
57 /** list of DNS attributes, as host_t */
62 * Destroy an attributes_t entry
64 static void attributes_destroy(attributes_t
*this)
66 this->dns
->destroy_offset(this->dns
, offsetof(host_t
, destroy
));
74 static mem_pool_t
*find_pool(private_stroke_attribute_t
*this, char *name
)
76 enumerator_t
*enumerator
;
77 mem_pool_t
*current
, *found
= NULL
;
79 enumerator
= this->pools
->create_enumerator(this->pools
);
80 while (enumerator
->enumerate(enumerator
, ¤t
))
82 if (streq(name
, current
->get_name(current
)))
88 enumerator
->destroy(enumerator
);
92 METHOD(attribute_provider_t
, acquire_address
, host_t
*,
93 private_stroke_attribute_t
*this, linked_list_t
*pools
, identification_t
*id
,
96 enumerator_t
*enumerator
;
101 enumerator
= pools
->create_enumerator(pools
);
102 this->lock
->read_lock(this->lock
);
103 while (enumerator
->enumerate(enumerator
, &name
))
105 pool
= find_pool(this, name
);
108 addr
= pool
->acquire_address(pool
, id
, requested
);
115 this->lock
->unlock(this->lock
);
116 enumerator
->destroy(enumerator
);
121 METHOD(attribute_provider_t
, release_address
, bool,
122 private_stroke_attribute_t
*this, linked_list_t
*pools
, host_t
*address
,
123 identification_t
*id
)
125 enumerator_t
*enumerator
;
130 enumerator
= pools
->create_enumerator(pools
);
131 this->lock
->read_lock(this->lock
);
132 while (enumerator
->enumerate(enumerator
, &name
))
134 pool
= find_pool(this, name
);
137 found
= pool
->release_address(pool
, address
, id
);
144 this->lock
->unlock(this->lock
);
145 enumerator
->destroy(enumerator
);
151 * Filter function to convert host to DNS configuration attributes
153 static bool attr_filter(void *lock
, host_t
**in
,
154 configuration_attribute_type_t
*type
,
155 void *dummy
, chunk_t
*data
)
159 switch (host
->get_family(host
))
162 *type
= INTERNAL_IP4_DNS
;
165 *type
= INTERNAL_IP6_DNS
;
170 *data
= host
->get_address(host
);
174 METHOD(attribute_provider_t
, create_attribute_enumerator
, enumerator_t
*,
175 private_stroke_attribute_t
*this, linked_list_t
*pools
,
176 identification_t
*id
, linked_list_t
*vips
)
179 peer_cfg_t
*peer_cfg
;
180 enumerator_t
*enumerator
;
183 ike_sa
= charon
->bus
->get_sa(charon
->bus
);
186 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
187 this->lock
->read_lock(this->lock
);
188 enumerator
= this->attrs
->create_enumerator(this->attrs
);
189 while (enumerator
->enumerate(enumerator
, &attr
))
191 if (streq(attr
->name
, peer_cfg
->get_name(peer_cfg
)))
193 enumerator
->destroy(enumerator
);
194 return enumerator_create_filter(
195 attr
->dns
->create_enumerator(attr
->dns
),
196 (void*)attr_filter
, this->lock
,
197 (void*)this->lock
->unlock
);
200 enumerator
->destroy(enumerator
);
201 this->lock
->unlock(this->lock
);
203 return enumerator_create_empty();
206 METHOD(stroke_attribute_t
, add_pool
, void,
207 private_stroke_attribute_t
*this, mem_pool_t
*pool
)
209 enumerator_t
*enumerator
;
214 base
= pool
->get_base(pool
);
215 size
= pool
->get_size(pool
);
217 this->lock
->write_lock(this->lock
);
219 enumerator
= this->pools
->create_enumerator(this->pools
);
220 while (enumerator
->enumerate(enumerator
, ¤t
))
222 if (base
&& current
->get_base(current
) &&
223 base
->ip_equals(base
, current
->get_base(current
)) &&
224 size
== current
->get_size(current
))
226 DBG1(DBG_CFG
, "reusing virtual IP address pool %s",
227 current
->get_name(current
));
233 enumerator
->destroy(enumerator
);
239 DBG1(DBG_CFG
, "adding virtual IP address pool %s",
240 pool
->get_name(pool
));
242 this->pools
->insert_last(this->pools
, pool
);
245 this->lock
->unlock(this->lock
);
248 METHOD(stroke_attribute_t
, add_dns
, void,
249 private_stroke_attribute_t
*this, stroke_msg_t
*msg
)
251 if (msg
->add_conn
.other
.dns
)
253 enumerator_t
*enumerator
;
254 attributes_t
*attr
= NULL
;
258 enumerator
= enumerator_create_token(msg
->add_conn
.other
.dns
, ",", " ");
259 while (enumerator
->enumerate(enumerator
, &token
))
261 host
= host_create_from_string(token
, 0);
267 .name
= strdup(msg
->add_conn
.name
),
268 .dns
= linked_list_create(),
271 attr
->dns
->insert_last(attr
->dns
, host
);
275 DBG1(DBG_CFG
, "ignoring invalid DNS address '%s'", token
);
278 enumerator
->destroy(enumerator
);
281 this->lock
->write_lock(this->lock
);
282 this->attrs
->insert_last(this->attrs
, attr
);
283 this->lock
->unlock(this->lock
);
288 METHOD(stroke_attribute_t
, del_dns
, void,
289 private_stroke_attribute_t
*this, stroke_msg_t
*msg
)
291 enumerator_t
*enumerator
;
294 this->lock
->write_lock(this->lock
);
296 enumerator
= this->attrs
->create_enumerator(this->attrs
);
297 while (enumerator
->enumerate(enumerator
, &attr
))
299 if (streq(msg
->del_conn
.name
, attr
->name
))
301 this->attrs
->remove_at(this->attrs
, enumerator
);
302 attributes_destroy(attr
);
306 enumerator
->destroy(enumerator
);
308 this->lock
->unlock(this->lock
);
312 * Pool enumerator filter function, converts pool_t to name, size, ...
314 static bool pool_filter(void *lock
, mem_pool_t
**poolp
, const char **name
,
315 void *d1
, u_int
*size
, void *d2
, u_int
*online
,
316 void *d3
, u_int
*offline
)
318 mem_pool_t
*pool
= *poolp
;
320 if (pool
->get_size(pool
) == 0)
324 *name
= pool
->get_name(pool
);
325 *size
= pool
->get_size(pool
);
326 *online
= pool
->get_online(pool
);
327 *offline
= pool
->get_offline(pool
);
331 METHOD(stroke_attribute_t
, create_pool_enumerator
, enumerator_t
*,
332 private_stroke_attribute_t
*this)
334 this->lock
->read_lock(this->lock
);
335 return enumerator_create_filter(this->pools
->create_enumerator(this->pools
),
337 this->lock
, (void*)this->lock
->unlock
);
340 METHOD(stroke_attribute_t
, create_lease_enumerator
, enumerator_t
*,
341 private_stroke_attribute_t
*this, char *name
)
344 this->lock
->read_lock(this->lock
);
345 pool
= find_pool(this, name
);
348 this->lock
->unlock(this->lock
);
351 return enumerator_create_cleaner(pool
->create_lease_enumerator(pool
),
352 (void*)this->lock
->unlock
, this->lock
);
355 METHOD(stroke_attribute_t
, destroy
, void,
356 private_stroke_attribute_t
*this)
358 this->lock
->destroy(this->lock
);
359 this->pools
->destroy_offset(this->pools
, offsetof(mem_pool_t
, destroy
));
360 this->attrs
->destroy_function(this->attrs
, (void*)attributes_destroy
);
367 stroke_attribute_t
*stroke_attribute_create()
369 private_stroke_attribute_t
*this;
374 .acquire_address
= _acquire_address
,
375 .release_address
= _release_address
,
376 .create_attribute_enumerator
= _create_attribute_enumerator
,
378 .add_pool
= _add_pool
,
381 .create_pool_enumerator
= _create_pool_enumerator
,
382 .create_lease_enumerator
= _create_lease_enumerator
,
385 .pools
= linked_list_create(),
386 .attrs
= linked_list_create(),
387 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
390 return &this->public;